diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 27b829148d..712f7aa71c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -92,11 +92,11 @@ implementation](https://github.com/googleapis/genai-toolbox/blob/main/internal/s `newdb.go`. Create a `Config` struct to include all the necessary parameters for connecting to the database (e.g., host, port, username, password, database name) and a `Source` struct to store necessary parameters for tools (e.g., - Name, Kind, connection object, additional config). + Name, Type, connection object, additional config). * **Implement the [`SourceConfig`](https://github.com/googleapis/genai-toolbox/blob/fd300dc606d88bf9f7bba689e2cee4e3565537dd/internal/sources/sources.go#L57) interface**. This interface requires two methods: - * `SourceConfigKind() string`: Returns a unique string identifier for your + * `SourceConfigType() string`: Returns a unique string identifier for your data source (e.g., `"newdb"`). * `Initialize(ctx context.Context, tracer trace.Tracer) (Source, error)`: Creates a new instance of your data source and establishes a connection to @@ -104,7 +104,7 @@ implementation](https://github.com/googleapis/genai-toolbox/blob/main/internal/s * **Implement the [`Source`](https://github.com/googleapis/genai-toolbox/blob/fd300dc606d88bf9f7bba689e2cee4e3565537dd/internal/sources/sources.go#L63) interface**. This interface requires one method: - * `SourceKind() string`: Returns the same string identifier as `SourceConfigKind()`. + * `SourceType() string`: Returns the same string identifier as `SourceConfigType()`. * **Implement `init()`** to register the new Source. * **Implement Unit Tests** in a file named `newdb_test.go`. @@ -126,7 +126,7 @@ tools. * **Implement the [`ToolConfig`](https://github.com/googleapis/genai-toolbox/blob/fd300dc606d88bf9f7bba689e2cee4e3565537dd/internal/tools/tools.go#L61) interface**. This interface requires one method: - * `ToolConfigKind() string`: Returns a unique string identifier for your tool + * `ToolConfigType() string`: Returns a unique string identifier for your tool (e.g., `"newdb-tool"`). * `Initialize(sources map[string]Source) (Tool, error)`: Creates a new instance of your tool and validates that it can connect to the specified @@ -243,7 +243,7 @@ resources. | style | Update src code, with only formatting and whitespace updates (e.g. code formatter or linter changes). | Pull requests should always add scope whenever possible. The scope is - formatted as `/` (e.g., `sources/postgres`, or + formatted as `/` (e.g., `sources/postgres`, or `tools/mssql-sql`). Ideally, **each PR covers only one scope**, if this is diff --git a/DEVELOPER.md b/DEVELOPER.md index ce9f827070..9836d6c9be 100644 --- a/DEVELOPER.md +++ b/DEVELOPER.md @@ -47,12 +47,13 @@ Before you begin, ensure you have the following: ### Tool Naming Conventions This section details the purpose and conventions for MCP Toolbox's tools naming -properties, **tool name** and **tool kind**. +properties, **tool name** and **tool type**. ``` -cancel_hotel: <- tool name - kind: postgres-sql <- tool kind - source: my_pg_source +kind: tools +name: cancel_hotel <- tool name +type: postgres-sql <- tool type +source: my_pg_source ``` #### Tool Name @@ -76,17 +77,17 @@ The following guidelines apply to tool names: to a function) until they can be validated through extensive testing to ensure they do not negatively impact agent's performances. -#### Tool Kind +#### Tool Type -Tool kind serves as a category or type that a user can assign to a tool. +Tool type serves as a category or type that a user can assign to a tool. -The following guidelines apply to tool kinds: +The following guidelines apply to tool types: -* Should user hyphens over underscores (e.g. `firestore-list-collections` or +* Should use hyphens over underscores (e.g. `firestore-list-collections` or `firestore_list_colelctions`). * Should use product name in name (e.g. `firestore-list-collections` over `list-collections`). -* Changes to tool kind are breaking changes and should be avoided. +* Changes to tool type are breaking changes and should be avoided. ## Testing diff --git a/README.md b/README.md index 7cf3ca9267..f0443e4a80 100644 --- a/README.md +++ b/README.md @@ -940,14 +940,14 @@ Toolbox should have access to. Most tools will have at least one source to execute against. ```yaml -sources: - my-pg-source: - kind: postgres - host: 127.0.0.1 - port: 5432 - database: toolbox_db - user: toolbox_user - password: my-password +kind: sources +name: my-pg-source +type: postgres +host: 127.0.0.1 +port: 5432 +database: toolbox_db +user: toolbox_user +password: my-password ``` For more details on configuring different types of sources, see the @@ -956,19 +956,19 @@ For more details on configuring different types of sources, see the ### Tools The `tools` section of a `tools.yaml` define the actions an agent can take: what -kind of tool it is, which source(s) it affects, what parameters it uses, etc. +type of tool it is, which source(s) it affects, what parameters it uses, etc. ```yaml -tools: - search-hotels-by-name: - kind: postgres-sql - source: my-pg-source - description: Search for hotels based on name. - parameters: - - name: name - type: string - description: The name of the hotel. - statement: SELECT * FROM hotels WHERE name ILIKE '%' || $1 || '%'; +kind: tools +name: search-hotels-by-name +type: postgres-sql +source: my-pg-source +description: Search for hotels based on name. +parameters: + - name: name + type: string + description: The name of the hotel. +statement: SELECT * FROM hotels WHERE name ILIKE '%' || $1 || '%'; ``` For more details on configuring different types of tools, see the diff --git a/cmd/root.go b/cmd/root.go index dfac1c250f..ce32662cea 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -15,6 +15,7 @@ package cmd import ( + "bytes" "context" _ "embed" "fmt" @@ -396,7 +397,6 @@ func NewCommand(opts ...Option) *Command { type ToolsFile struct { Sources server.SourceConfigs `yaml:"sources"` - AuthSources server.AuthServiceConfigs `yaml:"authSources"` // Deprecated: Kept for compatibility. AuthServices server.AuthServiceConfigs `yaml:"authServices"` EmbeddingModels server.EmbeddingModelConfigs `yaml:"embeddingModels"` Tools server.ToolConfigs `yaml:"tools"` @@ -427,6 +427,129 @@ func parseEnv(input string) (string, error) { return output, err } +func convertToolsFile(raw []byte) ([]byte, error) { + var input yaml.MapSlice + decoder := yaml.NewDecoder(bytes.NewReader(raw), yaml.UseOrderedMap()) + + // convert to tools file v2 + var buf bytes.Buffer + encoder := yaml.NewEncoder(&buf) + + v1keys := []string{"sources", "authSources", "authServices", "embeddingModels", "tools", "toolsets", "prompts"} + for { + if err := decoder.Decode(&input); err != nil { + if err == io.EOF { + break + } + return nil, err + } + for _, item := range input { + key, ok := item.Key.(string) + if !ok { + return nil, fmt.Errorf("unexpected non-string key in input: %v", item.Key) + } + // check if the key is config file v1's key + if slices.Contains(v1keys, key) { + // check if value conversion to yaml.MapSlice successfully + // fields such as "tools" in toolsets might pass the first check but + // fail to convert to MapSlice + if slice, ok := item.Value.(yaml.MapSlice); ok { + // Deprecated: convert authSources to authServices + if key == "authSources" { + key = "authServices" + } + transformed, err := transformDocs(key, slice) + if err != nil { + return nil, err + } + // encode per-doc + for _, doc := range transformed { + if err := encoder.Encode(doc); err != nil { + return nil, err + } + } + } else { + // invalid input will be ignored + // we don't want to throw error here since the config could + // be valid but with a different order such as: + // --- + // tools: + // - tool_a + // kind: toolsets + // --- + continue + } + } else { + // this doc is already v2, encode to buf + if err := encoder.Encode(input); err != nil { + return nil, err + } + break + } + } + } + return buf.Bytes(), nil +} + +// transformDocs transforms the configuration file from v1 format to v2 +// yaml.MapSlice will preserve the order in a map +func transformDocs(kind string, input yaml.MapSlice) ([]yaml.MapSlice, error) { + var transformed []yaml.MapSlice + for _, entry := range input { + entryName, ok := entry.Key.(string) + if !ok { + return nil, fmt.Errorf("unexpected non-string key for entry in '%s': %v", kind, entry.Key) + } + entryBody := ProcessValue(entry.Value, kind == "toolsets") + + currentTransformed := yaml.MapSlice{ + {Key: "kind", Value: kind}, + {Key: "name", Value: entryName}, + } + + // Merge the transformed body into our result + if bodySlice, ok := entryBody.(yaml.MapSlice); ok { + currentTransformed = append(currentTransformed, bodySlice...) + } else { + return nil, fmt.Errorf("unable to convert entryBody to MapSlice") + } + transformed = append(transformed, currentTransformed) + } + return transformed, nil +} + +// ProcessValue recursively looks for MapSlices to rename 'kind' -> 'type' +func ProcessValue(v any, isToolset bool) any { + switch val := v.(type) { + case yaml.MapSlice: + // creating a new MapSlice is safer for recursive transformation + newVal := make(yaml.MapSlice, len(val)) + for i, item := range val { + // Perform renaming + if item.Key == "kind" { + item.Key = "type" + } + // Recursive call for nested values (e.g., nested objects or lists) + item.Value = ProcessValue(item.Value, false) + newVal[i] = item + } + return newVal + case []any: + // Process lists: If it's a toolset top-level list, wrap it. + if isToolset { + return yaml.MapSlice{{Key: "tools", Value: val}} + } + // Otherwise, recurse into list items (to catch nested objects) + newVal := make([]any, len(val)) + for i := range val { + newVal[i] = ProcessValue(val[i], false) + } + return newVal + default: + return val + } +} + // parseToolsFile parses the provided yaml into appropriate configs. func parseToolsFile(ctx context.Context, raw []byte) (ToolsFile, error) { var toolsFile ToolsFile @@ -437,8 +560,13 @@ func parseToolsFile(ctx context.Context, raw []byte) (ToolsFile, error) { } raw = []byte(output) + raw, err = convertToolsFile(raw) + if err != nil { + return toolsFile, fmt.Errorf("error converting tools file: %s", err) + } + // Parse contents - err = yaml.UnmarshalContext(ctx, raw, &toolsFile, yaml.Strict()) + toolsFile.Sources, toolsFile.AuthServices, toolsFile.EmbeddingModels, toolsFile.Tools, toolsFile.Toolsets, toolsFile.Prompts, err = server.UnmarshalResourceConfig(ctx, raw) if err != nil { return toolsFile, err } @@ -470,18 +598,6 @@ func mergeToolsFiles(files ...ToolsFile) (ToolsFile, error) { } } - // Check for conflicts and merge authSources (deprecated, but still support) - for name, authSource := range file.AuthSources { - if _, exists := merged.AuthSources[name]; exists { - conflicts = append(conflicts, fmt.Sprintf("authSource '%s' (file #%d)", name, fileIndex+1)) - } else { - if merged.AuthSources == nil { - merged.AuthSources = make(server.AuthServiceConfigs) - } - merged.AuthSources[name] = authSource - } - } - // Check for conflicts and merge authServices for name, authService := range file.AuthServices { if _, exists := merged.AuthServices[name]; exists { @@ -965,20 +1081,6 @@ func run(cmd *Command) error { cmd.cfg.ToolsetConfigs = finalToolsFile.Toolsets cmd.cfg.PromptConfigs = finalToolsFile.Prompts - authSourceConfigs := finalToolsFile.AuthSources - if authSourceConfigs != nil { - cmd.logger.WarnContext(ctx, "`authSources` is deprecated, use `authServices` instead") - - for k, v := range authSourceConfigs { - if _, exists := cmd.cfg.AuthServiceConfigs[k]; exists { - errMsg := fmt.Errorf("resource conflict detected: authSource '%s' has the same name as an existing authService. Please rename your authSource", k) - cmd.logger.ErrorContext(ctx, errMsg.Error()) - return errMsg - } - cmd.cfg.AuthServiceConfigs[k] = v - } - } - instrumentation, err := telemetry.CreateTelemetryInstrumentation(versionString) if err != nil { errMsg := fmt.Errorf("unable to create telemetry instrumentation: %w", err) diff --git a/cmd/root_test.go b/cmd/root_test.go index 17058d18ff..c69399a800 100644 --- a/cmd/root_test.go +++ b/cmd/root_test.go @@ -514,6 +514,437 @@ func TestDefaultLogLevel(t *testing.T) { } } +func TestConvertToolsFile(t *testing.T) { + tcs := []struct { + desc string + in string + want string + isErr bool + errStr string + }{ + { + desc: "basic convert", + in: ` + sources: + my-pg-instance: + kind: cloud-sql-postgres + project: my-project + region: my-region + instance: my-instance + database: my_db + user: my_user + password: my_pass + authServices: + my-google-auth: + kind: google + clientId: testing-id + tools: + example_tool: + kind: postgres-sql + source: my-pg-instance + description: some description + statement: SELECT * FROM SQL_STATEMENT; + parameters: + - name: country + type: string + description: some description + toolsets: + example_toolset: + - example_tool + prompts: + code_review: + description: ask llm to analyze code quality + messages: + - content: "please review the following code for quality: {{.code}}" + arguments: + - name: code + description: the code to review + embeddingModels: + gemini-model: + kind: gemini + model: gemini-embedding-001 + apiKey: some-key + dimension: 768`, + want: `kind: sources +name: my-pg-instance +type: cloud-sql-postgres +project: my-project +region: my-region +instance: my-instance +database: my_db +user: my_user +password: my_pass +--- +kind: authServices +name: my-google-auth +type: google +clientId: testing-id +--- +kind: tools +name: example_tool +type: postgres-sql +source: my-pg-instance +description: some description +statement: SELECT * FROM SQL_STATEMENT; +parameters: +- name: country + type: string + description: some description +--- +kind: toolsets +name: example_toolset +tools: +- example_tool +--- +kind: prompts +name: code_review +description: ask llm to analyze code quality +messages: +- content: "please review the following code for quality: {{.code}}" +arguments: +- name: code + description: the code to review +--- +kind: embeddingModels +name: gemini-model +type: gemini +model: gemini-embedding-001 +apiKey: some-key +dimension: 768 +`, + }, + { + desc: "preserve resource order", + in: ` + tools: + example_tool: + kind: postgres-sql + source: my-pg-instance + description: some description + statement: SELECT * FROM SQL_STATEMENT; + parameters: + - name: country + type: string + description: some description + sources: + my-pg-instance: + kind: cloud-sql-postgres + project: my-project + region: my-region + instance: my-instance + database: my_db + user: my_user + password: my_pass + authServices: + my-google-auth: + kind: google + clientId: testing-id + toolsets: + example_toolset: + - example_tool + authSources: + my-google-auth2: + kind: google + clientId: testing-id`, + want: `kind: tools +name: example_tool +type: postgres-sql +source: my-pg-instance +description: some description +statement: SELECT * FROM SQL_STATEMENT; +parameters: +- name: country + type: string + description: some description +--- +kind: sources +name: my-pg-instance +type: cloud-sql-postgres +project: my-project +region: my-region +instance: my-instance +database: my_db +user: my_user +password: my_pass +--- +kind: authServices +name: my-google-auth +type: google +clientId: testing-id +--- +kind: toolsets +name: example_toolset +tools: +- example_tool +--- +kind: authServices +name: my-google-auth2 +type: google +clientId: testing-id +`, + }, + { + desc: "convert combination of v1 and v2", + in: ` + sources: + my-pg-instance: + kind: cloud-sql-postgres + project: my-project + region: my-region + instance: my-instance + database: my_db + user: my_user + password: my_pass + authServices: + my-google-auth: + kind: google + clientId: testing-id + tools: + example_tool: + kind: postgres-sql + source: my-pg-instance + description: some description + statement: SELECT * FROM SQL_STATEMENT; + parameters: + - name: country + type: string + description: some description + toolsets: + example_toolset: + - example_tool + prompts: + code_review: + description: ask llm to analyze code quality + messages: + - content: "please review the following code for quality: {{.code}}" + arguments: + - name: code + description: the code to review + embeddingModels: + gemini-model: + kind: gemini + model: gemini-embedding-001 + apiKey: some-key + dimension: 768 +--- + kind: sources + name: my-pg-instance2 + type: cloud-sql-postgres + project: my-project + region: my-region + instance: my-instance +--- + kind: authServices + name: my-google-auth2 + type: google + clientId: testing-id +--- + kind: tools + name: example_tool2 + type: postgres-sql + source: my-pg-instance + description: some description + statement: SELECT * FROM SQL_STATEMENT; + parameters: + - name: country + type: string + description: some description +--- + kind: toolsets + name: example_toolset2 + tools: + - example_tool +--- + tools: + - example_tool + kind: toolsets + name: example_toolset3 +--- + kind: prompts + name: code_review2 + description: ask llm to analyze code quality + messages: + - content: "please review the following code for quality: {{.code}}" + arguments: + - name: code + description: the code to review +--- + kind: embeddingModels + name: gemini-model2 + type: gemini`, + want: `kind: sources +name: my-pg-instance +type: cloud-sql-postgres +project: my-project +region: my-region +instance: my-instance +database: my_db +user: my_user +password: my_pass +--- +kind: authServices +name: my-google-auth +type: google +clientId: testing-id +--- +kind: tools +name: example_tool +type: postgres-sql +source: my-pg-instance +description: some description +statement: SELECT * FROM SQL_STATEMENT; +parameters: +- name: country + type: string + description: some description +--- +kind: toolsets +name: example_toolset +tools: +- example_tool +--- +kind: prompts +name: code_review +description: ask llm to analyze code quality +messages: +- content: "please review the following code for quality: {{.code}}" +arguments: +- name: code + description: the code to review +--- +kind: embeddingModels +name: gemini-model +type: gemini +model: gemini-embedding-001 +apiKey: some-key +dimension: 768 +--- +kind: sources +name: my-pg-instance2 +type: cloud-sql-postgres +project: my-project +region: my-region +instance: my-instance +--- +kind: authServices +name: my-google-auth2 +type: google +clientId: testing-id +--- +kind: tools +name: example_tool2 +type: postgres-sql +source: my-pg-instance +description: some description +statement: SELECT * FROM SQL_STATEMENT; +parameters: +- name: country + type: string + description: some description +--- +kind: toolsets +name: example_toolset2 +tools: +- example_tool +--- +tools: +- example_tool +kind: toolsets +name: example_toolset3 +--- +kind: prompts +name: code_review2 +description: ask llm to analyze code quality +messages: +- content: "please review the following code for quality: {{.code}}" +arguments: +- name: code + description: the code to review +--- +kind: embeddingModels +name: gemini-model2 +type: gemini +`, + }, + { + desc: "no convertion needed", + in: `kind: sources +name: my-pg-instance +type: cloud-sql-postgres +project: my-project +region: my-region +instance: my-instance +database: my_db +user: my_user +password: my_pass +--- +kind: tools +name: example_tool +type: postgres-sql +source: my-pg-instance +description: some description +statement: SELECT * FROM SQL_STATEMENT; +parameters: +- name: country + type: string + description: some description +--- +kind: toolsets +name: example_toolset +tools: +- example_tool`, + want: `kind: sources +name: my-pg-instance +type: cloud-sql-postgres +project: my-project +region: my-region +instance: my-instance +database: my_db +user: my_user +password: my_pass +--- +kind: tools +name: example_tool +type: postgres-sql +source: my-pg-instance +description: some description +statement: SELECT * FROM SQL_STATEMENT; +parameters: +- name: country + type: string + description: some description +--- +kind: toolsets +name: example_toolset +tools: +- example_tool +`, + }, + { + desc: "invalid source", + in: `sources: invalid`, + want: "", + }, + { + desc: "invalid toolset", + in: `toolsets: invalid`, + want: "", + }, + } + for _, tc := range tcs { + t.Run(tc.desc, func(t *testing.T) { + output, err := convertToolsFile([]byte(tc.in)) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + + if diff := cmp.Diff(string(output), tc.want); diff != "" { + t.Fatalf("incorrect toolsets parse: diff %v", diff) + } + }) + } +} + func TestParseToolFile(t *testing.T) { ctx, err := testutils.ContextWithNewLogger() if err != nil { @@ -525,7 +956,7 @@ func TestParseToolFile(t *testing.T) { wantToolsFile ToolsFile }{ { - description: "basic example", + description: "basic example tools file v1", in: ` sources: my-pg-instance: @@ -555,7 +986,7 @@ func TestParseToolFile(t *testing.T) { Sources: server.SourceConfigs{ "my-pg-instance": cloudsqlpgsrc.Config{ Name: "my-pg-instance", - Kind: cloudsqlpgsrc.SourceKind, + Type: cloudsqlpgsrc.SourceType, Project: "my-project", Region: "my-region", Instance: "my-instance", @@ -568,7 +999,7 @@ func TestParseToolFile(t *testing.T) { Tools: server.ToolConfigs{ "example_tool": postgressql.Config{ Name: "example_tool", - Kind: "postgres-sql", + Type: "postgres-sql", Source: "my-pg-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -584,20 +1015,135 @@ func TestParseToolFile(t *testing.T) { ToolNames: []string{"example_tool"}, }, }, - Prompts: nil, + AuthServices: nil, + Prompts: nil, }, }, { - description: "with prompts example", + description: "basic example tools file v2", in: ` - prompts: - my-prompt: - description: A prompt template for data analysis. - arguments: - - name: country - description: The country to analyze. - messages: - - content: Analyze the data for {{.country}}. + kind: sources + name: my-pg-instance + type: cloud-sql-postgres + project: my-project + region: my-region + instance: my-instance + database: my_db + user: my_user + password: my_pass +--- + kind: authServices + name: my-google-auth + type: google + clientId: testing-id +--- + kind: embeddingModels + name: gemini-model + type: gemini + model: gemini-embedding-001 + apiKey: some-key + dimension: 768 +--- + kind: tools + name: example_tool + type: postgres-sql + source: my-pg-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + parameters: + - name: country + type: string + description: some description +--- + kind: toolsets + name: example_toolset + tools: + - example_tool +--- + kind: prompts + name: code_review + description: ask llm to analyze code quality + messages: + - content: "please review the following code for quality: {{.code}}" + arguments: + - name: code + description: the code to review + `, + wantToolsFile: ToolsFile{ + Sources: server.SourceConfigs{ + "my-pg-instance": cloudsqlpgsrc.Config{ + Name: "my-pg-instance", + Type: cloudsqlpgsrc.SourceType, + Project: "my-project", + Region: "my-region", + Instance: "my-instance", + IPType: "public", + Database: "my_db", + User: "my_user", + Password: "my_pass", + }, + }, + AuthServices: server.AuthServiceConfigs{ + "my-google-auth": google.Config{ + Name: "my-google-auth", + Type: google.AuthServiceType, + ClientID: "testing-id", + }, + }, + EmbeddingModels: server.EmbeddingModelConfigs{ + "gemini-model": gemini.Config{ + Name: "gemini-model", + Type: gemini.EmbeddingModelType, + Model: "gemini-embedding-001", + ApiKey: "some-key", + Dimension: 768, + }, + }, + Tools: server.ToolConfigs{ + "example_tool": postgressql.Config{ + Name: "example_tool", + Type: "postgres-sql", + Source: "my-pg-instance", + Description: "some description", + Statement: "SELECT * FROM SQL_STATEMENT;\n", + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("country", "some description"), + }, + AuthRequired: []string{}, + }, + }, + Toolsets: server.ToolsetConfigs{ + "example_toolset": tools.ToolsetConfig{ + Name: "example_toolset", + ToolNames: []string{"example_tool"}, + }, + }, + Prompts: server.PromptConfigs{ + "code_review": &custom.Config{ + Name: "code_review", + Description: "ask llm to analyze code quality", + Arguments: prompts.Arguments{ + {Parameter: parameters.NewStringParameter("code", "the code to review")}, + }, + Messages: []prompts.Message{ + {Role: "user", Content: "please review the following code for quality: {{.code}}"}, + }, + }, + }, + }, + }, + { + description: "only prompts", + in: ` + kind: prompts + name: my-prompt + description: A prompt template for data analysis. + arguments: + - name: country + description: The country to analyze. + messages: + - content: Analyze the data for {{.country}}. `, wantToolsFile: ToolsFile{ Sources: nil, @@ -658,58 +1204,62 @@ func TestParseToolFileWithAuth(t *testing.T) { { description: "basic example", in: ` - sources: - my-pg-instance: - kind: cloud-sql-postgres - project: my-project - region: my-region - instance: my-instance - database: my_db - user: my_user - password: my_pass - authServices: - my-google-service: - kind: google - clientId: my-client-id - other-google-service: - kind: google - clientId: other-client-id - - tools: - example_tool: - kind: postgres-sql - source: my-pg-instance + kind: sources + name: my-pg-instance + type: cloud-sql-postgres + project: my-project + region: my-region + instance: my-instance + database: my_db + user: my_user + password: my_pass +--- + kind: authServices + name: my-google-service + type: google + clientId: my-client-id +--- + kind: authServices + name: other-google-service + type: google + clientId: other-client-id +--- + kind: tools + name: example_tool + type: postgres-sql + source: my-pg-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + parameters: + - name: country + type: string description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - parameters: - - name: country - type: string - description: some description - - name: id - type: integer - description: user id - authServices: - - name: my-google-service - field: user_id - - name: email - type: string - description: user email - authServices: - - name: my-google-service - field: email - - name: other-google-service - field: other_email - - toolsets: - example_toolset: - - example_tool + - name: id + type: integer + description: user id + authServices: + - name: my-google-service + field: user_id + - name: email + type: string + description: user email + authServices: + - name: my-google-service + field: email + - name: other-google-service + field: other_email +--- + kind: toolsets + name: example_toolset + tools: + - example_tool `, wantToolsFile: ToolsFile{ Sources: server.SourceConfigs{ "my-pg-instance": cloudsqlpgsrc.Config{ Name: "my-pg-instance", - Kind: cloudsqlpgsrc.SourceKind, + Type: cloudsqlpgsrc.SourceType, Project: "my-project", Region: "my-region", Instance: "my-instance", @@ -722,19 +1272,19 @@ func TestParseToolFileWithAuth(t *testing.T) { AuthServices: server.AuthServiceConfigs{ "my-google-service": google.Config{ Name: "my-google-service", - Kind: google.AuthServiceKind, + Type: google.AuthServiceType, ClientID: "my-client-id", }, "other-google-service": google.Config{ Name: "other-google-service", - Kind: google.AuthServiceKind, + Type: google.AuthServiceType, ClientID: "other-client-id", }, }, Tools: server.ToolConfigs{ "example_tool": postgressql.Config{ Name: "example_tool", - Kind: "postgres-sql", + Type: "postgres-sql", Source: "my-pg-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -809,7 +1359,7 @@ func TestParseToolFileWithAuth(t *testing.T) { Sources: server.SourceConfigs{ "my-pg-instance": cloudsqlpgsrc.Config{ Name: "my-pg-instance", - Kind: cloudsqlpgsrc.SourceKind, + Type: cloudsqlpgsrc.SourceType, Project: "my-project", Region: "my-region", Instance: "my-instance", @@ -819,22 +1369,22 @@ func TestParseToolFileWithAuth(t *testing.T) { Password: "my_pass", }, }, - AuthSources: server.AuthServiceConfigs{ + AuthServices: server.AuthServiceConfigs{ "my-google-service": google.Config{ Name: "my-google-service", - Kind: google.AuthServiceKind, + Type: google.AuthServiceType, ClientID: "my-client-id", }, "other-google-service": google.Config{ Name: "other-google-service", - Kind: google.AuthServiceKind, + Type: google.AuthServiceType, ClientID: "other-client-id", }, }, Tools: server.ToolConfigs{ "example_tool": postgressql.Config{ Name: "example_tool", - Kind: "postgres-sql", + Type: "postgres-sql", Source: "my-pg-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -858,60 +1408,64 @@ func TestParseToolFileWithAuth(t *testing.T) { { description: "basic example with authRequired", in: ` - sources: - my-pg-instance: - kind: cloud-sql-postgres - project: my-project - region: my-region - instance: my-instance - database: my_db - user: my_user - password: my_pass - authServices: - my-google-service: - kind: google - clientId: my-client-id - other-google-service: - kind: google - clientId: other-client-id - - tools: - example_tool: - kind: postgres-sql - source: my-pg-instance + kind: sources + name: my-pg-instance + type: cloud-sql-postgres + project: my-project + region: my-region + instance: my-instance + database: my_db + user: my_user + password: my_pass +--- + kind: authServices + name: my-google-service + type: google + clientId: my-client-id +--- + kind: authServices + name: other-google-service + type: google + clientId: other-client-id +--- + kind: tools + name: example_tool + type: postgres-sql + source: my-pg-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + authRequired: + - my-google-service + parameters: + - name: country + type: string description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - authRequired: - - my-google-service - parameters: - - name: country - type: string - description: some description - - name: id - type: integer - description: user id - authServices: - - name: my-google-service - field: user_id - - name: email - type: string - description: user email - authServices: - - name: my-google-service - field: email - - name: other-google-service - field: other_email - - toolsets: - example_toolset: - - example_tool + - name: id + type: integer + description: user id + authServices: + - name: my-google-service + field: user_id + - name: email + type: string + description: user email + authServices: + - name: my-google-service + field: email + - name: other-google-service + field: other_email +--- + kind: toolsets + name: example_toolset + tools: + - example_tool `, wantToolsFile: ToolsFile{ Sources: server.SourceConfigs{ "my-pg-instance": cloudsqlpgsrc.Config{ Name: "my-pg-instance", - Kind: cloudsqlpgsrc.SourceKind, + Type: cloudsqlpgsrc.SourceType, Project: "my-project", Region: "my-region", Instance: "my-instance", @@ -924,19 +1478,19 @@ func TestParseToolFileWithAuth(t *testing.T) { AuthServices: server.AuthServiceConfigs{ "my-google-service": google.Config{ Name: "my-google-service", - Kind: google.AuthServiceKind, + Type: google.AuthServiceType, ClientID: "my-client-id", }, "other-google-service": google.Config{ Name: "other-google-service", - Kind: google.AuthServiceKind, + Type: google.AuthServiceType, ClientID: "other-client-id", }, }, Tools: server.ToolConfigs{ "example_tool": postgressql.Config{ Name: "example_tool", - Kind: "postgres-sql", + Type: "postgres-sql", Source: "my-pg-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -1082,7 +1636,7 @@ func TestEnvVarReplacement(t *testing.T) { Sources: server.SourceConfigs{ "my-http-instance": httpsrc.Config{ Name: "my-http-instance", - Kind: httpsrc.SourceKind, + Type: httpsrc.SourceType, BaseURL: "http://test_server/", Timeout: "10s", DefaultHeaders: map[string]string{"Authorization": "ACTUAL_HEADER"}, @@ -1092,19 +1646,165 @@ func TestEnvVarReplacement(t *testing.T) { AuthServices: server.AuthServiceConfigs{ "my-google-service": google.Config{ Name: "my-google-service", - Kind: google.AuthServiceKind, + Type: google.AuthServiceType, ClientID: "ACTUAL_CLIENT_ID", }, "other-google-service": google.Config{ Name: "other-google-service", - Kind: google.AuthServiceKind, + Type: google.AuthServiceType, ClientID: "ACTUAL_CLIENT_ID_2", }, }, Tools: server.ToolConfigs{ "example_tool": http.Config{ Name: "example_tool", - Kind: "http", + Type: "http", + Source: "my-instance", + Method: "GET", + Path: "search?name=alice&pet=cat", + Description: "some description", + AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, + 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: `{ + "age": {{.age}}, + "city": "{{.city}}", + "food": "food", + "other": "$OTHER" +} +`, + 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: []parameters.Parameter{parameters.NewStringParameter("Language", "language string")}, + }, + }, + Toolsets: server.ToolsetConfigs{ + "ACTUAL_TOOLSET_NAME": tools.ToolsetConfig{ + Name: "ACTUAL_TOOLSET_NAME", + ToolNames: []string{"example_tool"}, + }, + }, + Prompts: server.PromptConfigs{ + "ACTUAL_PROMPT_NAME": &custom.Config{ + Name: "ACTUAL_PROMPT_NAME", + Description: "A test prompt for {{.name}}.", + Messages: []prompts.Message{ + { + Role: "user", + Content: "ACTUAL_CONTENT", + }, + }, + Arguments: nil, + }, + }, + }, + }, + { + description: "file with env var example toolsfile v2", + in: ` + kind: sources + name: my-http-instance + type: http + baseUrl: http://test_server/ + timeout: 10s + headers: + Authorization: ${TestHeader} + queryParams: + api-key: ${API_KEY} +--- + kind: authServices + name: my-google-service + type: google + clientId: ${clientId} +--- + kind: authServices + name: other-google-service + type: google + clientId: ${clientId2} +--- + kind: tools + name: example_tool + type: http + source: my-instance + method: GET + path: "search?name=alice&pet=${cat_string}" + description: some description + authRequired: + - my-google-auth-service + - other-auth-service + queryParams: + - name: country + type: string + description: some description + authServices: + - name: my-google-auth-service + field: user_id + - name: other-auth-service + field: user_id + requestBody: | + { + "age": {{.age}}, + "city": "{{.city}}", + "food": "${food_string}", + "other": "$OTHER" + } + bodyParams: + - name: age + type: integer + description: age num + - name: city + type: string + description: city string + headers: + Authorization: API_KEY + Content-Type: application/json + headerParams: + - name: Language + type: string + description: language string +--- + kind: toolsets + name: ${toolset_name} + tools: + - example_tool +--- + kind: prompts + name: ${prompt_name} + description: A test prompt for {{.name}}. + messages: + - role: user + content: ${prompt_content} + `, + wantToolsFile: ToolsFile{ + Sources: server.SourceConfigs{ + "my-http-instance": httpsrc.Config{ + Name: "my-http-instance", + Type: httpsrc.SourceType, + BaseURL: "http://test_server/", + Timeout: "10s", + DefaultHeaders: map[string]string{"Authorization": "ACTUAL_HEADER"}, + QueryParams: map[string]string{"api-key": "ACTUAL_API_KEY"}, + }, + }, + AuthServices: server.AuthServiceConfigs{ + "my-google-service": google.Config{ + Name: "my-google-service", + Type: google.AuthServiceType, + ClientID: "ACTUAL_CLIENT_ID", + }, + "other-google-service": google.Config{ + Name: "other-google-service", + Type: google.AuthServiceType, + ClientID: "ACTUAL_CLIENT_ID_2", + }, + }, + Tools: server.ToolConfigs{ + "example_tool": http.Config{ + Name: "example_tool", + Type: "http", Source: "my-instance", Method: "GET", Path: "search?name=alice&pet=cat", @@ -1970,17 +2670,18 @@ func TestPrebuiltAndCustomTools(t *testing.T) { t.Setenv("SQLITE_DATABASE", "test.db") // Setup custom tools file customContent := ` -tools: - custom_tool: - kind: http - source: my-http - method: GET - path: / - description: "A custom tool for testing" -sources: - my-http: - kind: http - baseUrl: http://example.com +kind: tools +name: custom_tool +type: http +source: my-http +method: GET +path: / +description: "A custom tool for testing" +--- +kind: sources +name: my-http +type: http +baseUrl: http://example.com ` customFile := filepath.Join(t.TempDir(), "custom.yaml") if err := os.WriteFile(customFile, []byte(customContent), 0644); err != nil { @@ -1990,17 +2691,18 @@ sources: // Tool Conflict File // SQLite prebuilt has a tool named 'list_tables' toolConflictContent := ` -tools: - list_tables: - kind: http - source: my-http - method: GET - path: / - description: "Conflicting tool" -sources: - my-http: - kind: http - baseUrl: http://example.com +kind: tools +name: list_tables +type: http +source: my-http +method: GET +path: / +description: "Conflicting tool" +--- +kind: sources +name: my-http +type: http +baseUrl: http://example.com ` toolConflictFile := filepath.Join(t.TempDir(), "tool_conflict.yaml") if err := os.WriteFile(toolConflictFile, []byte(toolConflictContent), 0644); err != nil { @@ -2010,17 +2712,18 @@ sources: // Source Conflict File // SQLite prebuilt has a source named 'sqlite-source' sourceConflictContent := ` -sources: - sqlite-source: - kind: http - baseUrl: http://example.com -tools: - dummy_tool: - kind: http - source: sqlite-source - method: GET - path: / - description: "Dummy" +kind: sources +name: sqlite-source +type: http +baseUrl: http://example.com +--- +kind: tools +name: dummy_tool +type: http +source: sqlite-source +method: GET +path: / +description: "Dummy" ` sourceConflictFile := filepath.Join(t.TempDir(), "source_conflict.yaml") if err := os.WriteFile(sourceConflictFile, []byte(sourceConflictContent), 0644); err != nil { @@ -2030,20 +2733,23 @@ tools: // Toolset Conflict File // SQLite prebuilt has a toolset named 'sqlite_database_tools' toolsetConflictContent := ` -sources: - dummy-src: - kind: http - baseUrl: http://example.com +kind: sources +name: dummy-src +type: http +baseUrl: http://example.com +--- +kind: tools +name: dummy_tool +type: http +source: dummy-src +method: GET +path: / +description: "Dummy" +--- +kind: toolsets +name: sqlite_database_tools tools: - dummy_tool: - kind: http - source: dummy-src - method: GET - path: / - description: "Dummy" -toolsets: - sqlite_database_tools: - - dummy_tool +- dummy_tool ` toolsetConflictFile := filepath.Join(t.TempDir(), "toolset_conflict.yaml") if err := os.WriteFile(toolsetConflictFile, []byte(toolsetConflictContent), 0644); err != nil { diff --git a/docs/en/about/faq.md b/docs/en/about/faq.md index 683c49c6b0..5ab557e099 100644 --- a/docs/en/about/faq.md +++ b/docs/en/about/faq.md @@ -45,7 +45,7 @@ most popular issues, so make sure to +1 ones you are the most interested in. ## Can Toolbox be used for non-database tools? **Yes!** While Toolbox is primarily focused on databases, it also supports generic -**HTTP tools** (`kind: http`). These allow you to connect your agents to REST APIs +**HTTP tools** (`type: http`). These allow you to connect your agents to REST APIs and other web services, enabling workflows that extend beyond database interactions. For configuration details, see the [HTTP Tools documentation](../resources/tools/http/http.md). diff --git a/docs/en/concepts/telemetry/index.md b/docs/en/concepts/telemetry/index.md index 49b7c9edca..9bd1598052 100644 --- a/docs/en/concepts/telemetry/index.md +++ b/docs/en/concepts/telemetry/index.md @@ -64,7 +64,7 @@ The structured logging outputs log as JSON: "timestamp":"2024-11-04T16:45:11.987299-08:00", "severity":"ERROR", "logging.googleapis.com/sourceLocation":{...}, - "message":"unable to parse tool file at \"tools.yaml\": \"cloud-sql-postgres1\" is not a valid kind of data source" + "message":"unable to parse tool file at \"tools.yaml\": \"cloud-sql-postgres1\" is not a valid type of data source" } ``` diff --git a/docs/en/getting-started/colab_quickstart.ipynb b/docs/en/getting-started/colab_quickstart.ipynb index 4260b60bb3..3281158147 100644 --- a/docs/en/getting-started/colab_quickstart.ipynb +++ b/docs/en/getting-started/colab_quickstart.ipynb @@ -300,78 +300,89 @@ "# You can also upload a tools file and use that to run toolbox.\n", "tools_file_name = \"tools.yml\"\n", "file_content = f\"\"\"\n", - "sources:\n", - " my-pg-source:\n", - " kind: postgres\n", - " host: 127.0.0.1\n", - " port: 5432\n", - " database: toolbox_db\n", - " user: toolbox_user\n", - " password: my-password\n", + "kind: sources\n", + "name: my-pg-source\n", + "type: postgres\n", + "host: 127.0.0.1\n", + "port: 5432\n", + "database: toolbox_db\n", + "user: toolbox_user\n", + "password: my-password\n", + "---\n", + "kind: tools\n", + "name: search-hotels-by-name\n", + "type: postgres-sql\n", + "source: my-pg-source\n", + "description: Search for hotels based on name.\n", + "parameters:\n", + " - name: name\n", + " type: string\n", + " description: The name of the hotel.\n", + "statement: SELECT * FROM hotels WHERE name ILIKE '%' || \\$1 || '%';\n", + "---\n", + "kind: tools\n", + "name: search-hotels-by-location\n", + "type: postgres-sql\n", + "source: my-pg-source\n", + "description: Search for hotels based on location.\n", + "parameters:\n", + " - name: location\n", + " type: string\n", + " description: The location of the hotel.\n", + "statement: SELECT * FROM hotels WHERE location ILIKE '%' || \\$1 || '%';\n", + "---\n", + "kind: tools\n", + "name: book-hotel\n", + "type: postgres-sql\n", + "source: my-pg-source\n", + "description: >-\n", + " Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not.\n", + "parameters:\n", + " - name: hotel_id\n", + " type: string\n", + " description: The ID of the hotel to book.\n", + "statement: UPDATE hotels SET booked = B'1' WHERE id = \\$1;\n", + "---\n", + "kind: tools\n", + "name: update-hotel\n", + "type: postgres-sql\n", + "source: my-pg-source\n", + "description: >-\n", + " Update a hotel's check-in and check-out dates by its ID. Returns a message\n", + " indicating whether the hotel was successfully updated or not.\n", + "parameters:\n", + " - name: hotel_id\n", + " type: string\n", + " description: The ID of the hotel to update.\n", + " - name: checkin_date\n", + " type: string\n", + " description: The new check-in date of the hotel.\n", + " - name: checkout_date\n", + " type: string\n", + " description: The new check-out date of the hotel.\n", + "statement: >-\n", + " UPDATE hotels SET checkin_date = CAST(\\$2 as date), checkout_date = CAST(\\$3\n", + " as date) WHERE id = \\$1;\n", + "---\n", + "kind: tools\n", + "name: cancel-hotel\n", + "type: postgres-sql\n", + "source: my-pg-source\n", + "description: Cancel a hotel by its ID.\n", + "parameters:\n", + " - name: hotel_id\n", + " type: string\n", + " description: The ID of the hotel to cancel.\n", + "statement: UPDATE hotels SET booked = B'0' WHERE id = \\$1;\n", + "---\n", + "kind: toolsets\n", + "name: my-toolset\n", "tools:\n", - " search-hotels-by-name:\n", - " kind: postgres-sql\n", - " source: my-pg-source\n", - " description: Search for hotels based on name.\n", - " parameters:\n", - " - name: name\n", - " type: string\n", - " description: The name of the hotel.\n", - " statement: SELECT * FROM hotels WHERE name ILIKE '%' || \\$1 || '%';\n", - " search-hotels-by-location:\n", - " kind: postgres-sql\n", - " source: my-pg-source\n", - " description: Search for hotels based on location.\n", - " parameters:\n", - " - name: location\n", - " type: string\n", - " description: The location of the hotel.\n", - " statement: SELECT * FROM hotels WHERE location ILIKE '%' || \\$1 || '%';\n", - " book-hotel:\n", - " kind: postgres-sql\n", - " source: my-pg-source\n", - " description: >-\n", - " Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not.\n", - " parameters:\n", - " - name: hotel_id\n", - " type: string\n", - " description: The ID of the hotel to book.\n", - " statement: UPDATE hotels SET booked = B'1' WHERE id = \\$1;\n", - " update-hotel:\n", - " kind: postgres-sql\n", - " source: my-pg-source\n", - " description: >-\n", - " Update a hotel's check-in and check-out dates by its ID. Returns a message\n", - " indicating whether the hotel was successfully updated or not.\n", - " parameters:\n", - " - name: hotel_id\n", - " type: string\n", - " description: The ID of the hotel to update.\n", - " - name: checkin_date\n", - " type: string\n", - " description: The new check-in date of the hotel.\n", - " - name: checkout_date\n", - " type: string\n", - " description: The new check-out date of the hotel.\n", - " statement: >-\n", - " UPDATE hotels SET checkin_date = CAST(\\$2 as date), checkout_date = CAST(\\$3\n", - " as date) WHERE id = \\$1;\n", - " cancel-hotel:\n", - " kind: postgres-sql\n", - " source: my-pg-source\n", - " description: Cancel a hotel by its ID.\n", - " parameters:\n", - " - name: hotel_id\n", - " type: string\n", - " description: The ID of the hotel to cancel.\n", - " statement: UPDATE hotels SET booked = B'0' WHERE id = \\$1;\n", - "toolsets:\n", - " my-toolset:\n", - " - search-hotels-by-name\n", - " - search-hotels-by-location\n", - " - book-hotel\n", - " - update-hotel\n", - " - cancel-hotel\n", + " - search-hotels-by-name\n", + " - search-hotels-by-location\n", + " - book-hotel\n", + " - update-hotel\n", + " - cancel-hotel\n", "\"\"\"" ] }, diff --git a/docs/en/getting-started/configure.md b/docs/en/getting-started/configure.md index 6155eb5608..e578c64dfc 100644 --- a/docs/en/getting-started/configure.md +++ b/docs/en/getting-started/configure.md @@ -36,14 +36,14 @@ Toolbox should have access to. Most tools will have at least one source to execute against. ```yaml -sources: - my-pg-source: - kind: postgres - host: 127.0.0.1 - port: 5432 - database: toolbox_db - user: ${USER_NAME} - password: ${PASSWORD} +kind: sources +name: my-pg-source +type: postgres +host: 127.0.0.1 +port: 5432 +database: toolbox_db +user: ${USER_NAME} +password: ${PASSWORD} ``` For more details on configuring different types of sources, see the @@ -52,20 +52,20 @@ For more details on configuring different types of sources, see the ### Tools The `tools` section of your `tools.yaml` defines the actions your agent can -take: what kind of tool it is, which source(s) it affects, what parameters it +take: what type of tool it is, which source(s) it affects, what parameters it uses, etc. ```yaml -tools: - search-hotels-by-name: - kind: postgres-sql - source: my-pg-source - description: Search for hotels based on name. - parameters: - - name: name - type: string - description: The name of the hotel. - statement: SELECT * FROM hotels WHERE name ILIKE '%' || $1 || '%'; +kind: tools +name: search-hotels-by-name +type: postgres-sql +source: my-pg-source +description: Search for hotels based on name. +parameters: + - name: name + type: string + description: The name of the hotel. +statement: SELECT * FROM hotels WHERE name ILIKE '%' || $1 || '%'; ``` For more details on configuring different types of tools, see the @@ -78,13 +78,17 @@ that you want to be able to load together. This can be useful for defining different sets for different agents or different applications. ```yaml -toolsets: - my_first_toolset: - - my_first_tool - - my_second_tool - my_second_toolset: - - my_second_tool - - my_third_tool +kind: toolsets +name: my_first_toolset +tools: + - my_first_tool + - my_second_tool +--- +kind: toolsets +name: my_second_toolset +tools: + - my_second_tool + - my_third_tool ``` You can load toolsets by name: @@ -103,14 +107,14 @@ The `prompts` section of your `tools.yaml` defines the templates containing structured messages and instructions for interacting with language models. ```yaml -prompts: - code_review: - description: "Asks the LLM to analyze code quality and suggest improvements." - messages: - - content: "Please review the following code for quality, correctness, and potential improvements: \n\n{{.code}}" - arguments: - - name: "code" - description: "The code to review" +kind: prompts +name: code_review +description: "Asks the LLM to analyze code quality and suggest improvements." +messages: + - content: "Please review the following code for quality, correctness, and potential improvements: \n\n{{.code}}" +arguments: + - name: "code" + description: "The code to review" ``` For more details on configuring different types of prompts, see the diff --git a/docs/en/getting-started/introduction/_index.md b/docs/en/getting-started/introduction/_index.md index 5fb0b757c8..0a3e2bff4d 100644 --- a/docs/en/getting-started/introduction/_index.md +++ b/docs/en/getting-started/introduction/_index.md @@ -16,6 +16,12 @@ Databases” as its initial development predated MCP, but was renamed to align with recently added MCP compatibility. {{< /notice >}} +{{< notice note >}} +This document has been updated to support the configuration file v2 format. To +view documentation with configuration file v1 format, please navigate to the +top-right menu and select versions v0.26.0 or older. +{{< /notice >}} + ## Why Toolbox? Toolbox helps you build Gen AI tools that let your agents access data in your diff --git a/docs/en/getting-started/mcp_quickstart/_index.md b/docs/en/getting-started/mcp_quickstart/_index.md index 7967d574a5..0bc7b94733 100644 --- a/docs/en/getting-started/mcp_quickstart/_index.md +++ b/docs/en/getting-started/mcp_quickstart/_index.md @@ -125,78 +125,89 @@ In this section, we will download Toolbox, configure our tools in a {{< /notice >}} ```yaml - sources: - my-pg-source: - kind: postgres - host: 127.0.0.1 - port: 5432 - database: toolbox_db - user: toolbox_user - password: my-password + kind: sources + name: my-pg-source + type: postgres + host: 127.0.0.1 + port: 5432 + database: toolbox_db + user: toolbox_user + password: my-password + --- + kind: tools + name: search-hotels-by-name + type: postgres-sql + source: my-pg-source + description: Search for hotels based on name. + parameters: + - name: name + type: string + description: The name of the hotel. + statement: SELECT * FROM hotels WHERE name ILIKE '%' || $1 || '%'; + --- + kind: tools + name: search-hotels-by-location + type: postgres-sql + source: my-pg-source + description: Search for hotels based on location. + parameters: + - name: location + type: string + description: The location of the hotel. + statement: SELECT * FROM hotels WHERE location ILIKE '%' || $1 || '%'; + --- + kind: tools + name: book-hotel + type: postgres-sql + source: my-pg-source + description: >- + Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not. + parameters: + - name: hotel_id + type: string + description: The ID of the hotel to book. + statement: UPDATE hotels SET booked = B'1' WHERE id = $1; + --- + kind: tools + name: update-hotel + type: postgres-sql + source: my-pg-source + description: >- + Update a hotel's check-in and check-out dates by its ID. Returns a message + indicating whether the hotel was successfully updated or not. + parameters: + - name: hotel_id + type: string + description: The ID of the hotel to update. + - name: checkin_date + type: string + description: The new check-in date of the hotel. + - name: checkout_date + type: string + description: The new check-out date of the hotel. + statement: >- + UPDATE hotels SET checkin_date = CAST($2 as date), checkout_date = CAST($3 + as date) WHERE id = $1; + --- + kind: tools + name: cancel-hotel + type: postgres-sql + source: my-pg-source + description: Cancel a hotel by its ID. + parameters: + - name: hotel_id + type: string + description: The ID of the hotel to cancel. + statement: UPDATE hotels SET booked = B'0' WHERE id = $1; + --- + kind: toolsets + name: my-toolset tools: - search-hotels-by-name: - kind: postgres-sql - source: my-pg-source - description: Search for hotels based on name. - parameters: - - name: name - type: string - description: The name of the hotel. - statement: SELECT * FROM hotels WHERE name ILIKE '%' || $1 || '%'; - search-hotels-by-location: - kind: postgres-sql - source: my-pg-source - description: Search for hotels based on location. - parameters: - - name: location - type: string - description: The location of the hotel. - statement: SELECT * FROM hotels WHERE location ILIKE '%' || $1 || '%'; - book-hotel: - kind: postgres-sql - source: my-pg-source - description: >- - Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not. - parameters: - - name: hotel_id - type: string - description: The ID of the hotel to book. - statement: UPDATE hotels SET booked = B'1' WHERE id = $1; - update-hotel: - kind: postgres-sql - source: my-pg-source - description: >- - Update a hotel's check-in and check-out dates by its ID. Returns a message - indicating whether the hotel was successfully updated or not. - parameters: - - name: hotel_id - type: string - description: The ID of the hotel to update. - - name: checkin_date - type: string - description: The new check-in date of the hotel. - - name: checkout_date - type: string - description: The new check-out date of the hotel. - statement: >- - UPDATE hotels SET checkin_date = CAST($2 as date), checkout_date = CAST($3 - as date) WHERE id = $1; - cancel-hotel: - kind: postgres-sql - source: my-pg-source - description: Cancel a hotel by its ID. - parameters: - - name: hotel_id - type: string - description: The ID of the hotel to cancel. - statement: UPDATE hotels SET booked = B'0' WHERE id = $1; - toolsets: - my-toolset: - - search-hotels-by-name - - search-hotels-by-location - - book-hotel - - update-hotel - - cancel-hotel + - search-hotels-by-name + - search-hotels-by-location + - book-hotel + - update-hotel + - cancel-hotel ``` For more info on tools, check out the diff --git a/docs/en/getting-started/prompts_quickstart_gemini_cli.md b/docs/en/getting-started/prompts_quickstart_gemini_cli.md index 2061acd7fa..47140ed2e7 100644 --- a/docs/en/getting-started/prompts_quickstart_gemini_cli.md +++ b/docs/en/getting-started/prompts_quickstart_gemini_cli.md @@ -157,61 +157,67 @@ Create a file named `tools.yaml`. This file defines the database connection, the SQL tools available, and the prompts the agents will use. ```yaml -sources: - my-foodiefind-db: - kind: postgres - host: 127.0.0.1 - port: 5432 - database: toolbox_db - user: toolbox_user - password: my-password -tools: - find_user_by_email: - kind: postgres-sql - source: my-foodiefind-db - description: Find a user's ID by their email address. - parameters: - - name: email - type: string - description: The email address of the user to find. - statement: SELECT id FROM users WHERE email = $1; - find_restaurant_by_name: - kind: postgres-sql - source: my-foodiefind-db - description: Find a restaurant's ID by its exact name. - parameters: - - name: name - type: string - description: The name of the restaurant to find. - statement: SELECT id FROM restaurants WHERE name = $1; - find_review_by_user_and_restaurant: - kind: postgres-sql - source: my-foodiefind-db - description: Find the full record for a specific review using the user's ID and the restaurant's ID. - parameters: - - name: user_id - type: integer - description: The numerical ID of the user. - - name: restaurant_id - type: integer - description: The numerical ID of the restaurant. - statement: SELECT * FROM reviews WHERE user_id = $1 AND restaurant_id = $2; -prompts: - investigate_missing_review: - description: "Investigates a user's missing review by finding the user, restaurant, and the review itself, then analyzing its status." - arguments: - - name: "user_email" - description: "The email of the user who wrote the review." - - name: "restaurant_name" - description: "The name of the restaurant being reviewed." - messages: - - content: >- - **Goal:** Find the review written by the user with email '{{.user_email}}' for the restaurant named '{{.restaurant_name}}' and understand its status. - **Workflow:** - 1. Use the `find_user_by_email` tool with the email '{{.user_email}}' to get the `user_id`. - 2. Use the `find_restaurant_by_name` tool with the name '{{.restaurant_name}}' to get the `restaurant_id`. - 3. Use the `find_review_by_user_and_restaurant` tool with the `user_id` and `restaurant_id` you just found. - 4. Analyze the results from the final tool call. Examine the `is_published` and `moderation_status` fields and explain the review's status to the user in a clear, human-readable sentence. +kind: sources +name: my-foodiefind-db +type: postgres +host: 127.0.0.1 +port: 5432 +database: toolbox_db +user: toolbox_user +password: my-password +--- +kind: tools +name: find_user_by_email +type: postgres-sql +source: my-foodiefind-db +description: Find a user's ID by their email address. +parameters: + - name: email + type: string + description: The email address of the user to find. +statement: SELECT id FROM users WHERE email = $1; +--- +kind: tools +name: find_restaurant_by_name +type: postgres-sql +source: my-foodiefind-db +description: Find a restaurant's ID by its exact name. +parameters: + - name: name + type: string + description: The name of the restaurant to find. +statement: SELECT id FROM restaurants WHERE name = $1; +--- +kind: tools +name: find_review_by_user_and_restaurant +type: postgres-sql +source: my-foodiefind-db +description: Find the full record for a specific review using the user's ID and the restaurant's ID. +parameters: + - name: user_id + type: integer + description: The numerical ID of the user. + - name: restaurant_id + type: integer + description: The numerical ID of the restaurant. +statement: SELECT * FROM reviews WHERE user_id = $1 AND restaurant_id = $2; +--- +kind: prompts +name: investigate_missing_review +description: "Investigates a user's missing review by finding the user, restaurant, and the review itself, then analyzing its status." +arguments: + - name: "user_email" + description: "The email of the user who wrote the review." + - name: "restaurant_name" + description: "The name of the restaurant being reviewed." +messages: + - content: >- + **Goal:** Find the review written by the user with email '{{.user_email}}' for the restaurant named '{{.restaurant_name}}' and understand its status. + **Workflow:** + 1. Use the `find_user_by_email` tool with the email '{{.user_email}}' to get the `user_id`. + 2. Use the `find_restaurant_by_name` tool with the name '{{.restaurant_name}}' to get the `restaurant_id`. + 3. Use the `find_review_by_user_and_restaurant` tool with the `user_id` and `restaurant_id` you just found. + 4. Analyze the results from the final tool call. Examine the `is_published` and `moderation_status` fields and explain the review's status to the user in a clear, human-readable sentence. ``` ## Step 3: Connect to Gemini CLI diff --git a/docs/en/getting-started/quickstart/shared/configure_toolbox.md b/docs/en/getting-started/quickstart/shared/configure_toolbox.md index 12436ee7d6..bea2ed4d60 100644 --- a/docs/en/getting-started/quickstart/shared/configure_toolbox.md +++ b/docs/en/getting-started/quickstart/shared/configure_toolbox.md @@ -33,78 +33,89 @@ In this section, we will download Toolbox, configure our tools in a {{< /notice >}} ```yaml - sources: - my-pg-source: - kind: postgres - host: 127.0.0.1 - port: 5432 - database: toolbox_db - user: ${USER_NAME} - password: ${PASSWORD} + kind: sources + name: my-pg-source + type: postgres + host: 127.0.0.1 + port: 5432 + database: toolbox_db + user: toolbox_user + password: my-password + --- + kind: tools + name: search-hotels-by-name + type: postgres-sql + source: my-pg-source + description: Search for hotels based on name. + parameters: + - name: name + type: string + description: The name of the hotel. + statement: SELECT * FROM hotels WHERE name ILIKE '%' || $1 || '%'; + --- + kind: tools + name: search-hotels-by-location + type: postgres-sql + source: my-pg-source + description: Search for hotels based on location. + parameters: + - name: location + type: string + description: The location of the hotel. + statement: SELECT * FROM hotels WHERE location ILIKE '%' || $1 || '%'; + --- + kind: tools + name: book-hotel + type: postgres-sql + source: my-pg-source + description: >- + Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not. + parameters: + - name: hotel_id + type: string + description: The ID of the hotel to book. + statement: UPDATE hotels SET booked = B'1' WHERE id = $1; + --- + kind: tools + name: update-hotel + type: postgres-sql + source: my-pg-source + description: >- + Update a hotel's check-in and check-out dates by its ID. Returns a message + indicating whether the hotel was successfully updated or not. + parameters: + - name: hotel_id + type: string + description: The ID of the hotel to update. + - name: checkin_date + type: string + description: The new check-in date of the hotel. + - name: checkout_date + type: string + description: The new check-out date of the hotel. + statement: >- + UPDATE hotels SET checkin_date = CAST($2 as date), checkout_date = CAST($3 + as date) WHERE id = $1; + --- + kind: tools + name: cancel-hotel + type: postgres-sql + source: my-pg-source + description: Cancel a hotel by its ID. + parameters: + - name: hotel_id + type: string + description: The ID of the hotel to cancel. + statement: UPDATE hotels SET booked = B'0' WHERE id = $1; + --- + kind: toolsets + name: my-toolset tools: - search-hotels-by-name: - kind: postgres-sql - source: my-pg-source - description: Search for hotels based on name. - parameters: - - name: name - type: string - description: The name of the hotel. - statement: SELECT * FROM hotels WHERE name ILIKE '%' || $1 || '%'; - search-hotels-by-location: - kind: postgres-sql - source: my-pg-source - description: Search for hotels based on location. - parameters: - - name: location - type: string - description: The location of the hotel. - statement: SELECT * FROM hotels WHERE location ILIKE '%' || $1 || '%'; - book-hotel: - kind: postgres-sql - source: my-pg-source - description: >- - Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not. - parameters: - - name: hotel_id - type: string - description: The ID of the hotel to book. - statement: UPDATE hotels SET booked = B'1' WHERE id = $1; - update-hotel: - kind: postgres-sql - source: my-pg-source - description: >- - Update a hotel's check-in and check-out dates by its ID. Returns a message - indicating whether the hotel was successfully updated or not. - parameters: - - name: hotel_id - type: string - description: The ID of the hotel to update. - - name: checkin_date - type: string - description: The new check-in date of the hotel. - - name: checkout_date - type: string - description: The new check-out date of the hotel. - statement: >- - UPDATE hotels SET checkin_date = CAST($2 as date), checkout_date = CAST($3 - as date) WHERE id = $1; - cancel-hotel: - kind: postgres-sql - source: my-pg-source - description: Cancel a hotel by its ID. - parameters: - - name: hotel_id - type: string - description: The ID of the hotel to cancel. - statement: UPDATE hotels SET booked = B'0' WHERE id = $1; - toolsets: - my-toolset: - - search-hotels-by-name - - search-hotels-by-location - - book-hotel - - update-hotel - - cancel-hotel + - search-hotels-by-name + - search-hotels-by-location + - book-hotel + - update-hotel + - cancel-hotel ``` For more info on tools, check out the `Resources` section of the docs. diff --git a/docs/en/resources/authServices/_index.md b/docs/en/resources/authServices/_index.md index 757b58a1a3..a40ce182d1 100644 --- a/docs/en/resources/authServices/_index.md +++ b/docs/en/resources/authServices/_index.md @@ -28,17 +28,19 @@ The following configurations are placed at the top level of a `tools.yaml` file. {{< notice tip >}} If you are accessing Toolbox with multiple applications, each application should register their own Client ID even if they use the same - "kind" of auth provider. + "type" of auth provider. {{< /notice >}} ```yaml -authServices: - my_auth_app_1: - kind: google - clientId: ${YOUR_CLIENT_ID_1} - my_auth_app_2: - kind: google - clientId: ${YOUR_CLIENT_ID_2} +kind: authServices +name: my_auth_app_1 +type: google +clientId: ${YOUR_CLIENT_ID_1} +--- +kind: authServices +name: my_auth_app_2 +type: google +clientId: ${YOUR_CLIENT_ID_2} ``` {{< notice tip >}} diff --git a/docs/en/resources/authServices/google.md b/docs/en/resources/authServices/google.md index b0950040d3..f44284731e 100644 --- a/docs/en/resources/authServices/google.md +++ b/docs/en/resources/authServices/google.md @@ -40,10 +40,10 @@ id-token][provided-claims] can be used for the parameter. ## Example ```yaml -authServices: - my-google-auth: - kind: google - clientId: ${YOUR_GOOGLE_CLIENT_ID} +kind: authServices +name: my-google-auth +type: google +clientId: ${YOUR_GOOGLE_CLIENT_ID} ``` {{< notice tip >}} @@ -55,5 +55,5 @@ instead of hardcoding your secrets into the configuration file. | **field** | **type** | **required** | **description** | |-----------|:--------:|:------------:|------------------------------------------------------------------| -| kind | string | true | Must be "google". | +| type | string | true | Must be "google". | | clientId | string | true | Client ID of your application from registering your application. | diff --git a/docs/en/resources/embeddingModels/_index.md b/docs/en/resources/embeddingModels/_index.md index d9da2b71c3..8fb867306f 100644 --- a/docs/en/resources/embeddingModels/_index.md +++ b/docs/en/resources/embeddingModels/_index.md @@ -54,12 +54,12 @@ ${ENV_NAME} instead of hardcoding your API keys into the configuration file. Define an embedding model in the `embeddingModels` section: ```yaml -embeddingModels: - gemini-model: # Name of the embedding model - kind: gemini - model: gemini-embedding-001 - apiKey: ${GOOGLE_API_KEY} - dimension: 768 +kind: embeddingModels +name: gemini-model # Name of the embedding model +type: gemini +model: gemini-embedding-001 +apiKey: ${GOOGLE_API_KEY} +dimension: 768 ``` ### Step 2 - Embed Tool Parameters @@ -68,38 +68,39 @@ Use the defined embedding model, embed your query parameters using the `embeddedBy` field. Only string-typed parameters can be embedded: ```yaml -tools: - # Vector ingestion tool - insert_embedding: - kind: postgres-sql - source: my-pg-instance - statement: | - INSERT INTO documents (content, embedding) - VALUES ($1, $2); - parameters: - - name: content - type: string - description: The raw text content to be stored in the database. - - name: vector_string - type: string - # This parameter is hidden from the LLM. - # It automatically copies the value from 'content' and embeds it. - valueFromParam: content - embeddedBy: gemini-model - - # Semantic search tool - search_embedding: - kind: postgres-sql - source: my-pg-instance - statement: | - SELECT id, content, embedding <-> $1 AS distance - FROM documents - ORDER BY distance LIMIT 1 - parameters: - - name: semantic_search_string - type: string - description: The search query that will be converted to a vector. - embeddedBy: gemini-model # refers to the name of a defined embedding model +# Vector ingestion tool +kind: tools +name: insert_embedding +type: postgres-sql +source: my-pg-instance +statement: | + INSERT INTO documents (content, embedding) + VALUES ($1, $2); +parameters: + - name: content + type: string + description: The raw text content to be stored in the database. + - name: vector_string + type: string + # This parameter is hidden from the LLM. + # It automatically copies the value from 'content' and embeds it. + valueFromParam: content + embeddedBy: gemini-model +--- +# Semantic search tool +kind: tools +name: search_embedding +type: postgres-sql +source: my-pg-instance +statement: | + SELECT id, content, embedding <-> $1 AS distance + FROM documents + ORDER BY distance LIMIT 1 +parameters: + - name: semantic_search_string + type: string + description: The search query that will be converted to a vector. + embeddedBy: gemini-model # refers to the name of a defined embedding model ``` ## Kinds of Embedding Models diff --git a/docs/en/resources/embeddingModels/gemini.md b/docs/en/resources/embeddingModels/gemini.md index 8fcf8cf358..7555c91f85 100644 --- a/docs/en/resources/embeddingModels/gemini.md +++ b/docs/en/resources/embeddingModels/gemini.md @@ -50,12 +50,12 @@ information. ## Example ```yaml -embeddingModels: - gemini-model: - kind: gemini - model: gemini-embedding-001 - apiKey: ${GOOGLE_API_KEY} - dimension: 768 +kind: embeddingModels +name: gemini-model +type: gemini +model: gemini-embedding-001 +apiKey: ${GOOGLE_API_KEY} +dimension: 768 ``` {{< notice tip >}} @@ -67,7 +67,7 @@ instead of hardcoding your secrets into the configuration file. | **field** | **type** | **required** | **description** | |-----------|:--------:|:------------:|--------------------------------------------------------------| -| kind | string | true | Must be `gemini`. | +| type | string | true | Must be `gemini`. | | model | string | true | The Gemini model ID to use (e.g., `gemini-embedding-001`). | | apiKey | string | false | Your API Key from Google AI Studio. | | dimension | integer | false | The number of dimensions in the output vector (e.g., `768`). | diff --git a/docs/en/resources/prompts/_index.md b/docs/en/resources/prompts/_index.md index 5227ba8470..b62f8d17ae 100644 --- a/docs/en/resources/prompts/_index.md +++ b/docs/en/resources/prompts/_index.md @@ -16,14 +16,14 @@ can be sent to a Large Language Model (LLM). The Toolbox server implements the specification, allowing clients to discover and retrieve these prompts. ```yaml -prompts: - code_review: - description: "Asks the LLM to analyze code quality and suggest improvements." - messages: - - content: "Please review the following code for quality, correctness, and potential improvements: \n\n{{.code}}" - arguments: - - name: "code" - description: "The code to review" +kind: prompts +name: code_review +description: "Asks the LLM to analyze code quality and suggest improvements." +messages: + - content: "Please review the following code for quality, correctness, and potential improvements: \n\n{{.code}}" +arguments: + - name: "code" + description: "The code to review" ``` ## Prompt Schema @@ -31,7 +31,7 @@ prompts: | **field** | **type** | **required** | **description** | |-------------|--------------------------------|--------------|--------------------------------------------------------------------------| | description | string | No | A brief explanation of what the prompt does. | -| kind | string | No | The kind of prompt. Defaults to `"custom"`. | +| type | string | No | The type of prompt. Defaults to `"custom"`. | | messages | [][Message](#message-schema) | Yes | A list of one or more message objects that make up the prompt's content. | | arguments | [][Argument](#argument-schema) | No | A list of arguments that can be interpolated into the prompt's content. | diff --git a/docs/en/resources/prompts/custom/_index.md b/docs/en/resources/prompts/custom/_index.md index 01eedafdbf..01a8db4ca9 100644 --- a/docs/en/resources/prompts/custom/_index.md +++ b/docs/en/resources/prompts/custom/_index.md @@ -17,14 +17,14 @@ Here is an example of a simple prompt that takes a single argument, code, and asks an LLM to review it. ```yaml -prompts: - code_review: - description: "Asks the LLM to analyze code quality and suggest improvements." - messages: - - content: "Please review the following code for quality, correctness, and potential improvements: \n\n{{.code}}" - arguments: - - name: "code" - description: "The code to review" +kind: prompts +name: code_review +description: "Asks the LLM to analyze code quality and suggest improvements." +messages: + - content: "Please review the following code for quality, correctness, and potential improvements: \n\n{{.code}}" +arguments: + - name: "code" + description: "The code to review" ``` ### Multi-message prompt @@ -33,19 +33,19 @@ You can define prompts with multiple messages to set up more complex conversational contexts, like a role-playing scenario. ```yaml -prompts: - roleplay_scenario: - description: "Sets up a roleplaying scenario with initial messages." - arguments: - - name: "character" - description: "The character the AI should embody." - - name: "situation" - description: "The initial situation for the roleplay." - messages: - - role: "user" - content: "Let's roleplay. You are {{.character}}. The situation is: {{.situation}}" - - role: "assistant" - content: "Okay, I understand. I am ready. What happens next?" +kind: prompts +name: roleplay_scenario +description: "Sets up a roleplaying scenario with initial messages." +arguments: + - name: "character" + description: "The character the AI should embody." + - name: "situation" + description: "The initial situation for the roleplay." +messages: + - role: "user" + content: "Let's roleplay. You are {{.character}}. The situation is: {{.situation}}" + - role: "assistant" + content: "Okay, I understand. I am ready. What happens next?" ``` ## Reference @@ -54,7 +54,7 @@ prompts: | **field** | **type** | **required** | **description** | |-------------|--------------------------------|--------------|--------------------------------------------------------------------------| -| kind | string | No | The kind of prompt. Must be `"custom"`. | +| type | string | No | The type of prompt. Must be `"custom"`. | | description | string | No | A brief explanation of what the prompt does. | | messages | [][Message](#message-schema) | Yes | A list of one or more message objects that make up the prompt's content. | | arguments | [][Argument](#argument-schema) | No | A list of arguments that can be interpolated into the prompt's content. | diff --git a/docs/en/resources/sources/_index.md b/docs/en/resources/sources/_index.md index a5f916726f..21d281f6a3 100644 --- a/docs/en/resources/sources/_index.md +++ b/docs/en/resources/sources/_index.md @@ -17,15 +17,15 @@ instead of hardcoding your secrets into the configuration file. {{< /notice >}} ```yaml -sources: - my-cloud-sql-source: - kind: cloud-sql-postgres - project: my-project-id - region: us-central1 - instance: my-instance-name - database: my_db - user: ${USER_NAME} - password: ${PASSWORD} +kind: sources +name: my-cloud-sql-source +type: cloud-sql-postgres +project: my-project-id +region: us-central1 +instance: my-instance-name +database: my_db +user: ${USER_NAME} +password: ${PASSWORD} ``` In implementation, each source is a different connection pool or client that used diff --git a/docs/en/resources/sources/alloydb-admin.md b/docs/en/resources/sources/alloydb-admin.md index cddff47533..0584994ab1 100644 --- a/docs/en/resources/sources/alloydb-admin.md +++ b/docs/en/resources/sources/alloydb-admin.md @@ -25,19 +25,20 @@ Authentication can be handled in two ways: ## Example ```yaml -sources: - my-alloydb-admin: - kind: alloy-admin - - my-oauth-alloydb-admin: - kind: alloydb-admin - useClientOAuth: true +kind: sources +name: my-alloydb-admin +type: alloydb-admin +--- +kind: sources +name: my-oauth-alloydb-admin +type: alloydb-admin +useClientOAuth: true ``` ## Reference | **field** | **type** | **required** | **description** | | -------------- | :------: | :----------: | ---------------------------------------------------------------------------------------------------------------------------------------------- | -| kind | string | true | Must be "alloydb-admin". | +| type | string | true | Must be "alloydb-admin". | | defaultProject | string | false | The Google Cloud project ID to use for AlloyDB infrastructure tools. | | useClientOAuth | boolean | false | If true, the source will use client-side OAuth for authorization. Otherwise, it will use Application Default Credentials. Defaults to `false`. | diff --git a/docs/en/resources/sources/alloydb-pg.md b/docs/en/resources/sources/alloydb-pg.md index 2fa502aaec..cf6d848ae6 100644 --- a/docs/en/resources/sources/alloydb-pg.md +++ b/docs/en/resources/sources/alloydb-pg.md @@ -176,17 +176,17 @@ To connect using IAM authentication: ## Example ```yaml -sources: - my-alloydb-pg-source: - kind: alloydb-postgres - project: my-project-id - region: us-central1 - cluster: my-cluster - instance: my-instance - database: my_db - user: ${USER_NAME} - password: ${PASSWORD} - # ipType: "public" +kind: sources +name: my-alloydb-pg-source +type: alloydb-postgres +project: my-project-id +region: us-central1 +cluster: my-cluster +instance: my-instance +database: my_db +user: ${USER_NAME} +password: ${PASSWORD} +# ipType: "public" ``` {{< notice tip >}} @@ -198,7 +198,7 @@ instead of hardcoding your secrets into the configuration file. | **field** | **type** | **required** | **description** | |-----------|:--------:|:------------:|--------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "alloydb-postgres". | +| type | string | true | Must be "alloydb-postgres". | | project | string | true | Id of the GCP project that the cluster was created in (e.g. "my-project-id"). | | region | string | true | Name of the GCP region that the cluster was created in (e.g. "us-central1"). | | cluster | string | true | Name of the AlloyDB cluster (e.g. "my-cluster"). | diff --git a/docs/en/resources/sources/bigquery.md b/docs/en/resources/sources/bigquery.md index 8cb05ccbb8..b898f9f383 100644 --- a/docs/en/resources/sources/bigquery.md +++ b/docs/en/resources/sources/bigquery.md @@ -121,47 +121,47 @@ identity used has been granted the correct IAM permissions. Initialize a BigQuery source that uses ADC: ```yaml -sources: - my-bigquery-source: - kind: "bigquery" - project: "my-project-id" - # location: "US" # Optional: Specifies the location for query jobs. - # writeMode: "allowed" # One of: allowed, blocked, protected. Defaults to "allowed". - # allowedDatasets: # Optional: Restricts tool access to a specific list of datasets. - # - "my_dataset_1" - # - "other_project.my_dataset_2" - # impersonateServiceAccount: "service-account@project-id.iam.gserviceaccount.com" # Optional: Service account to impersonate - # scopes: # Optional: List of OAuth scopes to request. - # - "https://www.googleapis.com/auth/bigquery" - # - "https://www.googleapis.com/auth/drive.readonly" - # maxQueryResultRows: 50 # Optional: Limits the number of rows returned by queries. Defaults to 50. +kind: sources +name: my-bigquery-source +type: "bigquery" +project: "my-project-id" +# location: "US" # Optional: Specifies the location for query jobs. +# writeMode: "allowed" # One of: allowed, blocked, protected. Defaults to "allowed". +# allowedDatasets: # Optional: Restricts tool access to a specific list of datasets. +# - "my_dataset_1" +# - "other_project.my_dataset_2" +# impersonateServiceAccount: "service-account@project-id.iam.gserviceaccount.com" # Optional: Service account to impersonate +# scopes: # Optional: List of OAuth scopes to request. +# - "https://www.googleapis.com/auth/bigquery" +# - "https://www.googleapis.com/auth/drive.readonly" +# maxQueryResultRows: 50 # Optional: Limits the number of rows returned by queries. Defaults to 50. ``` Initialize a BigQuery source that uses the client's access token: ```yaml -sources: - my-bigquery-client-auth-source: - kind: "bigquery" - project: "my-project-id" - useClientOAuth: true - # location: "US" # Optional: Specifies the location for query jobs. - # writeMode: "allowed" # One of: allowed, blocked, protected. Defaults to "allowed". - # allowedDatasets: # Optional: Restricts tool access to a specific list of datasets. - # - "my_dataset_1" - # - "other_project.my_dataset_2" - # impersonateServiceAccount: "service-account@project-id.iam.gserviceaccount.com" # Optional: Service account to impersonate - # scopes: # Optional: List of OAuth scopes to request. - # - "https://www.googleapis.com/auth/bigquery" - # - "https://www.googleapis.com/auth/drive.readonly" - # maxQueryResultRows: 50 # Optional: Limits the number of rows returned by queries. Defaults to 50. +kind: sources +name: my-bigquery-client-auth-source +type: "bigquery" +project: "my-project-id" +useClientOAuth: true +# location: "US" # Optional: Specifies the location for query jobs. +# writeMode: "allowed" # One of: allowed, blocked, protected. Defaults to "allowed". +# allowedDatasets: # Optional: Restricts tool access to a specific list of datasets. +# - "my_dataset_1" +# - "other_project.my_dataset_2" +# impersonateServiceAccount: "service-account@project-id.iam.gserviceaccount.com" # Optional: Service account to impersonate +# scopes: # Optional: List of OAuth scopes to request. +# - "https://www.googleapis.com/auth/bigquery" +# - "https://www.googleapis.com/auth/drive.readonly" +# maxQueryResultRows: 50 # Optional: Limits the number of rows returned by queries. Defaults to 50. ``` ## Reference | **field** | **type** | **required** | **description** | |---------------------------|:--------:|:------------:|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "bigquery". | +| type | string | true | Must be "bigquery". | | project | string | true | Id of the Google Cloud project to use for billing and as the default project for BigQuery resources. | | location | string | false | Specifies the location (e.g., 'us', 'asia-northeast1') in which to run the query job. This location must match the location of any tables referenced in the query. Defaults to the table's location or 'US' if the location cannot be determined. [Learn More](https://cloud.google.com/bigquery/docs/locations) | | writeMode | string | false | Controls the write behavior for tools. `allowed` (default): All queries are permitted. `blocked`: Only `SELECT` statements are allowed for the `bigquery-execute-sql` tool. `protected`: Enables session-based execution where all tools associated with this source instance share the same [BigQuery session](https://cloud.google.com/bigquery/docs/sessions-intro). This allows for stateful operations using temporary tables (e.g., `CREATE TEMP TABLE`). For `bigquery-execute-sql`, `SELECT` statements can be used on all tables, but write operations are restricted to the session's temporary dataset. For tools like `bigquery-sql`, `bigquery-forecast`, and `bigquery-analyze-contribution`, the `writeMode` restrictions do not apply, but they will operate within the shared session. **Note:** The `protected` mode cannot be used with `useClientOAuth: true`. It is also not recommended for multi-user server environments, as all users would share the same session. A session is terminated automatically after 24 hours of inactivity or after 7 days, whichever comes first. A new session is created on the next request, and any temporary data from the previous session will be lost. | diff --git a/docs/en/resources/sources/bigtable.md b/docs/en/resources/sources/bigtable.md index e05653ac05..7e4207e9c5 100644 --- a/docs/en/resources/sources/bigtable.md +++ b/docs/en/resources/sources/bigtable.md @@ -59,17 +59,17 @@ applying IAM permissions and roles to an identity. ## Example ```yaml -sources: - my-bigtable-source: - kind: "bigtable" - project: "my-project-id" - instance: "test-instance" +kind: sources +name: my-bigtable-source +type: "bigtable" +project: "my-project-id" +instance: "test-instance" ``` ## Reference | **field** | **type** | **required** | **description** | |-----------|:--------:|:------------:|-------------------------------------------------------------------------------| -| kind | string | true | Must be "bigtable". | +| type | string | true | Must be "bigtable". | | project | string | true | Id of the GCP project that the cluster was created in (e.g. "my-project-id"). | | instance | string | true | Name of the Bigtable instance. | diff --git a/docs/en/resources/sources/cassandra.md b/docs/en/resources/sources/cassandra.md index 6a149718b4..1009a2bce0 100644 --- a/docs/en/resources/sources/cassandra.md +++ b/docs/en/resources/sources/cassandra.md @@ -23,19 +23,19 @@ distributed architectures, and a flexible approach to schema definition. ## Example ```yaml -sources: - my-cassandra-source: - kind: cassandra - hosts: - - 127.0.0.1 - keyspace: my_keyspace - protoVersion: 4 - username: ${USER_NAME} - password: ${PASSWORD} - caPath: /path/to/ca.crt # Optional: path to CA certificate - certPath: /path/to/client.crt # Optional: path to client certificate - keyPath: /path/to/client.key # Optional: path to client key - enableHostVerification: true # Optional: enable host verification +kind: sources +name: my-cassandra-source +type: cassandra +hosts: + - 127.0.0.1 +keyspace: my_keyspace +protoVersion: 4 +username: ${USER_NAME} +password: ${PASSWORD} +caPath: /path/to/ca.crt # Optional: path to CA certificate +certPath: /path/to/client.crt # Optional: path to client certificate +keyPath: /path/to/client.key # Optional: path to client key +enableHostVerification: true # Optional: enable host verification ``` {{< notice tip >}} @@ -47,7 +47,7 @@ instead of hardcoding your secrets into the configuration file. | **field** | **type** | **required** | **description** | |------------------------|:--------:|:------------:|----------------------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "cassandra". | +| type | string | true | Must be "cassandra". | | hosts | string[] | true | List of IP addresses to connect to (e.g., ["192.168.1.1:9042", "192.168.1.2:9042","192.168.1.3:9042"]). The default port is 9042 if not specified. | | keyspace | string | true | Name of the Cassandra keyspace to connect to (e.g., "my_keyspace"). | | protoVersion | integer | false | Protocol version for the Cassandra connection (e.g., 4). | diff --git a/docs/en/resources/sources/clickhouse.md b/docs/en/resources/sources/clickhouse.md index 2442899ce5..378e52b22c 100644 --- a/docs/en/resources/sources/clickhouse.md +++ b/docs/en/resources/sources/clickhouse.md @@ -46,31 +46,31 @@ ClickHouse supports multiple protocols: ### Secure Connection Example ```yaml -sources: - secure-clickhouse-source: - kind: clickhouse - host: clickhouse.example.com - port: "8443" - database: analytics - user: ${CLICKHOUSE_USER} - password: ${CLICKHOUSE_PASSWORD} - protocol: https - secure: true +kind: sources +name: secure-clickhouse-source +type: clickhouse +host: clickhouse.example.com +port: "8443" +database: analytics +user: ${CLICKHOUSE_USER} +password: ${CLICKHOUSE_PASSWORD} +protocol: https +secure: true ``` ### HTTP Protocol Example ```yaml -sources: - http-clickhouse-source: - kind: clickhouse - host: localhost - port: "8123" - database: logs - user: ${CLICKHOUSE_USER} - password: ${CLICKHOUSE_PASSWORD} - protocol: http - secure: false +kind: sources +name: http-clickhouse-source +type: clickhouse +host: localhost +port: "8123" +database: logs +user: ${CLICKHOUSE_USER} +password: ${CLICKHOUSE_PASSWORD} +protocol: http +secure: false ``` {{< notice tip >}} @@ -82,7 +82,7 @@ instead of hardcoding your secrets into the configuration file. | **field** | **type** | **required** | **description** | |-----------|:--------:|:------------:|-------------------------------------------------------------------------------------| -| kind | string | true | Must be "clickhouse". | +| type | string | true | Must be "clickhouse". | | host | string | true | IP address or hostname to connect to (e.g. "127.0.0.1" or "clickhouse.example.com") | | port | string | true | Port to connect to (e.g. "8443" for HTTPS, "8123" for HTTP) | | database | string | true | Name of the ClickHouse database to connect to (e.g. "my_database"). | diff --git a/docs/en/resources/sources/cloud-gda.md b/docs/en/resources/sources/cloud-gda.md index dc400f17e8..5d65df3cb7 100644 --- a/docs/en/resources/sources/cloud-gda.md +++ b/docs/en/resources/sources/cloud-gda.md @@ -20,21 +20,22 @@ Authentication can be handled in two ways: ## Example ```yaml -sources: - my-gda-source: - kind: cloud-gemini-data-analytics - projectId: my-project-id - - my-oauth-gda-source: - kind: cloud-gemini-data-analytics - projectId: my-project-id - useClientOAuth: true +kind: sources +name: my-gda-source +type: cloud-gemini-data-analytics +projectId: my-project-id +--- +kind: sources +name: my-oauth-gda-source +type: cloud-gemini-data-analytics +projectId: my-project-id +useClientOAuth: true ``` ## Reference | **field** | **type** | **required** | **description** | | -------------- | :------: | :----------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| kind | string | true | Must be "cloud-gemini-data-analytics". | +| type | string | true | Must be "cloud-gemini-data-analytics". | | projectId | string | true | The Google Cloud Project ID where the API is enabled. | | useClientOAuth | boolean | false | If true, the source uses the token provided by the caller (forwarded to the API). Otherwise, it uses server-side Application Default Credentials (ADC). Defaults to `false`. | diff --git a/docs/en/resources/sources/cloud-healthcare.md b/docs/en/resources/sources/cloud-healthcare.md index 117079688a..b1bf3d6c35 100644 --- a/docs/en/resources/sources/cloud-healthcare.md +++ b/docs/en/resources/sources/cloud-healthcare.md @@ -123,41 +123,41 @@ identity used has been granted the correct IAM permissions. Initialize a Cloud Healthcare API source that uses ADC: ```yaml -sources: - my-healthcare-source: - kind: "cloud-healthcare" - project: "my-project-id" - region: "us-central1" - dataset: "my-healthcare-dataset-id" - # allowedFhirStores: # Optional: Restricts tool access to a specific list of FHIR store IDs. - # - "my_fhir_store_1" - # allowedDicomStores: # Optional: Restricts tool access to a specific list of DICOM store IDs. - # - "my_dicom_store_1" - # - "my_dicom_store_2" +kind: sources +name: my-healthcare-source +type: "cloud-healthcare" +project: "my-project-id" +region: "us-central1" +dataset: "my-healthcare-dataset-id" +# allowedFhirStores: # Optional: Restricts tool access to a specific list of FHIR store IDs. +# - "my_fhir_store_1" +# allowedDicomStores: # Optional: Restricts tool access to a specific list of DICOM store IDs. +# - "my_dicom_store_1" +# - "my_dicom_store_2" ``` Initialize a Cloud Healthcare API source that uses the client's access token: ```yaml -sources: - my-healthcare-client-auth-source: - kind: "cloud-healthcare" - project: "my-project-id" - region: "us-central1" - dataset: "my-healthcare-dataset-id" - useClientOAuth: true - # allowedFhirStores: # Optional: Restricts tool access to a specific list of FHIR store IDs. - # - "my_fhir_store_1" - # allowedDicomStores: # Optional: Restricts tool access to a specific list of DICOM store IDs. - # - "my_dicom_store_1" - # - "my_dicom_store_2" +kind: sources +name: my-healthcare-client-auth-source +type: "cloud-healthcare" +project: "my-project-id" +region: "us-central1" +dataset: "my-healthcare-dataset-id" +useClientOAuth: true +# allowedFhirStores: # Optional: Restricts tool access to a specific list of FHIR store IDs. +# - "my_fhir_store_1" +# allowedDicomStores: # Optional: Restricts tool access to a specific list of DICOM store IDs. +# - "my_dicom_store_1" +# - "my_dicom_store_2" ``` ## Reference | **field** | **type** | **required** | **description** | |--------------------|:--------:|:------------:|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "cloud-healthcare". | +| type | string | true | Must be "cloud-healthcare". | | project | string | true | ID of the GCP project that the dataset lives in. | | region | string | true | Specifies the region (e.g., 'us', 'asia-northeast1') of the healthcare dataset. [Learn More](https://cloud.google.com/healthcare-api/docs/regions) | | dataset | string | true | ID of the healthcare dataset. | diff --git a/docs/en/resources/sources/cloud-monitoring.md b/docs/en/resources/sources/cloud-monitoring.md index 84b700721f..dc4847549a 100644 --- a/docs/en/resources/sources/cloud-monitoring.md +++ b/docs/en/resources/sources/cloud-monitoring.md @@ -25,18 +25,19 @@ Authentication can be handled in two ways: ## Example ```yaml -sources: - my-cloud-monitoring: - kind: cloud-monitoring - - my-oauth-cloud-monitoring: - kind: cloud-monitoring - useClientOAuth: true +kind: sources +name: my-cloud-monitoring +type: cloud-monitoring +--- +kind: sources +name: my-oauth-cloud-monitoring +type: cloud-monitoring +useClientOAuth: true ``` ## Reference | **field** | **type** | **required** | **description** | |----------------|:--------:|:------------:|------------------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "cloud-monitoring". | +| type | string | true | Must be "cloud-monitoring". | | useClientOAuth | boolean | false | If true, the source will use client-side OAuth for authorization. Otherwise, it will use Application Default Credentials. Defaults to `false`. | diff --git a/docs/en/resources/sources/cloud-sql-admin.md b/docs/en/resources/sources/cloud-sql-admin.md index e66448725e..51462e982d 100644 --- a/docs/en/resources/sources/cloud-sql-admin.md +++ b/docs/en/resources/sources/cloud-sql-admin.md @@ -24,19 +24,20 @@ Authentication can be handled in two ways: ## Example ```yaml -sources: - my-cloud-sql-admin: - kind: cloud-sql-admin - - my-oauth-cloud-sql-admin: - kind: cloud-sql-admin - useClientOAuth: true +kind: sources +name: my-cloud-sql-admin +type: cloud-sql-admin +--- +kind: sources +name: my-oauth-cloud-sql-admin +type: cloud-sql-admin +useClientOAuth: true ``` ## Reference | **field** | **type** | **required** | **description** | | -------------- | :------: | :----------: | ---------------------------------------------------------------------------------------------------------------------------------------------- | -| kind | string | true | Must be "cloud-sql-admin". | +| type | string | true | Must be "cloud-sql-admin". | | defaultProject | string | false | The Google Cloud project ID to use for Cloud SQL infrastructure tools. | | useClientOAuth | boolean | false | If true, the source will use client-side OAuth for authorization. Otherwise, it will use Application Default Credentials. Defaults to `false`. | diff --git a/docs/en/resources/sources/cloud-sql-mssql.md b/docs/en/resources/sources/cloud-sql-mssql.md index 9477e44c93..ef3ce3cebe 100644 --- a/docs/en/resources/sources/cloud-sql-mssql.md +++ b/docs/en/resources/sources/cloud-sql-mssql.md @@ -87,16 +87,16 @@ Currently, this source only uses standard authentication. You will need to ## Example ```yaml -sources: - my-cloud-sql-mssql-instance: - kind: cloud-sql-mssql - project: my-project - region: my-region - instance: my-instance - database: my_db - user: ${USER_NAME} - password: ${PASSWORD} - # ipType: private +kind: sources +name: my-cloud-sql-mssql-instance +type: cloud-sql-mssql +project: my-project +region: my-region +instance: my-instance +database: my_db +user: ${USER_NAME} +password: ${PASSWORD} +# ipType: private ``` {{< notice tip >}} @@ -108,7 +108,7 @@ instead of hardcoding your secrets into the configuration file. | **field** | **type** | **required** | **description** | |-----------|:--------:|:------------:|------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "cloud-sql-mssql". | +| type | string | true | Must be "cloud-sql-mssql". | | project | string | true | Id of the GCP project that the cluster was created in (e.g. "my-project-id"). | | region | string | true | Name of the GCP region that the cluster was created in (e.g. "us-central1"). | | instance | string | true | Name of the Cloud SQL instance within the cluster (e.g. "my-instance"). | diff --git a/docs/en/resources/sources/cloud-sql-mysql.md b/docs/en/resources/sources/cloud-sql-mysql.md index e9f89f22a9..ba0c1b1f26 100644 --- a/docs/en/resources/sources/cloud-sql-mysql.md +++ b/docs/en/resources/sources/cloud-sql-mysql.md @@ -128,16 +128,16 @@ To connect using IAM authentication: ## Example ```yaml -sources: - my-cloud-sql-mysql-source: - kind: cloud-sql-mysql - project: my-project-id - region: us-central1 - instance: my-instance - database: my_db - user: ${USER_NAME} - password: ${PASSWORD} - # ipType: "private" +kind: sources +name: my-cloud-sql-mysql-source +type: cloud-sql-mysql +project: my-project-id +region: us-central1 +instance: my-instance +database: my_db +user: ${USER_NAME} +password: ${PASSWORD} +# ipType: "private" ``` {{< notice tip >}} @@ -149,7 +149,7 @@ instead of hardcoding your secrets into the configuration file. | **field** | **type** | **required** | **description** | |-----------|:--------:|:------------:|------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "cloud-sql-mysql". | +| type | string | true | Must be "cloud-sql-mysql". | | project | string | true | Id of the GCP project that the cluster was created in (e.g. "my-project-id"). | | region | string | true | Name of the GCP region that the cluster was created in (e.g. "us-central1"). | | instance | string | true | Name of the Cloud SQL instance within the cluster (e.g. "my-instance"). | diff --git a/docs/en/resources/sources/cloud-sql-pg.md b/docs/en/resources/sources/cloud-sql-pg.md index 2ecdcee6ac..3b5f54781d 100644 --- a/docs/en/resources/sources/cloud-sql-pg.md +++ b/docs/en/resources/sources/cloud-sql-pg.md @@ -178,16 +178,16 @@ To connect using IAM authentication: ## Example ```yaml -sources: - my-cloud-sql-pg-source: - kind: cloud-sql-postgres - project: my-project-id - region: us-central1 - instance: my-instance - database: my_db - user: ${USER_NAME} - password: ${PASSWORD} - # ipType: "private" +kind: sources +name: my-cloud-sql-pg-source +type: cloud-sql-postgres +project: my-project-id +region: us-central1 +instance: my-instance +database: my_db +user: ${USER_NAME} +password: ${PASSWORD} +# ipType: "private" ``` {{< notice tip >}} @@ -199,7 +199,7 @@ instead of hardcoding your secrets into the configuration file. | **field** | **type** | **required** | **description** | |-----------|:--------:|:------------:|--------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "cloud-sql-postgres". | +| type | string | true | Must be "cloud-sql-postgres". | | project | string | true | Id of the GCP project that the cluster was created in (e.g. "my-project-id"). | | region | string | true | Name of the GCP region that the cluster was created in (e.g. "us-central1"). | | instance | string | true | Name of the Cloud SQL instance within the cluster (e.g. "my-instance"). | diff --git a/docs/en/resources/sources/couchbase.md b/docs/en/resources/sources/couchbase.md index b571d11cfe..18703f68b8 100644 --- a/docs/en/resources/sources/couchbase.md +++ b/docs/en/resources/sources/couchbase.md @@ -19,14 +19,14 @@ allowing tools to execute SQL queries against it. ## Example ```yaml -sources: - my-couchbase-instance: - kind: couchbase - connectionString: couchbase://localhost - bucket: travel-sample - scope: inventory - username: Administrator - password: password +kind: sources +name: my-couchbase-instance +type: couchbase +connectionString: couchbase://localhost +bucket: travel-sample +scope: inventory +username: Administrator +password: password ``` {{< notice note >}} @@ -38,7 +38,7 @@ Connections](https://docs.couchbase.com/java-sdk/current/howtos/managing-connect | **field** | **type** | **required** | **description** | |----------------------|:--------:|:------------:|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "couchbase". | +| type | string | true | Must be "couchbase". | | connectionString | string | true | Connection string for the Couchbase cluster. | | bucket | string | true | Name of the bucket to connect to. | | scope | string | true | Name of the scope within the bucket. | diff --git a/docs/en/resources/sources/dataplex.md b/docs/en/resources/sources/dataplex.md index 828ee5b698..52c44166f5 100644 --- a/docs/en/resources/sources/dataplex.md +++ b/docs/en/resources/sources/dataplex.md @@ -23,10 +23,10 @@ applying artificial intelligence and machine learning. ## Example ```yaml -sources: - my-dataplex-source: - kind: "dataplex" - project: "my-project-id" +kind: sources +name: my-dataplex-source +type: "dataplex" +project: "my-project-id" ``` ## Sample System Prompt @@ -355,5 +355,5 @@ This abbreviated syntax works for the qualified predicates except for `label` in | **field** | **type** | **required** | **description** | |-----------|:--------:|:------------:|----------------------------------------------------------------------------------| -| kind | string | true | Must be "dataplex". | +| type | string | true | Must be "dataplex". | | project | string | true | ID of the GCP project used for quota and billing purposes (e.g. "my-project-id").| diff --git a/docs/en/resources/sources/dgraph.md b/docs/en/resources/sources/dgraph.md index 8ac82e03c4..e99721b73c 100644 --- a/docs/en/resources/sources/dgraph.md +++ b/docs/en/resources/sources/dgraph.md @@ -51,14 +51,14 @@ and user credentials for that namespace. ## Example ```yaml -sources: - my-dgraph-source: - kind: dgraph - dgraphUrl: https://xxxx.cloud.dgraph.io - user: ${USER_NAME} - password: ${PASSWORD} - apiKey: ${API_KEY} - namespace : 0 +kind: sources +name: my-dgraph-source +type: dgraph +dgraphUrl: https://xxxx.cloud.dgraph.io +user: ${USER_NAME} +password: ${PASSWORD} +apiKey: ${API_KEY} +namespace : 0 ``` {{< notice tip >}} @@ -70,7 +70,7 @@ instead of hardcoding your secrets into the configuration file. | **Field** | **Type** | **Required** | **Description** | |-------------|:--------:|:------------:|--------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "dgraph". | +| type | string | true | Must be "dgraph". | | dgraphUrl | string | true | Connection URI (e.g. "", ""). | | user | string | false | Name of the Dgraph user to connect as (e.g., "groot"). | | password | string | false | Password of the Dgraph user (e.g., "password"). | diff --git a/docs/en/resources/sources/elasticsearch.md b/docs/en/resources/sources/elasticsearch.md index d0451c16b1..57527e6800 100644 --- a/docs/en/resources/sources/elasticsearch.md +++ b/docs/en/resources/sources/elasticsearch.md @@ -59,18 +59,18 @@ applying permissions to an API key. ## Example ```yaml -sources: - my-elasticsearch-source: - kind: "elasticsearch" - addresses: - - "http://localhost:9200" - apikey: "my-api-key" +kind: sources +name: my-elasticsearch-source +type: "elasticsearch" +addresses: + - "http://localhost:9200" +apikey: "my-api-key" ``` ## Reference | **field** | **type** | **required** | **description** | |-----------|:--------:|:------------:|--------------------------------------------| -| kind | string | true | Must be "elasticsearch". | +| type | string | true | Must be "elasticsearch". | | addresses | []string | true | List of Elasticsearch hosts to connect to. | | apikey | string | true | The API key to use for authentication. | diff --git a/docs/en/resources/sources/firebird.md b/docs/en/resources/sources/firebird.md index 1c3a8a7696..fe7a1003a1 100644 --- a/docs/en/resources/sources/firebird.md +++ b/docs/en/resources/sources/firebird.md @@ -36,14 +36,14 @@ user][fb-users] to login to the database with. ## Example ```yaml -sources: - my_firebird_db: - kind: firebird - host: "localhost" - port: 3050 - database: "/path/to/your/database.fdb" - user: ${FIREBIRD_USER} - password: ${FIREBIRD_PASS} +kind: sources +name: my_firebird_db +type: firebird +host: "localhost" +port: 3050 +database: "/path/to/your/database.fdb" +user: ${FIREBIRD_USER} +password: ${FIREBIRD_PASS} ``` {{< notice tip >}} @@ -55,7 +55,7 @@ instead of hardcoding your secrets into the configuration file. | **field** | **type** | **required** | **description** | |-----------|:--------:|:------------:|------------------------------------------------------------------------------| -| kind | string | true | Must be "firebird". | +| type | string | true | Must be "firebird". | | host | string | true | IP address to connect to (e.g. "127.0.0.1") | | port | string | true | Port to connect to (e.g. "3050") | | database | string | true | Path to the Firebird database file (e.g. "/var/lib/firebird/data/test.fdb"). | diff --git a/docs/en/resources/sources/firestore.md b/docs/en/resources/sources/firestore.md index 5fe3c875d1..d15a44507d 100644 --- a/docs/en/resources/sources/firestore.md +++ b/docs/en/resources/sources/firestore.md @@ -61,17 +61,17 @@ database named `(default)` will be used. ## Example ```yaml -sources: - my-firestore-source: - kind: "firestore" - project: "my-project-id" - # database: "my-database" # Optional, defaults to "(default)" +kind: sources +name: my-firestore-source +type: "firestore" +project: "my-project-id" +# database: "my-database" # Optional, defaults to "(default)" ``` ## Reference | **field** | **type** | **required** | **description** | |-----------|:--------:|:------------:|----------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "firestore". | +| type | string | true | Must be "firestore". | | project | string | true | Id of the GCP project that contains the Firestore database (e.g. "my-project-id"). | | database | string | false | Name of the Firestore database to connect to. Defaults to "(default)" if not specified. | diff --git a/docs/en/resources/sources/http.md b/docs/en/resources/sources/http.md index edb25002f8..cd840318b8 100644 --- a/docs/en/resources/sources/http.md +++ b/docs/en/resources/sources/http.md @@ -21,18 +21,18 @@ and other HTTP-accessible resources. ## Example ```yaml -sources: - my-http-source: - kind: http - baseUrl: https://api.example.com/data - timeout: 10s # default to 30s - headers: - Authorization: Bearer ${API_KEY} - Content-Type: application/json - queryParams: - param1: value1 - param2: value2 - # disableSslVerification: false +kind: sources +name: my-http-source +type: http +baseUrl: https://api.example.com/data +timeout: 10s # default to 30s +headers: + Authorization: Bearer ${API_KEY} + Content-Type: application/json +queryParams: + param1: value1 + param2: value2 +# disableSslVerification: false ``` {{< notice tip >}} @@ -44,7 +44,7 @@ instead of hardcoding your secrets into the configuration file. | **field** | **type** | **required** | **description** | |------------------------|:-----------------:|:------------:|------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "http". | +| type | string | true | Must be "http". | | baseUrl | string | true | The base URL for the HTTP requests (e.g., `https://api.example.com`). | | timeout | string | false | The timeout for HTTP requests (e.g., "5s", "1m", refer to [ParseDuration][parse-duration-doc] for more examples). Defaults to 30s. | | headers | map[string]string | false | Default headers to include in the HTTP requests. | diff --git a/docs/en/resources/sources/looker.md b/docs/en/resources/sources/looker.md index 75bebf37ea..d731f05138 100644 --- a/docs/en/resources/sources/looker.md +++ b/docs/en/resources/sources/looker.md @@ -56,16 +56,16 @@ To initialize the application default credential run `gcloud auth login ## Example ```yaml -sources: - my-looker-source: - kind: looker - base_url: http://looker.example.com - client_id: ${LOOKER_CLIENT_ID} - client_secret: ${LOOKER_CLIENT_SECRET} - project: ${LOOKER_PROJECT} - location: ${LOOKER_LOCATION} - verify_ssl: true - timeout: 600s +kind: sources +name: my-looker-source +type: looker +base_url: http://looker.example.com +client_id: ${LOOKER_CLIENT_ID} +client_secret: ${LOOKER_CLIENT_SECRET} +project: ${LOOKER_PROJECT} +location: ${LOOKER_LOCATION} +verify_ssl: true +timeout: 600s ``` The Looker base url will look like "https://looker.example.com", don't include @@ -93,7 +93,7 @@ instead of hardcoding your secrets into the configuration file. | **field** | **type** | **required** | **description** | |----------------------|:--------:|:------------:|-----------------------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "looker". | +| type | string | true | Must be "looker". | | base_url | string | true | The URL of your Looker server with no trailing /. | | client_id | string | false | The client id assigned by Looker. | | client_secret | string | false | The client secret assigned by Looker. | diff --git a/docs/en/resources/sources/mariadb.md b/docs/en/resources/sources/mariadb.md index c956274fde..67854f4a3d 100644 --- a/docs/en/resources/sources/mariadb.md +++ b/docs/en/resources/sources/mariadb.md @@ -45,18 +45,18 @@ MariaDB user][mariadb-users] to log in to the database. ## Example ```yaml -sources: - my_mariadb_db: - kind: mysql - host: 127.0.0.1 - port: 3306 - database: my_db - user: ${MARIADB_USER} - password: ${MARIADB_PASS} - # Optional TLS and other driver parameters. For example, enable preferred TLS: - # queryParams: - # tls: preferred - queryTimeout: 30s # Optional: query timeout duration +kind: sources +name: my_mariadb_db +type: mysql +host: 127.0.0.1 +port: 3306 +database: my_db +user: ${MARIADB_USER} +password: ${MARIADB_PASS} +# Optional TLS and other driver parameters. For example, enable preferred TLS: +# queryParams: +# tls: preferred +queryTimeout: 30s # Optional: query timeout duration ``` {{< notice tip >}} @@ -68,7 +68,7 @@ Use environment variables instead of committing credentials to source files. | **field** | **type** | **required** | **description** | | ------------ | :------: | :----------: | ----------------------------------------------------------------------------------------------- | -| kind | string | true | Must be `mysql`. | +| type | string | true | Must be `mysql`. | | host | string | true | IP address to connect to (e.g. "127.0.0.1"). | | port | string | true | Port to connect to (e.g. "3307"). | | database | string | true | Name of the MariaDB database to connect to (e.g. "my_db"). | diff --git a/docs/en/resources/sources/mindsdb.md b/docs/en/resources/sources/mindsdb.md index 5ea8f4a147..6ec7e57021 100644 --- a/docs/en/resources/sources/mindsdb.md +++ b/docs/en/resources/sources/mindsdb.md @@ -125,15 +125,15 @@ can omit the password field. ## Example ```yaml -sources: - my-mindsdb-source: - kind: mindsdb - host: 127.0.0.1 - port: 3306 - database: my_db - user: ${USER_NAME} - password: ${PASSWORD} # Optional: omit if MindsDB is configured without authentication - queryTimeout: 30s # Optional: query timeout duration +kind: sources +name: my-mindsdb-source +type: mindsdb +host: 127.0.0.1 +port: 3306 +database: my_db +user: ${USER_NAME} +password: ${PASSWORD} # Optional: omit if MindsDB is configured without authentication +queryTimeout: 30s # Optional: query timeout duration ``` ### Working Configuration Example @@ -141,13 +141,13 @@ sources: Here's a working configuration that has been tested: ```yaml -sources: - my-pg-source: - kind: mindsdb - host: 127.0.0.1 - port: 47335 - database: files - user: mindsdb +kind: sources +name: my-pg-source +type: mindsdb +host: 127.0.0.1 +port: 47335 +database: files +user: mindsdb ``` {{< notice tip >}} @@ -176,7 +176,7 @@ With MindsDB integration, you can: | **field** | **type** | **required** | **description** | |--------------|:--------:|:------------:|--------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "mindsdb". | +| type | string | true | Must be "mindsdb". | | host | string | true | IP address to connect to (e.g. "127.0.0.1"). | | port | string | true | Port to connect to (e.g. "3306"). | | database | string | true | Name of the MindsDB database to connect to (e.g. "my_db"). | diff --git a/docs/en/resources/sources/mongodb.md b/docs/en/resources/sources/mongodb.md index 91fbe23957..50e3a63dce 100644 --- a/docs/en/resources/sources/mongodb.md +++ b/docs/en/resources/sources/mongodb.md @@ -17,10 +17,10 @@ flexible, JSON-like documents, making it easy to develop and scale applications. ## Example ```yaml -sources: - my-mongodb: - kind: mongodb - uri: "mongodb+srv://username:password@host.mongodb.net" +kind: sources +name: my-mongodb +type: mongodb +uri: "mongodb+srv://username:password@host.mongodb.net" ``` @@ -28,5 +28,5 @@ sources: | **field** | **type** | **required** | **description** | |-----------|:--------:|:------------:|-------------------------------------------------------------------| -| kind | string | true | Must be "mongodb". | +| type | string | true | Must be "mongodb". | | uri | string | true | connection string to connect to MongoDB | diff --git a/docs/en/resources/sources/mssql.md b/docs/en/resources/sources/mssql.md index 424d781c33..e1b36228ad 100644 --- a/docs/en/resources/sources/mssql.md +++ b/docs/en/resources/sources/mssql.md @@ -39,15 +39,15 @@ SQL Server user][mssql-users] to login to the database with. ## Example ```yaml -sources: - my-mssql-source: - kind: mssql - host: 127.0.0.1 - port: 1433 - database: my_db - user: ${USER_NAME} - password: ${PASSWORD} - # encrypt: strict +kind: sources +name: my-mssql-source +type: mssql +host: 127.0.0.1 +port: 1433 +database: my_db +user: ${USER_NAME} +password: ${PASSWORD} +# encrypt: strict ``` {{< notice tip >}} @@ -59,7 +59,7 @@ instead of hardcoding your secrets into the configuration file. | **field** | **type** | **required** | **description** | |-----------|:--------:|:------------:|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "mssql". | +| type | string | true | Must be "mssql". | | host | string | true | IP address to connect to (e.g. "127.0.0.1"). | | port | string | true | Port to connect to (e.g. "1433"). | | database | string | true | Name of the SQL Server database to connect to (e.g. "my_db"). | diff --git a/docs/en/resources/sources/mysql.md b/docs/en/resources/sources/mysql.md index 95f2b96d7c..ee294bc8ff 100644 --- a/docs/en/resources/sources/mysql.md +++ b/docs/en/resources/sources/mysql.md @@ -49,18 +49,18 @@ MySQL user][mysql-users] to login to the database with. ## Example ```yaml -sources: - my-mysql-source: - kind: mysql - host: 127.0.0.1 - port: 3306 - database: my_db - user: ${USER_NAME} - password: ${PASSWORD} - # Optional TLS and other driver parameters. For example, enable preferred TLS: - # queryParams: - # tls: preferred - queryTimeout: 30s # Optional: query timeout duration +kind: sources +name: my-mysql-source +type: mysql +host: 127.0.0.1 +port: 3306 +database: my_db +user: ${USER_NAME} +password: ${PASSWORD} +# Optional TLS and other driver parameters. For example, enable preferred TLS: +# queryParams: +# tls: preferred +queryTimeout: 30s # Optional: query timeout duration ``` {{< notice tip >}} @@ -72,7 +72,7 @@ instead of hardcoding your secrets into the configuration file. | **field** | **type** | **required** | **description** | | ------------ | :------: | :----------: | ----------------------------------------------------------------------------------------------- | -| kind | string | true | Must be "mysql". | +| type | string | true | Must be "mysql". | | host | string | true | IP address to connect to (e.g. "127.0.0.1"). | | port | string | true | Port to connect to (e.g. "3306"). | | database | string | true | Name of the MySQL database to connect to (e.g. "my_db"). | diff --git a/docs/en/resources/sources/neo4j.md b/docs/en/resources/sources/neo4j.md index 223915c337..0400ea25d5 100644 --- a/docs/en/resources/sources/neo4j.md +++ b/docs/en/resources/sources/neo4j.md @@ -33,13 +33,13 @@ user if available. ## Example ```yaml -sources: - my-neo4j-source: - kind: neo4j - uri: neo4j+s://xxxx.databases.neo4j.io:7687 - user: ${USER_NAME} - password: ${PASSWORD} - database: "neo4j" +kind: sources +name: my-neo4j-source +type: neo4j +uri: neo4j+s://xxxx.databases.neo4j.io:7687 +user: ${USER_NAME} +password: ${PASSWORD} +database: "neo4j" ``` {{< notice tip >}} @@ -51,7 +51,7 @@ instead of hardcoding your secrets into the configuration file. | **field** | **type** | **required** | **description** | |-----------|:--------:|:------------:|----------------------------------------------------------------------| -| kind | string | true | Must be "neo4j". | +| type | string | true | Must be "neo4j". | | uri | string | true | Connect URI ("bolt://localhost", "neo4j+s://xxx.databases.neo4j.io") | | user | string | true | Name of the Neo4j user to connect as (e.g. "neo4j"). | | password | string | true | Password of the Neo4j user (e.g. "my-password"). | diff --git a/docs/en/resources/sources/oceanbase.md b/docs/en/resources/sources/oceanbase.md index b26b46b8be..24e24f5bfe 100644 --- a/docs/en/resources/sources/oceanbase.md +++ b/docs/en/resources/sources/oceanbase.md @@ -33,15 +33,15 @@ with SSL). ## Example ```yaml -sources: - my-oceanbase-source: - kind: oceanbase - host: 127.0.0.1 - port: 2881 - database: my_db - user: ${USER_NAME} - password: ${PASSWORD} - queryTimeout: 30s # Optional: query timeout duration +kind: sources +name: my-oceanbase-source +type: oceanbase +host: 127.0.0.1 +port: 2881 +database: my_db +user: ${USER_NAME} +password: ${PASSWORD} +queryTimeout: 30s # Optional: query timeout duration ``` {{< notice tip >}} @@ -53,7 +53,7 @@ instead of hardcoding your secrets into the configuration file. | **field** | **type** | **required** | **description** | | ------------ | :------: | :----------: |-------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "oceanbase". | +| type | string | true | Must be "oceanbase". | | host | string | true | IP address to connect to (e.g. "127.0.0.1"). | | port | string | true | Port to connect to (e.g. "2881"). | | database | string | true | Name of the OceanBase database to connect to (e.g. "my_db"). | diff --git a/docs/en/resources/sources/oracle.md b/docs/en/resources/sources/oracle.md index 51fa18fe13..8778838cf6 100644 --- a/docs/en/resources/sources/oracle.md +++ b/docs/en/resources/sources/oracle.md @@ -90,27 +90,27 @@ using a TNS (Transparent Network Substrate) alias. This example demonstrates the four connection methods you could choose from: ```yaml -sources: - my-oracle-source: - kind: oracle - - # --- Choose one connection method --- - # 1. Host, Port, and Service Name - host: 127.0.0.1 - port: 1521 - serviceName: XEPDB1 +kind: sources +name: my-oracle-source +type: oracle - # 2. Direct Connection String - connectionString: "127.0.0.1:1521/XEPDB1" +# --- Choose one connection method --- +# 1. Host, Port, and Service Name +host: 127.0.0.1 +port: 1521 +serviceName: XEPDB1 - # 3. TNS Alias (requires tnsnames.ora) - tnsAlias: "MY_DB_ALIAS" - tnsAdmin: "/opt/oracle/network/admin" # Optional: overrides TNS_ADMIN env var +# 2. Direct Connection String +connectionString: "127.0.0.1:1521/XEPDB1" - user: ${USER_NAME} - password: ${PASSWORD} +# 3. TNS Alias (requires tnsnames.ora) +tnsAlias: "MY_DB_ALIAS" +tnsAdmin: "/opt/oracle/network/admin" # Optional: overrides TNS_ADMIN env var - # Optional: Set to true to use the OCI-based driver for advanced features (Requires Oracle Instant Client) +user: ${USER_NAME} +password: ${PASSWORD} + +# Optional: Set to true to use the OCI-based driver for advanced features (Requires Oracle Instant Client) ``` ### Using an Oracle Wallet @@ -122,15 +122,15 @@ Oracle Wallet allows you to store credentails used for database connection. Depe The `go-ora` driver uses the `walletLocation` field to connect to a database secured with an Oracle Wallet without standard username and password. ```yaml -sources: - pure-go-wallet: - kind: oracle - connectionString: "127.0.0.1:1521/XEPDB1" - user: ${USER_NAME} - password: ${PASSWORD} - # The TNS Alias is often required to connect to a service registered in tnsnames.ora - tnsAlias: "SECURE_DB_ALIAS" - walletLocation: "/path/to/my/wallet/directory" +kind: sources +name: pure-go-wallet +type: oracle +connectionString: "127.0.0.1:1521/XEPDB1" +user: ${USER_NAME} +password: ${PASSWORD} +# The TNS Alias is often required to connect to a service registered in tnsnames.ora +tnsAlias: "SECURE_DB_ALIAS" +walletLocation: "/path/to/my/wallet/directory" ``` #### OCI-Based Driver (`useOCI: true`) - Oracle Wallet @@ -138,15 +138,15 @@ sources: For the OCI-based driver, wallet authentication is triggered by setting tnsAdmin to the wallet directory and connecting via a tnsAlias. ```yaml -sources: - oci-wallet: - kind: oracle - connectionString: "127.0.0.1:1521/XEPDB1" - user: ${USER_NAME} - password: ${PASSWORD} - tnsAlias: "WALLET_DB_ALIAS" - tnsAdmin: "/opt/oracle/wallet" # Directory containing tnsnames.ora, sqlnet.ora, and wallet files - useOCI: true +kind: sources +name: oci-wallet +type: oracle +connectionString: "127.0.0.1:1521/XEPDB1" +user: ${USER_NAME} +password: ${PASSWORD} +tnsAlias: "WALLET_DB_ALIAS" +tnsAdmin: "/opt/oracle/wallet" # Directory containing tnsnames.ora, sqlnet.ora, and wallet files +useOCI: true ``` {{< notice tip >}} @@ -158,7 +158,7 @@ instead of hardcoding your secrets into the configuration file. | **field** | **type** | **required** | **description** | |------------------|:--------:|:------------:|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "oracle". | +| type | string | true | Must be "oracle". | | user | string | true | Name of the Oracle user to connect as (e.g. "my-oracle-user"). | | password | string | true | Password of the Oracle user (e.g. "my-password"). | | host | string | false | IP address or hostname to connect to (e.g. "127.0.0.1"). Required if not using `connectionString` or `tnsAlias`. | diff --git a/docs/en/resources/sources/postgres.md b/docs/en/resources/sources/postgres.md index 8668b46190..ed7c77aeee 100644 --- a/docs/en/resources/sources/postgres.md +++ b/docs/en/resources/sources/postgres.md @@ -107,14 +107,14 @@ PostgreSQL user][pg-users] to login to the database with. ## Example ```yaml -sources: - my-pg-source: - kind: postgres - host: 127.0.0.1 - port: 5432 - database: my_db - user: ${USER_NAME} - password: ${PASSWORD} +kind: sources +name: my-pg-source +type: postgres +host: 127.0.0.1 +port: 5432 +database: my_db +user: ${USER_NAME} +password: ${PASSWORD} ``` {{< notice tip >}} @@ -126,7 +126,7 @@ instead of hardcoding your secrets into the configuration file. | **field** | **type** | **required** | **description** | |-------------|:------------------:|:------------:|------------------------------------------------------------------------| -| kind | string | true | Must be "postgres". | +| type | string | true | Must be "postgres". | | host | string | true | IP address to connect to (e.g. "127.0.0.1") | | port | string | true | Port to connect to (e.g. "5432") | | database | string | true | Name of the Postgres database to connect to (e.g. "my_db"). | diff --git a/docs/en/resources/sources/redis.md b/docs/en/resources/sources/redis.md index c0dee699e0..51c8cfde00 100644 --- a/docs/en/resources/sources/redis.md +++ b/docs/en/resources/sources/redis.md @@ -34,16 +34,16 @@ connections must authenticate in order to connect. Specify your AUTH string in the password field: ```yaml -sources: - my-redis-instance: - kind: redis - address: - - 127.0.0.1:6379 - username: ${MY_USER_NAME} - password: ${MY_AUTH_STRING} # Omit this field if you don't have a password. - # database: 0 - # clusterEnabled: false - # useGCPIAM: false +kind: sources +name: my-redis-instance +type: redis +address: + - 127.0.0.1:6379 +username: ${MY_USER_NAME} +password: ${MY_AUTH_STRING} # Omit this field if you don't have a password. +# database: 0 +# clusterEnabled: false +# useGCPIAM: false ``` {{< notice tip >}} @@ -59,14 +59,14 @@ string. Here is an example tools.yaml config with [AUTH][auth] enabled: ```yaml -sources: - my-redis-cluster-instance: - kind: memorystore-redis - address: - - 127.0.0.1:6379 - password: ${MY_AUTH_STRING} - # useGCPIAM: false - # clusterEnabled: false +kind: sources +name: my-redis-cluster-instance +type: memorystore-redis +address: + - 127.0.0.1:6379 +password: ${MY_AUTH_STRING} +# useGCPIAM: false +# clusterEnabled: false ``` Memorystore Redis Cluster supports IAM authentication instead. Grant your @@ -76,13 +76,13 @@ Here is an example tools.yaml config for Memorystore Redis Cluster instances using IAM authentication: ```yaml -sources: - my-redis-cluster-instance: - kind: memorystore-redis - address: - - 127.0.0.1:6379 - useGCPIAM: true - clusterEnabled: true +kind: sources +name: my-redis-cluster-instance +type: memorystore-redis +address: + - 127.0.0.1:6379 +useGCPIAM: true +clusterEnabled: true ``` [iam]: https://cloud.google.com/memorystore/docs/cluster/about-iam-auth @@ -91,7 +91,7 @@ sources: | **field** | **type** | **required** | **description** | |----------------|:--------:|:------------:|---------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "memorystore-redis". | +| type | string | true | Must be "memorystore-redis". | | address | string | true | Primary endpoint for the Memorystore Redis instance to connect to. | | username | string | false | If you are using a non-default user, specify the user name here. If you are using Memorystore for Redis, leave this field blank | | password | string | false | If you have [Redis AUTH][auth] enabled, specify the AUTH string here | diff --git a/docs/en/resources/sources/serverless-spark.md b/docs/en/resources/sources/serverless-spark.md index 1f2afc3cec..f08c6c5e79 100644 --- a/docs/en/resources/sources/serverless-spark.md +++ b/docs/en/resources/sources/serverless-spark.md @@ -49,17 +49,17 @@ set up your ADC. ## Example ```yaml -sources: - my-serverless-spark-source: - kind: serverless-spark - project: my-project-id - location: us-central1 +kind: sources +name: my-serverless-spark-source +type: serverless-spark +project: my-project-id +location: us-central1 ``` ## Reference | **field** | **type** | **required** | **description** | | --------- | :------: | :----------: | ----------------------------------------------------------------- | -| kind | string | true | Must be "serverless-spark". | +| type | string | true | Must be "serverless-spark". | | project | string | true | ID of the GCP project with Serverless for Apache Spark resources. | | location | string | true | Location containing Serverless for Apache Spark resources. | diff --git a/docs/en/resources/sources/singlestore.md b/docs/en/resources/sources/singlestore.md index fef332a7d8..9acde19ff0 100644 --- a/docs/en/resources/sources/singlestore.md +++ b/docs/en/resources/sources/singlestore.md @@ -39,15 +39,15 @@ database user][singlestore-user] to login to the database with. ## Example ```yaml -sources: - my-singlestore-source: - kind: singlestore - host: 127.0.0.1 - port: 3306 - database: my_db - user: ${USER_NAME} - password: ${PASSWORD} - queryTimeout: 30s # Optional: query timeout duration +kind: sources +name: my-singlestore-source +type: singlestore +host: 127.0.0.1 +port: 3306 +database: my_db +user: ${USER_NAME} +password: ${PASSWORD} +queryTimeout: 30s # Optional: query timeout duration ``` {{< notice tip >}} @@ -59,7 +59,7 @@ instead of hardcoding your secrets into the configuration file. | **field** | **type** | **required** | **description** | |--------------|:--------:|:------------:|-------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "singlestore". | +| type | string | true | Must be "singlestore". | | host | string | true | IP address to connect to (e.g. "127.0.0.1"). | | port | string | true | Port to connect to (e.g. "3306"). | | database | string | true | Name of the SingleStore database to connect to (e.g. "my_db"). | diff --git a/docs/en/resources/sources/snowflake.md b/docs/en/resources/sources/snowflake.md index 5981538ec5..3a048470e7 100644 --- a/docs/en/resources/sources/snowflake.md +++ b/docs/en/resources/sources/snowflake.md @@ -31,16 +31,16 @@ Snowflake user to login to the database with. ## Example ```yaml -sources: - my-sf-source: - kind: snowflake - account: ${SNOWFLAKE_ACCOUNT} - user: ${SNOWFLAKE_USER} - password: ${SNOWFLAKE_PASSWORD} - database: ${SNOWFLAKE_DATABASE} - schema: ${SNOWFLAKE_SCHEMA} - warehouse: ${SNOWFLAKE_WAREHOUSE} - role: ${SNOWFLAKE_ROLE} +kind: sources +name: my-sf-source +type: snowflake +account: ${SNOWFLAKE_ACCOUNT} +user: ${SNOWFLAKE_USER} +password: ${SNOWFLAKE_PASSWORD} +database: ${SNOWFLAKE_DATABASE} +schema: ${SNOWFLAKE_SCHEMA} +warehouse: ${SNOWFLAKE_WAREHOUSE} +role: ${SNOWFLAKE_ROLE} ``` {{< notice tip >}} @@ -52,7 +52,7 @@ instead of hardcoding your secrets into the configuration file. | **field** | **type** | **required** | **description** | |-----------|:--------:|:------------:|------------------------------------------------------------------------| -| kind | string | true | Must be "snowflake". | +| type | string | true | Must be "snowflake". | | account | string | true | Your Snowflake account identifier. | | user | string | true | Name of the Snowflake user to connect as (e.g. "my-sf-user"). | | password | string | true | Password of the Snowflake user (e.g. "my-password"). | diff --git a/docs/en/resources/sources/spanner.md b/docs/en/resources/sources/spanner.md index 373ba75446..c8039583ac 100644 --- a/docs/en/resources/sources/spanner.md +++ b/docs/en/resources/sources/spanner.md @@ -64,20 +64,20 @@ applying IAM permissions and roles to an identity. ## Example ```yaml -sources: - my-spanner-source: - kind: "spanner" - project: "my-project-id" - instance: "my-instance" - database: "my_db" - # dialect: "googlesql" +kind: sources +name: my-spanner-source +type: "spanner" +project: "my-project-id" +instance: "my-instance" +database: "my_db" +# dialect: "googlesql" ``` ## Reference | **field** | **type** | **required** | **description** | |-----------|:--------:|:------------:|---------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "spanner". | +| type | string | true | Must be "spanner". | | project | string | true | Id of the GCP project that the cluster was created in (e.g. "my-project-id"). | | instance | string | true | Name of the Spanner instance. | | database | string | true | Name of the database on the Spanner instance | diff --git a/docs/en/resources/sources/sqlite.md b/docs/en/resources/sources/sqlite.md index 5a3c6df918..aae3030347 100644 --- a/docs/en/resources/sources/sqlite.md +++ b/docs/en/resources/sources/sqlite.md @@ -48,19 +48,19 @@ You need a SQLite database file. This can be: ## Example ```yaml -sources: - my-sqlite-db: - kind: "sqlite" - database: "/path/to/database.db" +kind: sources +name: my-sqlite-db +type: "sqlite" +database: "/path/to/database.db" ``` For an in-memory database: ```yaml -sources: - my-sqlite-memory-db: - kind: "sqlite" - database: ":memory:" +kind: sources +name: my-sqlite-memory-db +type: "sqlite" +database: ":memory:" ``` ## Reference @@ -69,7 +69,7 @@ sources: | **field** | **type** | **required** | **description** | |-----------|:--------:|:------------:|---------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "sqlite". | +| type | string | true | Must be "sqlite". | | database | string | true | Path to SQLite database file, or ":memory:" for an in-memory database. | ### Connection Properties diff --git a/docs/en/resources/sources/tidb.md b/docs/en/resources/sources/tidb.md index 3b22db0bdb..2bb4b62c66 100644 --- a/docs/en/resources/sources/tidb.md +++ b/docs/en/resources/sources/tidb.md @@ -46,29 +46,29 @@ console. - TiDB Cloud ```yaml - sources: - my-tidb-cloud-source: - kind: tidb - host: gateway01.us-west-2.prod.aws.tidbcloud.com - port: 4000 - database: my_db - user: ${TIDB_USERNAME} - password: ${TIDB_PASSWORD} - # SSL is automatically enabled for TiDB Cloud + kind: sources + name: my-tidb-cloud-source + type: tidb + host: gateway01.us-west-2.prod.aws.tidbcloud.com + port: 4000 + database: my_db + user: ${TIDB_USERNAME} + password: ${TIDB_PASSWORD} + # SSL is automatically enabled for TiDB Cloud ``` - Self-Hosted TiDB ```yaml - sources: - my-tidb-source: - kind: tidb - host: 127.0.0.1 - port: 4000 - database: my_db - user: ${TIDB_USERNAME} - password: ${TIDB_PASSWORD} - # ssl: true # Optional: enable SSL for secure connections + kind: sources + name: my-tidb-source + type: tidb + host: 127.0.0.1 + port: 4000 + database: my_db + user: ${TIDB_USERNAME} + password: ${TIDB_PASSWORD} + # ssl: true # Optional: enable SSL for secure connections ``` {{< notice tip >}} @@ -80,7 +80,7 @@ instead of hardcoding your secrets into the configuration file. | **field** | **type** | **required** | **description** | |-----------|:--------:|:------------:|--------------------------------------------------------------------------------------------| -| kind | string | true | Must be "tidb". | +| type | string | true | Must be "tidb". | | host | string | true | IP address or hostname to connect to (e.g. "127.0.0.1" or "gateway01.*.tidbcloud.com"). | | port | string | true | Port to connect to (typically "4000" for TiDB). | | database | string | true | Name of the TiDB database to connect to (e.g. "my_db"). | diff --git a/docs/en/resources/sources/trino.md b/docs/en/resources/sources/trino.md index e6a9122681..d3ae1e6fcf 100644 --- a/docs/en/resources/sources/trino.md +++ b/docs/en/resources/sources/trino.md @@ -32,15 +32,15 @@ the catalogs and schemas you want to query. ## Example ```yaml -sources: - my-trino-source: - kind: trino - host: trino.example.com - port: "8080" - user: ${TRINO_USER} # Optional for anonymous access - password: ${TRINO_PASSWORD} # Optional - catalog: hive - schema: default +kind: sources +name: my-trino-source +type: trino +host: trino.example.com +port: "8080" +user: ${TRINO_USER} # Optional for anonymous access +password: ${TRINO_PASSWORD} # Optional +catalog: hive +schema: default ``` {{< notice tip >}} @@ -52,7 +52,7 @@ instead of hardcoding your secrets into the configuration file. | **field** | **type** | **required** | **description** | | ---------------------- | :------: | :----------: | ---------------------------------------------------------------------------- | -| kind | string | true | Must be "trino". | +| type | string | true | Must be "trino". | | host | string | true | Trino coordinator hostname (e.g. "trino.example.com") | | port | string | true | Trino coordinator port (e.g. "8080", "8443") | | user | string | false | Username for authentication (e.g. "analyst"). Optional for anonymous access. | diff --git a/docs/en/resources/sources/valkey.md b/docs/en/resources/sources/valkey.md index 8b1e68e947..aedb8759aa 100644 --- a/docs/en/resources/sources/valkey.md +++ b/docs/en/resources/sources/valkey.md @@ -27,16 +27,16 @@ the [official Valkey website](https://valkey.io/topics/quickstart/). ## Example ```yaml -sources: - my-valkey-instance: - kind: valkey - address: - - 127.0.0.1:6379 - username: ${YOUR_USERNAME} - password: ${YOUR_PASSWORD} - # database: 0 - # useGCPIAM: false - # disableCache: false +kind: sources +name: my-valkey-instance +type: valkey +address: + - 127.0.0.1:6379 +username: ${YOUR_USERNAME} +password: ${YOUR_PASSWORD} +# database: 0 +# useGCPIAM: false +# disableCache: false ``` {{< notice tip >}} @@ -51,12 +51,12 @@ authentication. Grant your account the required [IAM role][iam] and set `useGCPIAM` to `true`: ```yaml -sources: - my-valkey-instance: - kind: valkey - address: - - 127.0.0.1:6379 - useGCPIAM: true +kind: sources +name: my-valkey-instance +type: valkey +address: + - 127.0.0.1:6379 +useGCPIAM: true ``` [iam]: https://cloud.google.com/memorystore/docs/valkey/about-iam-auth @@ -65,7 +65,7 @@ sources: | **field** | **type** | **required** | **description** | |--------------|:--------:|:------------:|----------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "valkey". | +| type | string | true | Must be "valkey". | | address | []string | true | Endpoints for the Valkey instance to connect to. | | username | string | false | If you are using a non-default user, specify the user name here. If you are using Memorystore for Valkey, leave this field blank | | password | string | false | Password for the Valkey instance | diff --git a/docs/en/resources/sources/yugabytedb.md b/docs/en/resources/sources/yugabytedb.md index cdd1362197..b923327cdc 100644 --- a/docs/en/resources/sources/yugabytedb.md +++ b/docs/en/resources/sources/yugabytedb.md @@ -17,23 +17,23 @@ compatibility. ## Example ```yaml -sources: - my-yb-source: - kind: yugabytedb - host: 127.0.0.1 - port: 5433 - database: yugabyte - user: ${USER_NAME} - password: ${PASSWORD} - loadBalance: true - topologyKeys: cloud.region.zone1:1,cloud.region.zone2:2 +kind: sources +name: my-yb-source +type: yugabytedb +host: 127.0.0.1 +port: 5433 +database: yugabyte +user: ${USER_NAME} +password: ${PASSWORD} +loadBalance: true +topologyKeys: cloud.region.zone1:1,cloud.region.zone2:2 ``` ## Reference | **field** | **type** | **required** | **description** | |------------------------------|:--------:|:------------:|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "yugabytedb". | +| type | string | true | Must be "yugabytedb". | | host | string | true | IP address to connect to. | | port | integer | true | Port to connect to. The default port is 5433. | | database | string | true | Name of the YugabyteDB database to connect to. The default database name is yugabyte. | diff --git a/docs/en/resources/tools/_index.md b/docs/en/resources/tools/_index.md index 43a72427f7..aaf8f73f74 100644 --- a/docs/en/resources/tools/_index.md +++ b/docs/en/resources/tools/_index.md @@ -12,41 +12,41 @@ statement. You can define Tools as a map in the `tools` section of your `tools.yaml` file. Typically, a tool will require a source to act on: ```yaml -tools: - search_flights_by_number: - kind: postgres-sql - source: my-pg-instance - statement: | - SELECT * FROM flights - WHERE airline = $1 - AND flight_number = $2 - LIMIT 10 - description: | - Use this tool to get information for a specific flight. - Takes an airline code and flight number and returns info on the flight. - Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. - An airline code is a code for an airline service consisting of a two-character - airline designator and followed by a flight number, which is a 1 to 4 digit number. - For example, if given CY 0123, the airline is "CY", and flight_number is "123". - Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". - If the tool returns more than one option choose the date closest to today. - Example: - {{ - "airline": "CY", - "flight_number": "888", - }} - Example: - {{ - "airline": "DL", - "flight_number": "1234", - }} - parameters: - - name: airline - type: string - description: Airline unique 2 letter identifier - - name: flight_number - type: string - description: 1 to 4 digit number +kind: tools +name: search_flights_by_number +type: postgres-sql +source: my-pg-instance +statement: | + SELECT * FROM flights + WHERE airline = $1 + AND flight_number = $2 + LIMIT 10 +description: | + Use this tool to get information for a specific flight. + Takes an airline code and flight number and returns info on the flight. + Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. + An airline code is a code for an airline service consisting of a two-character + airline designator and followed by a flight number, which is a 1 to 4 digit number. + For example, if given CY 0123, the airline is "CY", and flight_number is "123". + Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". + If the tool returns more than one option choose the date closest to today. + Example: + {{ + "airline": "CY", + "flight_number": "888", + }} + Example: + {{ + "airline": "DL", + "flight_number": "1234", + }} +parameters: + - name: airline + type: string + description: Airline unique 2 letter identifier + - name: flight_number + type: string + description: 1 to 4 digit number ``` ## Specifying Parameters @@ -55,13 +55,13 @@ Parameters for each Tool will define what inputs the agent will need to provide to invoke them. Parameters should be pass as a list of Parameter objects: ```yaml - parameters: - - name: airline - type: string - description: Airline unique 2 letter identifier - - name: flight_number - type: string - description: 1 to 4 digit number +parameters: + - name: airline + type: string + description: Airline unique 2 letter identifier + - name: flight_number + type: string + description: 1 to 4 digit number ``` ### Basic Parameters @@ -71,10 +71,10 @@ most cases, the description will be provided to the LLM as context on specifying the parameter. ```yaml - parameters: - - name: airline - type: string - description: Airline unique 2 letter identifier +parameters: + - name: airline + type: string + description: Airline unique 2 letter identifier ``` | **field** | **type** | **required** | **description** | @@ -97,16 +97,16 @@ To use the `array` type, you must also specify what kind of items are in the list using the items field: ```yaml - parameters: - - name: preferred_airlines - type: array - description: A list of airline, ordered by preference. - items: - name: name - type: string - description: Name of the airline. - statement: | - SELECT * FROM airlines WHERE preferred_airlines = ANY($1); +parameters: + - name: preferred_airlines + type: array + description: A list of airline, ordered by preference. + items: + name: name + type: string + description: Name of the airline. +statement: | + SELECT * FROM airlines WHERE preferred_airlines = ANY($1); ``` | **field** | **type** | **required** | **description** | @@ -141,10 +141,10 @@ This is the default behavior when valueType is omitted. It's useful for passing a flexible group of settings. ```yaml - parameters: - - name: execution_context - type: map - description: A flexible set of key-value pairs for the execution environment. +parameters: + - name: execution_context + type: map + description: A flexible set of key-value pairs for the execution environment. ``` #### Typed Map @@ -153,11 +153,11 @@ Specify valueType to ensure all values in the map are of the same type. An error will be thrown in case of value type mismatch. ```yaml - parameters: - - name: user_scores - type: map - description: A map of user IDs to their scores. All scores must be integers. - valueType: integer # This enforces the value type for all entries. +parameters: + - name: user_scores + type: map + description: A map of user IDs to their scores. All scores must be integers. + valueType: integer # This enforces the value type for all entries. ``` ### Authenticated Parameters @@ -171,21 +171,21 @@ the required [authServices](../authServices/) to specific claims within the user's ID token. ```yaml - tools: - search_flights_by_user_id: - kind: postgres-sql - source: my-pg-instance - statement: | - SELECT * FROM flights WHERE user_id = $1 - parameters: - - name: user_id - type: string - description: Auto-populated from Google login - authServices: - # Refer to one of the `authServices` defined - - name: my-google-auth - # `sub` is the OIDC claim field for user ID - field: sub +kind: tools +name: search_flights_by_user_id +type: postgres-sql +source: my-pg-instance +statement: | + SELECT * FROM flights WHERE user_id = $1 +parameters: + - name: user_id + type: string + description: Auto-populated from Google login + authServices: + # Refer to one of the `authServices` defined + - name: my-google-auth + # `sub` is the OIDC claim field for user ID + field: sub ``` | **field** | **type** | **required** | **description** | @@ -222,31 +222,31 @@ can use `minValue` and `maxValue` to define the allowable range. {{< /notice >}} ```yaml -tools: - select_columns_from_table: - kind: postgres-sql - source: my-pg-instance - statement: | - SELECT {{array .columnNames}} FROM {{.tableName}} - description: | - Use this tool to list all information from a specific table. - Example: - {{ - "tableName": "flights", - "columnNames": ["id", "name"] - }} - templateParameters: - - name: tableName - type: string - description: Table to select from - - name: columnNames - type: array - description: The columns to select - items: - name: column - type: string - description: Name of a column to select - escape: double-quotes # with this, the statement will resolve to `SELECT "id", "name" FROM flights` +kind: tools +name: select_columns_from_table +type: postgres-sql +source: my-pg-instance +statement: | + SELECT {{array .columnNames}} FROM {{.tableName}} +description: | + Use this tool to list all information from a specific table. + Example: + {{ + "tableName": "flights", + "columnNames": ["id", "name"] + }} +templateParameters: + - name: tableName + type: string + description: Table to select from + - name: columnNames + type: array + description: The columns to select + items: + name: column + type: string + description: Name of a column to select + escape: double-quotes # with this, the statement will resolve to `SELECT "id", "name" FROM flights` ``` | **field** | **type** | **required** | **description** | @@ -267,16 +267,16 @@ specifying an `authRequired` field. Specify a list of [authServices](../authServices/) defined in the previous section. ```yaml -tools: - search_all_flight: - kind: postgres-sql - source: my-pg-instance - statement: | - SELECT * FROM flights - # A list of `authServices` defined previously - authRequired: - - my-google-auth - - other-auth-service +kind: tools +name: search_all_flight +type: postgres-sql +source: my-pg-instance +statement: | + SELECT * FROM flights +# A list of `authServices` defined previously +authRequired: + - my-google-auth + - other-auth-service ``` ## Kinds of tools diff --git a/docs/en/resources/tools/alloydb/alloydb-create-cluster.md b/docs/en/resources/tools/alloydb/alloydb-create-cluster.md index b70d320213..621feb1852 100644 --- a/docs/en/resources/tools/alloydb/alloydb-create-cluster.md +++ b/docs/en/resources/tools/alloydb/alloydb-create-cluster.md @@ -40,17 +40,17 @@ The tool takes the following input parameters: ## Example ```yaml -tools: - create_cluster: - kind: alloydb-create-cluster - source: alloydb-admin-source - description: Use this tool to create a new AlloyDB cluster in a given project and location. +kind: tools +name: create_cluster +type: alloydb-create-cluster +source: alloydb-admin-source +description: Use this tool to create a new AlloyDB cluster in a given project and location. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|------------------------------------------------------| -| kind | string | true | Must be alloydb-create-cluster. | +| type | string | true | Must be alloydb-create-cluster. | | source | string | true | The name of an `alloydb-admin` source. | | description | string | false | Description of the tool that is passed to the agent. | diff --git a/docs/en/resources/tools/alloydb/alloydb-create-instance.md b/docs/en/resources/tools/alloydb/alloydb-create-instance.md index 6a8680af94..19f6aaa95c 100644 --- a/docs/en/resources/tools/alloydb/alloydb-create-instance.md +++ b/docs/en/resources/tools/alloydb/alloydb-create-instance.md @@ -45,17 +45,17 @@ The tool takes the following input parameters: ## Example ```yaml -tools: - create_instance: - kind: alloydb-create-instance - source: alloydb-admin-source - description: Use this tool to create a new AlloyDB instance within a specified cluster. +kind: tools +name: create_instance +type: alloydb-create-instance +source: alloydb-admin-source +description: Use this tool to create a new AlloyDB instance within a specified cluster. ``` ## Reference | **field** | **type** | **required** | **description** | | ----------- | :------: | :----------: | ---------------------------------------------------- | -| kind | string | true | Must be alloydb-create-instance. | +| type | string | true | Must be alloydb-create-instance. | | source | string | true | The name of an `alloydb-admin` source. | -| description | string | false | Description of the tool that is passed to the agent. | +| description | string | false | Description of the tool that is passed to the agent. | \ No newline at end of file diff --git a/docs/en/resources/tools/alloydb/alloydb-create-user.md b/docs/en/resources/tools/alloydb/alloydb-create-user.md index b4ca9bcbb3..3c7e450781 100644 --- a/docs/en/resources/tools/alloydb/alloydb-create-user.md +++ b/docs/en/resources/tools/alloydb/alloydb-create-user.md @@ -39,17 +39,17 @@ The tool takes the following input parameters: ## Example ```yaml -tools: - create_user: - kind: alloydb-create-user - source: alloydb-admin-source - description: Use this tool to create a new database user for an AlloyDB cluster. +kind: tools +name: create_user +type: alloydb-create-user +source: alloydb-admin-source +description: Use this tool to create a new database user for an AlloyDB cluster. ``` ## Reference | **field** | **type** | **required** | **description** | | ----------- | :------: | :----------: | ---------------------------------------------------- | -| kind | string | true | Must be alloydb-create-user. | +| type | string | true | Must be alloydb-create-user. | | source | string | true | The name of an `alloydb-admin` source. | -| description | string | false | Description of the tool that is passed to the agent. | +| description | string | false | Description of the tool that is passed to the agent. | \ No newline at end of file diff --git a/docs/en/resources/tools/alloydb/alloydb-get-cluster.md b/docs/en/resources/tools/alloydb/alloydb-get-cluster.md index 29f5af0cf5..fcd5049393 100644 --- a/docs/en/resources/tools/alloydb/alloydb-get-cluster.md +++ b/docs/en/resources/tools/alloydb/alloydb-get-cluster.md @@ -3,7 +3,7 @@ title: alloydb-get-cluster type: docs weight: 1 description: "The \"alloydb-get-cluster\" tool retrieves details for a specific AlloyDB cluster.\n" -aliases: [/resources/tools/alloydb-get-cluster] +alias: [/resources/tools/alloydb-get-cluster] --- ## About @@ -21,17 +21,17 @@ specified AlloyDB cluster. It is compatible with ## Example ```yaml -tools: - get_specific_cluster: - kind: alloydb-get-cluster - source: my-alloydb-admin-source - description: Use this tool to retrieve details for a specific AlloyDB cluster. +kind: tools +name: get_specific_cluster +type: alloydb-get-cluster +source: my-alloydb-admin-source +description: Use this tool to retrieve details for a specific AlloyDB cluster. ``` ## Reference | **field** | **type** | **required** | **description** | | ----------- | :------: | :----------: | ---------------------------------------------------- | -| kind | string | true | Must be alloydb-get-cluster. | +| type | string | true | Must be alloydb-get-cluster. | | source | string | true | The name of an `alloydb-admin` source. | -| description | string | false | Description of the tool that is passed to the agent. | +| description | string | false | Description of the tool that is passed to the agent. | \ No newline at end of file diff --git a/docs/en/resources/tools/alloydb/alloydb-get-instance.md b/docs/en/resources/tools/alloydb/alloydb-get-instance.md index 0305c4bcc0..65a9a7ec81 100644 --- a/docs/en/resources/tools/alloydb/alloydb-get-instance.md +++ b/docs/en/resources/tools/alloydb/alloydb-get-instance.md @@ -22,17 +22,17 @@ specified AlloyDB instance. It is compatible with ## Example ```yaml -tools: - get_specific_instance: - kind: alloydb-get-instance - source: my-alloydb-admin-source - description: Use this tool to retrieve details for a specific AlloyDB instance. +kind: tools +name: get_specific_instance +type: alloydb-get-instance +source: my-alloydb-admin-source +description: Use this tool to retrieve details for a specific AlloyDB instance. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|------------------------------------------------------| -| kind | string | true | Must be alloydb-get-instance. | +| type | string | true | Must be alloydb-get-instance. | | source | string | true | The name of an `alloydb-admin` source. | -| description | string | false | Description of the tool that is passed to the agent. | +| description | string | false | Description of the tool that is passed to the agent. | \ No newline at end of file diff --git a/docs/en/resources/tools/alloydb/alloydb-get-user.md b/docs/en/resources/tools/alloydb/alloydb-get-user.md index afee54aab5..a223afe8f7 100644 --- a/docs/en/resources/tools/alloydb/alloydb-get-user.md +++ b/docs/en/resources/tools/alloydb/alloydb-get-user.md @@ -22,17 +22,17 @@ specified AlloyDB user. It is compatible with ## Example ```yaml -tools: - get_specific_user: - kind: alloydb-get-user - source: my-alloydb-admin-source - description: Use this tool to retrieve details for a specific AlloyDB user. +kind: tools +name: get_specific_user +type: alloydb-get-user +source: my-alloydb-admin-source +description: Use this tool to retrieve details for a specific AlloyDB user. ``` ## Reference | **field** | **type** | **required** | **description** | | ----------- | :------: | :----------: | ---------------------------------------------------- | -| kind | string | true | Must be alloydb-get-user. | +| type | string | true | Must be alloydb-get-user. | | source | string | true | The name of an `alloydb-admin` source. | -| description | string | false | Description of the tool that is passed to the agent. | +| description | string | false | Description of the tool that is passed to the agent. | \ No newline at end of file diff --git a/docs/en/resources/tools/alloydb/alloydb-list-clusters.md b/docs/en/resources/tools/alloydb/alloydb-list-clusters.md index 6f0beb3a67..644f98729b 100644 --- a/docs/en/resources/tools/alloydb/alloydb-list-clusters.md +++ b/docs/en/resources/tools/alloydb/alloydb-list-clusters.md @@ -24,17 +24,17 @@ location. The tool takes the following input parameters: ## Example ```yaml -tools: - list_clusters: - kind: alloydb-list-clusters - source: alloydb-admin-source - description: Use this tool to list all AlloyDB clusters in a given project and location. +kind: tools +name: list_clusters +type: alloydb-list-clusters +source: alloydb-admin-source +description: Use this tool to list all AlloyDB clusters in a given project and location. ``` ## Reference | **field** | **type** | **required** | **description** | | ----------- | :------: | :----------: | ---------------------------------------------------- | -| kind | string | true | Must be alloydb-list-clusters. | +| type | string | true | Must be alloydb-list-clusters. | | source | string | true | The name of an `alloydb-admin` source. | -| description | string | false | Description of the tool that is passed to the agent. | +| description | string | false | Description of the tool that is passed to the agent. | \ No newline at end of file diff --git a/docs/en/resources/tools/alloydb/alloydb-list-instances.md b/docs/en/resources/tools/alloydb/alloydb-list-instances.md index ecf1f9a8dd..fdf0c35c9d 100644 --- a/docs/en/resources/tools/alloydb/alloydb-list-instances.md +++ b/docs/en/resources/tools/alloydb/alloydb-list-instances.md @@ -26,17 +26,17 @@ parameters: ## Example ```yaml -tools: - list_instances: - kind: alloydb-list-instances - source: alloydb-admin-source - description: Use this tool to list all AlloyDB instances for a given project, cluster and location. +kind: tools +name: list_instances +type: alloydb-list-instances +source: alloydb-admin-source +description: Use this tool to list all AlloyDB instances for a given project, cluster and location. ``` ## Reference | **field** | **type** | **required** | **description** | | ----------- | :------: | :----------: | ---------------------------------------------------- | -| kind | string | true | Must be alloydb-list-instances. | +| type | string | true | Must be alloydb-list-instances. | | source | string | true | The name of an `alloydb-admin` source. | | description | string | false | Description of the tool that is passed to the agent. | diff --git a/docs/en/resources/tools/alloydb/alloydb-list-users.md b/docs/en/resources/tools/alloydb/alloydb-list-users.md index 73d3015b88..b735cd0607 100644 --- a/docs/en/resources/tools/alloydb/alloydb-list-users.md +++ b/docs/en/resources/tools/alloydb/alloydb-list-users.md @@ -22,17 +22,17 @@ The tool takes the following input parameters: ## Example ```yaml -tools: - list_users: - kind: alloydb-list-users - source: alloydb-admin-source - description: Use this tool to list all database users within an AlloyDB cluster +kind: tools +name: list_users +type: alloydb-list-users +source: alloydb-admin-source +description: Use this tool to list all database users within an AlloyDB cluster ``` ## Reference | **field** | **type** | **required** | **description** | | ----------- | :------: | :----------: | ---------------------------------------------------- | -| kind | string | true | Must be alloydb-list-users. | +| type | string | true | Must be alloydb-list-users. | | source | string | true | The name of an `alloydb-admin` source. | | description | string | false | Description of the tool that is passed to the agent. | diff --git a/docs/en/resources/tools/alloydb/alloydb-wait-for-operation.md b/docs/en/resources/tools/alloydb/alloydb-wait-for-operation.md index f5e84e5b97..98d67e9084 100644 --- a/docs/en/resources/tools/alloydb/alloydb-wait-for-operation.md +++ b/docs/en/resources/tools/alloydb/alloydb-wait-for-operation.md @@ -25,22 +25,22 @@ and shouldn't be used for production agents. ## Example ```yaml -tools: - wait_for_operation: - kind: alloydb-wait-for-operation - source: my-alloydb-admin-source - description: "This will poll on operations API until the operation is done. For checking operation status we need projectId, locationID and operationId. Once instance is created give follow up steps on how to use the variables to bring data plane MCP server up in local and remote setup." - delay: 1s - maxDelay: 4m - multiplier: 2 - maxRetries: 10 +kind: tools +name: wait_for_operation +type: alloydb-wait-for-operation +source: my-alloydb-admin-source +description: "This will poll on operations API until the operation is done. For checking operation status we need projectId, locationID and operationId. Once instance is created give follow up steps on how to use the variables to bring data plane MCP server up in local and remote setup." +delay: 1s +maxDelay: 4m +multiplier: 2 +maxRetries: 10 ``` ## Reference | **field** | **type** | **required** | **description** | | ----------- | :------: | :----------: | ---------------------------------------------------------------------------------------------------------------- | -| kind | string | true | Must be "alloydb-wait-for-operation". | +| type | string | true | Must be "alloydb-wait-for-operation". | | source | string | true | The name of a `alloydb-admin` source to use for authentication. | | description | string | false | A description of the tool. | | delay | duration | false | The initial delay between polling requests (e.g., `3s`). Defaults to 3 seconds. | diff --git a/docs/en/resources/tools/alloydbainl/alloydb-ai-nl.md b/docs/en/resources/tools/alloydbainl/alloydb-ai-nl.md index aa6d377f2c..97364c5dd8 100644 --- a/docs/en/resources/tools/alloydbainl/alloydb-ai-nl.md +++ b/docs/en/resources/tools/alloydbainl/alloydb-ai-nl.md @@ -103,29 +103,29 @@ CREATE EXTENSION IF NOT EXISTS parameterized_views; ## Example ```yaml -tools: - ask_questions: - kind: alloydb-ai-nl - source: my-alloydb-source - description: "Ask questions to check information about flights" - nlConfig: "cymbal_air_nl_config" - nlConfigParameters: - - name: user_email - type: string - description: User ID of the logged in user. - # note: we strongly recommend using features like Authenticated or - # Bound parameters to prevent the LLM from seeing these params and - # specifying values it shouldn't in the tool input - authServices: - - name: my_google_service - field: email +kind: tools +name: ask_questions +type: alloydb-ai-nl +source: my-alloydb-source +description: "Ask questions to check information about flights" +nlConfig: "cymbal_air_nl_config" +nlConfigParameters: + - name: user_email + type: string + description: User ID of the logged in user. + # note: we strongly recommend using features like Authenticated or + # Bound parameters to prevent the LLM from seeing these params and + # specifying values it shouldn't in the tool input + authServices: + - name: my_google_service + field: email ``` ## Reference | **field** | **type** | **required** | **description** | |--------------------|:---------------------------------------:|:------------:|--------------------------------------------------------------------------| -| kind | string | true | Must be "alloydb-ai-nl". | +| type | string | true | Must be "alloydb-ai-nl". | | source | string | true | Name of the AlloyDB source the natural language query should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | nlConfig | string | true | The name of the `nl_config` in AlloyDB | diff --git a/docs/en/resources/tools/bigquery/bigquery-analyze-contribution.md b/docs/en/resources/tools/bigquery/bigquery-analyze-contribution.md index 3561af3dd3..ed126246a4 100644 --- a/docs/en/resources/tools/bigquery/bigquery-analyze-contribution.md +++ b/docs/en/resources/tools/bigquery/bigquery-analyze-contribution.md @@ -64,11 +64,11 @@ the `bigquery` source: ## Example ```yaml -tools: - contribution_analyzer: - kind: bigquery-analyze-contribution - source: my-bigquery-source - description: Use this tool to run contribution analysis on a dataset in BigQuery. +kind: tools +name: contribution_analyzer +type: bigquery-analyze-contribution +source: my-bigquery-source +description: Use this tool to run contribution analysis on a dataset in BigQuery. ``` ## Sample Prompt @@ -88,6 +88,6 @@ And use the following sample prompts to call this tool: | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "bigquery-analyze-contribution". | +| type | string | true | Must be "bigquery-analyze-contribution". | | source | string | true | Name of the source the tool should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/bigquery/bigquery-conversational-analytics.md b/docs/en/resources/tools/bigquery/bigquery-conversational-analytics.md index 2c8ef29083..486db6083e 100644 --- a/docs/en/resources/tools/bigquery/bigquery-conversational-analytics.md +++ b/docs/en/resources/tools/bigquery/bigquery-conversational-analytics.md @@ -53,19 +53,19 @@ dataset specified in the `table_references` parameter. ## Example ```yaml -tools: - ask_data_insights: - kind: bigquery-conversational-analytics - source: my-bigquery-source - description: | - Use this tool to perform data analysis, get insights, or answer complex - questions about the contents of specific BigQuery tables. +kind: tools +name: ask_data_insights +type: bigquery-conversational-analytics +source: my-bigquery-source +description: | + Use this tool to perform data analysis, get insights, or answer complex + questions about the contents of specific BigQuery tables. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "bigquery-conversational-analytics". | +| type | string | true | Must be "bigquery-conversational-analytics". | | source | string | true | Name of the source for chat. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/bigquery/bigquery-execute-sql.md b/docs/en/resources/tools/bigquery/bigquery-execute-sql.md index b59ae58249..783ba5c742 100644 --- a/docs/en/resources/tools/bigquery/bigquery-execute-sql.md +++ b/docs/en/resources/tools/bigquery/bigquery-execute-sql.md @@ -54,17 +54,17 @@ layer of security by controlling which datasets can be accessed: ## Example ```yaml -tools: - execute_sql_tool: - kind: bigquery-execute-sql - source: my-bigquery-source - description: Use this tool to execute sql statement. +kind: tools +name: execute_sql_tool +type: bigquery-execute-sql +source: my-bigquery-source +description: Use this tool to execute sql statement. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "bigquery-execute-sql". | +| type | string | true | Must be "bigquery-execute-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/bigquery/bigquery-forecast.md b/docs/en/resources/tools/bigquery/bigquery-forecast.md index 823eb487e1..188a7d11c7 100644 --- a/docs/en/resources/tools/bigquery/bigquery-forecast.md +++ b/docs/en/resources/tools/bigquery/bigquery-forecast.md @@ -58,11 +58,11 @@ the `bigquery` source: ## Example ```yaml -tools: - forecast_tool: - kind: bigquery-forecast - source: my-bigquery-source - description: Use this tool to forecast time series data in BigQuery. +kind: tools +name: forecast_tool +type: bigquery-forecast +source: my-bigquery-source +description: Use this tool to forecast time series data in BigQuery. ``` ## Sample Prompt @@ -78,6 +78,6 @@ You can use the following sample prompts to call this tool: | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|---------------------------------------------------------| -| kind | string | true | Must be "bigquery-forecast". | +| type | string | true | Must be "bigquery-forecast". | | source | string | true | Name of the source the forecast tool should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/bigquery/bigquery-get-dataset-info.md b/docs/en/resources/tools/bigquery/bigquery-get-dataset-info.md index 460816d290..e68fe83574 100644 --- a/docs/en/resources/tools/bigquery/bigquery-get-dataset-info.md +++ b/docs/en/resources/tools/bigquery/bigquery-get-dataset-info.md @@ -34,17 +34,17 @@ The tool's behavior regarding these parameters is influenced by the ## Example ```yaml -tools: - bigquery_get_dataset_info: - kind: bigquery-get-dataset-info - source: my-bigquery-source - description: Use this tool to get dataset metadata. +kind: tools +name: bigquery_get_dataset_info +type: bigquery-get-dataset-info +source: my-bigquery-source +description: Use this tool to get dataset metadata. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:------------------------------------------:|:------------:|--------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "bigquery-get-dataset-info". | +| type | string | true | Must be "bigquery-get-dataset-info". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/bigquery/bigquery-get-table-info.md b/docs/en/resources/tools/bigquery/bigquery-get-table-info.md index e05f74c131..807e9a8f04 100644 --- a/docs/en/resources/tools/bigquery/bigquery-get-table-info.md +++ b/docs/en/resources/tools/bigquery/bigquery-get-table-info.md @@ -35,17 +35,17 @@ The tool's behavior regarding these parameters is influenced by the ## Example ```yaml -tools: - bigquery_get_table_info: - kind: bigquery-get-table-info - source: my-bigquery-source - description: Use this tool to get table metadata. +kind: tools +name: bigquery_get_table_info +type: bigquery-get-table-info +source: my-bigquery-source +description: Use this tool to get table metadata. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:------------------------------------------:|:------------:|--------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "bigquery-get-table-info". | +| type | string | true | Must be "bigquery-get-table-info". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/bigquery/bigquery-list-dataset-ids.md b/docs/en/resources/tools/bigquery/bigquery-list-dataset-ids.md index 176ad78dfe..c2cd8b7609 100644 --- a/docs/en/resources/tools/bigquery/bigquery-list-dataset-ids.md +++ b/docs/en/resources/tools/bigquery/bigquery-list-dataset-ids.md @@ -32,17 +32,17 @@ The tool's behavior regarding this parameter is influenced by the ## Example ```yaml -tools: - bigquery_list_dataset_ids: - kind: bigquery-list-dataset-ids - source: my-bigquery-source - description: Use this tool to get dataset metadata. +kind: tools +name: bigquery_list_dataset_ids +type: bigquery-list-dataset-ids +source: my-bigquery-source +description: Use this tool to get dataset metadata. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:------------------------------------------:|:------------:|--------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "bigquery-list-dataset-ids". | +| type | string | true | Must be "bigquery-list-dataset-ids". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/bigquery/bigquery-list-table-ids.md b/docs/en/resources/tools/bigquery/bigquery-list-table-ids.md index 5e72d0b22a..828e84cb8f 100644 --- a/docs/en/resources/tools/bigquery/bigquery-list-table-ids.md +++ b/docs/en/resources/tools/bigquery/bigquery-list-table-ids.md @@ -34,17 +34,17 @@ will be used as the default value for the `dataset` parameter. ## Example ```yaml -tools: - bigquery_list_table_ids: - kind: bigquery-list-table-ids - source: my-bigquery-source - description: Use this tool to get table metadata. +kind: tools +name: bigquery_list_table_ids +type: bigquery-list-table-ids +source: my-bigquery-source +description: Use this tool to get table metadata. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:------------------------------------------:|:------------:|--------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "bigquery-list-table-ids". | +| type | string | true | Must be "bigquery-list-table-ids". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/bigquery/bigquery-search-catalog.md b/docs/en/resources/tools/bigquery/bigquery-search-catalog.md index 32a107983e..3994e4744a 100644 --- a/docs/en/resources/tools/bigquery/bigquery-search-catalog.md +++ b/docs/en/resources/tools/bigquery/bigquery-search-catalog.md @@ -48,17 +48,17 @@ applying IAM permissions and roles to an identity. ## Example ```yaml -tools: - search_catalog: - kind: bigquery-search-catalog - source: bigquery-source - description: Use this tool to find tables, views, models, routines or connections. +kind: tools +name: search_catalog +type: bigquery-search-catalog +source: bigquery-source +description: Use this tool to find tables, views, models, routines or connections. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:------------------------------------------:|:------------:|--------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "bigquery-search-catalog". | +| type | string | true | Must be "bigquery-search-catalog". | | source | string | true | Name of the source the tool should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/bigquery/bigquery-sql.md b/docs/en/resources/tools/bigquery/bigquery-sql.md index c07192f710..39d5c750ff 100644 --- a/docs/en/resources/tools/bigquery/bigquery-sql.md +++ b/docs/en/resources/tools/bigquery/bigquery-sql.md @@ -46,36 +46,36 @@ same query. > identifiers, column names, table names, or other parts of the query. ```yaml -tools: - # Example: Querying a user table in BigQuery - search_users_bq: - kind: bigquery-sql - source: my-bigquery-source - statement: | - SELECT - id, - name, - email - FROM - `my-project.my-dataset.users` - WHERE - id = @id OR email = @email; - description: | - Use this tool to get information for a specific user. - Takes an id number or a name and returns info on the user. +# Example: Querying a user table in BigQuery +kind: tools +name: search_users_bq +type: bigquery-sql +source: my-bigquery-source +statement: | + SELECT + id, + name, + email + FROM + `my-project.my-dataset.users` + WHERE + id = @id OR email = @email; +description: | + Use this tool to get information for a specific user. + Takes an id number or a name and returns info on the user. - Example: - {{ - "id": 123, - "name": "Alice", - }} - parameters: - - name: id - type: integer - description: User ID - - name: email - type: string - description: Email address of the user + Example: + {{ + "id": 123, + "name": "Alice", + }} +parameters: + - name: id + type: integer + description: User ID + - name: email + type: string + description: Email address of the user ``` ### Example with Template Parameters @@ -87,31 +87,31 @@ tools: > [templateParameters](../#template-parameters). ```yaml -tools: - list_table: - kind: bigquery-sql - source: my-bigquery-source - statement: | - SELECT * FROM {{.tableName}}; - description: | - Use this tool to list all information from a specific table. - Example: - {{ - "tableName": "flights", - }} - templateParameters: - - name: tableName - type: string - description: Table to select from +kind: tools +name: list_table +type: bigquery-sql +source: my-bigquery-source +statement: | + SELECT * FROM {{.tableName}}; +description: | + Use this tool to list all information from a specific table. + Example: + {{ + "tableName": "flights", + }} +templateParameters: + - name: tableName + type: string + description: Table to select from ``` ## Reference | **field** | **type** | **required** | **description** | |--------------------|:---------------------------------------------:|:------------:|-----------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "bigquery-sql". | +| type | string | true | Must be "bigquery-sql". | | source | string | true | Name of the source the GoogleSQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | statement | string | true | The GoogleSQL statement to execute. | | parameters | [parameters](../#specifying-parameters) | false | List of [parameters](../#specifying-parameters) that will be inserted into the SQL statement. | -| templateParameters | [templateParameters](../#template-parameters) | false | List of [templateParameters](../#template-parameters) that will be inserted into the SQL statement before executing prepared statement. | +| templateParameters | [templateParameters](../#template-parameters) | false | List of [templateParameters](../#template-parameters) that will be inserted into the SQL statement before executing prepared statement. | \ No newline at end of file diff --git a/docs/en/resources/tools/bigtable/bigtable-sql.md b/docs/en/resources/tools/bigtable/bigtable-sql.md index cce122f94d..7d56be05b5 100644 --- a/docs/en/resources/tools/bigtable/bigtable-sql.md +++ b/docs/en/resources/tools/bigtable/bigtable-sql.md @@ -40,35 +40,35 @@ inserted according to their name: e.g. `@name`. > names, or other parts of the query. ```yaml -tools: - search_user_by_id_or_name: - kind: bigtable-sql - source: my-bigtable-instance - statement: | - SELECT - TO_INT64(cf[ 'id' ]) as id, - CAST(cf[ 'name' ] AS string) as name, - FROM - mytable - WHERE - TO_INT64(cf[ 'id' ]) = @id - OR CAST(cf[ 'name' ] AS string) = @name; - description: | - Use this tool to get information for a specific user. - Takes an id number or a name and returns info on the user. +kind: tools +name: search_user_by_id_or_name +type: bigtable-sql +source: my-bigtable-instance +statement: | + SELECT + TO_INT64(cf[ 'id' ]) as id, + CAST(cf[ 'name' ] AS string) as name, + FROM + mytable + WHERE + TO_INT64(cf[ 'id' ]) = @id + OR CAST(cf[ 'name' ] AS string) = @name; +description: | + Use this tool to get information for a specific user. + Takes an id number or a name and returns info on the user. - Example: - {{ - "id": 123, - "name": "Alice", - }} - parameters: - - name: id - type: integer - description: User ID - - name: name - type: string - description: Name of the user + Example: + {{ + "id": 123, + "name": "Alice", + }} +parameters: + - name: id + type: integer + description: User ID + - name: name + type: string + description: Name of the user ``` ### Example with Template Parameters @@ -80,29 +80,29 @@ tools: > [templateParameters](..#template-parameters). ```yaml -tools: - list_table: - kind: bigtable-sql - source: my-bigtable-instance - statement: | - SELECT * FROM {{.tableName}}; - description: | - Use this tool to list all information from a specific table. - Example: - {{ - "tableName": "flights", - }} - templateParameters: - - name: tableName - type: string - description: Table to select from +kind: tools +name: list_table +type: bigtable-sql +source: my-bigtable-instance +statement: | + SELECT * FROM {{.tableName}}; +description: | + Use this tool to list all information from a specific table. + Example: + {{ + "tableName": "flights", + }} +templateParameters: + - name: tableName + type: string + description: Table to select from ``` ## Reference | **field** | **type** | **required** | **description** | |--------------------|:--------------------------------------------:|:------------:|----------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "bigtable-sql". | +| type | string | true | Must be "bigtable-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | statement | string | true | SQL statement to execute on. | diff --git a/docs/en/resources/tools/cassandra/cassandra-cql.md b/docs/en/resources/tools/cassandra/cassandra-cql.md index feb092ee21..14f1eb8e01 100644 --- a/docs/en/resources/tools/cassandra/cassandra-cql.md +++ b/docs/en/resources/tools/cassandra/cassandra-cql.md @@ -31,27 +31,27 @@ the form of placeholders `?`. > names, or other parts of the query. ```yaml -tools: - search_users_by_email: - kind: cassandra-cql - source: my-cassandra-cluster - statement: | - SELECT user_id, email, first_name, last_name, created_at - FROM users - WHERE email = ? - description: | - Use this tool to retrieve specific user information by their email address. - Takes an email address and returns user details including user ID, email, - first name, last name, and account creation timestamp. - Do NOT use this tool with a user ID or other identifiers. - Example: - {{ - "email": "user@example.com", - }} - parameters: - - name: email - type: string - description: User's email address +kind: tools +name: search_users_by_email +type: cassandra-cql +source: my-cassandra-cluster +statement: | + SELECT user_id, email, first_name, last_name, created_at + FROM users + WHERE email = ? +description: | + Use this tool to retrieve specific user information by their email address. + Takes an email address and returns user details including user ID, email, + first name, last name, and account creation timestamp. + Do NOT use this tool with a user ID or other identifiers. + Example: + {{ + "email": "user@example.com", + }} +parameters: + - name: email + type: string + description: User's email address ``` ### Example with Template Parameters @@ -63,33 +63,33 @@ tools: > [templateParameters](../#template-parameters). ```yaml -tools: - list_keyspace_table: - kind: cassandra-cql - source: my-cassandra-cluster - statement: | - SELECT * FROM {{.keyspace}}.{{.tableName}}; - description: | - Use this tool to list all information from a specific table in a keyspace. - Example: - {{ - "keyspace": "my_keyspace", - "tableName": "users", - }} - templateParameters: - - name: keyspace - type: string - description: Keyspace containing the table - - name: tableName - type: string - description: Table to select from +kind: tools +name: list_keyspace_table +type: cassandra-cql +source: my-cassandra-cluster +statement: | + SELECT * FROM {{.keyspace}}.{{.tableName}}; +description: | + Use this tool to list all information from a specific table in a keyspace. + Example: + {{ + "keyspace": "my_keyspace", + "tableName": "users", + }} +templateParameters: + - name: keyspace + type: string + description: Keyspace containing the table + - name: tableName + type: string + description: Table to select from ``` ## Reference | **field** | **type** | **required** | **description** | |--------------------|:---------------------------------------------:|:------------:|-----------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "cassandra-cql". | +| type | string | true | Must be "cassandra-cql". | | source | string | true | Name of the source the CQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | statement | string | true | CQL statement to execute. | diff --git a/docs/en/resources/tools/clickhouse/clickhouse-execute-sql.md b/docs/en/resources/tools/clickhouse/clickhouse-execute-sql.md index e197c1f05b..5e28b54386 100644 --- a/docs/en/resources/tools/clickhouse/clickhouse-execute-sql.md +++ b/docs/en/resources/tools/clickhouse/clickhouse-execute-sql.md @@ -25,11 +25,11 @@ capabilities for monitoring and debugging purposes. ## Example ```yaml -tools: - execute_sql_tool: - kind: clickhouse-execute-sql - source: my-clickhouse-instance - description: Use this tool to execute SQL statements against ClickHouse. +kind: tools +name: execute_sql_tool +type: clickhouse-execute-sql +source: my-clickhouse-instance +description: Use this tool to execute SQL statements against ClickHouse. ``` ## Parameters @@ -42,6 +42,6 @@ tools: | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|-------------------------------------------------------| -| kind | string | true | Must be "clickhouse-execute-sql". | +| type | string | true | Must be "clickhouse-execute-sql". | | source | string | true | Name of the ClickHouse source to execute SQL against. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/clickhouse/clickhouse-list-databases.md b/docs/en/resources/tools/clickhouse/clickhouse-list-databases.md index 43e5f0e982..eedf197b41 100644 --- a/docs/en/resources/tools/clickhouse/clickhouse-list-databases.md +++ b/docs/en/resources/tools/clickhouse/clickhouse-list-databases.md @@ -21,11 +21,11 @@ discovery and exploration tasks. ## Example ```yaml -tools: - list_clickhouse_databases: - kind: clickhouse-list-databases - source: my-clickhouse-instance - description: List all available databases in the ClickHouse instance +kind: tools +name: list_clickhouse_databases +type: clickhouse-list-databases +source: my-clickhouse-instance +description: List all available databases in the ClickHouse instance ``` ## Return Value @@ -49,7 +49,7 @@ Example response: | **field** | **type** | **required** | **description** | |--------------|:------------------:|:------------:|-------------------------------------------------------| -| kind | string | true | Must be "clickhouse-list-databases". | +| type | string | true | Must be "clickhouse-list-databases". | | source | string | true | Name of the ClickHouse source to list databases from. | | description | string | true | Description of the tool that is passed to the LLM. | | authRequired | array of string | false | Authentication services required to use this tool. | diff --git a/docs/en/resources/tools/clickhouse/clickhouse-list-tables.md b/docs/en/resources/tools/clickhouse/clickhouse-list-tables.md index a886813e17..dbeb49c79c 100644 --- a/docs/en/resources/tools/clickhouse/clickhouse-list-tables.md +++ b/docs/en/resources/tools/clickhouse/clickhouse-list-tables.md @@ -21,11 +21,11 @@ user, making it useful for schema exploration and table discovery tasks. ## Example ```yaml -tools: - list_clickhouse_tables: - kind: clickhouse-list-tables - source: my-clickhouse-instance - description: List all tables in a specific ClickHouse database +kind: tools +name: list_clickhouse_tables +type: clickhouse-list-tables +source: my-clickhouse-instance +description: List all tables in a specific ClickHouse database ``` ## Parameters @@ -56,7 +56,7 @@ Example response: | **field** | **type** | **required** | **description** | |--------------|:------------------:|:------------:|---------------------------------------------------------| -| kind | string | true | Must be "clickhouse-list-tables". | +| type | string | true | Must be "clickhouse-list-tables". | | source | string | true | Name of the ClickHouse source to list tables from. | | description | string | true | Description of the tool that is passed to the LLM. | | authRequired | array of string | false | Authentication services required to use this tool. | diff --git a/docs/en/resources/tools/clickhouse/clickhouse-sql.md b/docs/en/resources/tools/clickhouse/clickhouse-sql.md index 5d66d6826f..b26bb6eade 100644 --- a/docs/en/resources/tools/clickhouse/clickhouse-sql.md +++ b/docs/en/resources/tools/clickhouse/clickhouse-sql.md @@ -21,60 +21,60 @@ query execution capabilities. ## Example ```yaml -tools: - my_analytics_query: - kind: clickhouse-sql - source: my-clickhouse-instance - description: Get user analytics for a specific date range - statement: | - SELECT - user_id, - count(*) as event_count, - max(timestamp) as last_event - FROM events - WHERE date >= ? AND date <= ? - GROUP BY user_id - ORDER BY event_count DESC - LIMIT ? - parameters: - - name: start_date - description: Start date for the query (YYYY-MM-DD format) - - name: end_date - description: End date for the query (YYYY-MM-DD format) - - name: limit - description: Maximum number of results to return +kind: tools +name: my_analytics_query +type: clickhouse-sql +source: my-clickhouse-instance +description: Get user analytics for a specific date range +statement: | + SELECT + user_id, + count(*) as event_count, + max(timestamp) as last_event + FROM events + WHERE date >= ? AND date <= ? + GROUP BY user_id + ORDER BY event_count DESC + LIMIT ? +parameters: + - name: start_date + description: Start date for the query (YYYY-MM-DD format) + - name: end_date + description: End date for the query (YYYY-MM-DD format) + - name: limit + description: Maximum number of results to return ``` ## Template Parameters Example ```yaml -tools: - flexible_table_query: - kind: clickhouse-sql - source: my-clickhouse-instance - description: Query any table with flexible columns - statement: | - SELECT {{columns}} - FROM {{table_name}} - WHERE created_date >= ? - LIMIT ? - templateParameters: - - name: columns - description: Comma-separated list of columns to select - - name: table_name - description: Name of the table to query - parameters: - - name: start_date - description: Start date filter - - name: limit - description: Maximum number of results +kind: tools +name: flexible_table_query +type: clickhouse-sql +source: my-clickhouse-instance +description: Query any table with flexible columns +statement: | + SELECT {{columns}} + FROM {{table_name}} + WHERE created_date >= ? + LIMIT ? +templateParameters: + - name: columns + description: Comma-separated list of columns to select + - name: table_name + description: Name of the table to query +parameters: + - name: start_date + description: Start date filter + - name: limit + description: Maximum number of results ``` ## Reference | **field** | **type** | **required** | **description** | |--------------------|:------------------:|:------------:|-------------------------------------------------------| -| kind | string | true | Must be "clickhouse-sql". | +| type | string | true | Must be "clickhouse-sql". | | source | string | true | Name of the ClickHouse source to execute SQL against. | | description | string | true | Description of the tool that is passed to the LLM. | | statement | string | true | The SQL statement template to execute. | diff --git a/docs/en/resources/tools/cloudgda/cloud-gda-query.md b/docs/en/resources/tools/cloudgda/cloud-gda-query.md index 39e5bf64ae..d416321424 100644 --- a/docs/en/resources/tools/cloudgda/cloud-gda-query.md +++ b/docs/en/resources/tools/cloudgda/cloud-gda-query.md @@ -18,28 +18,28 @@ The `cloud-gemini-data-analytics-query` tool allows you to send natural language ## Example ```yaml -tools: - my-gda-query-tool: - kind: cloud-gemini-data-analytics-query - source: my-gda-source - description: "Use this tool to send natural language queries to the Gemini Data Analytics API and receive SQL, natural language answers, and explanations." - location: ${your_database_location} - context: - datasourceReferences: - cloudSqlReference: - databaseReference: - projectId: "${your_project_id}" - region: "${your_database_instance_region}" - instanceId: "${your_database_instance_id}" - databaseId: "${your_database_name}" - engine: "POSTGRESQL" - agentContextReference: - contextSetId: "${your_context_set_id}" # E.g. projects/${project_id}/locations/${context_set_location}/contextSets/${context_set_id} - generationOptions: - generateQueryResult: true - generateNaturalLanguageAnswer: true - generateExplanation: true - generateDisambiguationQuestion: true +kind: tools +name: my-gda-query-tool +type: cloud-gemini-data-analytics-query +source: my-gda-source +description: "Use this tool to send natural language queries to the Gemini Data Analytics API and receive SQL, natural language answers, and explanations." +location: ${your_database_location} +context: + datasourceReferences: + cloudSqlReference: + databaseReference: + projectId: "${your_project_id}" + region: "${your_database_instance_region}" + instanceId: "${your_database_instance_id}" + databaseId: "${your_database_name}" + engine: "POSTGRESQL" + agentContextReference: + contextSetId: "${your_context_set_id}" # E.g. projects/${project_id}/locations/${context_set_location}/contextSets/${context_set_id} +generationOptions: + generateQueryResult: true + generateNaturalLanguageAnswer: true + generateExplanation: true + generateDisambiguationQuestion: true ``` ### Usage Flow @@ -87,7 +87,7 @@ How many accounts who have region in Prague are eligible for loans? A3 contains | **field** | **type** | **required** | **description** | | ----------------- | :------: | :----------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| kind | string | true | Must be "cloud-gemini-data-analytics-query". | +| type | string | true | Must be "cloud-gemini-data-analytics-query". | | source | string | true | The name of the `cloud-gemini-data-analytics` source to use. | | description | string | true | A description of the tool's purpose. | | location | string | true | The Google Cloud location of the target database resource (e.g., "us-central1"). This is used to construct the parent resource name in the API call. | diff --git a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-fhir-fetch-page.md b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-fhir-fetch-page.md index 0e990c9fee..f8cd93cef8 100644 --- a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-fhir-fetch-page.md +++ b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-fhir-fetch-page.md @@ -23,18 +23,18 @@ response bundle. ## Example ```yaml -tools: - get_fhir_store: - kind: cloud-healthcare-fhir-fetch-page - source: my-healthcare-source - description: Use this tool to fetch a page of FHIR resources from a FHIR Bundle's entry.link.url +kind: tools +name: get_fhir_store +type: cloud-healthcare-fhir-fetch-page +source: my-healthcare-source +description: Use this tool to fetch a page of FHIR resources from a FHIR Bundle's entry.link.url ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "cloud-healthcare-fhir-fetch-page". | +| type | string | true | Must be "cloud-healthcare-fhir-fetch-page". | | source | string | true | Name of the healthcare source. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-fhir-patient-everything.md b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-fhir-patient-everything.md index b66f65f4bc..8f74aa1392 100644 --- a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-fhir-patient-everything.md +++ b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-fhir-patient-everything.md @@ -22,18 +22,18 @@ types, or only resources that have been updated after a given time. ## Example ```yaml -tools: - fhir_patient_everything: - kind: cloud-healthcare-fhir-patient-everything - source: my-healthcare-source - description: Use this tool to retrieve all the information about a given patient. +kind: tools +name: fhir_patient_everything +type: cloud-healthcare-fhir-patient-everything +source: my-healthcare-source +description: Use this tool to retrieve all the information about a given patient. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|-----------------------------------------------------| -| kind | string | true | Must be "cloud-healthcare-fhir-patient-everything". | +| type | string | true | Must be "cloud-healthcare-fhir-patient-everything". | | source | string | true | Name of the healthcare source. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-fhir-patient-search.md b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-fhir-patient-search.md index 73155c90e1..f3cdab733b 100644 --- a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-fhir-patient-search.md +++ b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-fhir-patient-search.md @@ -21,18 +21,18 @@ given criteria. ## Example ```yaml -tools: - fhir_patient_search: - kind: cloud-healthcare-fhir-patient-search - source: my-healthcare-source - description: Use this tool to search for patients in the FHIR store. +kind: tools +name: fhir_patient_search +type: cloud-healthcare-fhir-patient-search +source: my-healthcare-source +description: Use this tool to search for patients in the FHIR store. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "cloud-healthcare-fhir-patient-search". | +| type | string | true | Must be "cloud-healthcare-fhir-patient-search". | | source | string | true | Name of the healthcare source. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-dataset.md b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-dataset.md index 0bcdb6896d..856e327251 100644 --- a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-dataset.md +++ b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-dataset.md @@ -21,17 +21,17 @@ configured in the source. It takes no extra parameters. ## Example ```yaml -tools: - get_dataset: - kind: cloud-healthcare-get-dataset - source: my-healthcare-source - description: Use this tool to get healthcare dataset metadata. +kind: tools +name: get_dataset +type: cloud-healthcare-get-dataset +source: my-healthcare-source +description: Use this tool to get healthcare dataset metadata. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:------------------------------------------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "cloud-healthcare-get-dataset". | +| type | string | true | Must be "cloud-healthcare-get-dataset". | | source | string | true | Name of the healthcare source. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-dicom-store-metrics.md b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-dicom-store-metrics.md index 8bd5d38b1f..8f0b4f152b 100644 --- a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-dicom-store-metrics.md +++ b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-dicom-store-metrics.md @@ -20,18 +20,18 @@ store. It's compatible with the following sources: ## Example ```yaml -tools: - get_dicom_store_metrics: - kind: cloud-healthcare-get-dicom-store-metrics - source: my-healthcare-source - description: Use this tool to get metrics for a DICOM store. +kind: tools +name: get_dicom_store_metrics +type: cloud-healthcare-get-dicom-store-metrics +source: my-healthcare-source +description: Use this tool to get metrics for a DICOM store. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|-----------------------------------------------------| -| kind | string | true | Must be "cloud-healthcare-get-dicom-store-metrics". | +| type | string | true | Must be "cloud-healthcare-get-dicom-store-metrics". | | source | string | true | Name of the healthcare source. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-dicom-store.md b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-dicom-store.md index 9828b06aea..ba44d9b2cc 100644 --- a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-dicom-store.md +++ b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-dicom-store.md @@ -20,18 +20,18 @@ compatible with the following sources: ## Example ```yaml -tools: - get_dicom_store: - kind: cloud-healthcare-get-dicom-store - source: my-healthcare-source - description: Use this tool to get information about a DICOM store. +kind: tools +name: get_dicom_store +type: cloud-healthcare-get-dicom-store +source: my-healthcare-source +description: Use this tool to get information about a DICOM store. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "cloud-healthcare-get-dicom-store". | +| type | string | true | Must be "cloud-healthcare-get-dicom-store". | | source | string | true | Name of the healthcare source. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-fhir-resource.md b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-fhir-resource.md index ef093ec1a3..ab36abd08d 100644 --- a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-fhir-resource.md +++ b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-fhir-resource.md @@ -23,18 +23,18 @@ by its type and ID. ## Example ```yaml -tools: - get_fhir_resource: - kind: cloud-healthcare-get-fhir-resource - source: my-healthcare-source - description: Use this tool to retrieve a specific FHIR resource. +kind: tools +name: get_fhir_resource +type: cloud-healthcare-get-fhir-resource +source: my-healthcare-source +description: Use this tool to retrieve a specific FHIR resource. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "cloud-healthcare-get-fhir-resource". | +| type | string | true | Must be "cloud-healthcare-get-fhir-resource". | | source | string | true | Name of the healthcare source. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-fhir-store-metrics.md b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-fhir-store-metrics.md index e5209e6118..f53aafac4e 100644 --- a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-fhir-store-metrics.md +++ b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-fhir-store-metrics.md @@ -20,18 +20,18 @@ compatible with the following sources: ## Example ```yaml -tools: - get_fhir_store_metrics: - kind: cloud-healthcare-get-fhir-store-metrics - source: my-healthcare-source - description: Use this tool to get metrics for a FHIR store. +kind: tools +name: get_fhir_store_metrics +type: cloud-healthcare-get-fhir-store-metrics +source: my-healthcare-source +description: Use this tool to get metrics for a FHIR store. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "cloud-healthcare-get-fhir-store-metrics". | +| type | string | true | Must be "cloud-healthcare-get-fhir-store-metrics". | | source | string | true | Name of the healthcare source. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-fhir-store.md b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-fhir-store.md index a9ce8d4aee..ff08bf3b31 100644 --- a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-fhir-store.md +++ b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-get-fhir-store.md @@ -20,18 +20,18 @@ compatible with the following sources: ## Example ```yaml -tools: - get_fhir_store: - kind: cloud-healthcare-get-fhir-store - source: my-healthcare-source - description: Use this tool to get information about a FHIR store. +kind: tools +name: get_fhir_store +type: cloud-healthcare-get-fhir-store +source: my-healthcare-source +description: Use this tool to get information about a FHIR store. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "cloud-healthcare-get-fhir-store". | +| type | string | true | Must be "cloud-healthcare-get-fhir-store". | | source | string | true | Name of the healthcare source. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-list-dicom-stores.md b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-list-dicom-stores.md index 7a6b493aca..ce1238d632 100644 --- a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-list-dicom-stores.md +++ b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-list-dicom-stores.md @@ -22,17 +22,17 @@ stores in the dataset of the healthcare source. It takes no extra parameters. ## Example ```yaml -tools: - list_dicom_stores: - kind: cloud-healthcare-list-dicom-stores - source: my-healthcare-source - description: Use this tool to list DICOM stores in the healthcare dataset. +kind: tools +name: list_dicom_stores +type: cloud-healthcare-list-dicom-stores +source: my-healthcare-source +description: Use this tool to list DICOM stores in the healthcare dataset. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "cloud-healthcare-list-dicom-stores". | +| type | string | true | Must be "cloud-healthcare-list-dicom-stores". | | source | string | true | Name of the healthcare source. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-list-fhir-stores.md b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-list-fhir-stores.md index ff10278203..12986af45d 100644 --- a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-list-fhir-stores.md +++ b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-list-fhir-stores.md @@ -22,17 +22,17 @@ stores in the dataset of the healthcare source. It takes no extra parameters. ## Example ```yaml -tools: - list_fhir_stores: - kind: cloud-healthcare-list-fhir-stores - source: my-healthcare-source - description: Use this tool to list FHIR stores in the healthcare dataset. +kind: tools +name: list_fhir_stores +type: cloud-healthcare-list-fhir-stores +source: my-healthcare-source +description: Use this tool to list FHIR stores in the healthcare dataset. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "cloud-healthcare-list-fhir-stores". | +| type | string | true | Must be "cloud-healthcare-list-fhir-stores". | | source | string | true | Name of the healthcare source. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-retrieve-rendered-dicom-instance.md b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-retrieve-rendered-dicom-instance.md index c1b99818ef..1d8eea9f29 100644 --- a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-retrieve-rendered-dicom-instance.md +++ b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-retrieve-rendered-dicom-instance.md @@ -22,18 +22,18 @@ string of the image in JPEG format. ## Example ```yaml -tools: - retrieve_rendered_dicom_instance: - kind: cloud-healthcare-retrieve-rendered-dicom-instance - source: my-healthcare-source - description: Use this tool to retrieve a rendered DICOM instance from the DICOM store. +kind: tools +name: retrieve_rendered_dicom_instance +type: cloud-healthcare-retrieve-rendered-dicom-instance +source: my-healthcare-source +description: Use this tool to retrieve a rendered DICOM instance from the DICOM store. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|--------------------------------------------------------------| -| kind | string | true | Must be "cloud-healthcare-retrieve-rendered-dicom-instance". | +| type | string | true | Must be "cloud-healthcare-retrieve-rendered-dicom-instance". | | source | string | true | Name of the healthcare source. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-search-dicom-instances.md b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-search-dicom-instances.md index 042253d91d..554290fe37 100644 --- a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-search-dicom-instances.md +++ b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-search-dicom-instances.md @@ -22,18 +22,18 @@ criteria. ## Example ```yaml -tools: - search_dicom_instances: - kind: cloud-healthcare-search-dicom-instances - source: my-healthcare-source - description: Use this tool to search for DICOM instances in the DICOM store. +kind: tools +name: search_dicom_instances +type: cloud-healthcare-search-dicom-instances +source: my-healthcare-source +description: Use this tool to search for DICOM instances in the DICOM store. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "cloud-healthcare-search-dicom-instances". | +| type | string | true | Must be "cloud-healthcare-search-dicom-instances". | | source | string | true | Name of the healthcare source. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-search-dicom-series.md b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-search-dicom-series.md index 1a8e76a183..2dba31f3cf 100644 --- a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-search-dicom-series.md +++ b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-search-dicom-series.md @@ -20,18 +20,18 @@ set of criteria. It's compatible with the following sources: ## Example ```yaml -tools: - search_dicom_series: - kind: cloud-healthcare-search-dicom-series - source: my-healthcare-source - description: Use this tool to search for DICOM series in the DICOM store. +kind: tools +name: search_dicom_series +type: cloud-healthcare-search-dicom-series +source: my-healthcare-source +description: Use this tool to search for DICOM series in the DICOM store. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "cloud-healthcare-search-dicom-series". | +| type | string | true | Must be "cloud-healthcare-search-dicom-series". | | source | string | true | Name of the healthcare source. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-search-dicom-studies.md b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-search-dicom-studies.md index 11d9036292..a3c8504444 100644 --- a/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-search-dicom-studies.md +++ b/docs/en/resources/tools/cloudhealthcare/cloud-healthcare-search-dicom-studies.md @@ -20,18 +20,18 @@ set of criteria. It's compatible with the following sources: ## Example ```yaml -tools: - search_dicom_studies: - kind: cloud-healthcare-search-dicom-studies - source: my-healthcare-source - description: Use this tool to search for DICOM studies in the DICOM store. +kind: tools +name: search_dicom_studies +type: cloud-healthcare-search-dicom-studies +source: my-healthcare-source +description: Use this tool to search for DICOM studies in the DICOM store. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "cloud-healthcare-search-dicom-studies". | +| type | string | true | Must be "cloud-healthcare-search-dicom-studies". | | source | string | true | Name of the healthcare source. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/cloudmonitoring/cloud-monitoring-query-prometheus.md b/docs/en/resources/tools/cloudmonitoring/cloud-monitoring-query-prometheus.md index 53ade0eb33..8597c1dc1a 100644 --- a/docs/en/resources/tools/cloudmonitoring/cloud-monitoring-query-prometheus.md +++ b/docs/en/resources/tools/cloudmonitoring/cloud-monitoring-query-prometheus.md @@ -55,21 +55,21 @@ Here are some examples of how to use the `cloud-monitoring-query-prometheus` tool. ```yaml -tools: - get_wait_time_metrics: - kind: cloud-monitoring-query-prometheus - source: cloud-monitoring-source - description: | - This tool fetches system wait time information for AlloyDB cluster, instance. Get the `projectID`, `clusterID` and `instanceID` from the user intent. To use this tool, you must provide the Google Cloud `projectId` and a PromQL `query`. - Generate `query` using these metric details: - metric: `alloydb.googleapis.com/instance/postgresql/wait_time`, monitored_resource: `alloydb.googleapis.com/Instance`. labels: `cluster_id`, `instance_id`, `wait_event_type`, `wait_event_name`. - Basic time series example promql query: `avg_over_time({"__name__"="alloydb.googleapis.com/instance/postgresql/wait_time","monitored_resource"="alloydb.googleapis.com/Instance","instance_id"="alloydb-instance"}[5m])` +kind: tools +name: get_wait_time_metrics +type: cloud-monitoring-query-prometheus +source: cloud-monitoring-source +description: | + This tool fetches system wait time information for AlloyDB cluster, instance. Get the `projectID`, `clusterID` and `instanceID` from the user intent. To use this tool, you must provide the Google Cloud `projectId` and a PromQL `query`. + Generate `query` using these metric details: + metric: `alloydb.googleapis.com/instance/postgresql/wait_time`, monitored_resource: `alloydb.googleapis.com/Instance`. labels: `cluster_id`, `instance_id`, `wait_event_type`, `wait_event_name`. + Basic time series example promql query: `avg_over_time({"__name__"="alloydb.googleapis.com/instance/postgresql/wait_time","monitored_resource"="alloydb.googleapis.com/Instance","instance_id"="alloydb-instance"}[5m])` ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|------------------------------------------------------| -| kind | string | true | Must be cloud-monitoring-query-prometheus. | +| type | string | true | Must be cloud-monitoring-query-prometheus. | | source | string | true | The name of an `cloud-monitoring` source. | | description | string | true | Description of the tool that is passed to the agent. | diff --git a/docs/en/resources/tools/cloudsql/cloudsqlcloneinstance.md b/docs/en/resources/tools/cloudsql/cloudsqlcloneinstance.md index 89fdb8d986..455381173d 100644 --- a/docs/en/resources/tools/cloudsql/cloudsqlcloneinstance.md +++ b/docs/en/resources/tools/cloudsql/cloudsqlcloneinstance.md @@ -8,7 +8,7 @@ description: "Clone a Cloud SQL instance." The `cloud-sql-clone-instance` tool clones a Cloud SQL instance using the Cloud SQL Admin API. {{< notice info dd>}} -This tool uses a `source` of kind `cloud-sql-admin`. +This tool uses a `source` of type `cloud-sql-admin`. {{< /notice >}} ## Examples @@ -16,21 +16,21 @@ This tool uses a `source` of kind `cloud-sql-admin`. Basic clone (current state) ```yaml -tools: - clone-instance-basic: - kind: cloud-sql-clone-instance - source: cloud-sql-admin-source - description: "Creates an exact copy of a Cloud SQL instance. Supports configuring instance zones and high-availability setup through zone preferences." +kind: tools +name: clone-instance-basic +type: cloud-sql-clone-instance +source: cloud-sql-admin-source +description: "Creates an exact copy of a Cloud SQL instance. Supports configuring instance zones and high-availability setup through zone preferences." ``` Point-in-time recovery (PITR) clone ```yaml -tools: - clone-instance-pitr: - kind: cloud-sql-clone-instance - source: cloud-sql-admin-source - description: "Creates an exact copy of a Cloud SQL instance at a specific point in time (PITR). Supports configuring instance zones and high-availability setup through zone preferences" +kind: tools +name: clone-instance-pitr +type: cloud-sql-clone-instance +source: cloud-sql-admin-source +description: "Creates an exact copy of a Cloud SQL instance at a specific point in time (PITR). Supports configuring instance zones and high-availability setup through zone preferences" ``` ## Reference @@ -39,7 +39,7 @@ tools: | **field** | **type** | **required** | **description** | | -------------- | :------: | :----------: | ------------------------------------------------------------- | -| kind | string | true | Must be "cloud-sql-clone-instance". | +| type | string | true | Must be "cloud-sql-clone-instance". | | source | string | true | The name of the `cloud-sql-admin` source to use. | | description | string | false | A description of the tool. | diff --git a/docs/en/resources/tools/cloudsql/cloudsqlcreatebackup.md b/docs/en/resources/tools/cloudsql/cloudsqlcreatebackup.md index 751534a0ba..b767389644 100644 --- a/docs/en/resources/tools/cloudsql/cloudsqlcreatebackup.md +++ b/docs/en/resources/tools/cloudsql/cloudsqlcreatebackup.md @@ -8,7 +8,7 @@ description: "Creates a backup on a Cloud SQL instance." The `cloud-sql-create-backup` tool creates an on-demand backup on a Cloud SQL instance using the Cloud SQL Admin API. {{< notice info dd>}} -This tool uses a `source` of kind `cloud-sql-admin`. +This tool uses a `source` of type `cloud-sql-admin`. {{< /notice >}} ## Examples @@ -16,17 +16,17 @@ This tool uses a `source` of kind `cloud-sql-admin`. Basic backup creation (current state) ```yaml -tools: - backup-creation-basic: - kind: cloud-sql-create-backup - source: cloud-sql-admin-source - description: "Creates a backup on the given Cloud SQL instance." +kind: tools +name: backup-creation-basic +type: cloud-sql-create-backup +source: cloud-sql-admin-source +description: "Creates a backup on the given Cloud SQL instance." ``` ## Reference ### Tool Configuration | **field** | **type** | **required** | **description** | | -------------- | :------: | :----------: | ------------------------------------------------------------- | -| kind | string | true | Must be "cloud-sql-create-backup". | +| type | string | true | Must be "cloud-sql-create-backup". | | source | string | true | The name of the `cloud-sql-admin` source to use. | | description | string | false | A description of the tool. | diff --git a/docs/en/resources/tools/cloudsql/cloudsqlcreatedatabase.md b/docs/en/resources/tools/cloudsql/cloudsqlcreatedatabase.md index dbad4f3376..96c41047d8 100644 --- a/docs/en/resources/tools/cloudsql/cloudsqlcreatedatabase.md +++ b/docs/en/resources/tools/cloudsql/cloudsqlcreatedatabase.md @@ -10,24 +10,24 @@ The `cloud-sql-create-database` tool creates a new database in a specified Cloud SQL instance. {{< notice info >}} -This tool uses a `source` of kind `cloud-sql-admin`. +This tool uses a `source` of type `cloud-sql-admin`. {{< /notice >}} ## Example ```yaml -tools: - create-cloud-sql-database: - kind: cloud-sql-create-database - source: my-cloud-sql-admin-source - description: "Creates a new database in a Cloud SQL instance." +kind: tools +name: create-cloud-sql-database +type: cloud-sql-create-database +source: my-cloud-sql-admin-source +description: "Creates a new database in a Cloud SQL instance." ``` ## Reference | **field** | **type** | **required** | **description** | | ----------- | :------: | :----------: | ------------------------------------------------ | -| kind | string | true | Must be "cloud-sql-create-database". | +| type | string | true | Must be "cloud-sql-create-database". | | source | string | true | The name of the `cloud-sql-admin` source to use. | | description | string | false | A description of the tool. | diff --git a/docs/en/resources/tools/cloudsql/cloudsqlcreateusers.md b/docs/en/resources/tools/cloudsql/cloudsqlcreateusers.md index affee91cfc..243e812100 100644 --- a/docs/en/resources/tools/cloudsql/cloudsqlcreateusers.md +++ b/docs/en/resources/tools/cloudsql/cloudsqlcreateusers.md @@ -10,23 +10,23 @@ The `cloud-sql-create-users` tool creates a new user in a specified Cloud SQL instance. It can create both built-in and IAM users. {{< notice info >}} -This tool uses a `source` of kind `cloud-sql-admin`. +This tool uses a `source` of type `cloud-sql-admin`. {{< /notice >}} ## Example ```yaml -tools: - create-cloud-sql-user: - kind: cloud-sql-create-users - source: my-cloud-sql-admin-source - description: "Creates a new user in a Cloud SQL instance. Both built-in and IAM users are supported. IAM users require an email account as the user name. IAM is the more secure and recommended way to manage users. The agent should always ask the user what type of user they want to create. For more information, see https://cloud.google.com/sql/docs/postgres/add-manage-iam-users" +kind: tools +name: create-cloud-sql-user +type: cloud-sql-create-users +source: my-cloud-sql-admin-source +description: "Creates a new user in a Cloud SQL instance. Both built-in and IAM users are supported. IAM users require an email account as the user name. IAM is the more secure and recommended way to manage users. The agent should always ask the user what type of user they want to create. For more information, see https://cloud.google.com/sql/docs/postgres/add-manage-iam-users" ``` ## Reference | **field** | **type** | **required** | **description** | | ------------ | :-------: | :----------: | ------------------------------------------------ | -| kind | string | true | Must be "cloud-sql-create-users". | +| type | string | true | Must be "cloud-sql-create-users". | | description | string | false | A description of the tool. | | source | string | true | The name of the `cloud-sql-admin` source to use. | diff --git a/docs/en/resources/tools/cloudsql/cloudsqlgetinstances.md b/docs/en/resources/tools/cloudsql/cloudsqlgetinstances.md index 711fc3b333..d6ab497995 100644 --- a/docs/en/resources/tools/cloudsql/cloudsqlgetinstances.md +++ b/docs/en/resources/tools/cloudsql/cloudsqlgetinstances.md @@ -10,23 +10,23 @@ The `cloud-sql-get-instance` tool retrieves a Cloud SQL instance resource using the Cloud SQL Admin API. {{< notice info >}} -This tool uses a `source` of kind `cloud-sql-admin`. +This tool uses a `source` of type `cloud-sql-admin`. {{< /notice >}} ## Example ```yaml -tools: - get-sql-instance: - kind: cloud-sql-get-instance - source: my-cloud-sql-admin-source - description: "Gets a particular cloud sql instance." +kind: tools +name: get-sql-instance +type: cloud-sql-get-instance +source: my-cloud-sql-admin-source +description: "Gets a particular cloud sql instance." ``` ## Reference | **field** | **type** | **required** | **description** | | ----------- | :------: | :----------: | ------------------------------------------------ | -| kind | string | true | Must be "cloud-sql-get-instance". | +| type | string | true | Must be "cloud-sql-get-instance". | | source | string | true | The name of the `cloud-sql-admin` source to use. | | description | string | false | A description of the tool. | diff --git a/docs/en/resources/tools/cloudsql/cloudsqllistdatabases.md b/docs/en/resources/tools/cloudsql/cloudsqllistdatabases.md index 54f8f3401d..2d86f5b23e 100644 --- a/docs/en/resources/tools/cloudsql/cloudsqllistdatabases.md +++ b/docs/en/resources/tools/cloudsql/cloudsqllistdatabases.md @@ -18,15 +18,15 @@ Here is an example of how to configure the `cloud-sql-list-databases` tool in yo `tools.yaml` file: ```yaml -sources: - my-cloud-sql-admin-source: - kind: cloud-sql-admin - -tools: - list_my_databases: - kind: cloud-sql-list-databases - source: my-cloud-sql-admin-source - description: Use this tool to list all Cloud SQL databases in an instance. +kind: sources +name: my-cloud-sql-admin-source +type: cloud-sql-admin +--- +kind: tools +name: list_my_databases +type: cloud-sql-list-databases +source: my-cloud-sql-admin-source +description: Use this tool to list all Cloud SQL databases in an instance. ``` ## Parameters @@ -42,6 +42,6 @@ The `cloud-sql-list-databases` tool has two required parameters: | **field** | **type** | **required** | **description** | | ----------- | :------: | :----------: | -------------------------------------------------------------- | -| kind | string | true | Must be "cloud-sql-list-databases". | +| type | string | true | Must be "cloud-sql-list-databases". | | source | string | true | The name of the `cloud-sql-admin` source to use for this tool. | | description | string | false | Description of the tool that is passed to the agent. | diff --git a/docs/en/resources/tools/cloudsql/cloudsqllistinstances.md b/docs/en/resources/tools/cloudsql/cloudsqllistinstances.md index 45e3c542e6..c078aa43bd 100644 --- a/docs/en/resources/tools/cloudsql/cloudsqllistinstances.md +++ b/docs/en/resources/tools/cloudsql/cloudsqllistinstances.md @@ -19,15 +19,15 @@ Here is an example of how to configure the `cloud-sql-list-instances` tool in your `tools.yaml` file: ```yaml -sources: - my-cloud-sql-admin-source: - kind: cloud-sql-admin - -tools: - list_my_instances: - kind: cloud-sql-list-instances - source: my-cloud-sql-admin-source - description: Use this tool to list all Cloud SQL instances in a project. +kind: sources +name: my-cloud-sql-admin-source +type: cloud-sql-admin +--- +kind: tools +name: list_my_instances +type: cloud-sql-list-instances +source: my-cloud-sql-admin-source +description: Use this tool to list all Cloud SQL instances in a project. ``` ## Parameters @@ -42,6 +42,6 @@ The `cloud-sql-list-instances` tool has one required parameter: | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------------------| -| kind | string | true | Must be "cloud-sql-list-instances". | +| type | string | true | Must be "cloud-sql-list-instances". | | description | string | false | Description of the tool that is passed to the agent. | | source | string | true | The name of the `cloud-sql-admin` source to use for this tool. | diff --git a/docs/en/resources/tools/cloudsql/cloudsqlmssqlcreateinstance.md b/docs/en/resources/tools/cloudsql/cloudsqlmssqlcreateinstance.md index 6b7cd9beb9..2053724237 100644 --- a/docs/en/resources/tools/cloudsql/cloudsqlmssqlcreateinstance.md +++ b/docs/en/resources/tools/cloudsql/cloudsqlmssqlcreateinstance.md @@ -9,17 +9,17 @@ The `cloud-sql-mssql-create-instance` tool creates a Cloud SQL for SQL Server instance using the Cloud SQL Admin API. {{< notice info dd>}} -This tool uses a `source` of kind `cloud-sql-admin`. +This tool uses a `source` of type `cloud-sql-admin`. {{< /notice >}} ## Example ```yaml -tools: - create-sql-instance: - kind: cloud-sql-mssql-create-instance - source: cloud-sql-admin-source - description: "Creates a SQL Server instance using `Production` and `Development` presets. For the `Development` template, it chooses a 2 vCPU, 8 GiB RAM (`db-custom-2-8192`) configuration with Non-HA/zonal availability. For the `Production` template, it chooses a 4 vCPU, 26 GiB RAM (`db-custom-4-26624`) configuration with HA/regional availability. The Enterprise edition is used in both cases. The default database version is `SQLSERVER_2022_STANDARD`. The agent should ask the user if they want to use a different version." +kind: tools +name: create-sql-instance +type: cloud-sql-mssql-create-instance +source: cloud-sql-admin-source +description: "Creates a SQL Server instance using `Production` and `Development` presets. For the `Development` template, it chooses a 2 vCPU, 8 GiB RAM (`db-custom-2-8192`) configuration with Non-HA/zonal availability. For the `Production` template, it chooses a 4 vCPU, 26 GiB RAM (`db-custom-4-26624`) configuration with HA/regional availability. The Enterprise edition is used in both cases. The default database version is `SQLSERVER_2022_STANDARD`. The agent should ask the user if they want to use a different version." ``` ## Reference @@ -28,7 +28,7 @@ tools: | **field** | **type** | **required** | **description** | | ----------- | :------: | :----------: | ------------------------------------------------ | -| kind | string | true | Must be "cloud-sql-mssql-create-instance". | +| type | string | true | Must be "cloud-sql-mssql-create-instance". | | source | string | true | The name of the `cloud-sql-admin` source to use. | | description | string | false | A description of the tool. | diff --git a/docs/en/resources/tools/cloudsql/cloudsqlmysqlcreateinstance.md b/docs/en/resources/tools/cloudsql/cloudsqlmysqlcreateinstance.md index 8707b8fea2..d9e5a7dcee 100644 --- a/docs/en/resources/tools/cloudsql/cloudsqlmysqlcreateinstance.md +++ b/docs/en/resources/tools/cloudsql/cloudsqlmysqlcreateinstance.md @@ -18,15 +18,15 @@ Here is an example of how to configure the `cloud-sql-mysql-create-instance` tool in your `tools.yaml` file: ```yaml -sources: - my-cloud-sql-admin-source: - kind: cloud-sql-admin - -tools: - create_my_mysql_instance: - kind: cloud-sql-mysql-create-instance - source: my-cloud-sql-admin-source - description: "Creates a MySQL instance using `Production` and `Development` presets. For the `Development` template, it chooses a 2 vCPU, 16 GiB RAM, 100 GiB SSD configuration with Non-HA/zonal availability. For the `Production` template, it chooses an 8 vCPU, 64 GiB RAM, 250 GiB SSD configuration with HA/regional availability. The Enterprise Plus edition is used in both cases. The default database version is `MYSQL_8_4`. The agent should ask the user if they want to use a different version." +kind: sources +name: my-cloud-sql-admin-source +type: cloud-sql-admin +--- +kind: tools +name: create_my_mysql_instance +type: cloud-sql-mysql-create-instance +source: my-cloud-sql-admin-source +description: "Creates a MySQL instance using `Production` and `Development` presets. For the `Development` template, it chooses a 2 vCPU, 16 GiB RAM, 100 GiB SSD configuration with Non-HA/zonal availability. For the `Production` template, it chooses an 8 vCPU, 64 GiB RAM, 250 GiB SSD configuration with HA/regional availability. The Enterprise Plus edition is used in both cases. The default database version is `MYSQL_8_4`. The agent should ask the user if they want to use a different version." ``` ## Parameters @@ -45,6 +45,6 @@ The `cloud-sql-mysql-create-instance` tool has the following parameters: | **field** | **type** | **required** | **description** | | ----------- | :------: | :----------: | -------------------------------------------------------------- | -| kind | string | true | Must be `cloud-sql-mysql-create-instance`. | +| type | string | true | Must be `cloud-sql-mysql-create-instance`. | | source | string | true | The name of the `cloud-sql-admin` source to use for this tool. | | description | string | false | A description of the tool that is passed to the agent. | diff --git a/docs/en/resources/tools/cloudsql/cloudsqlpgcreateinstances.md b/docs/en/resources/tools/cloudsql/cloudsqlpgcreateinstances.md index b567537592..0d41a89e03 100644 --- a/docs/en/resources/tools/cloudsql/cloudsqlpgcreateinstances.md +++ b/docs/en/resources/tools/cloudsql/cloudsqlpgcreateinstances.md @@ -9,17 +9,17 @@ The `cloud-sql-postgres-create-instance` tool creates a Cloud SQL for PostgreSQL instance using the Cloud SQL Admin API. {{< notice info >}} -This tool uses a `source` of kind `cloud-sql-admin`. +This tool uses a `source` of type `cloud-sql-admin`. {{< /notice >}} ## Example ```yaml -tools: - create-sql-instance: - kind: cloud-sql-postgres-create-instance - source: cloud-sql-admin-source - description: "Creates a Postgres instance using `Production` and `Development` presets. For the `Development` template, it chooses a 2 vCPU, 16 GiB RAM, 100 GiB SSD configuration with Non-HA/zonal availability. For the `Production` template, it chooses an 8 vCPU, 64 GiB RAM, 250 GiB SSD configuration with HA/regional availability. The Enterprise Plus edition is used in both cases. The default database version is `POSTGRES_17`. The agent should ask the user if they want to use a different version." +kind: tools +name: create-sql-instance +type: cloud-sql-postgres-create-instance +source: cloud-sql-admin-source +description: "Creates a Postgres instance using `Production` and `Development` presets. For the `Development` template, it chooses a 2 vCPU, 16 GiB RAM, 100 GiB SSD configuration with Non-HA/zonal availability. For the `Production` template, it chooses an 8 vCPU, 64 GiB RAM, 250 GiB SSD configuration with HA/regional availability. The Enterprise Plus edition is used in both cases. The default database version is `POSTGRES_17`. The agent should ask the user if they want to use a different version." ``` ## Reference @@ -28,7 +28,7 @@ tools: | **field** | **type** | **required** | **description** | | ----------- | :------: | :----------: | ------------------------------------------------ | -| kind | string | true | Must be "cloud-sql-postgres-create-instance". | +| type | string | true | Must be "cloud-sql-postgres-create-instance". | | source | string | true | The name of the `cloud-sql-admin` source to use. | | description | string | false | A description of the tool. | diff --git a/docs/en/resources/tools/cloudsql/cloudsqlpgupgradeprecheck.md b/docs/en/resources/tools/cloudsql/cloudsqlpgupgradeprecheck.md index 4b5933a176..820bf44031 100644 --- a/docs/en/resources/tools/cloudsql/cloudsqlpgupgradeprecheck.md +++ b/docs/en/resources/tools/cloudsql/cloudsqlpgupgradeprecheck.md @@ -10,7 +10,7 @@ instance to assess its readiness for a major version upgrade using the Cloud SQL It helps identify potential incompatibilities or issues before starting the actual upgrade process. {{< notice info >}} -This tool uses a `source` of kind `cloud-sql-admin`. +This tool uses a `source` of type `cloud-sql-admin`. {{< /notice >}} ## Tool Inputs @@ -18,18 +18,18 @@ This tool uses a `source` of kind `cloud-sql-admin`. ### Example ```yaml -tools: - postgres-upgrade-precheck: - kind: postgres-upgrade-precheck - source: cloud-sql-admin-source - description: "Checks if a Cloud SQL PostgreSQL instance is ready for a major version upgrade to the specified target version." +kind: tools +name: postgres-upgrade-precheck +type: postgres-upgrade-precheck +source: cloud-sql-admin-source +description: "Checks if a Cloud SQL PostgreSQL instance is ready for a major version upgrade to the specified target version." ``` ### Reference | **field** | **type** | **required** | **description** | | ------------ | :------: | :----------: | --------------------------------------------------------- | -| kind | string | true | Must be "postgres-upgrade-precheck". | +| type | string | true | Must be "postgres-upgrade-precheck". | | source | string | true | The name of the `cloud-sql-admin` source to use. | | description | string | false | A description of the tool. | diff --git a/docs/en/resources/tools/cloudsql/cloudsqlwaitforoperation.md b/docs/en/resources/tools/cloudsql/cloudsqlwaitforoperation.md index 3816d12bf3..728d0e2bc8 100644 --- a/docs/en/resources/tools/cloudsql/cloudsqlwaitforoperation.md +++ b/docs/en/resources/tools/cloudsql/cloudsqlwaitforoperation.md @@ -14,22 +14,22 @@ exponential backoff. ## Example ```yaml -tools: - cloudsql-operations-get: - kind: cloud-sql-wait-for-operation - source: my-cloud-sql-source - description: "This will poll on operations API until the operation is done. For checking operation status we need projectId and operationId. Once instance is created give follow up steps on how to use the variables to bring data plane MCP server up in local and remote setup." - delay: 1s - maxDelay: 4m - multiplier: 2 - maxRetries: 10 +kind: tools +name: cloudsql-operations-get +type: cloud-sql-wait-for-operation +source: my-cloud-sql-source +description: "This will poll on operations API until the operation is done. For checking operation status we need projectId and operationId. Once instance is created give follow up steps on how to use the variables to bring data plane MCP server up in local and remote setup." +delay: 1s +maxDelay: 4m +multiplier: 2 +maxRetries: 10 ``` ## Reference | **field** | **type** | **required** | **description** | | ----------- | :------: | :----------: | ---------------------------------------------------------------------------------------------------------------- | -| kind | string | true | Must be "cloud-sql-wait-for-operation". | +| type | string | true | Must be "cloud-sql-wait-for-operation". | | source | string | true | The name of a `cloud-sql-admin` source to use for authentication. | | description | string | false | A description of the tool. | | delay | duration | false | The initial delay between polling requests (e.g., `3s`). Defaults to 3 seconds. | diff --git a/docs/en/resources/tools/couchbase/couchbase-sql.md b/docs/en/resources/tools/couchbase/couchbase-sql.md index 0f83f3cf5d..3932bf0613 100644 --- a/docs/en/resources/tools/couchbase/couchbase-sql.md +++ b/docs/en/resources/tools/couchbase/couchbase-sql.md @@ -27,37 +27,37 @@ parameters will be used according to their name: e.g. `$id`. > names, or other parts of the query. ```yaml -tools: - search_products_by_category: - kind: couchbase-sql - source: my-couchbase-instance - statement: | - SELECT p.name, p.price, p.description - FROM products p - WHERE p.category = $category AND p.price < $max_price - ORDER BY p.price DESC - LIMIT 10 - description: | - Use this tool to get a list of products for a specific category under a maximum price. - Takes a category name, e.g. "Electronics" and a maximum price e.g 500 and returns a list of product names, prices, and descriptions. - Do NOT use this tool with invalid category names. Do NOT guess a category name, Do NOT guess a price. - Example: - {{ - "category": "Electronics", - "max_price": 500 - }} - Example: - {{ - "category": "Furniture", - "max_price": 1000 - }} - parameters: - - name: category - type: string - description: Product category name - - name: max_price - type: integer - description: Maximum price (positive integer) +kind: tools +name: search_products_by_category +type: couchbase-sql +source: my-couchbase-instance +statement: | + SELECT p.name, p.price, p.description + FROM products p + WHERE p.category = $category AND p.price < $max_price + ORDER BY p.price DESC + LIMIT 10 +description: | + Use this tool to get a list of products for a specific category under a maximum price. + Takes a category name, e.g. "Electronics" and a maximum price e.g 500 and returns a list of product names, prices, and descriptions. + Do NOT use this tool with invalid category names. Do NOT guess a category name, Do NOT guess a price. + Example: + {{ + "category": "Electronics", + "max_price": 500 + }} + Example: + {{ + "category": "Furniture", + "max_price": 1000 + }} +parameters: + - name: category + type: string + description: Product category name + - name: max_price + type: integer + description: Maximum price (positive integer) ``` ### Example with Template Parameters @@ -69,29 +69,29 @@ tools: > [templateParameters](..#template-parameters). ```yaml -tools: - list_table: - kind: couchbase-sql - source: my-couchbase-instance - statement: | - SELECT * FROM {{.tableName}}; - description: | - Use this tool to list all information from a specific table. - Example: - {{ - "tableName": "flights", - }} - templateParameters: - - name: tableName - type: string - description: Table to select from +kind: tools +name: list_table +type: couchbase-sql +source: my-couchbase-instance +statement: | + SELECT * FROM {{.tableName}}; +description: | + Use this tool to list all information from a specific table. + Example: + {{ + "tableName": "flights", + }} +templateParameters: + - name: tableName + type: string + description: Table to select from ``` ## Reference | **field** | **type** | **required** | **description** | |--------------------|:--------------------------------------------:|:------------:|----------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "couchbase-sql". | +| type | string | true | Must be "couchbase-sql". | | source | string | true | Name of the source the SQL query should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | statement | string | true | SQL statement to execute | diff --git a/docs/en/resources/tools/dataform/dataform-compile-local.md b/docs/en/resources/tools/dataform/dataform-compile-local.md index eb1127772e..ba24656260 100644 --- a/docs/en/resources/tools/dataform/dataform-compile-local.md +++ b/docs/en/resources/tools/dataform/dataform-compile-local.md @@ -44,15 +44,15 @@ for more details. ## Example ```yaml -tools: - my_dataform_compiler: - kind: dataform-compile-local - description: Use this tool to compile a local Dataform project. +kind: tools +name: my_dataform_compiler +type: dataform-compile-local +description: Use this tool to compile a local Dataform project. ``` ## Reference | **field** | **type** | **required** | **description** | |:------------|:---------|:-------------|:---------------------------------------------------| -| kind | string | true | Must be "dataform-compile-local". | +| type | string | true | Must be "dataform-compile-local". | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/dataplex/dataplex-lookup-entry.md b/docs/en/resources/tools/dataplex/dataplex-lookup-entry.md index ea19ed6451..669d47efc7 100644 --- a/docs/en/resources/tools/dataplex/dataplex-lookup-entry.md +++ b/docs/en/resources/tools/dataplex/dataplex-lookup-entry.md @@ -56,17 +56,17 @@ applying IAM permissions and roles to an identity. ## Example ```yaml -tools: - lookup_entry: - kind: dataplex-lookup-entry - source: my-dataplex-source - description: Use this tool to retrieve a specific entry in Dataplex Catalog. +kind: tools +name: lookup_entry +type: dataplex-lookup-entry +source: my-dataplex-source +description: Use this tool to retrieve a specific entry in Dataplex Catalog. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "dataplex-lookup-entry". | +| type | string | true | Must be "dataplex-lookup-entry". | | source | string | true | Name of the source the tool should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/dataplex/dataplex-search-aspect-types.md b/docs/en/resources/tools/dataplex/dataplex-search-aspect-types.md index 75d7793966..1bb17579ba 100644 --- a/docs/en/resources/tools/dataplex/dataplex-search-aspect-types.md +++ b/docs/en/resources/tools/dataplex/dataplex-search-aspect-types.md @@ -49,17 +49,17 @@ applying IAM permissions and roles to an identity. ## Example ```yaml -tools: - dataplex-search-aspect-types: - kind: dataplex-search-aspect-types - source: my-dataplex-source - description: Use this tool to find aspect types relevant to the query. +kind: tools +name: dataplex-search-aspect-types +type: dataplex-search-aspect-types +source: my-dataplex-source +description: Use this tool to find aspect types relevant to the query. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "dataplex-search-aspect-types". | +| type | string | true | Must be "dataplex-search-aspect-types". | | source | string | true | Name of the source the tool should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/dataplex/dataplex-search-entries.md b/docs/en/resources/tools/dataplex/dataplex-search-entries.md index 75099d64e8..b7c0bd3deb 100644 --- a/docs/en/resources/tools/dataplex/dataplex-search-entries.md +++ b/docs/en/resources/tools/dataplex/dataplex-search-entries.md @@ -49,17 +49,17 @@ applying IAM permissions and roles to an identity. ## Example ```yaml -tools: - dataplex-search-entries: - kind: dataplex-search-entries - source: my-dataplex-source - description: Use this tool to get all the entries based on the provided query. +kind: tools +name: dataplex-search-entries +type: dataplex-search-entries +source: my-dataplex-source +description: Use this tool to get all the entries based on the provided query. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "dataplex-search-entries". | +| type | string | true | Must be "dataplex-search-entries". | | source | string | true | Name of the source the tool should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/dgraph/dgraph-dql.md b/docs/en/resources/tools/dgraph/dgraph-dql.md index 3c8e7685f3..ba33a35a60 100644 --- a/docs/en/resources/tools/dgraph/dgraph-dql.md +++ b/docs/en/resources/tools/dgraph/dgraph-dql.md @@ -41,83 +41,83 @@ query. {{< tabpane persist="header" >}} {{< tab header="Query" lang="yaml" >}} -tools: - search_user: - kind: dgraph-dql - source: my-dgraph-source - statement: | - query all($role: string){ - users(func: has(name)) @filter(eq(role, $role) AND ge(age, 30) AND le(age, 50)) { - uid - name - email - role - age - } - } - isQuery: true - timeout: 20s - description: | - Use this tool to retrieve the details of users who are admins and are between 30 and 50 years old. - The query returns the user's name, email, role, and age. - This can be helpful when you want to fetch admin users within a specific age range. - Example: Fetch admins aged between 30 and 50: - [ - { - "name": "Alice", - "role": "admin", - "age": 35 - }, - { - "name": "Bob", - "role": "admin", - "age": 45 - } - ] - parameters: - - name: $role - type: string - description: admin +kind: tools +name: search_user +type: dgraph-dql +source: my-dgraph-source +statement: | + query all($role: string){ + users(func: has(name)) @filter(eq(role, $role) AND ge(age, 30) AND le(age, 50)) { + uid + name + email + role + age + } + } +isQuery: true +timeout: 20s +description: | + Use this tool to retrieve the details of users who are admins and are between 30 and 50 years old. + The query returns the user's name, email, role, and age. + This can be helpful when you want to fetch admin users within a specific age range. + Example: Fetch admins aged between 30 and 50: + [ + { + "name": "Alice", + "role": "admin", + "age": 35 + }, + { + "name": "Bob", + "role": "admin", + "age": 45 + } + ] +parameters: + - name: $role + type: string + description: admin {{< /tab >}} {{< tab header="Mutation" lang="yaml" >}} -tools: - dgraph-manage-user-instance: - kind: dgraph-dql - source: my-dgraph-source - isQuery: false - statement: | - { - set { - _:user1 $user1 . - _:user1 $email1 . - _:user1 "admin" . - _:user1 "35" . +kind: tools +name: dgraph-manage-user-instance +type: dgraph-dql +source: my-dgraph-source +isQuery: false +statement: | + { + set { + _:user1 $user1 . + _:user1 $email1 . + _:user1 "admin" . + _:user1 "35" . - _:user2 $user2 . - _:user2 $email2 . - _:user2 "admin" . - _:user2 "45" . - } - } - description: | - Use this tool to insert or update user data into the Dgraph database. - The mutation adds or updates user details like name, email, role, and age. - Example: Add users Alice and Bob as admins with specific ages. - parameters: - - name: user1 - type: string - description: Alice - - name: email1 - type: string - description: alice@email.com - - name: user2 - type: string - description: Bob - - name: email2 - type: string - description: bob@email.com + _:user2 $user2 . + _:user2 $email2 . + _:user2 "admin" . + _:user2 "45" . + } + } +description: | + Use this tool to insert or update user data into the Dgraph database. + The mutation adds or updates user details like name, email, role, and age. + Example: Add users Alice and Bob as admins with specific ages. +parameters: + - name: user1 + type: string + description: Alice + - name: email1 + type: string + description: alice@email.com + - name: user2 + type: string + description: Bob + - name: email2 + type: string + description: bob@email.com {{< /tab >}} {{< /tabpane >}} @@ -126,7 +126,7 @@ tools: | **field** | **type** | **required** | **description** | |-------------|:---------------------------------------:|:------------:|-------------------------------------------------------------------------------------------| -| kind | string | true | Must be "dgraph-dql". | +| type | string | true | Must be "dgraph-dql". | | source | string | true | Name of the source the dql query should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | statement | string | true | dql statement to execute | diff --git a/docs/en/resources/tools/elasticsearch/elasticsearch-esql.md b/docs/en/resources/tools/elasticsearch/elasticsearch-esql.md index 2df0ef6e54..1e0f5c70c1 100644 --- a/docs/en/resources/tools/elasticsearch/elasticsearch-esql.md +++ b/docs/en/resources/tools/elasticsearch/elasticsearch-esql.md @@ -20,20 +20,20 @@ for more information. ## Example ```yaml -tools: - query_my_index: - kind: elasticsearch-esql - source: elasticsearch-source - description: Use this tool to execute ES|QL queries. - query: | - FROM my-index - | KEEP * - | LIMIT ?limit - parameters: - - name: limit - type: integer - description: Limit the number of results. - required: true +kind: tools +name: query_my_index +type: elasticsearch-esql +source: elasticsearch-source +description: Use this tool to execute ES|QL queries. +query: | + FROM my-index + | KEEP * + | LIMIT ?limit +parameters: + - name: limit + type: integer + description: Limit the number of results. + required: true ``` ## Parameters diff --git a/docs/en/resources/tools/firebird/firebird-execute-sql.md b/docs/en/resources/tools/firebird/firebird-execute-sql.md index fa75d04137..830037c3cf 100644 --- a/docs/en/resources/tools/firebird/firebird-execute-sql.md +++ b/docs/en/resources/tools/firebird/firebird-execute-sql.md @@ -25,17 +25,17 @@ statement against the `source`. ## Example ```yaml -tools: - execute_sql_tool: - kind: firebird-execute-sql - source: my_firebird_db - description: Use this tool to execute a SQL statement against the Firebird database. +kind: tools +name: execute_sql_tool +type: firebird-execute-sql +source: my_firebird_db +description: Use this tool to execute a SQL statement against the Firebird database. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "firebird-execute-sql". | +| type | string | true | Must be "firebird-execute-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/firebird/firebird-sql.md b/docs/en/resources/tools/firebird/firebird-sql.md index d07c3cb53a..3e6614b9af 100644 --- a/docs/en/resources/tools/firebird/firebird-sql.md +++ b/docs/en/resources/tools/firebird/firebird-sql.md @@ -32,68 +32,68 @@ prepared statement. > names, or other parts of the query. ```yaml -tools: - search_flights_by_number: - kind: firebird-sql - source: my_firebird_db - statement: | - SELECT * FROM flights - WHERE airline = ? - AND flight_number = ? - LIMIT 10 - description: | - Use this tool to get information for a specific flight. - Takes an airline code and flight number and returns info on the flight. - Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. - A airline code is a code for an airline service consisting of two-character - airline designator and followed by flight number, which is 1 to 4 digit number. - For example, if given CY 0123, the airline is "CY", and flight_number is "123". - Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". - If the tool returns more than one option choose the date closes to today. - Example: - {{ - "airline": "CY", - "flight_number": "888", - }} - Example: - {{ - "airline": "DL", - "flight_number": "1234", - }} - parameters: - - name: airline - type: string - description: Airline unique 2 letter identifier - - name: flight_number - type: string - description: 1 to 4 digit number +kind: tools +name: search_flights_by_number +type: firebird-sql +source: my_firebird_db +statement: | + SELECT * FROM flights + WHERE airline = ? + AND flight_number = ? + LIMIT 10 +description: | + Use this tool to get information for a specific flight. + Takes an airline code and flight number and returns info on the flight. + Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. + A airline code is a code for an airline service consisting of two-character + airline designator and followed by flight number, which is 1 to 4 digit number. + For example, if given CY 0123, the airline is "CY", and flight_number is "123". + Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". + If the tool returns more than one option choose the date closes to today. + Example: + {{ + "airline": "CY", + "flight_number": "888", + }} + Example: + {{ + "airline": "DL", + "flight_number": "1234", + }} +parameters: + - name: airline + type: string + description: Airline unique 2 letter identifier + - name: flight_number + type: string + description: 1 to 4 digit number ``` ### Example with Named Parameters ```yaml -tools: - search_flights_by_airline: - kind: firebird-sql - source: my_firebird_db - statement: | - SELECT * FROM flights - WHERE airline = :airline - AND departure_date >= :start_date - AND departure_date <= :end_date - ORDER BY departure_date - description: | - Search for flights by airline within a date range using named parameters. - parameters: - - name: airline - type: string - description: Airline unique 2 letter identifier - - name: start_date - type: string - description: Start date in YYYY-MM-DD format - - name: end_date - type: string - description: End date in YYYY-MM-DD format +kind: tools +name: search_flights_by_airline +type: firebird-sql +source: my_firebird_db +statement: | + SELECT * FROM flights + WHERE airline = :airline + AND departure_date >= :start_date + AND departure_date <= :end_date + ORDER BY departure_date +description: | + Search for flights by airline within a date range using named parameters. +parameters: + - name: airline + type: string + description: Airline unique 2 letter identifier + - name: start_date + type: string + description: Start date in YYYY-MM-DD format + - name: end_date + type: string + description: End date in YYYY-MM-DD format ``` ### Example with Template Parameters @@ -105,29 +105,29 @@ tools: > [templateParameters](../#template-parameters). ```yaml -tools: - list_table: - kind: firebird-sql - source: my_firebird_db - statement: | - SELECT * FROM {{.tableName}} - description: | - Use this tool to list all information from a specific table. - Example: - {{ - "tableName": "flights", - }} - templateParameters: - - name: tableName - type: string - description: Table to select from +kind: tools +name: list_table +type: firebird-sql +source: my_firebird_db +statement: | + SELECT * FROM {{.tableName}} +description: | + Use this tool to list all information from a specific table. + Example: + {{ + "tableName": "flights", + }} +templateParameters: + - name: tableName + type: string + description: Table to select from ``` ## Reference | **field** | **type** | **required** | **description** | |--------------------|:---------------------------------------------:|:------------:|-----------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "firebird-sql". | +| type | string | true | Must be "firebird-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | statement | string | true | SQL statement to execute on. | diff --git a/docs/en/resources/tools/firestore/firestore-add-documents.md b/docs/en/resources/tools/firestore/firestore-add-documents.md index 13f8b207ea..b777be7f8d 100644 --- a/docs/en/resources/tools/firestore/firestore-add-documents.md +++ b/docs/en/resources/tools/firestore/firestore-add-documents.md @@ -59,11 +59,11 @@ must be wrapped with its type indicator: ### Basic Document Creation ```yaml -tools: - add-company-doc: - kind: firestore-add-documents - source: my-firestore - description: Add a new company document +kind: tools +name: add-company-doc +type: firestore-add-documents +source: my-firestore +description: Add a new company document ``` Usage: @@ -246,14 +246,14 @@ Usage: The tool can be configured to require authentication: ```yaml -tools: - secure-add-docs: - kind: firestore-add-documents - source: prod-firestore - description: Add documents with authentication required - authRequired: - - google-oauth - - api-key +kind: tools +name: secure-add-docs +type: firestore-add-documents +source: prod-firestore +description: Add documents with authentication required +authRequired: + - google-oauth + - api-key ``` ## Error Handling diff --git a/docs/en/resources/tools/firestore/firestore-delete-documents.md b/docs/en/resources/tools/firestore/firestore-delete-documents.md index 66343231d0..36d6b61fc3 100644 --- a/docs/en/resources/tools/firestore/firestore-delete-documents.md +++ b/docs/en/resources/tools/firestore/firestore-delete-documents.md @@ -23,17 +23,17 @@ efficient batch deletion and returns the success status for each document. ## Example ```yaml -tools: - delete_user_documents: - kind: firestore-delete-documents - source: my-firestore-source - description: Use this tool to delete multiple documents from Firestore. +kind: tools +name: delete_user_documents +type: firestore-delete-documents +source: my-firestore-source +description: Use this tool to delete multiple documents from Firestore. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------------:|:------------:|----------------------------------------------------------| -| kind | string | true | Must be "firestore-delete-documents". | +| type | string | true | Must be "firestore-delete-documents". | | source | string | true | Name of the Firestore source to delete documents from. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/firestore/firestore-get-documents.md b/docs/en/resources/tools/firestore/firestore-get-documents.md index 0bc1bef1b8..a4a5b0df0c 100644 --- a/docs/en/resources/tools/firestore/firestore-get-documents.md +++ b/docs/en/resources/tools/firestore/firestore-get-documents.md @@ -23,17 +23,17 @@ such as existence status, creation time, update time, and read time. ## Example ```yaml -tools: - get_user_documents: - kind: firestore-get-documents - source: my-firestore-source - description: Use this tool to retrieve multiple documents from Firestore. +kind: tools +name: get_user_documents +type: firestore-get-documents +source: my-firestore-source +description: Use this tool to retrieve multiple documents from Firestore. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------------:|:------------:|------------------------------------------------------------| -| kind | string | true | Must be "firestore-get-documents". | +| type | string | true | Must be "firestore-get-documents". | | source | string | true | Name of the Firestore source to retrieve documents from. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/firestore/firestore-get-rules.md b/docs/en/resources/tools/firestore/firestore-get-rules.md index 568dc6b1da..28b48e53ab 100644 --- a/docs/en/resources/tools/firestore/firestore-get-rules.md +++ b/docs/en/resources/tools/firestore/firestore-get-rules.md @@ -23,17 +23,17 @@ content along with metadata such as the ruleset name, and timestamps. ## Example ```yaml -tools: - get_firestore_rules: - kind: firestore-get-rules - source: my-firestore-source - description: Use this tool to retrieve the active Firestore security rules. +kind: tools +name: get_firestore_rules +type: firestore-get-rules +source: my-firestore-source +description: Use this tool to retrieve the active Firestore security rules. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:-------------:|:------------:|-------------------------------------------------------| -| kind | string | true | Must be "firestore-get-rules". | +| type | string | true | Must be "firestore-get-rules". | | source | string | true | Name of the Firestore source to retrieve rules from. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/firestore/firestore-list-collections.md b/docs/en/resources/tools/firestore/firestore-list-collections.md index b2cc7ef6b6..971aed02b8 100644 --- a/docs/en/resources/tools/firestore/firestore-list-collections.md +++ b/docs/en/resources/tools/firestore/firestore-list-collections.md @@ -26,17 +26,17 @@ not provided, it lists all root-level collections in the database. ## Example ```yaml -tools: - list_firestore_collections: - kind: firestore-list-collections - source: my-firestore-source - description: Use this tool to list collections in Firestore. +kind: tools +name: list_firestore_collections +type: firestore-list-collections +source: my-firestore-source +description: Use this tool to list collections in Firestore. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:----------------:|:------------:|--------------------------------------------------------| -| kind | string | true | Must be "firestore-list-collections". | +| type | string | true | Must be "firestore-list-collections". | | source | string | true | Name of the Firestore source to list collections from. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/firestore/firestore-query-collection.md b/docs/en/resources/tools/firestore/firestore-query-collection.md index f615a9bc2e..774aa9f29e 100644 --- a/docs/en/resources/tools/firestore/firestore-query-collection.md +++ b/docs/en/resources/tools/firestore/firestore-query-collection.md @@ -18,17 +18,17 @@ with filters, ordering, and limit capabilities. To use this tool, you need to configure it in your YAML configuration file: ```yaml -sources: - my-firestore: - kind: firestore - project: my-gcp-project - database: "(default)" - -tools: - query_collection: - kind: firestore-query-collection - source: my-firestore - description: Query Firestore collections with advanced filtering +kind: sources +name: my-firestore +type: firestore +project: my-gcp-project +database: "(default)" +--- +kind: tools +name: query_collection +type: firestore-query-collection +source: my-firestore +description: Query Firestore collections with advanced filtering ``` ## Parameters diff --git a/docs/en/resources/tools/firestore/firestore-query.md b/docs/en/resources/tools/firestore/firestore-query.md index 20fe9c8fd7..a3027e02d2 100644 --- a/docs/en/resources/tools/firestore/firestore-query.md +++ b/docs/en/resources/tools/firestore/firestore-query.md @@ -38,87 +38,87 @@ developers can use to create custom tools with specific query patterns. ### Basic Configuration ```yaml -tools: - query_countries: - kind: firestore-query - source: my-firestore-source - description: Query countries with dynamic filters - collectionPath: "countries" - filters: | - { - "field": "continent", - "op": "==", - "value": {"stringValue": "{{.continent}}"} - } - parameters: - - name: continent - type: string - description: Continent to filter by - required: true +kind: tools +name: query_countries +type: firestore-query +source: my-firestore-source +description: Query countries with dynamic filters +collectionPath: "countries" +filters: | + { + "field": "continent", + "op": "==", + "value": {"stringValue": "{{.continent}}"} + } +parameters: + - name: continent + type: string + description: Continent to filter by + required: true ``` ### Advanced Configuration with Complex Filters ```yaml -tools: - advanced_query: - kind: firestore-query - source: my-firestore-source - description: Advanced query with complex filters - collectionPath: "{{.collection}}" - filters: | +kind: tools +name: advanced_query +type: firestore-query +source: my-firestore-source +description: Advanced query with complex filters +collectionPath: "{{.collection}}" +filters: | + { + "or": [ + {"field": "status", "op": "==", "value": {"stringValue": "{{.status}}"}}, { - "or": [ - {"field": "status", "op": "==", "value": {"stringValue": "{{.status}}"}}, - { - "and": [ - {"field": "priority", "op": ">", "value": {"integerValue": "{{.priority}}"}}, - {"field": "area", "op": "<", "value": {"doubleValue": {{.maxArea}}}}, - {"field": "active", "op": "==", "value": {"booleanValue": {{.isActive}}}} - ] - } + "and": [ + {"field": "priority", "op": ">", "value": {"integerValue": "{{.priority}}"}}, + {"field": "area", "op": "<", "value": {"doubleValue": {{.maxArea}}}}, + {"field": "active", "op": "==", "value": {"booleanValue": {{.isActive}}}} ] } - select: - - name - - status - - priority - orderBy: - field: "{{.sortField}}" - direction: "{{.sortDirection}}" - limit: 100 - analyzeQuery: true - parameters: - - name: collection - type: string - description: Collection to query - required: true - - name: status - type: string - description: Status to filter by - required: true - - name: priority - type: string - description: Minimum priority value - required: true - - name: maxArea - type: float - description: Maximum area value - required: true - - name: isActive - type: boolean - description: Filter by active status - required: true - - name: sortField - type: string - description: Field to sort by - required: false - default: "createdAt" - - name: sortDirection - type: string - description: Sort direction (ASCENDING or DESCENDING) - required: false - default: "DESCENDING" + ] + } +select: + - name + - status + - priority +orderBy: + field: "{{.sortField}}" + direction: "{{.sortDirection}}" +limit: 100 +analyzeQuery: true +parameters: + - name: collection + type: string + description: Collection to query + required: true + - name: status + type: string + description: Status to filter by + required: true + - name: priority + type: string + description: Minimum priority value + required: true + - name: maxArea + type: float + description: Maximum area value + required: true + - name: isActive + type: boolean + description: Filter by active status + required: true + - name: sortField + type: string + description: Field to sort by + required: false + default: "createdAt" + - name: sortDirection + type: string + description: Sort direction (ASCENDING or DESCENDING) + required: false + default: "DESCENDING" ``` ## Parameters @@ -127,7 +127,7 @@ tools: | Parameter | Type | Required | Description | |------------------|---------|----------|-------------------------------------------------------------------------------------------------------------| -| `kind` | string | Yes | Must be `firestore-query` | +| `type` | string | Yes | Must be `firestore-query` | | `source` | string | Yes | Name of the Firestore source to use | | `description` | string | Yes | Description of what this tool does | | `collectionPath` | string | Yes | Path to the collection to query (supports templates) | @@ -254,103 +254,103 @@ The tool supports all Firestore native JSON value types: ### Example 1: Query with Dynamic Collection Path ```yaml -tools: - user_documents: - kind: firestore-query - source: my-firestore - description: Query user-specific documents - collectionPath: "users/{{.userId}}/documents" - filters: | - { - "field": "type", - "op": "==", - "value": {"stringValue": "{{.docType}}"} - } - parameters: - - name: userId - type: string - description: User ID - required: true - - name: docType - type: string - description: Document type to filter - required: true +kind: tools +name: user_documents +type: firestore-query +source: my-firestore +description: Query user-specific documents +collectionPath: "users/{{.userId}}/documents" +filters: | + { + "field": "type", + "op": "==", + "value": {"stringValue": "{{.docType}}"} + } +parameters: + - name: userId + type: string + description: User ID + required: true + - name: docType + type: string + description: Document type to filter + required: true ``` ### Example 2: Complex Geographic Query ```yaml -tools: - location_search: - kind: firestore-query - source: my-firestore - description: Search locations by area and population - collectionPath: "cities" - filters: | - { - "and": [ - {"field": "country", "op": "==", "value": {"stringValue": "{{.country}}"}}, - {"field": "population", "op": ">", "value": {"integerValue": "{{.minPopulation}}"}}, - {"field": "area", "op": "<", "value": {"doubleValue": {{.maxArea}}}} - ] - } - orderBy: - field: "population" - direction: "DESCENDING" - limit: 50 - parameters: - - name: country - type: string - description: Country code - required: true - - name: minPopulation - type: string - description: Minimum population (as string for large numbers) - required: true - - name: maxArea - type: float - description: Maximum area in square kilometers - required: true +kind: tools +name: location_search +type: firestore-query +source: my-firestore +description: Search locations by area and population +collectionPath: "cities" +filters: | + { + "and": [ + {"field": "country", "op": "==", "value": {"stringValue": "{{.country}}"}}, + {"field": "population", "op": ">", "value": {"integerValue": "{{.minPopulation}}"}}, + {"field": "area", "op": "<", "value": {"doubleValue": {{.maxArea}}}} + ] + } +orderBy: + field: "population" + direction: "DESCENDING" +limit: 50 +parameters: + - name: country + type: string + description: Country code + required: true + - name: minPopulation + type: string + description: Minimum population (as string for large numbers) + required: true + - name: maxArea + type: float + description: Maximum area in square kilometers + required: true ``` ### Example 3: Time-based Query with Analysis ```yaml -tools: - activity_log: - kind: firestore-query - source: my-firestore - description: Query activity logs within time range - collectionPath: "logs" - filters: | - { - "and": [ - {"field": "timestamp", "op": ">=", "value": {"timestampValue": "{{.startTime}}"}}, - {"field": "timestamp", "op": "<=", "value": {"timestampValue": "{{.endTime}}"}}, - {"field": "severity", "op": "in", "value": {"arrayValue": {"values": [ - {"stringValue": "ERROR"}, - {"stringValue": "CRITICAL"} - ]}}} - ] - } - select: - - timestamp - - message - - severity - - userId - orderBy: - field: "timestamp" - direction: "DESCENDING" - analyzeQuery: true - parameters: - - name: startTime - type: string - description: Start time in RFC3339 format - required: true - - name: endTime - type: string - description: End time in RFC3339 format - required: true +kind: tools +name: activity_log +type: firestore-query +source: my-firestore +description: Query activity logs within time range +collectionPath: "logs" +filters: | + { + "and": [ + {"field": "timestamp", "op": ">=", "value": {"timestampValue": "{{.startTime}}"}}, + {"field": "timestamp", "op": "<=", "value": {"timestampValue": "{{.endTime}}"}}, + {"field": "severity", "op": "in", "value": {"arrayValue": {"values": [ + {"stringValue": "ERROR"}, + {"stringValue": "CRITICAL"} + ]}}} + ] + } +select: + - timestamp + - message + - severity + - userId +orderBy: + field: "timestamp" + direction: "DESCENDING" +analyzeQuery: true +parameters: + - name: startTime + type: string + description: Start time in RFC3339 format + required: true + - name: endTime + type: string + description: End time in RFC3339 format + required: true ``` ## Usage diff --git a/docs/en/resources/tools/firestore/firestore-update-document.md b/docs/en/resources/tools/firestore/firestore-update-document.md index 56aad8d371..0cbda2cbfa 100644 --- a/docs/en/resources/tools/firestore/firestore-update-document.md +++ b/docs/en/resources/tools/firestore/firestore-update-document.md @@ -76,7 +76,7 @@ deleted. To delete a field, include it in the `updateMask` but omit it from | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|------------------------------------------------------| -| kind | string | true | Must be "firestore-update-document". | +| type | string | true | Must be "firestore-update-document". | | source | string | true | Name of the Firestore source to update documents in. | | description | string | true | Description of the tool that is passed to the LLM. | @@ -85,11 +85,11 @@ deleted. To delete a field, include it in the `updateMask` but omit it from ### Basic Document Update (Full Merge) ```yaml -tools: - update-user-doc: - kind: firestore-update-document - source: my-firestore - description: Update a user document +kind: tools +name: update-user-doc +type: firestore-update-document +source: my-firestore +description: Update a user document ``` Usage: @@ -299,14 +299,14 @@ In this example: The tool can be configured to require authentication: ```yaml -tools: - secure-update-doc: - kind: firestore-update-document - source: prod-firestore - description: Update documents with authentication required - authRequired: - - google-oauth - - api-key +kind: tools +name: secure-update-doc +type: firestore-update-document +source: prod-firestore +description: Update documents with authentication required +authRequired: + - google-oauth + - api-key ``` ## Error Handling diff --git a/docs/en/resources/tools/firestore/firestore-validate-rules.md b/docs/en/resources/tools/firestore/firestore-validate-rules.md index 6f74bec527..3e6b069521 100644 --- a/docs/en/resources/tools/firestore/firestore-validate-rules.md +++ b/docs/en/resources/tools/firestore/firestore-validate-rules.md @@ -17,11 +17,11 @@ reporting with source positions and code snippets. ## Configuration ```yaml -tools: - firestore-validate-rules: - kind: firestore-validate-rules - source: - description: "Checks the provided Firestore Rules source for syntax and validation errors" +kind: tools +name: firestore-validate-rules +type: firestore-validate-rules +source: +description: "Checks the provided Firestore Rules source for syntax and validation errors" ``` ## Authentication diff --git a/docs/en/resources/tools/http/http.md b/docs/en/resources/tools/http/http.md index 466a86c36d..19272c9035 100644 --- a/docs/en/resources/tools/http/http.md +++ b/docs/en/resources/tools/http/http.md @@ -31,36 +31,38 @@ For example, the following config allows you to reach different paths of the same server using multiple Tools: ```yaml -sources: - my-http-source: - kind: http - baseUrl: https://api.example.com - -tools: - my-post-tool: - kind: http - source: my-http-source - method: POST - path: /update - description: Tool to update information to the example API - - my-get-tool: - kind: http - source: my-http-source - method: GET - path: /search - description: Tool to search information from the example API - - my-dynamic-path-tool: - kind: http - source: my-http-source - method: GET - path: /{{.myPathParam}}/search - description: Tool to reach endpoint based on the input to `myPathParam` - pathParams: - - name: myPathParam - type: string - description: The dynamic path parameter +kind: sources +name: my-http-source +type: http +baseUrl: https://api.example.com +--- +kind: tools +name: my-post-tool +type: http +source: my-http-source +method: POST +path: /update +description: Tool to update information to the example API +--- +kind: tools +name: my-get-tool +type: http +source: my-http-source +method: GET +path: /search +description: Tool to search information from the example API +--- +kind: tools +name: my-dynamic-path-tool +type: http +source: my-http-source +method: GET +path: /{{.myPathParam}}/search +description: Tool to reach endpoint based on the input to `myPathParam` +pathParams: + - name: myPathParam + type: string + description: The dynamic path parameter ``` @@ -77,15 +79,16 @@ The HTTP Tool allows you to specify headers in two different ways: same for every invocation: ```yaml -my-http-tool: - kind: http - source: my-http-source - method: GET - path: /search - description: Tool to search data from API - headers: - Authorization: API_KEY - Content-Type: application/json +kind: tools +name: my-http-tool +type: http +source: my-http-source +method: GET +path: /search +description: Tool to search data from API +headers: + Authorization: API_KEY + Content-Type: application/json ``` - Dynamic headers can be specified as parameters in the `headerParams` field. @@ -93,16 +96,17 @@ my-http-tool: is determined by the LLM input upon Tool invocation: ```yaml -my-http-tool: - kind: http - source: my-http-source - method: GET - path: /search - description: some description - headerParams: - - name: Content-Type # Example LLM input: "application/json" - description: request content type - type: string +kind: tools +name: my-http-tool +type: http +source: my-http-source +method: GET +path: /search +description: some description +headerParams: + - name: Content-Type # Example LLM input: "application/json" + description: request content type + type: string ``` ### Query parameters @@ -115,28 +119,30 @@ filtering or sorting data. the URL itself: ```yaml -my-http-tool: - kind: http - source: my-http-source - method: GET - path: /search?language=en&id=1 - description: Tool to search for item with ID 1 in English +kind: tools +name: my-http-tool +type: http +source: my-http-source +method: GET +path: /search?language=en&id=1 +description: Tool to search for item with ID 1 in English ``` - Dynamic request query parameters should be specified as parameters in the `queryParams` section: ```yaml -my-http-tool: - kind: http - source: my-http-source - method: GET - path: /search - description: Tool to search for item with ID - queryParams: - - name: id - description: item ID - type: integer +kind: tools +name: my-http-tool +type: http +source: my-http-source +method: GET +path: /search +description: Tool to search for item with ID +queryParams: + - name: id + description: item ID + type: integer ``` ### Request body @@ -150,24 +156,25 @@ body payload upon Tool invocation. Example: ```yaml -my-http-tool: - kind: http - source: my-http-source - method: GET - path: /search - description: Tool to search for person with name and age - requestBody: | - { - "age": {{.age}}, - "name": "{{.name}}" - } - bodyParams: - - name: age - description: age number - type: integer - - name: name - description: name string - type: string +kind: tools +name: my-http-tool +type: http +source: my-http-source +method: GET +path: /search +description: Tool to search for person with name and age +requestBody: | + { + "age": {{.age}}, + "name": "{{.name}}" + } +bodyParams: + - name: age + description: age number + type: integer + - name: name + description: name string + type: string ``` #### Formatting Parameters @@ -211,45 +218,46 @@ will send the following output: ## Example ```yaml -my-http-tool: - kind: http - source: my-http-source - method: GET - path: /search +kind: tools +name: my-http-tool +type: http +source: my-http-source +method: GET +path: /search +description: some description +authRequired: + - my-google-auth-service + - other-auth-service +queryParams: + - name: country description: some description - authRequired: - - my-google-auth-service - - other-auth-service - queryParams: - - name: country - description: some description - type: string - requestBody: | - { - "age": {{.age}}, - "city": "{{.city}}" - } - bodyParams: - - name: age - description: age number - type: integer - - name: city - description: city string - type: string - headers: - Authorization: API_KEY - Content-Type: application/json - headerParams: - - name: Language - description: language string - type: string + type: string +requestBody: | + { + "age": {{.age}}, + "city": "{{.city}}" + } +bodyParams: + - name: age + description: age number + type: integer + - name: city + description: city string + type: string +headers: + Authorization: API_KEY + Content-Type: application/json +headerParams: + - name: Language + description: language string + type: string ``` ## Reference | **field** | **type** | **required** | **description** | |--------------|:---------------------------------------:|:------------:|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "http". | +| type | string | true | Must be "http". | | source | string | true | Name of the source the HTTP request should be sent to. | | description | string | true | Description of the tool that is passed to the LLM. | | path | string | true | The path of the HTTP request. You can include static query parameters in the path string. | diff --git a/docs/en/resources/tools/looker/looker-add-dashboard-element.md b/docs/en/resources/tools/looker/looker-add-dashboard-element.md index 3c0a65f2d3..5e217fc865 100644 --- a/docs/en/resources/tools/looker/looker-add-dashboard-element.md +++ b/docs/en/resources/tools/looker/looker-add-dashboard-element.md @@ -25,42 +25,42 @@ It's compatible with the following sources: ## Example ```yaml -tools: - add_dashboard_element: - kind: looker-add-dashboard-element - source: looker-source - description: | - This tool creates a new tile (element) within an existing Looker dashboard. - Tiles are added in the order this tool is called for a given `dashboard_id`. +kind: tools +name: add_dashboard_element +type: looker-add-dashboard-element +source: looker-source +description: | + This tool creates a new tile (element) within an existing Looker dashboard. + Tiles are added in the order this tool is called for a given `dashboard_id`. - CRITICAL ORDER OF OPERATIONS: - 1. Create the dashboard using `make_dashboard`. - 2. Add any dashboard-level filters using `add_dashboard_filter`. - 3. Then, add elements (tiles) using this tool. + CRITICAL ORDER OF OPERATIONS: + 1. Create the dashboard using `make_dashboard`. + 2. Add any dashboard-level filters using `add_dashboard_filter`. + 3. Then, add elements (tiles) using this tool. - Required Parameters: - - dashboard_id: The ID of the target dashboard, obtained from `make_dashboard`. - - model_name, explore_name, fields: These query parameters are inherited - from the `query` tool and are required to define the data for the tile. + Required Parameters: + - dashboard_id: The ID of the target dashboard, obtained from `make_dashboard`. + - model_name, explore_name, fields: These query parameters are inherited + from the `query` tool and are required to define the data for the tile. - Optional Parameters: - - title: An optional title for the dashboard tile. - - pivots, filters, sorts, limit, query_timezone: These query parameters are - inherited from the `query` tool and can be used to customize the tile's query. - - vis_config: A JSON object defining the visualization settings for this tile. - The structure and options are the same as for the `query_url` tool's `vis_config`. + Optional Parameters: + - title: An optional title for the dashboard tile. + - pivots, filters, sorts, limit, query_timezone: These query parameters are + inherited from the `query` tool and can be used to customize the tile's query. + - vis_config: A JSON object defining the visualization settings for this tile. + The structure and options are the same as for the `query_url` tool's `vis_config`. - Connecting to Dashboard Filters: - A dashboard element can be connected to one or more dashboard filters (created with - `add_dashboard_filter`). To do this, specify the `name` of the dashboard filter - and the `field` from the element's query that the filter should apply to. - The format for specifying the field is `view_name.field_name`. + Connecting to Dashboard Filters: + A dashboard element can be connected to one or more dashboard filters (created with + `add_dashboard_filter`). To do this, specify the `name` of the dashboard filter + and the `field` from the element's query that the filter should apply to. + The format for specifying the field is `view_name.field_name`. ``` ## Reference | **field** | **type** | **required** | **description** | |:------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-add-dashboard-element". | +| type | string | true | Must be "looker-add-dashboard-element". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | \ No newline at end of file diff --git a/docs/en/resources/tools/looker/looker-add-dashboard-filter.md b/docs/en/resources/tools/looker/looker-add-dashboard-filter.md index e5cf5ba34d..ca88afebfc 100644 --- a/docs/en/resources/tools/looker/looker-add-dashboard-filter.md +++ b/docs/en/resources/tools/looker/looker-add-dashboard-filter.md @@ -39,37 +39,37 @@ It's compatible with the following sources: ## Example ```yaml -tools: - add_dashboard_filter: - kind: looker-add-dashboard-filter - source: looker-source - description: | - This tool adds a filter to a Looker dashboard. +kind: tools +name: add_dashboard_filter +type: looker-add-dashboard-filter +source: looker-source +description: | + This tool adds a filter to a Looker dashboard. - CRITICAL ORDER OF OPERATIONS: - 1. Create a dashboard using `make_dashboard`. - 2. Add all desired filters using this tool (`add_dashboard_filter`). - 3. Finally, add dashboard elements (tiles) using `add_dashboard_element`. + CRITICAL ORDER OF OPERATIONS: + 1. Create a dashboard using `make_dashboard`. + 2. Add all desired filters using this tool (`add_dashboard_filter`). + 3. Finally, add dashboard elements (tiles) using `add_dashboard_element`. - Parameters: - - dashboard_id (required): The ID from `make_dashboard`. - - name (required): A unique internal identifier for the filter. You will use this `name` later in `add_dashboard_element` to bind tiles to this filter. - - title (required): The label displayed to users in the UI. - - filter_type (required): One of `date_filter`, `number_filter`, `string_filter`, or `field_filter`. - - default_value (optional): The initial value for the filter. + Parameters: + - dashboard_id (required): The ID from `make_dashboard`. + - name (required): A unique internal identifier for the filter. You will use this `name` later in `add_dashboard_element` to bind tiles to this filter. + - title (required): The label displayed to users in the UI. + - filter_type (required): One of `date_filter`, `number_filter`, `string_filter`, or `field_filter`. + - default_value (optional): The initial value for the filter. - Field Filters (`flter_type: field_filter`): - If creating a field filter, you must also provide: - - model - - explore - - dimension - The filter will inherit suggestions and type information from this LookML field. + Field Filters (`flter_type: field_filter`): + If creating a field filter, you must also provide: + - model + - explore + - dimension + The filter will inherit suggestions and type information from this LookML field. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-add-dashboard-filter". | +| type | string | true | Must be "looker-add-dashboard-filter". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | \ No newline at end of file diff --git a/docs/en/resources/tools/looker/looker-conversational-analytics.md b/docs/en/resources/tools/looker/looker-conversational-analytics.md index 150f347cf7..6e064cf7a4 100644 --- a/docs/en/resources/tools/looker/looker-conversational-analytics.md +++ b/docs/en/resources/tools/looker/looker-conversational-analytics.md @@ -29,21 +29,21 @@ It's compatible with the following sources: ## Example ```yaml -tools: - ask_data_insights: - kind: looker-conversational-analytics - source: looker-source - description: | - Use this tool to ask questions about your data using the Looker Conversational - Analytics API. You must provide a natural language query and a list of - 1 to 5 model and explore combinations (e.g. [{'model': 'the_model', 'explore': 'the_explore'}]). - Use the 'get_models' and 'get_explores' tools to discover available models and explores. +kind: tools +name: ask_data_insights +type: looker-conversational-analytics +source: looker-source +description: | + Use this tool to ask questions about your data using the Looker Conversational + Analytics API. You must provide a natural language query and a list of + 1 to 5 model and explore combinations (e.g. [{'model': 'the_model', 'explore': 'the_explore'}]). + Use the 'get_models' and 'get_explores' tools to discover available models and explores. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "lookerca-conversational-analytics". | +| type | string | true | Must be "lookerca-conversational-analytics". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-create-project-file.md b/docs/en/resources/tools/looker/looker-create-project-file.md index 826dda98e9..3e36fe73d0 100644 --- a/docs/en/resources/tools/looker/looker-create-project-file.md +++ b/docs/en/resources/tools/looker/looker-create-project-file.md @@ -22,29 +22,29 @@ as well as the file content. ## Example ```yaml -tools: - create_project_file: - kind: looker-create-project-file - source: looker-source - description: | - This tool creates a new LookML file within a specified project, populating - it with the provided content. +kind: tools +name: create_project_file +type: looker-create-project-file +source: looker-source +description: | + This tool creates a new LookML file within a specified project, populating + it with the provided content. - Prerequisite: The Looker session must be in Development Mode. Use `dev_mode: true` first. + Prerequisite: The Looker session must be in Development Mode. Use `dev_mode: true` first. - Parameters: - - project_id (required): The unique ID of the LookML project. - - file_path (required): The desired path and filename for the new file within the project. - - content (required): The full LookML content to write into the new file. + Parameters: + - project_id (required): The unique ID of the LookML project. + - file_path (required): The desired path and filename for the new file within the project. + - content (required): The full LookML content to write into the new file. - Output: - A confirmation message upon successful file creation. + Output: + A confirmation message upon successful file creation. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-create-project-file". | +| type | string | true | Must be "looker-create-project-file". | | source | string | true | Name of the source Looker instance. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-delete-project-file.md b/docs/en/resources/tools/looker/looker-delete-project-file.md index e5bf06948d..11419b8a19 100644 --- a/docs/en/resources/tools/looker/looker-delete-project-file.md +++ b/docs/en/resources/tools/looker/looker-delete-project-file.md @@ -21,28 +21,28 @@ It's compatible with the following sources: ## Example ```yaml -tools: - delete_project_file: - kind: looker-delete-project-file - source: looker-source - description: | - This tool permanently deletes a specified LookML file from within a project. - Use with caution, as this action cannot be undone through the API. +kind: tools +name: delete_project_file +type: looker-delete-project-file +source: looker-source +description: | + This tool permanently deletes a specified LookML file from within a project. + Use with caution, as this action cannot be undone through the API. - Prerequisite: The Looker session must be in Development Mode. Use `dev_mode: true` first. + Prerequisite: The Looker session must be in Development Mode. Use `dev_mode: true` first. - Parameters: - - project_id (required): The unique ID of the LookML project. - - file_path (required): The exact path to the LookML file to delete within the project. + Parameters: + - project_id (required): The unique ID of the LookML project. + - file_path (required): The exact path to the LookML file to delete within the project. - Output: - A confirmation message upon successful file deletion. + Output: + A confirmation message upon successful file deletion. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-delete-project-file". | +| type | string | true | Must be "looker-delete-project-file". | | source | string | true | Name of the source Looker instance. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-dev-mode.md b/docs/en/resources/tools/looker/looker-dev-mode.md index 9f69343ad5..33509ea54b 100644 --- a/docs/en/resources/tools/looker/looker-dev-mode.md +++ b/docs/en/resources/tools/looker/looker-dev-mode.md @@ -22,24 +22,24 @@ to exit dev mode. ## Example ```yaml -tools: - dev_mode: - kind: looker-dev-mode - source: looker-source - description: | - This tool allows toggling the Looker IDE session between Development Mode and Production Mode. - Development Mode enables making and testing changes to LookML projects. +kind: tools +name: dev_mode +type: looker-dev-mode +source: looker-source +description: | + This tool allows toggling the Looker IDE session between Development Mode and Production Mode. + Development Mode enables making and testing changes to LookML projects. - Parameters: - - enable (required): A boolean value. - - `true`: Switches the current session to Development Mode. - - `false`: Switches the current session to Production Mode. + Parameters: + - enable (required): A boolean value. + - `true`: Switches the current session to Development Mode. + - `false`: Switches the current session to Production Mode. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-dev-mode". | +| type | string | true | Must be "looker-dev-mode". | | source | string | true | Name of the source Looker instance. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-generate-embed-url.md b/docs/en/resources/tools/looker/looker-generate-embed-url.md index 1e136165da..bf7f4c1f23 100644 --- a/docs/en/resources/tools/looker/looker-generate-embed-url.md +++ b/docs/en/resources/tools/looker/looker-generate-embed-url.md @@ -31,28 +31,28 @@ supplied to this tool. ## Example ```yaml -tools: - generate_embed_url: - kind: looker-generate-embed-url - source: looker-source - description: | - This tool generates a signed, private embed URL for specific Looker content, - allowing users to access it directly. +kind: tools +name: generate_embed_url +type: looker-generate-embed-url +source: looker-source +description: | + This tool generates a signed, private embed URL for specific Looker content, + allowing users to access it directly. - Parameters: - - type (required): The type of content to embed. Common values include: - - `dashboards` - - `looks` - - `explore` - - id (required): The unique identifier for the content. - - For dashboards and looks, use the numeric ID (e.g., "123"). - - For explores, use the format "model_name/explore_name". + Parameters: + - type (required): The type of content to embed. Common values include: + - `dashboards` + - `looks` + - `explore` + - id (required): The unique identifier for the content. + - For dashboards and looks, use the numeric ID (e.g., "123"). + - For explores, use the format "model_name/explore_name". ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-generate-embed-url" | +| type | string | true | Must be "looker-generate-embed-url" | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-get-connection-databases.md b/docs/en/resources/tools/looker/looker-get-connection-databases.md index 23611fc2a1..b46459c26e 100644 --- a/docs/en/resources/tools/looker/looker-get-connection-databases.md +++ b/docs/en/resources/tools/looker/looker-get-connection-databases.md @@ -21,27 +21,27 @@ It's compatible with the following sources: ## Example ```yaml -tools: - get_connection_databases: - kind: looker-get-connection-databases - source: looker-source - description: | - This tool retrieves a list of databases available through a specified Looker connection. - This is only applicable for connections that support multiple databases. - Use `get_connections` to check if a connection supports multiple databases. +kind: tools +name: get_connection_databases +type: looker-get-connection-databases +source: looker-source +description: | + This tool retrieves a list of databases available through a specified Looker connection. + This is only applicable for connections that support multiple databases. + Use `get_connections` to check if a connection supports multiple databases. - Parameters: - - connection_name (required): The name of the database connection, obtained from `get_connections`. + Parameters: + - connection_name (required): The name of the database connection, obtained from `get_connections`. - Output: - A JSON array of strings, where each string is the name of an available database. - If the connection does not support multiple databases, an empty list or an error will be returned. + Output: + A JSON array of strings, where each string is the name of an available database. + If the connection does not support multiple databases, an empty list or an error will be returned. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-get-connection-databases". | +| type | string | true | Must be "looker-get-connection-databases". | | source | string | true | Name of the source Looker instance. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-get-connection-schemas.md b/docs/en/resources/tools/looker/looker-get-connection-schemas.md index 0ef34015c3..de568b8e0e 100644 --- a/docs/en/resources/tools/looker/looker-get-connection-schemas.md +++ b/docs/en/resources/tools/looker/looker-get-connection-schemas.md @@ -21,27 +21,27 @@ It's compatible with the following sources: ## Example ```yaml -tools: - get_connection_schemas: - kind: looker-get-connection-schemas - source: looker-source - description: | - This tool retrieves a list of database schemas available through a specified - Looker connection. +kind: tools +name: get_connection_schemas +type: looker-get-connection-schemas +source: looker-source +description: | + This tool retrieves a list of database schemas available through a specified + Looker connection. - Parameters: - - connection_name (required): The name of the database connection, obtained from `get_connections`. - - database (optional): An optional database name to filter the schemas. - Only applicable for connections that support multiple databases. + Parameters: + - connection_name (required): The name of the database connection, obtained from `get_connections`. + - database (optional): An optional database name to filter the schemas. + Only applicable for connections that support multiple databases. - Output: - A JSON array of strings, where each string is the name of an available schema. + Output: + A JSON array of strings, where each string is the name of an available schema. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-get-connection-schemas". | +| type | string | true | Must be "looker-get-connection-schemas". | | source | string | true | Name of the source Looker instance. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-get-connection-table-columns.md b/docs/en/resources/tools/looker/looker-get-connection-table-columns.md index f4db6445fe..8f19bd372b 100644 --- a/docs/en/resources/tools/looker/looker-get-connection-table-columns.md +++ b/docs/en/resources/tools/looker/looker-get-connection-table-columns.md @@ -21,31 +21,31 @@ It's compatible with the following sources: ## Example ```yaml -tools: - get_connection_table_columns: - kind: looker-get-connection-table-columns - source: looker-source - description: | - This tool retrieves a list of columns for one or more specified tables within a - given database schema and connection. +kind: tools +name: get_connection_table_columns +type: looker-get-connection-table-columns +source: looker-source +description: | + This tool retrieves a list of columns for one or more specified tables within a + given database schema and connection. - Parameters: - - connection_name (required): The name of the database connection, obtained from `get_connections`. - - schema (required): The name of the schema where the tables reside, obtained from `get_connection_schemas`. - - tables (required): A comma-separated string of table names for which to retrieve columns - (e.g., "users,orders,products"), obtained from `get_connection_tables`. - - database (optional): The name of the database to filter by. Only applicable for connections - that support multiple databases (check with `get_connections`). + Parameters: + - connection_name (required): The name of the database connection, obtained from `get_connections`. + - schema (required): The name of the schema where the tables reside, obtained from `get_connection_schemas`. + - tables (required): A comma-separated string of table names for which to retrieve columns + (e.g., "users,orders,products"), obtained from `get_connection_tables`. + - database (optional): The name of the database to filter by. Only applicable for connections + that support multiple databases (check with `get_connections`). - Output: - A JSON array of objects, where each object represents a column and contains details - such as `table_name`, `column_name`, `data_type`, and `is_nullable`. + Output: + A JSON array of objects, where each object represents a column and contains details + such as `table_name`, `column_name`, `data_type`, and `is_nullable`. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-get-connection-table-columns". | +| type | string | true | Must be "looker-get-connection-table-columns". | | source | string | true | Name of the source Looker instance. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-get-connection-tables.md b/docs/en/resources/tools/looker/looker-get-connection-tables.md index 86a2830cd9..5d191828bf 100644 --- a/docs/en/resources/tools/looker/looker-get-connection-tables.md +++ b/docs/en/resources/tools/looker/looker-get-connection-tables.md @@ -22,28 +22,28 @@ and an optional `db` parameter. ## Example ```yaml -tools: - get_connection_tables: - kind: looker-get-connection-tables - source: looker-source - description: | - This tool retrieves a list of tables available within a specified database schema - through a Looker connection. +kind: tools +name: get_connection_tables +type: looker-get-connection-tables +source: looker-source +description: | + This tool retrieves a list of tables available within a specified database schema + through a Looker connection. - Parameters: - - connection_name (required): The name of the database connection, obtained from `get_connections`. - - schema (required): The name of the schema to list tables from, obtained from `get_connection_schemas`. - - database (optional): The name of the database to filter by. Only applicable for connections - that support multiple databases (check with `get_connections`). + Parameters: + - connection_name (required): The name of the database connection, obtained from `get_connections`. + - schema (required): The name of the schema to list tables from, obtained from `get_connection_schemas`. + - database (optional): The name of the database to filter by. Only applicable for connections + that support multiple databases (check with `get_connections`). - Output: - A JSON array of strings, where each string is the name of an available table. + Output: + A JSON array of strings, where each string is the name of an available table. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-get-connection-tables". | +| type | string | true | Must be "looker-get-connection-tables". | | source | string | true | Name of the source Looker instance. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-get-connections.md b/docs/en/resources/tools/looker/looker-get-connections.md index c6c0159789..52a1c96780 100644 --- a/docs/en/resources/tools/looker/looker-get-connections.md +++ b/docs/en/resources/tools/looker/looker-get-connections.md @@ -21,29 +21,29 @@ It's compatible with the following sources: ## Example ```yaml -tools: - get_connections: - kind: looker-get-connections - source: looker-source - description: | - This tool retrieves a list of all database connections configured in the Looker system. +kind: tools +name: get_connections +type: looker-get-connections +source: looker-source +description: | + This tool retrieves a list of all database connections configured in the Looker system. - Parameters: - This tool takes no parameters. + Parameters: + This tool takes no parameters. - Output: - A JSON array of objects, each representing a database connection and including details such as: - - `name`: The connection's unique identifier. - - `dialect`: The database dialect (e.g., "mysql", "postgresql", "bigquery"). - - `default_schema`: The default schema for the connection. - - `database`: The associated database name (if applicable). - - `supports_multiple_databases`: A boolean indicating if the connection can access multiple databases. + Output: + A JSON array of objects, each representing a database connection and including details such as: + - `name`: The connection's unique identifier. + - `dialect`: The database dialect (e.g., "mysql", "postgresql", "bigquery"). + - `default_schema`: The default schema for the connection. + - `database`: The associated database name (if applicable). + - `supports_multiple_databases`: A boolean indicating if the connection can access multiple databases. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-get-connections". | +| type | string | true | Must be "looker-get-connections". | | source | string | true | Name of the source Looker instance. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-get-dashboards.md b/docs/en/resources/tools/looker/looker-get-dashboards.md index db5c9e532e..a8f117d278 100644 --- a/docs/en/resources/tools/looker/looker-get-dashboards.md +++ b/docs/en/resources/tools/looker/looker-get-dashboards.md @@ -28,36 +28,36 @@ default to 100 and 0. ## Example ```yaml -tools: - get_dashboards: - kind: looker-get-dashboards - source: looker-source - description: | - This tool searches for saved dashboards in a Looker instance. It returns a list of JSON objects, each representing a dashboard. - - Search Parameters: - - title (optional): Filter by dashboard title (supports wildcards). - - folder_id (optional): Filter by the ID of the folder where the dashboard is saved. - - user_id (optional): Filter by the ID of the user who created the dashboard. - - description (optional): Filter by description content (supports wildcards). - - id (optional): Filter by specific dashboard ID. - - limit (optional): Maximum number of results to return. Defaults to a system limit. - - offset (optional): Starting point for pagination. - - String Search Behavior: - - Case-insensitive matching. - - Supports SQL LIKE pattern match wildcards: - - `%`: Matches any sequence of zero or more characters. (e.g., `"finan%"` matches "financial", "finance") - - `_`: Matches any single character. (e.g., `"s_les"` matches "sales") - - Special expressions for null checks: - - `"IS NULL"`: Matches dashboards where the field is null. - - `"NOT NULL"`: Excludes dashboards where the field is null. +kind: tools +name: get_dashboards +type: looker-get-dashboards +source: looker-source +description: | + This tool searches for saved dashboards in a Looker instance. It returns a list of JSON objects, each representing a dashboard. + + Search Parameters: + - title (optional): Filter by dashboard title (supports wildcards). + - folder_id (optional): Filter by the ID of the folder where the dashboard is saved. + - user_id (optional): Filter by the ID of the user who created the dashboard. + - description (optional): Filter by description content (supports wildcards). + - id (optional): Filter by specific dashboard ID. + - limit (optional): Maximum number of results to return. Defaults to a system limit. + - offset (optional): Starting point for pagination. + + String Search Behavior: + - Case-insensitive matching. + - Supports SQL LIKE pattern match wildcards: + - `%`: Matches any sequence of zero or more characters. (e.g., `"finan%"` matches "financial", "finance") + - `_`: Matches any single character. (e.g., `"s_les"` matches "sales") + - Special expressions for null checks: + - `"IS NULL"`: Matches dashboards where the field is null. + - `"NOT NULL"`: Excludes dashboards where the field is null. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-get-dashboards" | +| type | string | true | Must be "looker-get-dashboards" | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-get-dimensions.md b/docs/en/resources/tools/looker/looker-get-dimensions.md index 17f3bb68f7..41a899eac7 100644 --- a/docs/en/resources/tools/looker/looker-get-dimensions.md +++ b/docs/en/resources/tools/looker/looker-get-dimensions.md @@ -23,25 +23,25 @@ It's compatible with the following sources: ## Example ```yaml -tools: - get_dimensions: - kind: looker-get-dimensions - source: looker-source - description: | - This tool retrieves a list of dimensions defined within a specific Looker explore. - Dimensions are non-aggregatable attributes or characteristics of your data - (e.g., product name, order date, customer city) that can be used for grouping, - filtering, or segmenting query results. +kind: tools +name: get_dimensions +type: looker-get-dimensions +source: looker-source +description: | + This tool retrieves a list of dimensions defined within a specific Looker explore. + Dimensions are non-aggregatable attributes or characteristics of your data + (e.g., product name, order date, customer city) that can be used for grouping, + filtering, or segmenting query results. - Parameters: - - model_name (required): The name of the LookML model, obtained from `get_models`. - - explore_name (required): The name of the explore within the model, obtained from `get_explores`. + Parameters: + - model_name (required): The name of the LookML model, obtained from `get_models`. + - explore_name (required): The name of the explore within the model, obtained from `get_explores`. - Output Details: - - If a dimension includes a `suggestions` field, its contents are valid values - that can be used directly as filters for that dimension. - - If a `suggest_explore` and `suggest_dimension` are provided, you can query - that specified explore and dimension to retrieve a list of valid filter values. + Output Details: + - If a dimension includes a `suggestions` field, its contents are valid values + that can be used directly as filters for that dimension. + - If a `suggest_explore` and `suggest_dimension` are provided, you can query + that specified explore and dimension to retrieve a list of valid filter values. ``` @@ -66,6 +66,6 @@ The response is a json array with the following elements: | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-get-dimensions". | +| type | string | true | Must be "looker-get-dimensions". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-get-explores.md b/docs/en/resources/tools/looker/looker-get-explores.md index d92942de9d..3b7a695d1b 100644 --- a/docs/en/resources/tools/looker/looker-get-explores.md +++ b/docs/en/resources/tools/looker/looker-get-explores.md @@ -35,24 +35,24 @@ The return type is an array of maps, each map is formatted like: ## Example ```yaml -tools: - get_explores: - kind: looker-get-explores - source: looker-source - description: | - This tool retrieves a list of explores defined within a specific LookML model. - Explores represent a curated view of your data, typically joining several - tables together to allow for focused analysis on a particular subject area. - The output provides details like the explore's `name` and `label`. +kind: tools +name: get_explores +type: looker-get-explores +source: looker-source +description: | + This tool retrieves a list of explores defined within a specific LookML model. + Explores represent a curated view of your data, typically joining several + tables together to allow for focused analysis on a particular subject area. + The output provides details like the explore's `name` and `label`. - Parameters: - - model_name (required): The name of the LookML model, obtained from `get_models`. + Parameters: + - model_name (required): The name of the LookML model, obtained from `get_models`. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-get-explores". | +| type | string | true | Must be "looker-get-explores". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-get-filters.md b/docs/en/resources/tools/looker/looker-get-filters.md index 2657936fd6..a455363de2 100644 --- a/docs/en/resources/tools/looker/looker-get-filters.md +++ b/docs/en/resources/tools/looker/looker-get-filters.md @@ -23,23 +23,23 @@ It's compatible with the following sources: ## Example ```yaml -tools: - get_filters: - kind: looker-get-filters - source: looker-source - description: | - This tool retrieves a list of "filter-only fields" defined within a specific - Looker explore. These are special fields defined in LookML specifically to - create user-facing filter controls that do not directly affect the `GROUP BY` - clause of the SQL query. They are often used in conjunction with liquid templating - to create dynamic queries. +kind: tools +name: get_filters +type: looker-get-filters +source: looker-source +description: | + This tool retrieves a list of "filter-only fields" defined within a specific + Looker explore. These are special fields defined in LookML specifically to + create user-facing filter controls that do not directly affect the `GROUP BY` + clause of the SQL query. They are often used in conjunction with liquid templating + to create dynamic queries. - Note: Regular dimensions and measures can also be used as filters in a query. - This tool *only* returns fields explicitly defined as `filter:` in LookML. + Note: Regular dimensions and measures can also be used as filters in a query. + This tool *only* returns fields explicitly defined as `filter:` in LookML. - Parameters: - - model_name (required): The name of the LookML model, obtained from `get_models`. - - explore_name (required): The name of the explore within the model, obtained from `get_explores`. + Parameters: + - model_name (required): The name of the LookML model, obtained from `get_models`. + - explore_name (required): The name of the explore within the model, obtained from `get_explores`. ``` The response is a json array with the following elements: @@ -63,6 +63,6 @@ The response is a json array with the following elements: | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-get-filters". | +| type | string | true | Must be "looker-get-filters". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-get-looks.md b/docs/en/resources/tools/looker/looker-get-looks.md index 06bc5f7856..a15f5f31ba 100644 --- a/docs/en/resources/tools/looker/looker-get-looks.md +++ b/docs/en/resources/tools/looker/looker-get-looks.md @@ -29,37 +29,37 @@ default to 100 and 0. ## Example ```yaml -tools: - get_looks: - kind: looker-get-looks - source: looker-source - description: | - This tool searches for saved Looks (pre-defined queries and visualizations) - in a Looker instance. It returns a list of JSON objects, each representing a Look. +kind: tools +name: get_looks +type: looker-get-looks +source: looker-source +description: | + This tool searches for saved Looks (pre-defined queries and visualizations) + in a Looker instance. It returns a list of JSON objects, each representing a Look. - Search Parameters: - - title (optional): Filter by Look title (supports wildcards). - - folder_id (optional): Filter by the ID of the folder where the Look is saved. - - user_id (optional): Filter by the ID of the user who created the Look. - - description (optional): Filter by description content (supports wildcards). - - id (optional): Filter by specific Look ID. - - limit (optional): Maximum number of results to return. Defaults to a system limit. - - offset (optional): Starting point for pagination. + Search Parameters: + - title (optional): Filter by Look title (supports wildcards). + - folder_id (optional): Filter by the ID of the folder where the Look is saved. + - user_id (optional): Filter by the ID of the user who created the Look. + - description (optional): Filter by description content (supports wildcards). + - id (optional): Filter by specific Look ID. + - limit (optional): Maximum number of results to return. Defaults to a system limit. + - offset (optional): Starting point for pagination. - String Search Behavior: - - Case-insensitive matching. - - Supports SQL LIKE pattern match wildcards: - - `%`: Matches any sequence of zero or more characters. (e.g., `"dan%"` matches "danger", "Danzig") - - `_`: Matches any single character. (e.g., `"D_m%"` matches "Damage", "dump") - - Special expressions for null checks: - - `"IS NULL"`: Matches Looks where the field is null. - - `"NOT NULL"`: Excludes Looks where the field is null. + String Search Behavior: + - Case-insensitive matching. + - Supports SQL LIKE pattern match wildcards: + - `%`: Matches any sequence of zero or more characters. (e.g., `"dan%"` matches "danger", "Danzig") + - `_`: Matches any single character. (e.g., `"D_m%"` matches "Damage", "dump") + - Special expressions for null checks: + - `"IS NULL"`: Matches Looks where the field is null. + - `"NOT NULL"`: Excludes Looks where the field is null. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-get-looks" | +| type | string | true | Must be "looker-get-looks" | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-get-measures.md b/docs/en/resources/tools/looker/looker-get-measures.md index 7304031855..bcc390a19f 100644 --- a/docs/en/resources/tools/looker/looker-get-measures.md +++ b/docs/en/resources/tools/looker/looker-get-measures.md @@ -23,24 +23,24 @@ It's compatible with the following sources: ## Example ```yaml -tools: - get_measures: - kind: looker-get-measures - source: looker-source - description: | - This tool retrieves a list of measures defined within a specific Looker explore. - Measures are aggregatable metrics (e.g., total sales, average price, count of users) - that are used for calculations and quantitative analysis in your queries. +kind: tools +name: get_measures +type: looker-get-measures +source: looker-source +description: | + This tool retrieves a list of measures defined within a specific Looker explore. + Measures are aggregatable metrics (e.g., total sales, average price, count of users) + that are used for calculations and quantitative analysis in your queries. - Parameters: - - model_name (required): The name of the LookML model, obtained from `get_models`. - - explore_name (required): The name of the explore within the model, obtained from `get_explores`. + Parameters: + - model_name (required): The name of the LookML model, obtained from `get_models`. + - explore_name (required): The name of the explore within the model, obtained from `get_explores`. - Output Details: - - If a measure includes a `suggestions` field, its contents are valid values - that can be used directly as filters for that measure. - - If a `suggest_explore` and `suggest_dimension` are provided, you can query - that specified explore and dimension to retrieve a list of valid filter values. + Output Details: + - If a measure includes a `suggestions` field, its contents are valid values + that can be used directly as filters for that measure. + - If a `suggest_explore` and `suggest_dimension` are provided, you can query + that specified explore and dimension to retrieve a list of valid filter values. ``` @@ -65,6 +65,6 @@ The response is a json array with the following elements: | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-get-measures". | +| type | string | true | Must be "looker-get-measures". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-get-models.md b/docs/en/resources/tools/looker/looker-get-models.md index 81002cf3a2..dbaf456384 100644 --- a/docs/en/resources/tools/looker/looker-get-models.md +++ b/docs/en/resources/tools/looker/looker-get-models.md @@ -21,23 +21,23 @@ It's compatible with the following sources: ## Example ```yaml -tools: - get_models: - kind: looker-get-models - source: looker-source - description: | - This tool retrieves a list of available LookML models in the Looker instance. - LookML models define the data structure and relationships that users can query. - The output includes details like the model's `name` and `label`, which are - essential for subsequent calls to tools like `get_explores` or `query`. +kind: tools +name: get_models +type: looker-get-models +source: looker-source +description: | + This tool retrieves a list of available LookML models in the Looker instance. + LookML models define the data structure and relationships that users can query. + The output includes details like the model's `name` and `label`, which are + essential for subsequent calls to tools like `get_explores` or `query`. - This tool takes no parameters. + This tool takes no parameters. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-get-models". | +| type | string | true | Must be "looker-get-models". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-get-parameters.md b/docs/en/resources/tools/looker/looker-get-parameters.md index f40398568d..bc3413093b 100644 --- a/docs/en/resources/tools/looker/looker-get-parameters.md +++ b/docs/en/resources/tools/looker/looker-get-parameters.md @@ -23,20 +23,20 @@ It's compatible with the following sources: ## Example ```yaml -tools: - get_parameters: - kind: looker-get-parameters - source: looker-source - description: | - This tool retrieves a list of parameters defined within a specific Looker explore. - LookML parameters are dynamic input fields that allow users to influence query - behavior without directly modifying the underlying LookML. They are often used - with `liquid` templating to create flexible dashboards and reports, enabling - users to choose dimensions, measures, or other query components at runtime. +kind: tools +name: get_parameters +type: looker-get-parameters +source: looker-source +description: | + This tool retrieves a list of parameters defined within a specific Looker explore. + LookML parameters are dynamic input fields that allow users to influence query + behavior without directly modifying the underlying LookML. They are often used + with `liquid` templating to create flexible dashboards and reports, enabling + users to choose dimensions, measures, or other query components at runtime. - Parameters: - - model_name (required): The name of the LookML model, obtained from `get_models`. - - explore_name (required): The name of the explore within the model, obtained from `get_explores`. + Parameters: + - model_name (required): The name of the LookML model, obtained from `get_models`. + - explore_name (required): The name of the explore within the model, obtained from `get_explores`. ``` The response is a json array with the following elements: @@ -60,6 +60,6 @@ The response is a json array with the following elements: | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-get-parameters". | +| type | string | true | Must be "looker-get-parameters". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-get-project-file.md b/docs/en/resources/tools/looker/looker-get-project-file.md index 440615efa4..83f23ce08e 100644 --- a/docs/en/resources/tools/looker/looker-get-project-file.md +++ b/docs/en/resources/tools/looker/looker-get-project-file.md @@ -21,26 +21,26 @@ It's compatible with the following sources: ## Example ```yaml -tools: - get_project_file: - kind: looker-get-project-file - source: looker-source - description: | - This tool retrieves the raw content of a specific LookML file from within a project. +kind: tools +name: get_project_file +type: looker-get-project-file +source: looker-source +description: | + This tool retrieves the raw content of a specific LookML file from within a project. - Parameters: - - project_id (required): The unique ID of the LookML project, obtained from `get_projects`. - - file_path (required): The path to the LookML file within the project, - typically obtained from `get_project_files`. + Parameters: + - project_id (required): The unique ID of the LookML project, obtained from `get_projects`. + - file_path (required): The path to the LookML file within the project, + typically obtained from `get_project_files`. - Output: - The raw text content of the specified LookML file. + Output: + The raw text content of the specified LookML file. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-get-project-file". | +| type | string | true | Must be "looker-get-project-file". | | source | string | true | Name of the source Looker instance. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-get-project-files.md b/docs/en/resources/tools/looker/looker-get-project-files.md index 48ea273228..dc28e61e66 100644 --- a/docs/en/resources/tools/looker/looker-get-project-files.md +++ b/docs/en/resources/tools/looker/looker-get-project-files.md @@ -21,26 +21,26 @@ It's compatible with the following sources: ## Example ```yaml -tools: - get_project_files: - kind: looker-get-project-files - source: looker-source - description: | - This tool retrieves a list of all LookML files within a specified project, - providing details about each file. +kind: tools +name: get_project_files +type: looker-get-project-files +source: looker-source +description: | + This tool retrieves a list of all LookML files within a specified project, + providing details about each file. - Parameters: - - project_id (required): The unique ID of the LookML project, obtained from `get_projects`. + Parameters: + - project_id (required): The unique ID of the LookML project, obtained from `get_projects`. - Output: - A JSON array of objects, each representing a LookML file and containing - details such as `path`, `id`, `type`, and `git_status`. + Output: + A JSON array of objects, each representing a LookML file and containing + details such as `path`, `id`, `type`, and `git_status`. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-get-project-files". | +| type | string | true | Must be "looker-get-project-files". | | source | string | true | Name of the source Looker instance. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-get-projects.md b/docs/en/resources/tools/looker/looker-get-projects.md index 7c582eeae0..f6ad8def95 100644 --- a/docs/en/resources/tools/looker/looker-get-projects.md +++ b/docs/en/resources/tools/looker/looker-get-projects.md @@ -21,27 +21,27 @@ It's compatible with the following sources: ## Example ```yaml -tools: - get_projects: - kind: looker-get-projects - source: looker-source - description: | - This tool retrieves a list of all LookML projects available on the Looker instance. - It is useful for identifying projects before performing actions like retrieving - project files or making modifications. +kind: tools +name: get_projects +type: looker-get-projects +source: looker-source +description: | + This tool retrieves a list of all LookML projects available on the Looker instance. + It is useful for identifying projects before performing actions like retrieving + project files or making modifications. - Parameters: - This tool takes no parameters. + Parameters: + This tool takes no parameters. - Output: - A JSON array of objects, each containing the `project_id` and `project_name` - for a LookML project. + Output: + A JSON array of objects, each containing the `project_id` and `project_name` + for a LookML project. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-get-projects". | +| type | string | true | Must be "looker-get-projects". | | source | string | true | Name of the source Looker instance. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-health-analyze.md b/docs/en/resources/tools/looker/looker-health-analyze.md index bc44d3f301..59b2575c44 100644 --- a/docs/en/resources/tools/looker/looker-health-analyze.md +++ b/docs/en/resources/tools/looker/looker-health-analyze.md @@ -37,29 +37,29 @@ instance. The `action` parameter selects the type of analysis to perform: ## Example ```yaml -tools: - health_analyze: - kind: looker-health-analyze - source: looker-source - description: | - This tool calculates the usage statistics for Looker projects, models, and explores. +kind: tools +name: health_analyze +type: looker-health-analyze +source: looker-source +description: | + This tool calculates the usage statistics for Looker projects, models, and explores. - Parameters: - - action (required): The type of resource to analyze. Can be `"projects"`, `"models"`, or `"explores"`. - - project (optional): The specific project ID to analyze. - - model (optional): The specific model name to analyze. Requires `project` if used without `explore`. - - explore (optional): The specific explore name to analyze. Requires `model` if used. - - timeframe (optional): The lookback period in days for usage data. Defaults to `90` days. - - min_queries (optional): The minimum number of queries for a resource to be considered active. Defaults to `1`. + Parameters: + - action (required): The type of resource to analyze. Can be `"projects"`, `"models"`, or `"explores"`. + - project (optional): The specific project ID to analyze. + - model (optional): The specific model name to analyze. Requires `project` if used without `explore`. + - explore (optional): The specific explore name to analyze. Requires `model` if used. + - timeframe (optional): The lookback period in days for usage data. Defaults to `90` days. + - min_queries (optional): The minimum number of queries for a resource to be considered active. Defaults to `1`. - Output: - The result is a JSON object containing usage metrics for the specified resources. + Output: + The result is a JSON object containing usage metrics for the specified resources. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-health-analyze" | +| type | string | true | Must be "looker-health-analyze" | | source | string | true | Looker source name | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-health-pulse.md b/docs/en/resources/tools/looker/looker-health-pulse.md index ccbc05be34..1ef1ab6e14 100644 --- a/docs/en/resources/tools/looker/looker-health-pulse.md +++ b/docs/en/resources/tools/looker/looker-health-pulse.md @@ -44,33 +44,33 @@ The `looker-health-pulse` tool performs health checks on a Looker instance. The ## Example ```yaml -tools: - health_pulse: - kind: looker-health-pulse - source: looker-source - description: | - This tool performs various health checks on a Looker instance. +kind: tools +name: health_pulse +type: looker-health-pulse +source: looker-source +description: | + This tool performs various health checks on a Looker instance. - Parameters: - - action (required): Specifies the type of health check to perform. - Choose one of the following: - - `check_db_connections`: Verifies database connectivity. - - `check_dashboard_performance`: Assesses dashboard loading performance. - - `check_dashboard_errors`: Identifies errors within dashboards. - - `check_explore_performance`: Evaluates explore query performance. - - `check_schedule_failures`: Reports on failed scheduled deliveries. - - `check_legacy_features`: Checks for the usage of legacy features. + Parameters: + - action (required): Specifies the type of health check to perform. + Choose one of the following: + - `check_db_connections`: Verifies database connectivity. + - `check_dashboard_performance`: Assesses dashboard loading performance. + - `check_dashboard_errors`: Identifies errors within dashboards. + - `check_explore_performance`: Evaluates explore query performance. + - `check_schedule_failures`: Reports on failed scheduled deliveries. + - `check_legacy_features`: Checks for the usage of legacy features. - Note on `check_legacy_features`: - This action is exclusively available in Looker Core instances. If invoked - on a non-Looker Core instance, it will return a notice rather than an error. - This notice should be considered normal behavior and not an indication of an issue. + Note on `check_legacy_features`: + This action is exclusively available in Looker Core instances. If invoked + on a non-Looker Core instance, it will return a notice rather than an error. + This notice should be considered normal behavior and not an indication of an issue. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-health-pulse" | +| type | string | true | Must be "looker-health-pulse" | | source | string | true | Looker source name | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-health-vacuum.md b/docs/en/resources/tools/looker/looker-health-vacuum.md index f4d635ccc5..dc9ec7545c 100644 --- a/docs/en/resources/tools/looker/looker-health-vacuum.md +++ b/docs/en/resources/tools/looker/looker-health-vacuum.md @@ -34,28 +34,28 @@ Identify unnused fields (*in this case, less than 1 query in the last 20 days*) and joins in the `order_items` explore and `thelook` model ```yaml -tools: - health_vacuum: - kind: looker-health-vacuum - source: looker-source - description: | - This tool identifies and suggests LookML models or explores that can be - safely removed due to inactivity or low usage. +kind: tools +name: health_vacuum +type: looker-health-vacuum +source: looker-source +description: | + This tool identifies and suggests LookML models or explores that can be + safely removed due to inactivity or low usage. - Parameters: - - action (required): The type of resource to analyze for removal candidates. Can be `"models"` or `"explores"`. - - project (optional): The specific project ID to consider. - - model (optional): The specific model name to consider. Requires `project` if used without `explore`. - - explore (optional): The specific explore name to consider. Requires `model` if used. - - timeframe (optional): The lookback period in days to assess usage. Defaults to `90` days. - - min_queries (optional): The minimum number of queries for a resource to be considered active. Defaults to `1`. + Parameters: + - action (required): The type of resource to analyze for removal candidates. Can be `"models"` or `"explores"`. + - project (optional): The specific project ID to consider. + - model (optional): The specific model name to consider. Requires `project` if used without `explore`. + - explore (optional): The specific explore name to consider. Requires `model` if used. + - timeframe (optional): The lookback period in days to assess usage. Defaults to `90` days. + - min_queries (optional): The minimum number of queries for a resource to be considered active. Defaults to `1`. - Output: - A JSON array of objects, each representing a model or explore that is a candidate for deletion due to low usage. + Output: + A JSON array of objects, each representing a model or explore that is a candidate for deletion due to low usage. ``` | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-health-vacuum" | +| type | string | true | Must be "looker-health-vacuum" | | source | string | true | Looker source name | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-make-dashboard.md b/docs/en/resources/tools/looker/looker-make-dashboard.md index f8112bcd5d..3e7dc03dda 100644 --- a/docs/en/resources/tools/looker/looker-make-dashboard.md +++ b/docs/en/resources/tools/looker/looker-make-dashboard.md @@ -27,30 +27,30 @@ It's compatible with the following sources: ## Example ```yaml -tools: - make_dashboard: - kind: looker-make-dashboard - source: looker-source - description: | - This tool creates a new, empty dashboard in Looker. Dashboards are stored - in the user's personal folder, and the dashboard name must be unique. - After creation, use `add_dashboard_filter` to add filters and - `add_dashboard_element` to add content tiles. +kind: tools +name: make_dashboard +type: looker-make-dashboard +source: looker-source +description: | + This tool creates a new, empty dashboard in Looker. Dashboards are stored + in the user's personal folder, and the dashboard name must be unique. + After creation, use `add_dashboard_filter` to add filters and + `add_dashboard_element` to add content tiles. - Required Parameters: - - title (required): A unique title for the new dashboard. - - description (required): A brief description of the dashboard's purpose. + Required Parameters: + - title (required): A unique title for the new dashboard. + - description (required): A brief description of the dashboard's purpose. - Output: - A JSON object containing a link (`url`) to the newly created dashboard and - its unique `id`. This `dashboard_id` is crucial for subsequent calls to - `add_dashboard_filter` and `add_dashboard_element`. + Output: + A JSON object containing a link (`url`) to the newly created dashboard and + its unique `id`. This `dashboard_id` is crucial for subsequent calls to + `add_dashboard_filter` and `add_dashboard_element`. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-make-dashboard" | +| type | string | true | Must be "looker-make-dashboard" | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-make-look.md b/docs/en/resources/tools/looker/looker-make-look.md index 9c69898437..58e8b09e0d 100644 --- a/docs/en/resources/tools/looker/looker-make-look.md +++ b/docs/en/resources/tools/looker/looker-make-look.md @@ -36,35 +36,35 @@ It's compatible with the following sources: ## Example ```yaml -tools: - make_look: - kind: looker-make-look - source: looker-source - description: | - This tool creates a new Look (saved query with visualization) in Looker. - The Look will be saved in the user's personal folder, and its name must be unique. +kind: tools +name: make_look +type: looker-make-look +source: looker-source +description: | + This tool creates a new Look (saved query with visualization) in Looker. + The Look will be saved in the user's personal folder, and its name must be unique. - Required Parameters: - - title: A unique title for the new Look. - - description: A brief description of the Look's purpose. - - model_name: The name of the LookML model (from `get_models`). - - explore_name: The name of the explore (from `get_explores`). - - fields: A list of field names (dimensions, measures, filters, or parameters) to include in the query. + Required Parameters: + - title: A unique title for the new Look. + - description: A brief description of the Look's purpose. + - model_name: The name of the LookML model (from `get_models`). + - explore_name: The name of the explore (from `get_explores`). + - fields: A list of field names (dimensions, measures, filters, or parameters) to include in the query. - Optional Parameters: - - pivots, filters, sorts, limit, query_timezone: These parameters are identical - to those described for the `query` tool. - - vis_config: A JSON object defining the visualization settings for the Look. - The structure and options are the same as for the `query_url` tool's `vis_config`. + Optional Parameters: + - pivots, filters, sorts, limit, query_timezone: These parameters are identical + to those described for the `query` tool. + - vis_config: A JSON object defining the visualization settings for the Look. + The structure and options are the same as for the `query_url` tool's `vis_config`. - Output: - A JSON object containing a link (`url`) to the newly created Look, along with its `id` and `slug`. + Output: + A JSON object containing a link (`url`) to the newly created Look, along with its `id` and `slug`. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-make-look" | +| type | string | true | Must be "looker-make-look" | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-query-sql.md b/docs/en/resources/tools/looker/looker-query-sql.md index 064464ea5d..ca61df1007 100644 --- a/docs/en/resources/tools/looker/looker-query-sql.md +++ b/docs/en/resources/tools/looker/looker-query-sql.md @@ -36,28 +36,28 @@ to find MCP Toolbox queries. ## Example ```yaml -tools: - query_sql: - kind: looker-query-sql - source: looker-source - description: | - This tool generates the underlying SQL query that Looker would execute - against the database for a given set of parameters. It is useful for - understanding how Looker translates a request into SQL. +kind: tools +name: query_sql +type: looker-query-sql +source: looker-source +description: | + This tool generates the underlying SQL query that Looker would execute + against the database for a given set of parameters. It is useful for + understanding how Looker translates a request into SQL. - Parameters: - All parameters for this tool are identical to those of the `query` tool. - This includes `model_name`, `explore_name`, `fields` (required), - and optional parameters like `pivots`, `filters`, `sorts`, `limit`, and `query_timezone`. + Parameters: + All parameters for this tool are identical to those of the `query` tool. + This includes `model_name`, `explore_name`, `fields` (required), + and optional parameters like `pivots`, `filters`, `sorts`, `limit`, and `query_timezone`. - Output: - The result of this tool is the raw SQL text. + Output: + The result of this tool is the raw SQL text. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-query-sql" | +| type | string | true | Must be "looker-query-sql" | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-query-url.md b/docs/en/resources/tools/looker/looker-query-url.md index af1f138509..b883a9c5d1 100644 --- a/docs/en/resources/tools/looker/looker-query-url.md +++ b/docs/en/resources/tools/looker/looker-query-url.md @@ -32,465 +32,465 @@ It's compatible with the following sources: ## Example ```yaml -tools: - query_url: - kind: looker-query-url - source: looker-source - description: | - This tool generates a shareable URL for a Looker query, allowing users to - explore the query further within the Looker UI. It returns the generated URL, - along with the `query_id` and `slug`. +kind: tools +name: query_url +type: looker-query-url +source: looker-source +description: | + This tool generates a shareable URL for a Looker query, allowing users to + explore the query further within the Looker UI. It returns the generated URL, + along with the `query_id` and `slug`. - Parameters: - All query parameters (e.g., `model_name`, `explore_name`, `fields`, `pivots`, - `filters`, `sorts`, `limit`, `query_timezone`) are the same as the `query` tool. + Parameters: + All query parameters (e.g., `model_name`, `explore_name`, `fields`, `pivots`, + `filters`, `sorts`, `limit`, `query_timezone`) are the same as the `query` tool. - Additionally, it accepts an optional `vis_config` parameter: - - vis_config (optional): A JSON object that controls the default visualization - settings for the generated query. + Additionally, it accepts an optional `vis_config` parameter: + - vis_config (optional): A JSON object that controls the default visualization + settings for the generated query. - vis_config Details: - The `vis_config` object supports a wide range of properties for various chart types. - Here are some notes on making visualizations. + vis_config Details: + The `vis_config` object supports a wide range of properties for various chart types. + Here are some notes on making visualizations. - ### Cartesian Charts (Area, Bar, Column, Line, Scatter) + ### Cartesian Charts (Area, Bar, Column, Line, Scatter) - These chart types share a large number of configuration options. + These chart types share a large number of configuration options. - **General** - * `type`: The type of visualization (`looker_area`, `looker_bar`, `looker_column`, `looker_line`, `looker_scatter`). - * `series_types`: Override the chart type for individual series. - * `show_view_names`: Display view names in labels and tooltips (`true`/`false`). - * `series_labels`: Provide custom names for series. + **General** + * `type`: The type of visualization (`looker_area`, `looker_bar`, `looker_column`, `looker_line`, `looker_scatter`). + * `series_types`: Override the chart type for individual series. + * `show_view_names`: Display view names in labels and tooltips (`true`/`false`). + * `series_labels`: Provide custom names for series. - **Styling & Colors** - * `colors`: An array of color values to be used for the chart series. - * `series_colors`: A mapping of series names to specific color values. - * `color_application`: Advanced controls for color palette application (collection, palette, reverse, etc.). - * `font_size`: Font size for labels (e.g., '12px'). + **Styling & Colors** + * `colors`: An array of color values to be used for the chart series. + * `series_colors`: A mapping of series names to specific color values. + * `color_application`: Advanced controls for color palette application (collection, palette, reverse, etc.). + * `font_size`: Font size for labels (e.g., '12px'). - **Legend** - * `hide_legend`: Show or hide the chart legend (`true`/`false`). - * `legend_position`: Placement of the legend (`'center'`, `'left'`, `'right'`). + **Legend** + * `hide_legend`: Show or hide the chart legend (`true`/`false`). + * `legend_position`: Placement of the legend (`'center'`, `'left'`, `'right'`). - **Axes** - * `swap_axes`: Swap the X and Y axes (`true`/`false`). - * `x_axis_scale`: Scale of the x-axis (`'auto'`, `'ordinal'`, `'linear'`, `'time'`). - * `x_axis_reversed`, `y_axis_reversed`: Reverse the direction of an axis (`true`/`false`). - * `x_axis_gridlines`, `y_axis_gridlines`: Display gridlines for an axis (`true`/`false`). - * `show_x_axis_label`, `show_y_axis_label`: Show or hide the axis title (`true`/`false`). - * `show_x_axis_ticks`, `show_y_axis_ticks`: Show or hide axis tick marks (`true`/`false`). - * `x_axis_label`, `y_axis_label`: Set a custom title for an axis. - * `x_axis_datetime_label`: A format string for datetime labels on the x-axis (e.g., `'%Y-%m'`). - * `x_padding_left`, `x_padding_right`: Adjust padding on the ends of the x-axis. - * `x_axis_label_rotation`, `x_axis_label_rotation_bar`: Set rotation for x-axis labels. - * `x_axis_zoom`, `y_axis_zoom`: Enable zooming on an axis (`true`/`false`). - * `y_axes`: An array of configuration objects for multiple y-axes. + **Axes** + * `swap_axes`: Swap the X and Y axes (`true`/`false`). + * `x_axis_scale`: Scale of the x-axis (`'auto'`, `'ordinal'`, `'linear'`, `'time'`). + * `x_axis_reversed`, `y_axis_reversed`: Reverse the direction of an axis (`true`/`false`). + * `x_axis_gridlines`, `y_axis_gridlines`: Display gridlines for an axis (`true`/`false`). + * `show_x_axis_label`, `show_y_axis_label`: Show or hide the axis title (`true`/`false`). + * `show_x_axis_ticks`, `show_y_axis_ticks`: Show or hide axis tick marks (`true`/`false`). + * `x_axis_label`, `y_axis_label`: Set a custom title for an axis. + * `x_axis_datetime_label`: A format string for datetime labels on the x-axis (e.g., `'%Y-%m'`). + * `x_padding_left`, `x_padding_right`: Adjust padding on the ends of the x-axis. + * `x_axis_label_rotation`, `x_axis_label_rotation_bar`: Set rotation for x-axis labels. + * `x_axis_zoom`, `y_axis_zoom`: Enable zooming on an axis (`true`/`false`). + * `y_axes`: An array of configuration objects for multiple y-axes. - **Data & Series** - * `stacking`: How to stack series (`''` for none, `'normal'`, `'percent'`). - * `ordering`: Order of series in a stack (`'none'`, etc.). - * `limit_displayed_rows`: Enable or disable limiting the number of rows displayed (`true`/`false`). - * `limit_displayed_rows_values`: Configuration for the row limit (e.g., `{ "first_last": "first", "show_hide": "show", "num_rows": 10 }`). - * `discontinuous_nulls`: How to render null values in line charts (`true`/`false`). - * `point_style`: Style for points on line and area charts (`'none'`, `'circle'`, `'circle_outline'`). - * `series_point_styles`: Override point styles for individual series. - * `interpolation`: Line interpolation style (`'linear'`, `'monotone'`, `'step'`, etc.). - * `show_value_labels`: Display values on data points (`true`/`false`). - * `label_value_format`: A format string for value labels. - * `show_totals_labels`: Display total labels on stacked charts (`true`/`false`). - * `totals_color`: Color for total labels. - * `show_silhouette`: Display a "silhouette" of hidden series in stacked charts (`true`/`false`). - * `hidden_series`: An array of series names to hide from the visualization. + **Data & Series** + * `stacking`: How to stack series (`''` for none, `'normal'`, `'percent'`). + * `ordering`: Order of series in a stack (`'none'`, etc.). + * `limit_displayed_rows`: Enable or disable limiting the number of rows displayed (`true`/`false`). + * `limit_displayed_rows_values`: Configuration for the row limit (e.g., `{ "first_last": "first", "show_hide": "show", "num_rows": 10 }`). + * `discontinuous_nulls`: How to render null values in line charts (`true`/`false`). + * `point_style`: Style for points on line and area charts (`'none'`, `'circle'`, `'circle_outline'`). + * `series_point_styles`: Override point styles for individual series. + * `interpolation`: Line interpolation style (`'linear'`, `'monotone'`, `'step'`, etc.). + * `show_value_labels`: Display values on data points (`true`/`false`). + * `label_value_format`: A format string for value labels. + * `show_totals_labels`: Display total labels on stacked charts (`true`/`false`). + * `totals_color`: Color for total labels. + * `show_silhouette`: Display a "silhouette" of hidden series in stacked charts (`true`/`false`). + * `hidden_series`: An array of series names to hide from the visualization. - **Scatter/Bubble Specific** - * `size_by_field`: The field used to determine the size of bubbles. - * `color_by_field`: The field used to determine the color of bubbles. - * `plot_size_by_field`: Whether to display the size-by field in the legend. - * `cluster_points`: Group nearby points into clusters (`true`/`false`). - * `quadrants_enabled`: Display quadrants on the chart (`true`/`false`). - * `quadrant_properties`: Configuration for quadrant labels and colors. - * `custom_quadrant_value_x`, `custom_quadrant_value_y`: Set quadrant boundaries as a percentage. - * `custom_quadrant_point_x`, `custom_quadrant_point_y`: Set quadrant boundaries to a specific value. + **Scatter/Bubble Specific** + * `size_by_field`: The field used to determine the size of bubbles. + * `color_by_field`: The field used to determine the color of bubbles. + * `plot_size_by_field`: Whether to display the size-by field in the legend. + * `cluster_points`: Group nearby points into clusters (`true`/`false`). + * `quadrants_enabled`: Display quadrants on the chart (`true`/`false`). + * `quadrant_properties`: Configuration for quadrant labels and colors. + * `custom_quadrant_value_x`, `custom_quadrant_value_y`: Set quadrant boundaries as a percentage. + * `custom_quadrant_point_x`, `custom_quadrant_point_y`: Set quadrant boundaries to a specific value. - **Miscellaneous** - * `reference_lines`: Configuration for displaying reference lines. - * `trend_lines`: Configuration for displaying trend lines. - * `trellis`: Configuration for creating trellis (small multiple) charts. - * `crossfilterEnabled`, `crossfilters`: Configuration for cross-filtering interactions. + **Miscellaneous** + * `reference_lines`: Configuration for displaying reference lines. + * `trend_lines`: Configuration for displaying trend lines. + * `trellis`: Configuration for creating trellis (small multiple) charts. + * `crossfilterEnabled`, `crossfilters`: Configuration for cross-filtering interactions. - ### Boxplot + ### Boxplot - * Inherits most of the Cartesian chart options. - * `type`: Must be `looker_boxplot`. + * Inherits most of the Cartesian chart options. + * `type`: Must be `looker_boxplot`. - ### Funnel + ### Funnel - * `type`: Must be `looker_funnel`. - * `orientation`: How data is read (`'automatic'`, `'dataInRows'`, `'dataInColumns'`). - * `percentType`: How percentages are calculated (`'percentOfMaxValue'`, `'percentOfPriorRow'`). - * `labelPosition`, `valuePosition`, `percentPosition`: Placement of labels (`'left'`, `'right'`, `'inline'`, `'hidden'`). - * `labelColor`, `labelColorEnabled`: Set a custom color for labels. - * `labelOverlap`: Allow labels to overlap (`true`/`false`). - * `barColors`: An array of colors for the funnel steps. - * `color_application`: Advanced color palette controls. - * `crossfilterEnabled`, `crossfilters`: Configuration for cross-filtering. + * `type`: Must be `looker_funnel`. + * `orientation`: How data is read (`'automatic'`, `'dataInRows'`, `'dataInColumns'`). + * `percentType`: How percentages are calculated (`'percentOfMaxValue'`, `'percentOfPriorRow'`). + * `labelPosition`, `valuePosition`, `percentPosition`: Placement of labels (`'left'`, `'right'`, `'inline'`, `'hidden'`). + * `labelColor`, `labelColorEnabled`: Set a custom color for labels. + * `labelOverlap`: Allow labels to overlap (`true`/`false`). + * `barColors`: An array of colors for the funnel steps. + * `color_application`: Advanced color palette controls. + * `crossfilterEnabled`, `crossfilters`: Configuration for cross-filtering. - ### Pie / Donut + ### Pie / Donut - * `type`: Must be `looker_pie`. - * `value_labels`: Where to display values (`'legend'`, `'labels'`). - * `label_type`: The format of data labels (`'labPer'`, `'labVal'`, `'lab'`, `'val'`, `'per'`). - * `start_angle`, `end_angle`: The start and end angles of the pie chart. - * `inner_radius`: The inner radius, used to create a donut chart. - * `series_colors`, `series_labels`: Override colors and labels for specific slices. - * `color_application`: Advanced color palette controls. - * `crossfilterEnabled`, `crossfilters`: Configuration for cross-filtering. - * `advanced_vis_config`: A string containing JSON for advanced Highcharts configuration. + * `type`: Must be `looker_pie`. + * `value_labels`: Where to display values (`'legend'`, `'labels'`). + * `label_type`: The format of data labels (`'labPer'`, `'labVal'`, `'lab'`, `'val'`, `'per'`). + * `start_angle`, `end_angle`: The start and end angles of the pie chart. + * `inner_radius`: The inner radius, used to create a donut chart. + * `series_colors`, `series_labels`: Override colors and labels for specific slices. + * `color_application`: Advanced color palette controls. + * `crossfilterEnabled`, `crossfilters`: Configuration for cross-filtering. + * `advanced_vis_config`: A string containing JSON for advanced Highcharts configuration. - ### Waterfall + ### Waterfall - * Inherits most of the Cartesian chart options. - * `type`: Must be `looker_waterfall`. - * `up_color`: Color for positive (increasing) values. - * `down_color`: Color for negative (decreasing) values. - * `total_color`: Color for the total bar. + * Inherits most of the Cartesian chart options. + * `type`: Must be `looker_waterfall`. + * `up_color`: Color for positive (increasing) values. + * `down_color`: Color for negative (decreasing) values. + * `total_color`: Color for the total bar. - ### Word Cloud + ### Word Cloud - * `type`: Must be `looker_wordcloud`. - * `rotation`: Enable random word rotation (`true`/`false`). - * `colors`: An array of colors for the words. - * `color_application`: Advanced color palette controls. - * `crossfilterEnabled`, `crossfilters`: Configuration for cross-filtering. + * `type`: Must be `looker_wordcloud`. + * `rotation`: Enable random word rotation (`true`/`false`). + * `colors`: An array of colors for the words. + * `color_application`: Advanced color palette controls. + * `crossfilterEnabled`, `crossfilters`: Configuration for cross-filtering. - These are some sample vis_config settings. + These are some sample vis_config settings. - A bar chart - - {{ - "defaults_version": 1, - "label_density": 25, - "legend_position": "center", - "limit_displayed_rows": false, - "ordering": "none", - "plot_size_by_field": false, - "point_style": "none", - "show_null_labels": false, - "show_silhouette": false, - "show_totals_labels": false, - "show_value_labels": false, - "show_view_names": false, - "show_x_axis_label": true, - "show_x_axis_ticks": true, - "show_y_axis_labels": true, - "show_y_axis_ticks": true, - "stacking": "normal", - "totals_color": "#808080", - "trellis": "", - "type": "looker_bar", - "x_axis_gridlines": false, - "x_axis_reversed": false, - "x_axis_scale": "auto", - "x_axis_zoom": true, - "y_axis_combined": true, - "y_axis_gridlines": true, - "y_axis_reversed": false, - "y_axis_scale_mode": "linear", - "y_axis_tick_density": "default", - "y_axis_tick_density_custom": 5, - "y_axis_zoom": true - }} + A bar chart - + {{ + "defaults_version": 1, + "label_density": 25, + "legend_position": "center", + "limit_displayed_rows": false, + "ordering": "none", + "plot_size_by_field": false, + "point_style": "none", + "show_null_labels": false, + "show_silhouette": false, + "show_totals_labels": false, + "show_value_labels": false, + "show_view_names": false, + "show_x_axis_label": true, + "show_x_axis_ticks": true, + "show_y_axis_labels": true, + "show_y_axis_ticks": true, + "stacking": "normal", + "totals_color": "#808080", + "trellis": "", + "type": "looker_bar", + "x_axis_gridlines": false, + "x_axis_reversed": false, + "x_axis_scale": "auto", + "x_axis_zoom": true, + "y_axis_combined": true, + "y_axis_gridlines": true, + "y_axis_reversed": false, + "y_axis_scale_mode": "linear", + "y_axis_tick_density": "default", + "y_axis_tick_density_custom": 5, + "y_axis_zoom": true + }} - A column chart with an option advanced_vis_config - - {{ - "advanced_vis_config": "{ chart: { type: 'pie', spacingBottom: 50, spacingLeft: 50, spacingRight: 50, spacingTop: 50, }, legend: { enabled: false, }, plotOptions: { pie: { dataLabels: { enabled: true, format: '\u003cb\u003e{key}\u003c/b\u003e\u003cspan style=\"font-weight: normal\"\u003e - {percentage:.2f}%\u003c/span\u003e', }, showInLegend: false, }, }, series: [], }", - "colors": [ - "grey" - ], - "defaults_version": 1, - "hidden_fields": [], - "label_density": 25, - "legend_position": "center", - "limit_displayed_rows": false, - "note_display": "below", - "note_state": "collapsed", - "note_text": "Unsold inventory only", - "ordering": "none", - "plot_size_by_field": false, - "point_style": "none", - "series_colors": {}, - "show_null_labels": false, - "show_silhouette": false, - "show_totals_labels": false, - "show_value_labels": true, - "show_view_names": false, - "show_x_axis_label": true, - "show_x_axis_ticks": true, - "show_y_axis_labels": true, - "show_y_axis_ticks": true, - "stacking": "normal", - "totals_color": "#808080", - "trellis": "", - "type": "looker_column", - "x_axis_gridlines": false, - "x_axis_reversed": false, - "x_axis_scale": "auto", - "x_axis_zoom": true, - "y_axes": [], - "y_axis_combined": true, - "y_axis_gridlines": true, - "y_axis_reversed": false, - "y_axis_scale_mode": "linear", - "y_axis_tick_density": "default", - "y_axis_tick_density_custom": 5, - "y_axis_zoom": true - }} + A column chart with an option advanced_vis_config - + {{ + "advanced_vis_config": "{ chart: { type: 'pie', spacingBottom: 50, spacingLeft: 50, spacingRight: 50, spacingTop: 50, }, legend: { enabled: false, }, plotOptions: { pie: { dataLabels: { enabled: true, format: '\u003cb\u003e{key}\u003c/b\u003e\u003cspan style=\"font-weight: normal\"\u003e - {percentage:.2f}%\u003c/span\u003e', }, showInLegend: false, }, }, series: [], }", + "colors": [ + "grey" + ], + "defaults_version": 1, + "hidden_fields": [], + "label_density": 25, + "legend_position": "center", + "limit_displayed_rows": false, + "note_display": "below", + "note_state": "collapsed", + "note_text": "Unsold inventory only", + "ordering": "none", + "plot_size_by_field": false, + "point_style": "none", + "series_colors": {}, + "show_null_labels": false, + "show_silhouette": false, + "show_totals_labels": false, + "show_value_labels": true, + "show_view_names": false, + "show_x_axis_label": true, + "show_x_axis_ticks": true, + "show_y_axis_labels": true, + "show_y_axis_ticks": true, + "stacking": "normal", + "totals_color": "#808080", + "trellis": "", + "type": "looker_column", + "x_axis_gridlines": false, + "x_axis_reversed": false, + "x_axis_scale": "auto", + "x_axis_zoom": true, + "y_axes": [], + "y_axis_combined": true, + "y_axis_gridlines": true, + "y_axis_reversed": false, + "y_axis_scale_mode": "linear", + "y_axis_tick_density": "default", + "y_axis_tick_density_custom": 5, + "y_axis_zoom": true + }} - A line chart - - {{ - "defaults_version": 1, - "hidden_pivots": {}, - "hidden_series": [], - "interpolation": "linear", - "label_density": 25, - "legend_position": "center", - "limit_displayed_rows": false, - "plot_size_by_field": false, - "point_style": "none", - "series_types": {}, - "show_null_points": true, - "show_value_labels": false, - "show_view_names": false, - "show_x_axis_label": true, - "show_x_axis_ticks": true, - "show_y_axis_labels": true, - "show_y_axis_ticks": true, - "stacking": "", - "trellis": "", - "type": "looker_line", - "x_axis_gridlines": false, - "x_axis_reversed": false, - "x_axis_scale": "auto", - "y_axis_combined": true, - "y_axis_gridlines": true, - "y_axis_reversed": false, - "y_axis_scale_mode": "linear", - "y_axis_tick_density": "default", - "y_axis_tick_density_custom": 5 - }} + A line chart - + {{ + "defaults_version": 1, + "hidden_pivots": {}, + "hidden_series": [], + "interpolation": "linear", + "label_density": 25, + "legend_position": "center", + "limit_displayed_rows": false, + "plot_size_by_field": false, + "point_style": "none", + "series_types": {}, + "show_null_points": true, + "show_value_labels": false, + "show_view_names": false, + "show_x_axis_label": true, + "show_x_axis_ticks": true, + "show_y_axis_labels": true, + "show_y_axis_ticks": true, + "stacking": "", + "trellis": "", + "type": "looker_line", + "x_axis_gridlines": false, + "x_axis_reversed": false, + "x_axis_scale": "auto", + "y_axis_combined": true, + "y_axis_gridlines": true, + "y_axis_reversed": false, + "y_axis_scale_mode": "linear", + "y_axis_tick_density": "default", + "y_axis_tick_density_custom": 5 + }} - An area chart - - {{ - "defaults_version": 1, - "interpolation": "linear", - "label_density": 25, - "legend_position": "center", - "limit_displayed_rows": false, - "plot_size_by_field": false, - "point_style": "none", - "series_types": {}, - "show_null_points": true, - "show_silhouette": false, - "show_totals_labels": false, - "show_value_labels": false, - "show_view_names": false, - "show_x_axis_label": true, - "show_x_axis_ticks": true, - "show_y_axis_labels": true, - "show_y_axis_ticks": true, - "stacking": "normal", - "totals_color": "#808080", - "trellis": "", - "type": "looker_area", - "x_axis_gridlines": false, - "x_axis_reversed": false, - "x_axis_scale": "auto", - "x_axis_zoom": true, - "y_axis_combined": true, - "y_axis_gridlines": true, - "y_axis_reversed": false, - "y_axis_scale_mode": "linear", - "y_axis_tick_density": "default", - "y_axis_tick_density_custom": 5, - "y_axis_zoom": true - }} + An area chart - + {{ + "defaults_version": 1, + "interpolation": "linear", + "label_density": 25, + "legend_position": "center", + "limit_displayed_rows": false, + "plot_size_by_field": false, + "point_style": "none", + "series_types": {}, + "show_null_points": true, + "show_silhouette": false, + "show_totals_labels": false, + "show_value_labels": false, + "show_view_names": false, + "show_x_axis_label": true, + "show_x_axis_ticks": true, + "show_y_axis_labels": true, + "show_y_axis_ticks": true, + "stacking": "normal", + "totals_color": "#808080", + "trellis": "", + "type": "looker_area", + "x_axis_gridlines": false, + "x_axis_reversed": false, + "x_axis_scale": "auto", + "x_axis_zoom": true, + "y_axis_combined": true, + "y_axis_gridlines": true, + "y_axis_reversed": false, + "y_axis_scale_mode": "linear", + "y_axis_tick_density": "default", + "y_axis_tick_density_custom": 5, + "y_axis_zoom": true + }} - A scatter plot - - {{ - "cluster_points": false, - "custom_quadrant_point_x": 5, - "custom_quadrant_point_y": 5, - "custom_value_label_column": "", - "custom_x_column": "", - "custom_y_column": "", - "defaults_version": 1, - "hidden_fields": [], - "hidden_pivots": {}, - "hidden_points_if_no": [], - "hidden_series": [], - "interpolation": "linear", - "label_density": 25, - "legend_position": "center", - "limit_displayed_rows": false, - "limit_displayed_rows_values": { - "first_last": "first", - "num_rows": 0, - "show_hide": "hide" - }, - "plot_size_by_field": false, - "point_style": "circle", - "quadrant_properties": { - "0": { - "color": "", - "label": "Quadrant 1" - }, - "1": { - "color": "", - "label": "Quadrant 2" - }, - "2": { - "color": "", - "label": "Quadrant 3" - }, - "3": { - "color": "", - "label": "Quadrant 4" - } - }, - "quadrants_enabled": false, - "series_labels": {}, - "series_types": {}, - "show_null_points": false, - "show_value_labels": false, - "show_view_names": true, - "show_x_axis_label": true, - "show_x_axis_ticks": true, - "show_y_axis_labels": true, - "show_y_axis_ticks": true, - "size_by_field": "roi", - "stacking": "normal", - "swap_axes": true, - "trellis": "", - "type": "looker_scatter", - "x_axis_gridlines": false, - "x_axis_reversed": false, - "x_axis_scale": "auto", - "x_axis_zoom": true, - "y_axes": [ - { - "label": "", - "orientation": "bottom", - "series": [ - { - "axisId": "Channel_0 - average_of_roi_first", - "id": "Channel_0 - average_of_roi_first", - "name": "Channel_0" - }, - { - "axisId": "Channel_1 - average_of_roi_first", - "id": "Channel_1 - average_of_roi_first", - "name": "Channel_1" - }, - { - "axisId": "Channel_2 - average_of_roi_first", - "id": "Channel_2 - average_of_roi_first", - "name": "Channel_2" - }, - { - "axisId": "Channel_3 - average_of_roi_first", - "id": "Channel_3 - average_of_roi_first", - "name": "Channel_3" - }, - { - "axisId": "Channel_4 - average_of_roi_first", - "id": "Channel_4 - average_of_roi_first", - "name": "Channel_4" - } - ], - "showLabels": true, - "showValues": true, - "tickDensity": "custom", - "tickDensityCustom": 100, - "type": "linear", - "unpinAxis": false - } - ], - "y_axis_combined": true, - "y_axis_gridlines": true, - "y_axis_reversed": false, - "y_axis_scale_mode": "linear", - "y_axis_tick_density": "default", - "y_axis_tick_density_custom": 5, - "y_axis_zoom": true - }} + A scatter plot - + {{ + "cluster_points": false, + "custom_quadrant_point_x": 5, + "custom_quadrant_point_y": 5, + "custom_value_label_column": "", + "custom_x_column": "", + "custom_y_column": "", + "defaults_version": 1, + "hidden_fields": [], + "hidden_pivots": {}, + "hidden_points_if_no": [], + "hidden_series": [], + "interpolation": "linear", + "label_density": 25, + "legend_position": "center", + "limit_displayed_rows": false, + "limit_displayed_rows_values": { + "first_last": "first", + "num_rows": 0, + "show_hide": "hide" + }, + "plot_size_by_field": false, + "point_style": "circle", + "quadrant_properties": { + "0": { + "color": "", + "label": "Quadrant 1" + }, + "1": { + "color": "", + "label": "Quadrant 2" + }, + "2": { + "color": "", + "label": "Quadrant 3" + }, + "3": { + "color": "", + "label": "Quadrant 4" + } + }, + "quadrants_enabled": false, + "series_labels": {}, + "series_types": {}, + "show_null_points": false, + "show_value_labels": false, + "show_view_names": true, + "show_x_axis_label": true, + "show_x_axis_ticks": true, + "show_y_axis_labels": true, + "show_y_axis_ticks": true, + "size_by_field": "roi", + "stacking": "normal", + "swap_axes": true, + "trellis": "", + "type": "looker_scatter", + "x_axis_gridlines": false, + "x_axis_reversed": false, + "x_axis_scale": "auto", + "x_axis_zoom": true, + "y_axes": [ + { + "label": "", + "orientation": "bottom", + "series": [ + { + "axisId": "Channel_0 - average_of_roi_first", + "id": "Channel_0 - average_of_roi_first", + "name": "Channel_0" + }, + { + "axisId": "Channel_1 - average_of_roi_first", + "id": "Channel_1 - average_of_roi_first", + "name": "Channel_1" + }, + { + "axisId": "Channel_2 - average_of_roi_first", + "id": "Channel_2 - average_of_roi_first", + "name": "Channel_2" + }, + { + "axisId": "Channel_3 - average_of_roi_first", + "id": "Channel_3 - average_of_roi_first", + "name": "Channel_3" + }, + { + "axisId": "Channel_4 - average_of_roi_first", + "id": "Channel_4 - average_of_roi_first", + "name": "Channel_4" + } + ], + "showLabels": true, + "showValues": true, + "tickDensity": "custom", + "tickDensityCustom": 100, + "type": "linear", + "unpinAxis": false + } + ], + "y_axis_combined": true, + "y_axis_gridlines": true, + "y_axis_reversed": false, + "y_axis_scale_mode": "linear", + "y_axis_tick_density": "default", + "y_axis_tick_density_custom": 5, + "y_axis_zoom": true + }} - A single record visualization - - {{ - "defaults_version": 1, - "show_view_names": false, - "type": "looker_single_record" - }} + A single record visualization - + {{ + "defaults_version": 1, + "show_view_names": false, + "type": "looker_single_record" + }} - A single value visualization - - {{ - "comparison_reverse_colors": false, - "comparison_type": "value", "conditional_formatting_include_nulls": false, "conditional_formatting_include_totals": false, - "custom_color": "#1A73E8", - "custom_color_enabled": true, - "defaults_version": 1, - "enable_conditional_formatting": false, - "series_types": {}, - "show_comparison": false, - "show_comparison_label": true, - "show_single_value_title": true, - "single_value_title": "Total Clicks", - "type": "single_value" - }} + A single value visualization - + {{ + "comparison_reverse_colors": false, + "comparison_type": "value", "conditional_formatting_include_nulls": false, "conditional_formatting_include_totals": false, + "custom_color": "#1A73E8", + "custom_color_enabled": true, + "defaults_version": 1, + "enable_conditional_formatting": false, + "series_types": {}, + "show_comparison": false, + "show_comparison_label": true, + "show_single_value_title": true, + "single_value_title": "Total Clicks", + "type": "single_value" + }} - A Pie chart - - {{ - "defaults_version": 1, - "label_density": 25, - "label_type": "labPer", - "legend_position": "center", - "limit_displayed_rows": false, - "ordering": "none", - "plot_size_by_field": false, - "point_style": "none", - "series_types": {}, - "show_null_labels": false, - "show_silhouette": false, - "show_totals_labels": false, - "show_value_labels": false, - "show_view_names": false, - "show_x_axis_label": true, - "show_x_axis_ticks": true, - "show_y_axis_labels": true, - "show_y_axis_ticks": true, - "stacking": "", - "totals_color": "#808080", - "trellis": "", - "type": "looker_pie", - "value_labels": "legend", - "x_axis_gridlines": false, - "x_axis_reversed": false, - "x_axis_scale": "auto", - "y_axis_combined": true, - "y_axis_gridlines": true, - "y_axis_reversed": false, - "y_axis_scale_mode": "linear", - "y_axis_tick_density": "default", - "y_axis_tick_density_custom": 5 - }} + A Pie chart - + {{ + "defaults_version": 1, + "label_density": 25, + "label_type": "labPer", + "legend_position": "center", + "limit_displayed_rows": false, + "ordering": "none", + "plot_size_by_field": false, + "point_style": "none", + "series_types": {}, + "show_null_labels": false, + "show_silhouette": false, + "show_totals_labels": false, + "show_value_labels": false, + "show_view_names": false, + "show_x_axis_label": true, + "show_x_axis_ticks": true, + "show_y_axis_labels": true, + "show_y_axis_ticks": true, + "stacking": "", + "totals_color": "#808080", + "trellis": "", + "type": "looker_pie", + "value_labels": "legend", + "x_axis_gridlines": false, + "x_axis_reversed": false, + "x_axis_scale": "auto", + "y_axis_combined": true, + "y_axis_gridlines": true, + "y_axis_reversed": false, + "y_axis_scale_mode": "linear", + "y_axis_tick_density": "default", + "y_axis_tick_density_custom": 5 + }} - The result is a JSON object with the id, slug, the url, and - the long_url. + The result is a JSON object with the id, slug, the url, and + the long_url. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-query-url" | +| type | string | true | Must be "looker-query-url" | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-query.md b/docs/en/resources/tools/looker/looker-query.md index 7ba3292763..6fe10c0a2e 100644 --- a/docs/en/resources/tools/looker/looker-query.md +++ b/docs/en/resources/tools/looker/looker-query.md @@ -36,37 +36,37 @@ to find MCP Toolbox queries. ## Example ```yaml -tools: - query: - kind: looker-query - source: looker-source - description: | - This tool runs a query against a LookML model and returns the results in JSON format. +kind: tools +name: query +type: looker-query +source: looker-source +description: | + This tool runs a query against a LookML model and returns the results in JSON format. - Required Parameters: - - model_name: The name of the LookML model (from `get_models`). - - explore_name: The name of the explore (from `get_explores`). - - fields: A list of field names (dimensions, measures, filters, or parameters) to include in the query. + Required Parameters: + - model_name: The name of the LookML model (from `get_models`). + - explore_name: The name of the explore (from `get_explores`). + - fields: A list of field names (dimensions, measures, filters, or parameters) to include in the query. - Optional Parameters: - - pivots: A list of fields to pivot the results by. These fields must also be included in the `fields` list. - - filters: A map of filter expressions, e.g., `{"view.field": "value", "view.date": "7 days"}`. - - Do not quote field names. - - Use `not null` instead of `-NULL`. - - If a value contains a comma, enclose it in single quotes (e.g., "'New York, NY'"). - - sorts: A list of fields to sort by, optionally including direction (e.g., `["view.field desc"]`). - - limit: Row limit (default 500). Use "-1" for unlimited. - - query_timezone: specific timezone for the query (e.g. `America/Los_Angeles`). + Optional Parameters: + - pivots: A list of fields to pivot the results by. These fields must also be included in the `fields` list. + - filters: A map of filter expressions, e.g., `{"view.field": "value", "view.date": "7 days"}`. + - Do not quote field names. + - Use `not null` instead of `-NULL`. + - If a value contains a comma, enclose it in single quotes (e.g., "'New York, NY'"). + - sorts: A list of fields to sort by, optionally including direction (e.g., `["view.field desc"]`). + - limit: Row limit (default 500). Use "-1" for unlimited. + - query_timezone: specific timezone for the query (e.g. `America/Los_Angeles`). - Note: Use `get_dimensions`, `get_measures`, `get_filters`, and `get_parameters` to find valid fields. + Note: Use `get_dimensions`, `get_measures`, `get_filters`, and `get_parameters` to find valid fields. - The result of the query tool is JSON + The result of the query tool is JSON ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-query" | +| type | string | true | Must be "looker-query" | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-run-dashboard.md b/docs/en/resources/tools/looker/looker-run-dashboard.md index cc2c2072df..2682977b49 100644 --- a/docs/en/resources/tools/looker/looker-run-dashboard.md +++ b/docs/en/resources/tools/looker/looker-run-dashboard.md @@ -22,26 +22,26 @@ It's compatible with the following sources: ## Example ```yaml -tools: - run_dashboard: - kind: looker-run-dashboard - source: looker-source - description: | - This tool executes the queries associated with each tile in a specified dashboard - and returns the aggregated data in a JSON structure. +kind: tools +name: run_dashboard +type: looker-run-dashboard +source: looker-source +description: | + This tool executes the queries associated with each tile in a specified dashboard + and returns the aggregated data in a JSON structure. - Parameters: - - dashboard_id (required): The unique identifier of the dashboard to run, - typically obtained from the `get_dashboards` tool. + Parameters: + - dashboard_id (required): The unique identifier of the dashboard to run, + typically obtained from the `get_dashboards` tool. - Output: - The data from all dashboard tiles is returned as a JSON object. + Output: + The data from all dashboard tiles is returned as a JSON object. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-run-dashboard" | +| type | string | true | Must be "looker-run-dashboard" | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-run-look.md b/docs/en/resources/tools/looker/looker-run-look.md index eb2f57eedb..f2a2989323 100644 --- a/docs/en/resources/tools/looker/looker-run-look.md +++ b/docs/en/resources/tools/looker/looker-run-look.md @@ -22,26 +22,26 @@ It's compatible with the following sources: ## Example ```yaml -tools: - run_look: - kind: looker-run-look - source: looker-source - description: | - This tool executes the query associated with a saved Look and - returns the resulting data in a JSON structure. +kind: tools +name: run_look +type: looker-run-look +source: looker-source +description: | + This tool executes the query associated with a saved Look and + returns the resulting data in a JSON structure. - Parameters: - - look_id (required): The unique identifier of the Look to run, - typically obtained from the `get_looks` tool. + Parameters: + - look_id (required): The unique identifier of the Look to run, + typically obtained from the `get_looks` tool. - Output: - The query results are returned as a JSON object. + Output: + The query results are returned as a JSON object. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-run-look" | +| type | string | true | Must be "looker-run-look" | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/looker/looker-update-project-file.md b/docs/en/resources/tools/looker/looker-update-project-file.md index af8cabd81b..de4b092f1c 100644 --- a/docs/en/resources/tools/looker/looker-update-project-file.md +++ b/docs/en/resources/tools/looker/looker-update-project-file.md @@ -22,28 +22,28 @@ as well as the new file content. ## Example ```yaml -tools: - update_project_file: - kind: looker-update-project-file - source: looker-source - description: | - This tool modifies the content of an existing LookML file within a specified project. +kind: tools +name: update_project_file +type: looker-update-project-file +source: looker-source +description: | + This tool modifies the content of an existing LookML file within a specified project. - Prerequisite: The Looker session must be in Development Mode. Use `dev_mode: true` first. + Prerequisite: The Looker session must be in Development Mode. Use `dev_mode: true` first. - Parameters: - - project_id (required): The unique ID of the LookML project. - - file_path (required): The exact path to the LookML file to modify within the project. - - content (required): The new, complete LookML content to overwrite the existing file. + Parameters: + - project_id (required): The unique ID of the LookML project. + - file_path (required): The exact path to the LookML file to modify within the project. + - content (required): The new, complete LookML content to overwrite the existing file. - Output: - A confirmation message upon successful file modification. + Output: + A confirmation message upon successful file modification. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "looker-update-project-file". | +| type | string | true | Must be "looker-update-project-file". | | source | string | true | Name of the source Looker instance. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/mindsdb/_index.md b/docs/en/resources/tools/mindsdb/_index.md index 1a2f2cdff1..89d7828adb 100644 --- a/docs/en/resources/tools/mindsdb/_index.md +++ b/docs/en/resources/tools/mindsdb/_index.md @@ -117,20 +117,20 @@ federated database capabilities. Here's a complete working configuration that has been tested: ```yaml -sources: - my-pg-source: - kind: mindsdb - host: 127.0.0.1 - port: 47335 - database: files - user: mindsdb - -tools: - mindsdb-execute-sql: - kind: mindsdb-execute-sql - source: my-pg-source - description: | - Execute SQL queries directly on MindsDB database. - Use this tool to run any SQL statement against your MindsDB instance. - Example: SELECT * FROM my_table LIMIT 10 +kind: sources +name: my-pg-source +type: mindsdb +host: 127.0.0.1 +port: 47335 +database: files +user: mindsdb +--- +kind: tools +name: mindsdb-execute-sql +type: mindsdb-execute-sql +source: my-pg-source +description: | + Execute SQL queries directly on MindsDB database. + Use this tool to run any SQL statement against your MindsDB instance. + Example: SELECT * FROM my_table LIMIT 10 ``` diff --git a/docs/en/resources/tools/mindsdb/mindsdb-execute-sql.md b/docs/en/resources/tools/mindsdb/mindsdb-execute-sql.md index 1228caf837..7b6da914d5 100644 --- a/docs/en/resources/tools/mindsdb/mindsdb-execute-sql.md +++ b/docs/en/resources/tools/mindsdb/mindsdb-execute-sql.md @@ -97,11 +97,11 @@ ORDER BY created_at DESC; ## Example ```yaml -tools: - execute_sql_tool: - kind: mindsdb-execute-sql - source: my-mindsdb-instance - description: Use this tool to execute SQL statements across multiple datasources and ML models. +kind: tools +name: execute_sql_tool +type: mindsdb-execute-sql +source: my-mindsdb-instance +description: Use this tool to execute SQL statements across multiple datasources and ML models. ``` ### Working Configuration Example @@ -109,28 +109,28 @@ tools: Here's a working configuration that has been tested: ```yaml -sources: - my-pg-source: - kind: mindsdb - host: 127.0.0.1 - port: 47335 - database: files - user: mindsdb - -tools: - mindsdb-execute-sql: - kind: mindsdb-execute-sql - source: my-pg-source - description: | - Execute SQL queries directly on MindsDB database. - Use this tool to run any SQL statement against your MindsDB instance. - Example: SELECT * FROM my_table LIMIT 10 +kind: sources +name: my-pg-source +type: mindsdb +host: 127.0.0.1 +port: 47335 +database: files +user: mindsdb +--- +kind: tools +name: mindsdb-execute-sql +type: mindsdb-execute-sql +source: my-pg-source +description: | + Execute SQL queries directly on MindsDB database. + Use this tool to run any SQL statement against your MindsDB instance. + Example: SELECT * FROM my_table LIMIT 10 ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "mindsdb-execute-sql". | +| type | string | true | Must be "mindsdb-execute-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/mindsdb/mindsdb-sql.md b/docs/en/resources/tools/mindsdb/mindsdb-sql.md index b0cfc189dc..44bea0d27c 100644 --- a/docs/en/resources/tools/mindsdb/mindsdb-sql.md +++ b/docs/en/resources/tools/mindsdb/mindsdb-sql.md @@ -97,41 +97,41 @@ ORDER BY created_at DESC; > names, or other parts of the query. ```yaml -tools: - search_flights_by_number: - kind: mindsdb-sql - source: my-mindsdb-instance - statement: | - SELECT * FROM flights - WHERE airline = ? - AND flight_number = ? - LIMIT 10 - description: | - Use this tool to get information for a specific flight. - Takes an airline code and flight number and returns info on the flight. - Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. - A airline code is a code for an airline service consisting of two-character - airline designator and followed by flight number, which is 1 to 4 digit number. - For example, if given CY 0123, the airline is "CY", and flight_number is "123". - Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". - If the tool returns more than one option choose the date closes to today. - Example: - {{ - "airline": "CY", - "flight_number": "888", - }} - Example: - {{ - "airline": "DL", - "flight_number": "1234", - }} - parameters: - - name: airline - type: string - description: Airline unique 2 letter identifier - - name: flight_number - type: string - description: 1 to 4 digit number +kind: tools +name: search_flights_by_number +type: mindsdb-sql +source: my-mindsdb-instance +statement: | + SELECT * FROM flights + WHERE airline = ? + AND flight_number = ? + LIMIT 10 +description: | + Use this tool to get information for a specific flight. + Takes an airline code and flight number and returns info on the flight. + Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. + A airline code is a code for an airline service consisting of two-character + airline designator and followed by flight number, which is 1 to 4 digit number. + For example, if given CY 0123, the airline is "CY", and flight_number is "123". + Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". + If the tool returns more than one option choose the date closes to today. + Example: + {{ + "airline": "CY", + "flight_number": "888", + }} + Example: + {{ + "airline": "DL", + "flight_number": "1234", + }} +parameters: + - name: airline + type: string + description: Airline unique 2 letter identifier + - name: flight_number + type: string + description: 1 to 4 digit number ``` ### Example with Template Parameters @@ -143,29 +143,29 @@ tools: > [templateParameters](../#template-parameters). ```yaml -tools: - list_table: - kind: mindsdb-sql - source: my-mindsdb-instance - statement: | - SELECT * FROM {{.tableName}}; - description: | - Use this tool to list all information from a specific table. - Example: - {{ - "tableName": "flights", - }} - templateParameters: - - name: tableName - type: string - description: Table to select from +kind: tools +name: list_table +type: mindsdb-sql +source: my-mindsdb-instance +statement: | + SELECT * FROM {{.tableName}}; +description: | + Use this tool to list all information from a specific table. + Example: + {{ + "tableName": "flights", + }} +templateParameters: + - name: tableName + type: string + description: Table to select from ``` ## Reference | **field** | **type** | **required** | **description** | |--------------------|:------------------------------------------------:|:------------:|--------------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "mindsdb-sql". | +| type | string | true | Must be "mindsdb-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | statement | string | true | SQL statement to execute on. | diff --git a/docs/en/resources/tools/mongodb/mongodb-aggregate.md b/docs/en/resources/tools/mongodb/mongodb-aggregate.md index e37217ec77..43707e2a4e 100644 --- a/docs/en/resources/tools/mongodb/mongodb-aggregate.md +++ b/docs/en/resources/tools/mongodb/mongodb-aggregate.md @@ -22,7 +22,7 @@ array of documents produced by the final stage of the pipeline. A `readOnly` flag can be set to `true` as a safety measure to ensure the pipeline does not contain any write stages (like `$out` or `$merge`). -This tool is compatible with the following source kind: +This tool is compatible with the following source type: * [`mongodb`](../../sources/mongodb.md) @@ -32,45 +32,45 @@ Here is an example that calculates the average price and total count of products for each category, but only for products with an "active" status. ```yaml -tools: - get_category_stats: - kind: mongodb-aggregate - source: my-mongo-source - description: Calculates average price and count of products, grouped by category. - database: ecommerce - collection: products - readOnly: true - pipelinePayload: | - [ - { - "$match": { - "status": {{json .status_filter}} - } - }, - { - "$group": { - "_id": "$category", - "average_price": { "$avg": "$price" }, - "item_count": { "$sum": 1 } - } - }, - { - "$sort": { - "average_price": -1 - } - } - ] - pipelineParams: - - name: status_filter - type: string - description: The product status to filter by (e.g., "active"). +kind: tools +name: get_category_stats +type: mongodb-aggregate +source: my-mongo-source +description: Calculates average price and count of products, grouped by category. +database: ecommerce +collection: products +readOnly: true +pipelinePayload: | + [ + { + "$match": { + "status": {{json .status_filter}} + } + }, + { + "$group": { + "_id": "$category", + "average_price": { "$avg": "$price" }, + "item_count": { "$sum": 1 } + } + }, + { + "$sort": { + "average_price": -1 + } + } + ] +pipelineParams: + - name: status_filter + type: string + description: The product status to filter by (e.g., "active"). ``` ## Reference | **field** | **type** | **required** | **description** | |:----------------|:---------|:-------------|:---------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be `mongodb-aggregate`. | +| type | string | true | Must be `mongodb-aggregate`. | | source | string | true | The name of the `mongodb` source to use. | | description | string | true | A description of the tool that is passed to the LLM. | | database | string | true | The name of the MongoDB database containing the collection. | diff --git a/docs/en/resources/tools/mongodb/mongodb-delete-many.md b/docs/en/resources/tools/mongodb/mongodb-delete-many.md index 9e35a72124..b6ffcacc25 100644 --- a/docs/en/resources/tools/mongodb/mongodb-delete-many.md +++ b/docs/en/resources/tools/mongodb/mongodb-delete-many.md @@ -17,7 +17,7 @@ The tool returns the total count of documents that were deleted. If the filter does not match any documents (i.e., the deleted count is 0), the tool will return an error. -This tool is compatible with the following source kind: +This tool is compatible with the following source type: * [`mongodb`](../../sources/mongodb.md) @@ -29,26 +29,26 @@ Here is an example that performs a cleanup task by deleting all products from the `inventory` collection that belong to a discontinued brand. ```yaml -tools: - retire_brand_products: - kind: mongodb-delete-many - source: my-mongo-source - description: Deletes all products from a specified discontinued brand. - database: ecommerce - collection: inventory - filterPayload: | - { "brand_name": {{json .brand_to_delete}} } - filterParams: - - name: brand_to_delete - type: string - description: The name of the discontinued brand whose products should be deleted. +kind: tools +name: retire_brand_products +type: mongodb-delete-many +source: my-mongo-source +description: Deletes all products from a specified discontinued brand. +database: ecommerce +collection: inventory +filterPayload: | + { "brand_name": {{json .brand_to_delete}} } +filterParams: + - name: brand_to_delete + type: string + description: The name of the discontinued brand whose products should be deleted. ``` ## Reference | **field** | **type** | **required** | **description** | |:--------------|:---------|:-------------|:--------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be `mongodb-delete-many`. | +| type | string | true | Must be `mongodb-delete-many`. | | source | string | true | The name of the `mongodb` source to use. | | description | string | true | A description of the tool that is passed to the LLM. | | database | string | true | The name of the MongoDB database containing the collection. | diff --git a/docs/en/resources/tools/mongodb/mongodb-delete-one.md b/docs/en/resources/tools/mongodb/mongodb-delete-one.md index 0cede56c13..3d9dc8dfa9 100644 --- a/docs/en/resources/tools/mongodb/mongodb-delete-one.md +++ b/docs/en/resources/tools/mongodb/mongodb-delete-one.md @@ -21,7 +21,7 @@ such as a user account or a single item from an inventory based on a unique ID. The tool returns the number of documents deleted, which will be either `1` if a document was found and deleted, or `0` if no matching document was found. -This tool is compatible with the following source kind: +This tool is compatible with the following source type: * [`mongodb`](../../sources/mongodb.md) @@ -33,26 +33,26 @@ Here is an example that deletes a specific user account from the `users` collection by matching their unique email address. This is a permanent action. ```yaml -tools: - delete_user_account: - kind: mongodb-delete-one - source: my-mongo-source - description: Permanently deletes a user account by their email address. - database: user_data - collection: users - filterPayload: | - { "email": {{json .email_address}} } - filterParams: - - name: email_address - type: string - description: The email of the user account to delete. +kind: tools +name: delete_user_account +type: mongodb-delete-one +source: my-mongo-source +description: Permanently deletes a user account by their email address. +database: user_data +collection: users +filterPayload: | + { "email": {{json .email_address}} } +filterParams: + - name: email_address + type: string + description: The email of the user account to delete. ``` ## Reference | **field** | **type** | **required** | **description** | |:--------------|:---------|:-------------|:-------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be `mongodb-delete-one`. | +| type | string | true | Must be `mongodb-delete-one`. | | source | string | true | The name of the `mongodb` source to use. | | description | string | true | A description of the tool that is passed to the LLM. | | database | string | true | The name of the MongoDB database containing the collection. | diff --git a/docs/en/resources/tools/mongodb/mongodb-find-one.md b/docs/en/resources/tools/mongodb/mongodb-find-one.md index 395262d91a..47f72cb289 100644 --- a/docs/en/resources/tools/mongodb/mongodb-find-one.md +++ b/docs/en/resources/tools/mongodb/mongodb-find-one.md @@ -18,7 +18,7 @@ returned. Otherwise, the selection is not guaranteed. The tool returns a single JSON object representing the document, wrapped in a JSON array. -This tool is compatible with the following source kind: +This tool is compatible with the following source type: * [`mongodb`](../../sources/mongodb.md) @@ -31,31 +31,31 @@ and returning their profile information, while excluding sensitive fields like the password hash. ```yaml -tools: - get_user_profile: - kind: mongodb-find-one - source: my-mongo-source - description: Retrieves a user's profile by their email address. - database: user_data - collection: profiles - filterPayload: | - { "email": {{json .email}} } - filterParams: - - name: email - type: string - description: The email address of the user to find. - projectPayload: | - { - "password_hash": 0, - "login_history": 0 - } +kind: tools +name: get_user_profile +type: mongodb-find-one +source: my-mongo-source +description: Retrieves a user's profile by their email address. +database: user_data +collection: profiles +filterPayload: | + { "email": {{json .email}} } +filterParams: + - name: email + type: string + description: The email address of the user to find. +projectPayload: | + { + "password_hash": 0, + "login_history": 0 + } ``` ## Reference | **field** | **type** | **required** | **description** | |:---------------|:---------|:-------------|:---------------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be `mongodb-find-one`. | +| type | string | true | Must be `mongodb-find-one`. | | source | string | true | The name of the `mongodb` source to use. | | description | string | true | A description of the tool that is passed to the LLM. | | database | string | true | The name of the MongoDB database to query. | diff --git a/docs/en/resources/tools/mongodb/mongodb-find.md b/docs/en/resources/tools/mongodb/mongodb-find.md index d927c737c1..c2ce3da0a3 100644 --- a/docs/en/resources/tools/mongodb/mongodb-find.md +++ b/docs/en/resources/tools/mongodb/mongodb-find.md @@ -18,7 +18,7 @@ results (**sorting**), and restricting the number of documents returned The tool returns a JSON array of the documents found. -This tool is compatible with the following source kind: +This tool is compatible with the following source type: * [`mongodb`](../../sources/mongodb.md) @@ -29,40 +29,40 @@ live in a specific city. The results are sorted by their last name, and only their first name, last name, and email are returned. ```yaml -tools: - find_local_customers: - kind: mongodb-find - source: my-mongo-source - description: Finds customers by city, sorted by last name. - database: crm - collection: customers - limit: 10 - filterPayload: | - { "address.city": {{json .city}} } - filterParams: - - name: city - type: string - description: The city to search for customers in. - projectPayload: | - { - "first_name": 1, - "last_name": 1, - "email": 1, - "_id": 0 - } - sortPayload: | - { "last_name": {{json .sort_order}} } - sortParams: - - name: sort_order - type: integer - description: The sort order (1 for ascending, -1 for descending). +kind: tools +name: find_local_customers +type: mongodb-find +source: my-mongo-source +description: Finds customers by city, sorted by last name. +database: crm +collection: customers +limit: 10 +filterPayload: | + { "address.city": {{json .city}} } +filterParams: + - name: city + type: string + description: The city to search for customers in. +projectPayload: | + { + "first_name": 1, + "last_name": 1, + "email": 1, + "_id": 0 + } +sortPayload: | + { "last_name": {{json .sort_order}} } +sortParams: + - name: sort_order + type: integer + description: The sort order (1 for ascending, -1 for descending). ``` ## Reference | **field** | **type** | **required** | **description** | |:---------------|:---------|:-------------|:----------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be `mongodb-find`. | +| type | string | true | Must be `mongodb-find`. | | source | string | true | The name of the `mongodb` source to use. | | description | string | true | A description of the tool that is passed to the LLM. | | database | string | true | The name of the MongoDB database to query. | diff --git a/docs/en/resources/tools/mongodb/mongodb-insert-many.md b/docs/en/resources/tools/mongodb/mongodb-insert-many.md index cc6c385375..cc6e0438d7 100644 --- a/docs/en/resources/tools/mongodb/mongodb-insert-many.md +++ b/docs/en/resources/tools/mongodb/mongodb-insert-many.md @@ -19,7 +19,7 @@ be a string containing a **JSON array of document objects**. Upon successful insertion, the tool returns a JSON array containing the unique `_id` of **each** new document that was created. -This tool is compatible with the following source kind: +This tool is compatible with the following source type: * [`mongodb`](../../sources/mongodb.md) @@ -30,14 +30,14 @@ This tool is compatible with the following source kind: Here is an example configuration for a tool that logs multiple events at once. ```yaml -tools: - log_batch_events: - kind: mongodb-insert-many - source: my-mongo-source - description: Inserts a batch of event logs into the database. - database: logging - collection: events - canonical: true +kind: tools +name: log_batch_events +type: mongodb-insert-many +source: my-mongo-source +description: Inserts a batch of event logs into the database. +database: logging +collection: events +canonical: true ``` An LLM would call this tool by providing an array of documents as a JSON string @@ -50,7 +50,7 @@ in the `data` parameter, like this: | **field** | **type** | **required** | **description** | |:------------|:---------|:-------------|:------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be `mongodb-insert-many`. | +| type | string | true | Must be `mongodb-insert-many`. | | source | string | true | The name of the `mongodb` source to use. | | description | string | true | A description of the tool that is passed to the LLM. | | database | string | true | The name of the MongoDB database containing the collection. | diff --git a/docs/en/resources/tools/mongodb/mongodb-insert-one.md b/docs/en/resources/tools/mongodb/mongodb-insert-one.md index 7214f2b4d6..8545cc8e10 100644 --- a/docs/en/resources/tools/mongodb/mongodb-insert-one.md +++ b/docs/en/resources/tools/mongodb/mongodb-insert-one.md @@ -17,7 +17,7 @@ This tool takes one required parameter named `data`, which must be a string containing the JSON object you want to insert. Upon successful insertion, the tool returns the unique `_id` of the newly created document. -This tool is compatible with the following source kind: +This tool is compatible with the following source type: * [`mongodb`](../../sources/mongodb.md) @@ -27,14 +27,14 @@ Here is an example configuration for a tool that adds a new user to a `users` collection. ```yaml -tools: - create_new_user: - kind: mongodb-insert-one - source: my-mongo-source - description: Creates a new user record in the database. - database: user_data - collection: users - canonical: false +kind: tools +name: create_new_user +type: mongodb-insert-one +source: my-mongo-source +description: Creates a new user record in the database. +database: user_data +collection: users +canonical: false ``` An LLM would call this tool by providing the document as a JSON string in the @@ -45,7 +45,7 @@ An LLM would call this tool by providing the document as a JSON string in the | **field** | **type** | **required** | **description** | |:------------|:---------|:-------------|:------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be `mongodb-insert-one`. | +| type | string | true | Must be `mongodb-insert-one`. | | source | string | true | The name of the `mongodb` source to use. | | description | string | true | A description of the tool that is passed to the LLM. | | database | string | true | The name of the MongoDB database containing the collection. | diff --git a/docs/en/resources/tools/mongodb/mongodb-update-many.md b/docs/en/resources/tools/mongodb/mongodb-update-many.md index ef3b144364..5fdb2e650e 100644 --- a/docs/en/resources/tools/mongodb/mongodb-update-many.md +++ b/docs/en/resources/tools/mongodb/mongodb-update-many.md @@ -17,7 +17,7 @@ MongoDB collection that match a given filter. It locates the documents using a The tool returns an array of three integers: `[ModifiedCount, UpsertedCount, MatchedCount]`. -This tool is compatible with the following source kind: +This tool is compatible with the following source type: * [`mongodb`](../../sources/mongodb.md) @@ -29,37 +29,37 @@ Here's an example configuration. This tool applies a discount to all items within a specific category and also marks them as being on sale. ```yaml -tools: - apply_category_discount: - kind: mongodb-update-many - source: my-mongo-source - description: Use this tool to apply a discount to all items in a given category. - database: products - collection: inventory - filterPayload: | - { "category": {{json .category_name}} } - filterParams: - - name: category_name - type: string - description: The category of items to update. - updatePayload: | - { - "$mul": { "price": {{json .discount_multiplier}} }, - "$set": { "on_sale": true } - } - updateParams: - - name: discount_multiplier - type: number - description: The multiplier to apply to the price (e.g., 0.8 for a 20% discount). - canonical: false - upsert: false +kind: tools +name: apply_category_discount +type: mongodb-update-many +source: my-mongo-source +description: Use this tool to apply a discount to all items in a given category. +database: products +collection: inventory +filterPayload: | + { "category": {{json .category_name}} } +filterParams: + - name: category_name + type: string + description: The category of items to update. +updatePayload: | + { + "$mul": { "price": {{json .discount_multiplier}} }, + "$set": { "on_sale": true } + } +updateParams: + - name: discount_multiplier + type: number + description: The multiplier to apply to the price (e.g., 0.8 for a 20% discount). +canonical: false +upsert: false ``` ## Reference | **field** | **type** | **required** | **description** | |:--------------|:---------|:-------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be `mongodb-update-many`. | +| type | string | true | Must be `mongodb-update-many`. | | source | string | true | The name of the `mongodb` source to use. | | description | string | true | A description of the tool that is passed to the LLM. | | database | string | true | The name of the MongoDB database containing the collection. | diff --git a/docs/en/resources/tools/mongodb/mongodb-update-one.md b/docs/en/resources/tools/mongodb/mongodb-update-one.md index 063ea0b192..e0bf51e3dd 100644 --- a/docs/en/resources/tools/mongodb/mongodb-update-one.md +++ b/docs/en/resources/tools/mongodb/mongodb-update-one.md @@ -15,7 +15,7 @@ collection. It locates the document to be updated using a `filterPayload` and applies modifications defined in an `updatePayload`. If the filter matches multiple documents, only the first one found will be updated. -This tool is compatible with the following source kind: +This tool is compatible with the following source type: * [`mongodb`](../../sources/mongodb.md) @@ -29,37 +29,37 @@ collection where the `item` field matches a provided value. If no matching document is found, the `upsert: true` option will create a new one. ```yaml -tools: - update_inventory_item: - kind: mongodb-update-one - source: my-mongo-source - description: Use this tool to update an item's stock and status in the inventory. - database: products - collection: inventory - filterPayload: | - { "item": {{json .item_name}} } - filterParams: - - name: item_name - type: string - description: The name of the item to update. - updatePayload: | - { "$set": { "stock": {{json .new_stock}}, "status": {{json .new_status}} } } - updateParams: - - name: new_stock - type: integer - description: The new stock quantity. - - name: new_status - type: string - description: The new status of the item (e.g., "In Stock", "Backordered"). - canonical: false - upsert: true +kind: tools +name: update_inventory_item +type: mongodb-update-one +source: my-mongo-source +description: Use this tool to update an item's stock and status in the inventory. +database: products +collection: inventory +filterPayload: | + { "item": {{json .item_name}} } +filterParams: + - name: item_name + type: string + description: The name of the item to update. +updatePayload: | + { "$set": { "stock": {{json .new_stock}}, "status": {{json .new_status}} } } +updateParams: + - name: new_stock + type: integer + description: The new stock quantity. + - name: new_status + type: string + description: The new status of the item (e.g., "In Stock", "Backordered"). +canonical: false +upsert: true ``` ## Reference | **field** | **type** | **required** | **description** | |:--------------|:---------|:-------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be `mongodb-update-one`. | +| type | string | true | Must be `mongodb-update-one`. | | source | string | true | The name of the `mongodb` source to use. | | description | string | true | A description of the tool that is passed to the LLM. | | database | string | true | The name of the MongoDB database containing the collection. | diff --git a/docs/en/resources/tools/mssql/mssql-execute-sql.md b/docs/en/resources/tools/mssql/mssql-execute-sql.md index 4667dcf46b..23bdbf6640 100644 --- a/docs/en/resources/tools/mssql/mssql-execute-sql.md +++ b/docs/en/resources/tools/mssql/mssql-execute-sql.md @@ -26,17 +26,17 @@ statement against the `source`. ## Example ```yaml -tools: - execute_sql_tool: - kind: mssql-execute-sql - source: my-mssql-instance - description: Use this tool to execute sql statement. +kind: tools +name: execute_sql_tool +type: mssql-execute-sql +source: my-mssql-instance +description: Use this tool to execute sql statement. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:------------------------------------------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "mssql-execute-sql". | +| type | string | true | Must be "mssql-execute-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/mssql/mssql-list-tables.md b/docs/en/resources/tools/mssql/mssql-list-tables.md index 4a7fdf7a8d..d80c79cc17 100644 --- a/docs/en/resources/tools/mssql/mssql-list-tables.md +++ b/docs/en/resources/tools/mssql/mssql-list-tables.md @@ -32,17 +32,17 @@ The tool takes the following input parameters: ## Example ```yaml -tools: - mssql_list_tables: - kind: mssql-list-tables - source: mssql-source - description: Use this tool to retrieve schema information for all or specified tables. Output format can be simple (only table names) or detailed. +kind: tools +name: mssql_list_tables +type: mssql-list-tables +source: mssql-source +description: Use this tool to retrieve schema information for all or specified tables. Output format can be simple (only table names) or detailed. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|------------------------------------------------------| -| kind | string | true | Must be "mssql-list-tables". | +| type | string | true | Must be "mssql-list-tables". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the agent. | diff --git a/docs/en/resources/tools/mssql/mssql-sql.md b/docs/en/resources/tools/mssql/mssql-sql.md index e4c63184c2..c5d212f096 100644 --- a/docs/en/resources/tools/mssql/mssql-sql.md +++ b/docs/en/resources/tools/mssql/mssql-sql.md @@ -36,41 +36,41 @@ db.QueryContext(ctx, `select * from t where ID = @ID and Name = @p2;`, sql.Named > names, or other parts of the query. ```yaml -tools: - search_flights_by_number: - kind: mssql-sql - source: my-instance - statement: | - SELECT * FROM flights - WHERE airline = @airline - AND flight_number = @flight_number - LIMIT 10 - description: | - Use this tool to get information for a specific flight. - Takes an airline code and flight number and returns info on the flight. - Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. - A airline code is a code for an airline service consisting of two-character - airline designator and followed by flight number, which is 1 to 4 digit number. - For example, if given CY 0123, the airline is "CY", and flight_number is "123". - Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". - If the tool returns more than one option choose the date closes to today. - Example: - {{ - "airline": "CY", - "flight_number": "888", - }} - Example: - {{ - "airline": "DL", - "flight_number": "1234", - }} - parameters: - - name: airline - type: string - description: Airline unique 2 letter identifier - - name: flight_number - type: string - description: 1 to 4 digit number +kind: tools +name: search_flights_by_number +type: mssql-sql +source: my-instance +statement: | + SELECT * FROM flights + WHERE airline = @airline + AND flight_number = @flight_number + LIMIT 10 +description: | + Use this tool to get information for a specific flight. + Takes an airline code and flight number and returns info on the flight. + Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. + A airline code is a code for an airline service consisting of two-character + airline designator and followed by flight number, which is 1 to 4 digit number. + For example, if given CY 0123, the airline is "CY", and flight_number is "123". + Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". + If the tool returns more than one option choose the date closes to today. + Example: + {{ + "airline": "CY", + "flight_number": "888", + }} + Example: + {{ + "airline": "DL", + "flight_number": "1234", + }} +parameters: + - name: airline + type: string + description: Airline unique 2 letter identifier + - name: flight_number + type: string + description: 1 to 4 digit number ``` ### Example with Template Parameters @@ -82,29 +82,29 @@ tools: > [templateParameters](..#template-parameters). ```yaml -tools: - list_table: - kind: mssql-sql - source: my-instance - statement: | - SELECT * FROM {{.tableName}}; - description: | - Use this tool to list all information from a specific table. - Example: - {{ - "tableName": "flights", - }} - templateParameters: - - name: tableName - type: string - description: Table to select from +kind: tools +name: list_table +type: mssql-sql +source: my-instance +statement: | + SELECT * FROM {{.tableName}}; +description: | + Use this tool to list all information from a specific table. + Example: + {{ + "tableName": "flights", + }} +templateParameters: + - name: tableName + type: string + description: Table to select from ``` ## Reference | **field** | **type** | **required** | **description** | |--------------------|:--------------------------------------------:|:------------:|----------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "mssql-sql". | +| type | string | true | Must be "mssql-sql". | | source | string | true | Name of the source the T-SQL statement should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | statement | string | true | SQL statement to execute. | diff --git a/docs/en/resources/tools/mysql/mysql-execute-sql.md b/docs/en/resources/tools/mysql/mysql-execute-sql.md index ff68b06516..dce8070471 100644 --- a/docs/en/resources/tools/mysql/mysql-execute-sql.md +++ b/docs/en/resources/tools/mysql/mysql-execute-sql.md @@ -26,17 +26,17 @@ statement against the `source`. ## Example ```yaml -tools: - execute_sql_tool: - kind: mysql-execute-sql - source: my-mysql-instance - description: Use this tool to execute sql statement. +kind: tools +name: execute_sql_tool +type: mysql-execute-sql +source: my-mysql-instance +description: Use this tool to execute sql statement. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:------------------------------------------:|:------------:|--------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "mysql-execute-sql". | +| type | string | true | Must be "mysql-execute-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/mysql/mysql-get-query-plan.md b/docs/en/resources/tools/mysql/mysql-get-query-plan.md index d77b81e097..b3e259b5af 100644 --- a/docs/en/resources/tools/mysql/mysql-get-query-plan.md +++ b/docs/en/resources/tools/mysql/mysql-get-query-plan.md @@ -23,17 +23,17 @@ statement against the `source`. ## Example ```yaml -tools: - get_query_plan_tool: - kind: mysql-get-query-plan - source: my-mysql-instance - description: Use this tool to get the execution plan for a sql statement. +kind: tools +name: get_query_plan_tool +type: mysql-get-query-plan +source: my-mysql-instance +description: Use this tool to get the execution plan for a sql statement. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:------------------------------------------:|:------------:|--------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "mysql-get-query-plan". | +| type | string | true | Must be "mysql-get-query-plan". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/mysql/mysql-list-active-queries.md b/docs/en/resources/tools/mysql/mysql-list-active-queries.md index f7a2721aba..7f0ba3c0fd 100644 --- a/docs/en/resources/tools/mysql/mysql-list-active-queries.md +++ b/docs/en/resources/tools/mysql/mysql-list-active-queries.md @@ -27,11 +27,11 @@ This tool takes 2 optional input parameters: ## Example ```yaml -tools: - list_active_queries: - kind: mysql-list-active-queries - source: my-mysql-instance - description: Lists top N (default 10) ongoing queries from processlist and innodb_trx, ordered by execution time in descending order. Returns detailed information of those queries in json format, including process id, query, transaction duration, transaction wait duration, process time, transaction state, process state, username with host, transaction rows locked, transaction rows modified, and db schema. +kind: tools +name: list_active_queries +type: mysql-list-active-queries +source: my-mysql-instance +description: Lists top N (default 10) ongoing queries from processlist and innodb_trx, ordered by execution time in descending order. Returns detailed information of those queries in json format, including process id, query, transaction duration, transaction wait duration, process time, transaction state, process state, username with host, transaction rows locked, transaction rows modified, and db schema. ``` The response is a json array with the following fields: @@ -57,6 +57,6 @@ The response is a json array with the following fields: | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "mysql-list-active-queries". | +| type | string | true | Must be "mysql-list-active-queries". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/mysql/mysql-list-table-fragmentation.md b/docs/en/resources/tools/mysql/mysql-list-table-fragmentation.md index 1af1308a71..3e0ce0c5a9 100644 --- a/docs/en/resources/tools/mysql/mysql-list-table-fragmentation.md +++ b/docs/en/resources/tools/mysql/mysql-list-table-fragmentation.md @@ -34,11 +34,11 @@ This tool takes 4 optional input parameters: ## Example ```yaml -tools: - list_table_fragmentation: - kind: mysql-list-table-fragmentation - source: my-mysql-instance - description: List table fragmentation in MySQL, by calculating the size of the data and index files and free space allocated to each table. The query calculates fragmentation percentage which represents the proportion of free space relative to the total data and index size. Storage can be reclaimed for tables with high fragmentation using OPTIMIZE TABLE. +kind: tools +name: list_table_fragmentation +type: mysql-list-table-fragmentation +source: my-mysql-instance +description: List table fragmentation in MySQL, by calculating the size of the data and index files and free space allocated to each table. The query calculates fragmentation percentage which represents the proportion of free space relative to the total data and index size. Storage can be reclaimed for tables with high fragmentation using OPTIMIZE TABLE. ``` The response is a json array with the following fields: @@ -58,6 +58,6 @@ The response is a json array with the following fields: | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "mysql-list-table-fragmentation". | +| type | string | true | Must be "mysql-list-table-fragmentation". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/mysql/mysql-list-tables-missing-unique-indexes.md b/docs/en/resources/tools/mysql/mysql-list-tables-missing-unique-indexes.md index 087860141a..7c1c08296a 100644 --- a/docs/en/resources/tools/mysql/mysql-list-tables-missing-unique-indexes.md +++ b/docs/en/resources/tools/mysql/mysql-list-tables-missing-unique-indexes.md @@ -27,11 +27,11 @@ parameters: ## Example ```yaml -tools: - list_tables_missing_unique_indexes: - kind: mysql-list-tables-missing-unique-indexes - source: my-mysql-instance - description: Find tables that do not have primary or unique key constraint. A primary key or unique key is the only mechanism that guaranttes a row is unique. Without them, the database-level protection against data integrity issues will be missing. +kind: tools +name: list_tables_missing_unique_indexes +type: mysql-list-tables-missing-unique-indexes +source: my-mysql-instance +description: Find tables that do not have primary or unique key constraint. A primary key or unique key is the only mechanism that guaranttes a row is unique. Without them, the database-level protection against data integrity issues will be missing. ``` The response is a json array with the following fields: @@ -47,6 +47,6 @@ The response is a json array with the following fields: | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "mysql-list-active-queries". | +| type | string | true | Must be "mysql-list-active-queries". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/mysql/mysql-list-tables.md b/docs/en/resources/tools/mysql/mysql-list-tables.md index f07eef7c68..62da629c3b 100644 --- a/docs/en/resources/tools/mysql/mysql-list-tables.md +++ b/docs/en/resources/tools/mysql/mysql-list-tables.md @@ -33,17 +33,17 @@ The tool takes the following input parameters: ## Example ```yaml -tools: - mysql_list_tables: - kind: mysql-list-tables - source: mysql-source - description: Use this tool to retrieve schema information for all or specified tables. Output format can be simple (only table names) or detailed. +kind: tools +name: mysql_list_tables +type: mysql-list-tables +source: mysql-source +description: Use this tool to retrieve schema information for all or specified tables. Output format can be simple (only table names) or detailed. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|------------------------------------------------------| -| kind | string | true | Must be "mysql-list-tables". | +| type | string | true | Must be "mysql-list-tables". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the agent. | diff --git a/docs/en/resources/tools/mysql/mysql-sql.md b/docs/en/resources/tools/mysql/mysql-sql.md index 56850ba0b2..9d534a6c03 100644 --- a/docs/en/resources/tools/mysql/mysql-sql.md +++ b/docs/en/resources/tools/mysql/mysql-sql.md @@ -30,41 +30,41 @@ and expects parameters in the SQL query to be in the form of placeholders `?`. > names, or other parts of the query. ```yaml -tools: - search_flights_by_number: - kind: mysql-sql - source: my-mysql-instance - statement: | - SELECT * FROM flights - WHERE airline = ? - AND flight_number = ? - LIMIT 10 - description: | - Use this tool to get information for a specific flight. - Takes an airline code and flight number and returns info on the flight. - Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. - A airline code is a code for an airline service consisting of two-character - airline designator and followed by flight number, which is 1 to 4 digit number. - For example, if given CY 0123, the airline is "CY", and flight_number is "123". - Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". - If the tool returns more than one option choose the date closes to today. - Example: - {{ - "airline": "CY", - "flight_number": "888", - }} - Example: - {{ - "airline": "DL", - "flight_number": "1234", - }} - parameters: - - name: airline - type: string - description: Airline unique 2 letter identifier - - name: flight_number - type: string - description: 1 to 4 digit number +kind: tools +name: search_flights_by_number +type: mysql-sql +source: my-mysql-instance +statement: | + SELECT * FROM flights + WHERE airline = ? + AND flight_number = ? + LIMIT 10 +description: | + Use this tool to get information for a specific flight. + Takes an airline code and flight number and returns info on the flight. + Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. + A airline code is a code for an airline service consisting of two-character + airline designator and followed by flight number, which is 1 to 4 digit number. + For example, if given CY 0123, the airline is "CY", and flight_number is "123". + Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". + If the tool returns more than one option choose the date closes to today. + Example: + {{ + "airline": "CY", + "flight_number": "888", + }} + Example: + {{ + "airline": "DL", + "flight_number": "1234", + }} +parameters: + - name: airline + type: string + description: Airline unique 2 letter identifier + - name: flight_number + type: string + description: 1 to 4 digit number ``` ### Example with Template Parameters @@ -76,29 +76,29 @@ tools: > [templateParameters](..#template-parameters). ```yaml -tools: - list_table: - kind: mysql-sql - source: my-mysql-instance - statement: | - SELECT * FROM {{.tableName}}; - description: | - Use this tool to list all information from a specific table. - Example: - {{ - "tableName": "flights", - }} - templateParameters: - - name: tableName - type: string - description: Table to select from +kind: tools +name: list_table +type: mysql-sql +source: my-mysql-instance +statement: | + SELECT * FROM {{.tableName}}; +description: | + Use this tool to list all information from a specific table. + Example: + {{ + "tableName": "flights", + }} +templateParameters: + - name: tableName + type: string + description: Table to select from ``` ## Reference | **field** | **type** | **required** | **description** | |--------------------|:------------------------------------------------:|:------------:|--------------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "mysql-sql". | +| type | string | true | Must be "mysql-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | statement | string | true | SQL statement to execute on. | diff --git a/docs/en/resources/tools/neo4j/neo4j-cypher.md b/docs/en/resources/tools/neo4j/neo4j-cypher.md index 1086f13693..f058c4eca6 100644 --- a/docs/en/resources/tools/neo4j/neo4j-cypher.md +++ b/docs/en/resources/tools/neo4j/neo4j-cypher.md @@ -31,46 +31,46 @@ their name: e.g. `$id`. ## Example ```yaml -tools: - search_movies_by_actor: - kind: neo4j-cypher - source: my-neo4j-movies-instance - statement: | - MATCH (m:Movie)<-[:ACTED_IN]-(p:Person) - WHERE p.name = $name AND m.year > $year - RETURN m.title, m.year - LIMIT 10 - description: | - Use this tool to get a list of movies for a specific actor and a given minimum release year. - Takes a full actor name, e.g. "Tom Hanks" and a year e.g 1993 and returns a list of movie titles and release years. - Do NOT use this tool with a movie title. Do NOT guess an actor name, Do NOT guess a year. - A actor name is a fully qualified name with first and last name separated by a space. - For example, if given "Hanks, Tom" the actor name is "Tom Hanks". - If the tool returns more than one option choose the most recent movies. - Example: - {{ - "name": "Meg Ryan", - "year": 1993 - }} - Example: - {{ - "name": "Clint Eastwood", - "year": 2000 - }} - parameters: - - name: name - type: string - description: Full actor name, "firstname lastname" - - name: year - type: integer - description: 4 digit number starting in 1900 up to the current year +kind: tools +name: search_movies_by_actor +type: neo4j-cypher +source: my-neo4j-movies-instance +statement: | + MATCH (m:Movie)<-[:ACTED_IN]-(p:Person) + WHERE p.name = $name AND m.year > $year + RETURN m.title, m.year + LIMIT 10 +description: | + Use this tool to get a list of movies for a specific actor and a given minimum release year. + Takes a full actor name, e.g. "Tom Hanks" and a year e.g 1993 and returns a list of movie titles and release years. + Do NOT use this tool with a movie title. Do NOT guess an actor name, Do NOT guess a year. + A actor name is a fully qualified name with first and last name separated by a space. + For example, if given "Hanks, Tom" the actor name is "Tom Hanks". + If the tool returns more than one option choose the most recent movies. + Example: + {{ + "name": "Meg Ryan", + "year": 1993 + }} + Example: + {{ + "name": "Clint Eastwood", + "year": 2000 + }} +parameters: + - name: name + type: string + description: Full actor name, "firstname lastname" + - name: year + type: integer + description: 4 digit number starting in 1900 up to the current year ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:---------------------------------------:|:------------:|----------------------------------------------------------------------------------------------| -| kind | string | true | Must be "neo4j-cypher". | +| type | string | true | Must be "neo4j-cypher". | | source | string | true | Name of the source the Cypher query should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | statement | string | true | Cypher statement to execute | diff --git a/docs/en/resources/tools/neo4j/neo4j-execute-cypher.md b/docs/en/resources/tools/neo4j/neo4j-execute-cypher.md index 642f4234cf..e3828693d8 100644 --- a/docs/en/resources/tools/neo4j/neo4j-execute-cypher.md +++ b/docs/en/resources/tools/neo4j/neo4j-execute-cypher.md @@ -37,26 +37,26 @@ parameter to validate a query without executing it. ## Example ```yaml -tools: - query_neo4j: - kind: neo4j-execute-cypher - source: my-neo4j-prod-db - readOnly: true - description: | - Use this tool to execute a Cypher query against the production database. - Only read-only queries are allowed. - Takes a single 'cypher' parameter containing the full query string. - Example: - {{ - "cypher": "MATCH (m:Movie {title: 'The Matrix'}) RETURN m.released" - }} +kind: tools +name: query_neo4j +type: neo4j-execute-cypher +source: my-neo4j-prod-db +readOnly: true +description: | + Use this tool to execute a Cypher query against the production database. + Only read-only queries are allowed. + Takes a single 'cypher' parameter containing the full query string. + Example: + {{ + "cypher": "MATCH (m:Movie {title: 'The Matrix'}) RETURN m.released" + }} ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "neo4j-cypher". | +| type | string | true | Must be "neo4j-cypher". | | source | string | true | Name of the source the Cypher query should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | readOnly | boolean | false | If set to `true`, the tool will reject any write operations in the Cypher query. Default is `false`. | diff --git a/docs/en/resources/tools/neo4j/neo4j-schema.md b/docs/en/resources/tools/neo4j/neo4j-schema.md index aee380ebc5..31c3bcb81a 100644 --- a/docs/en/resources/tools/neo4j/neo4j-schema.md +++ b/docs/en/resources/tools/neo4j/neo4j-schema.md @@ -28,24 +28,24 @@ tool is compatible with a `neo4j` source and takes no parameters. ## Example ```yaml -tools: - get_movie_db_schema: - kind: neo4j-schema - source: my-neo4j-movies-instance - description: | - Use this tool to get the full schema of the movie database. - This provides information on all available node labels (like Movie, Person), - relationships (like ACTED_IN), and the properties on each. - This tool takes no parameters. - # Optional configuration to cache the schema for 2 hours - cacheExpireMinutes: 120 +kind: tools +name: get_movie_db_schema +type: neo4j-schema +source: my-neo4j-movies-instance +description: | + Use this tool to get the full schema of the movie database. + This provides information on all available node labels (like Movie, Person), + relationships (like ACTED_IN), and the properties on each. + This tool takes no parameters. +# Optional configuration to cache the schema for 2 hours +cacheExpireMinutes: 120 ``` ## Reference | **field** | **type** | **required** | **description** | |--------------------|:--------:|:------------:|---------------------------------------------------------| -| kind | string | true | Must be `neo4j-schema`. | +| type | string | true | Must be `neo4j-schema`. | | source | string | true | Name of the source the schema should be extracted from. | | description | string | true | Description of the tool that is passed to the LLM. | | cacheExpireMinutes | integer | false | Cache expiration time in minutes. Defaults to 60. | diff --git a/docs/en/resources/tools/oceanbase/oceanbase-execute-sql.md b/docs/en/resources/tools/oceanbase/oceanbase-execute-sql.md index 36432b2e8b..fe43ff54b9 100644 --- a/docs/en/resources/tools/oceanbase/oceanbase-execute-sql.md +++ b/docs/en/resources/tools/oceanbase/oceanbase-execute-sql.md @@ -24,17 +24,17 @@ statement against the `source`. ## Example ```yaml -tools: - execute_sql_tool: - kind: oceanbase-execute-sql - source: my-oceanbase-instance - description: Use this tool to execute sql statement. +kind: tools +name: execute_sql_tool +type: oceanbase-execute-sql +source: my-oceanbase-instance +description: Use this tool to execute sql statement. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "oceanbase-execute-sql". | +| type | string | true | Must be "oceanbase-execute-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/oceanbase/oceanbase-sql.md b/docs/en/resources/tools/oceanbase/oceanbase-sql.md index ee33d3cd7c..aafdadc3d6 100644 --- a/docs/en/resources/tools/oceanbase/oceanbase-sql.md +++ b/docs/en/resources/tools/oceanbase/oceanbase-sql.md @@ -29,31 +29,31 @@ form of placeholders `?`. > names, or other parts of the query. ```yaml -tools: - search_flights_by_number: - kind: oceanbase-sql - source: my-oceanbase-instance - statement: | - SELECT * FROM flights - WHERE airline = ? - AND flight_number = ? - LIMIT 10 - description: | - Use this tool to get information for a specific flight. - Takes an airline code and flight number and returns info on the flight. - Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. - Example: - {{ - "airline": "CY", - "flight_number": "888", - }} - parameters: - - name: airline - type: string - description: Airline unique 2 letter identifier - - name: flight_number - type: string - description: 1 to 4 digit number +kind: tools +name: search_flights_by_number +type: oceanbase-sql +source: my-oceanbase-instance +statement: | + SELECT * FROM flights + WHERE airline = ? + AND flight_number = ? + LIMIT 10 +description: | + Use this tool to get information for a specific flight. + Takes an airline code and flight number and returns info on the flight. + Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. + Example: + {{ + "airline": "CY", + "flight_number": "888", + }} +parameters: + - name: airline + type: string + description: Airline unique 2 letter identifier + - name: flight_number + type: string + description: 1 to 4 digit number ``` ### Example with Template Parameters @@ -64,64 +64,64 @@ tools: > recommended for performance and safety reasons. ```yaml -tools: - list_table: - kind: oceanbase-sql - source: my-oceanbase-instance - statement: | - SELECT * FROM {{.tableName}}; - description: | - Use this tool to list all information from a specific table. - Example: - {{ - "tableName": "flights", - }} - templateParameters: - - name: tableName - type: string - description: Table to select from +kind: tools +name: list_table +type: oceanbase-sql +source: my-oceanbase-instance +statement: | + SELECT * FROM {{.tableName}}; +description: | + Use this tool to list all information from a specific table. + Example: + {{ + "tableName": "flights", + }} +templateParameters: + - name: tableName + type: string + description: Table to select from ``` ### Example with Array Parameters ```yaml -tools: - search_flights_by_ids: - kind: oceanbase-sql - source: my-oceanbase-instance - statement: | - SELECT * FROM flights - WHERE id IN (?) - AND status IN (?) - description: | - Use this tool to get information for multiple flights by their IDs and statuses. - Example: - {{ - "flight_ids": [1, 2, 3], - "statuses": ["active", "scheduled"] - }} - parameters: - - name: flight_ids - type: array - description: List of flight IDs to search for - items: - name: flight_id - type: integer - description: Individual flight ID - - name: statuses - type: array - description: List of flight statuses to filter by - items: - name: status - type: string - description: Individual flight status +kind: tools +name: search_flights_by_ids +type: oceanbase-sql +source: my-oceanbase-instance +statement: | + SELECT * FROM flights + WHERE id IN (?) + AND status IN (?) +description: | + Use this tool to get information for multiple flights by their IDs and statuses. + Example: + {{ + "flight_ids": [1, 2, 3], + "statuses": ["active", "scheduled"] + }} +parameters: + - name: flight_ids + type: array + description: List of flight IDs to search for + items: + name: flight_id + type: integer + description: Individual flight ID + - name: statuses + type: array + description: List of flight statuses to filter by + items: + name: status + type: string + description: Individual flight status ``` ## Reference | **field** | **type** | **required** | **description** | |--------------------|:--------------------------------------------:|:------------:|----------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "oceanbase-sql". | +| type | string | true | Must be "oceanbase-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | statement | string | true | SQL statement to execute on. | diff --git a/docs/en/resources/tools/oracle/oracle-execute-sql.md b/docs/en/resources/tools/oracle/oracle-execute-sql.md index c66cce2b8c..cbfd79037b 100644 --- a/docs/en/resources/tools/oracle/oracle-execute-sql.md +++ b/docs/en/resources/tools/oracle/oracle-execute-sql.md @@ -24,8 +24,9 @@ statement against the `source`. ## Example ```yaml -tools: - execute_sql_tool: - kind: oracle-execute-sql - source: my-oracle-instance - description: Use this tool to execute sql statement. +kind: tools +name: execute_sql_tool +type: oracle-execute-sql +source: my-oracle-instance +description: Use this tool to execute sql statement. +``` diff --git a/docs/en/resources/tools/oracle/oracle-sql.md b/docs/en/resources/tools/oracle/oracle-sql.md index 045031f60c..49d665be36 100644 --- a/docs/en/resources/tools/oracle/oracle-sql.md +++ b/docs/en/resources/tools/oracle/oracle-sql.md @@ -29,29 +29,29 @@ to be in the native Oracle format (e.g., `:1`, `:2`). > names, or other parts of the query. ```yaml -tools: - search_flights_by_number: - kind: oracle-sql - source: my-oracle-instance - statement: | - SELECT * FROM flights - WHERE airline = :1 - AND flight_number = :2 - FETCH FIRST 10 ROWS ONLY - description: | - Use this tool to get information for a specific flight. - Takes an airline code and flight number and returns info on the flight. - Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. - Example: - {{ - "airline": "CY", - "flight_number": "888", - }} - parameters: - - name: airline - type: string - description: Airline unique 2 letter identifier - - name: flight_number - type: string - description: 1 to 4 digit number +kind: tools +name: search_flights_by_number +type: oracle-sql +source: my-oracle-instance +statement: | + SELECT * FROM flights + WHERE airline = :1 + AND flight_number = :2 + FETCH FIRST 10 ROWS ONLY +description: | + Use this tool to get information for a specific flight. + Takes an airline code and flight number and returns info on the flight. + Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. + Example: + {{ + "airline": "CY", + "flight_number": "888", + }} +parameters: + - name: airline + type: string + description: Airline unique 2 letter identifier + - name: flight_number + type: string + description: 1 to 4 digit number ``` diff --git a/docs/en/resources/tools/postgres/postgres-database-overview.md b/docs/en/resources/tools/postgres/postgres-database-overview.md index 485a8625fb..1dcb23dc45 100644 --- a/docs/en/resources/tools/postgres/postgres-database-overview.md +++ b/docs/en/resources/tools/postgres/postgres-database-overview.md @@ -23,12 +23,12 @@ This tool does not take any input parameters. ## Example ```yaml -tools: - database_overview: - kind: postgres-database-overview - source: cloudsql-pg-source - description: | - fetches the current state of the PostgreSQL server. It returns the postgres 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. +kind: tools +name: database_overview +type: postgres-database-overview +source: cloudsql-pg-source +description: | + fetches the current state of the PostgreSQL server. It returns the postgres 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. ``` The response is a JSON object with the following elements: @@ -49,6 +49,6 @@ The response is a JSON object with the following elements: | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|------------------------------------------------------| -| kind | string | true | Must be "postgres-database-overview". | +| type | string | true | Must be "postgres-database-overview". | | source | string | true | Name of the source the SQL should execute on. | | description | string | false | Description of the tool that is passed to the agent. | diff --git a/docs/en/resources/tools/postgres/postgres-execute-sql.md b/docs/en/resources/tools/postgres/postgres-execute-sql.md index 6670efcb0b..07a3847405 100644 --- a/docs/en/resources/tools/postgres/postgres-execute-sql.md +++ b/docs/en/resources/tools/postgres/postgres-execute-sql.md @@ -27,17 +27,17 @@ statement against the `source`. ## Example ```yaml -tools: - execute_sql_tool: - kind: postgres-execute-sql - source: my-pg-instance - description: Use this tool to execute sql statement. +kind: tools +name: execute_sql_tool +type: postgres-execute-sql +source: my-pg-instance +description: Use this tool to execute sql statement. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:------------------------------------------:|:------------:|--------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "postgres-execute-sql". | +| type | string | true | Must be "postgres-execute-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/postgres/postgres-get-column-cardinality.md b/docs/en/resources/tools/postgres/postgres-get-column-cardinality.md index 2563ead4f1..4cd778d19d 100644 --- a/docs/en/resources/tools/postgres/postgres-get-column-cardinality.md +++ b/docs/en/resources/tools/postgres/postgres-get-column-cardinality.md @@ -30,11 +30,11 @@ the following input parameters: ## Example ```yaml -tools: - get_column_cardinality: - kind: postgres-get-column-cardinality - source: postgres-source - description: Estimates the number of unique values (cardinality) quickly for one or all columns in a specific PostgreSQL table by using the database's internal statistics, returning the results in descending order of estimated cardinality. Please run ANALYZE on the table before using this tool to get accurate results. The tool returns the column_name and the estimated_cardinality. If the column_name is not provided, the tool returns all columns along with their estimated cardinality. +kind: tools +name: get_column_cardinality +type: postgres-get-column-cardinality +source: postgres-source +description: Estimates the number of unique values (cardinality) quickly for one or all columns in a specific PostgreSQL table by using the database's internal statistics, returning the results in descending order of estimated cardinality. Please run ANALYZE on the table before using this tool to get accurate results. The tool returns the column_name and the estimated_cardinality. If the column_name is not provided, the tool returns all columns along with their estimated cardinality. ``` The response is a json array with the following elements: @@ -58,6 +58,6 @@ to estimate cardinality. | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|------------------------------------------------------| -| kind | string | true | Must be "postgres-get-column-cardinality". | +| type | string | true | Must be "postgres-get-column-cardinality". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/postgres/postgres-list-active-queries.md b/docs/en/resources/tools/postgres/postgres-list-active-queries.md index 2184d96f70..2c533b15ba 100644 --- a/docs/en/resources/tools/postgres/postgres-list-active-queries.md +++ b/docs/en/resources/tools/postgres/postgres-list-active-queries.md @@ -33,11 +33,11 @@ active queries. The tool takes the following input parameters: ## Example ```yaml -tools: - list_active_queries: - kind: postgres-list-active-queries - source: postgres-source - description: List the top N (default 50) currently running queries (state='active') from pg_stat_activity, ordered by longest-running first. Returns pid, user, database, application_name, client_addr, state, wait_event_type/wait_event, backend/xact/query start times, computed query_duration, and the SQL text. +kind: tools +name: list_active_queries +type: postgres-list-active-queries +source: postgres-source +description: List the top N (default 50) currently running queries (state='active') from pg_stat_activity, ordered by longest-running first. Returns pid, user, database, application_name, client_addr, state, wait_event_type/wait_event, backend/xact/query start times, computed query_duration, and the SQL text. ``` The response is a json array with the following elements: @@ -64,6 +64,6 @@ The response is a json array with the following elements: | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "postgres-list-active-queries". | +| type | string | true | Must be "postgres-list-active-queries". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/postgres/postgres-list-available-extensions.md b/docs/en/resources/tools/postgres/postgres-list-available-extensions.md index dc823c78a5..cc2845baa3 100644 --- a/docs/en/resources/tools/postgres/postgres-list-available-extensions.md +++ b/docs/en/resources/tools/postgres/postgres-list-available-extensions.md @@ -26,11 +26,11 @@ not support any input parameter. ## Example ```yaml -tools: - list_available_extensions: - kind: postgres-list-available-extensions - source: postgres-source - description: Discover all PostgreSQL extensions available for installation on this server, returning name, default_version, and description. +kind: tools +name: list_available_extensions +type: postgres-list-available-extensions +source: postgres-source +description: Discover all PostgreSQL extensions available for installation on this server, returning name, default_version, and description. ``` ## Reference diff --git a/docs/en/resources/tools/postgres/postgres-list-database-stats.md b/docs/en/resources/tools/postgres/postgres-list-database-stats.md index 01537bcfa7..7d9e3f57aa 100644 --- a/docs/en/resources/tools/postgres/postgres-list-database-stats.md +++ b/docs/en/resources/tools/postgres/postgres-list-database-stats.md @@ -30,31 +30,31 @@ takes the following input parameters: ## Example ```yaml -tools: - list_database_stats: - kind: postgres-list-database-stats - source: postgres-source - description: | - Lists the key performance and activity statistics for each PostgreSQL - database in the instance, offering insights into cache efficiency, - transaction throughput row-level activity, temporary file usage, and - contention. It returns: the database name, whether the database is - connectable, database owner, default tablespace name, the percentage of - data blocks found in the buffer cache rather than being read from disk - (a higher value indicates better cache performance), the total number of - disk blocks read from disk, the total number of times disk blocks were - found already in the cache; the total number of committed transactions, - the total number of rolled back transactions, the percentage of rolled - back transactions compared to the total number of completed - transactions, the total number of rows returned by queries, the total - number of live rows fetched by scans, the total number of rows inserted, - the total number of rows updated, the total number of rows deleted, the - number of temporary files created by queries, the total size of - temporary files used by queries in bytes, the number of query - cancellations due to conflicts with recovery, the number of deadlocks - detected, the current number of active backend connections, the - timestamp when the database statistics were last reset, and the total - database size in bytes. +kind: tools +name: list_database_stats +type: postgres-list-database-stats +source: postgres-source +description: | + Lists the key performance and activity statistics for each PostgreSQL + database in the instance, offering insights into cache efficiency, + transaction throughput row-level activity, temporary file usage, and + contention. It returns: the database name, whether the database is + connectable, database owner, default tablespace name, the percentage of + data blocks found in the buffer cache rather than being read from disk + (a higher value indicates better cache performance), the total number of + disk blocks read from disk, the total number of times disk blocks were + found already in the cache; the total number of committed transactions, + the total number of rolled back transactions, the percentage of rolled + back transactions compared to the total number of completed + transactions, the total number of rows returned by queries, the total + number of live rows fetched by scans, the total number of rows inserted, + the total number of rows updated, the total number of rows deleted, the + number of temporary files created by queries, the total size of + temporary files used by queries in bytes, the number of query + cancellations due to conflicts with recovery, the number of deadlocks + detected, the current number of active backend connections, the + timestamp when the database statistics were last reset, and the total + database size in bytes. ``` The response is a json array with the following elements: @@ -90,6 +90,6 @@ The response is a json array with the following elements: | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|------------------------------------------------------| -| kind | string | true | Must be "postgres-list-database-stats". | +| type | string | true | Must be "postgres-list-database-stats". | | source | string | true | Name of the source the SQL should execute on. | | description | string | false | Description of the tool that is passed to the agent. | diff --git a/docs/en/resources/tools/postgres/postgres-list-indexes.md b/docs/en/resources/tools/postgres/postgres-list-indexes.md index f528ae97ec..590b09bb33 100644 --- a/docs/en/resources/tools/postgres/postgres-list-indexes.md +++ b/docs/en/resources/tools/postgres/postgres-list-indexes.md @@ -30,18 +30,18 @@ takes the following input parameters: ## Example ```yaml -tools: - list_indexes: - kind: postgres-list-indexes - source: postgres-source - description: | - Lists available user indexes in the database, excluding system schemas (pg_catalog, - information_schema). For each index, the following properties are returned: - schema name, table name, index name, index type (access method), a boolean - indicating if it's a unique index, a boolean indicating if it's for a primary key, - the index definition, index size in bytes, the number of index scans, the number of - index tuples read, the number of table tuples fetched via index scans, and a boolean - indicating if the index has been used at least once. +kind: tools +name: list_indexes +type: postgres-list-indexes +source: postgres-source +description: | + Lists available user indexes in the database, excluding system schemas (pg_catalog, + information_schema). For each index, the following properties are returned: + schema name, table name, index name, index type (access method), a boolean + indicating if it's a unique index, a boolean indicating if it's for a primary key, + the index definition, index size in bytes, the number of index scans, the number of + index tuples read, the number of table tuples fetched via index scans, and a boolean + indicating if the index has been used at least once. ``` The response is a json array with the following elements: @@ -67,6 +67,6 @@ The response is a json array with the following elements: | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|------------------------------------------------------| -| kind | string | true | Must be "postgres-list-indexes". | +| type | string | true | Must be "postgres-list-indexes". | | source | string | true | Name of the source the SQL should execute on. | | description | string | false | Description of the tool that is passed to the agent. | diff --git a/docs/en/resources/tools/postgres/postgres-list-installed-extensions.md b/docs/en/resources/tools/postgres/postgres-list-installed-extensions.md index d3ff4eb26f..afda5031bc 100644 --- a/docs/en/resources/tools/postgres/postgres-list-installed-extensions.md +++ b/docs/en/resources/tools/postgres/postgres-list-installed-extensions.md @@ -26,17 +26,17 @@ support any input parameter. ## Example ```yaml -tools: - list_installed_extensions: - kind: postgres-list-installed-extensions - source: postgres-source - description: List all installed PostgreSQL extensions with their name, version, schema, owner, and description. +kind: tools +name: list_installed_extensions +type: postgres-list-installed-extensions +source: postgres-source +description: List all installed PostgreSQL extensions with their name, version, schema, owner, and description. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "postgres-list-active-queries". | +| type | string | true | Must be "postgres-list-active-queries". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/postgres/postgres-list-locks.md b/docs/en/resources/tools/postgres/postgres-list-locks.md index a0d60e93d9..4b7b8c6bb2 100644 --- a/docs/en/resources/tools/postgres/postgres-list-locks.md +++ b/docs/en/resources/tools/postgres/postgres-list-locks.md @@ -49,11 +49,11 @@ GROUP BY ## Example ```yaml -tools: - list_locks: - kind: postgres-list-locks - source: postgres-source - description: "Lists active locks with associated process and query information." +kind: tools +name: list_locks +type: postgres-list-locks +source: postgres-source +description: "Lists active locks with associated process and query information." ``` Example response element (aggregated per process): diff --git a/docs/en/resources/tools/postgres/postgres-list-pg-settings.md b/docs/en/resources/tools/postgres/postgres-list-pg-settings.md index 23d5e28e92..895dbebf21 100644 --- a/docs/en/resources/tools/postgres/postgres-list-pg-settings.md +++ b/docs/en/resources/tools/postgres/postgres-list-pg-settings.md @@ -25,16 +25,16 @@ takes the following input parameters: ## Example ```yaml -tools: - list_indexes: - kind: postgres-list-pg-settings - source: postgres-source - description: | - Lists configuration parameters for the postgres server ordered lexicographically, - with a default limit of 50 rows. It returns the parameter name, its current setting, - unit of measurement, a short description, the source of the current setting (e.g., - default, configuration file, session), and whether a restart is required when the - parameter value is changed." +kind: tools +name: list_indexes +type: postgres-list-pg-settings +source: postgres-source +description: | + Lists configuration parameters for the postgres server ordered lexicographically, + with a default limit of 50 rows. It returns the parameter name, its current setting, + unit of measurement, a short description, the source of the current setting (e.g., + default, configuration file, session), and whether a restart is required when the + parameter value is changed." ``` The response is a json array with the following elements: @@ -54,6 +54,6 @@ The response is a json array with the following elements: | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|------------------------------------------------------| -| kind | string | true | Must be "postgres-list-pg-settings". | +| type | string | true | Must be "postgres-list-pg-settings". | | source | string | true | Name of the source the SQL should execute on. | | description | string | false | Description of the tool that is passed to the agent. | diff --git a/docs/en/resources/tools/postgres/postgres-list-publication-tables.md b/docs/en/resources/tools/postgres/postgres-list-publication-tables.md index a437d11783..981402aa15 100644 --- a/docs/en/resources/tools/postgres/postgres-list-publication-tables.md +++ b/docs/en/resources/tools/postgres/postgres-list-publication-tables.md @@ -28,18 +28,18 @@ of tables) as part of the logical replication feature. The tool takes the follow ## Example ```yaml -tools: - list_indexes: - kind: postgres-list-publication-tables - source: postgres-source - description: | - Lists all tables that are explicitly part of a publication in the database. - Tables that are part of a publication via 'FOR ALL TABLES' are not included, - unless they are also explicitly added to the publication. - Returns the publication name, schema name, and table name, along with - definition details indicating if it publishes all tables, whether it - replicates inserts, updates, deletes, or truncates, and the publication - owner. +kind: tools +name: list_indexes +type: postgres-list-publication-tables +source: postgres-source +description: | + Lists all tables that are explicitly part of a publication in the database. + Tables that are part of a publication via 'FOR ALL TABLES' are not included, + unless they are also explicitly added to the publication. + Returns the publication name, schema name, and table name, along with + definition details indicating if it publishes all tables, whether it + replicates inserts, updates, deletes, or truncates, and the publication + owner. ``` The response is a JSON array with the following elements: @@ -61,6 +61,6 @@ The response is a JSON array with the following elements: | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|------------------------------------------------------| -| kind | string | true | Must be "postgres-list-publication-tables". | +| type | string | true | Must be "postgres-list-publication-tables". | | source | string | true | Name of the source the SQL should execute on. | | description | string | false | Description of the tool that is passed to the agent. | diff --git a/docs/en/resources/tools/postgres/postgres-list-query-stats.md b/docs/en/resources/tools/postgres/postgres-list-query-stats.md index d6bfc9cb57..b5120cf357 100644 --- a/docs/en/resources/tools/postgres/postgres-list-query-stats.md +++ b/docs/en/resources/tools/postgres/postgres-list-query-stats.md @@ -29,11 +29,11 @@ total execution time in descending order. The tool takes the following input par ## Example ```yaml -tools: - list_query_stats: - kind: postgres-list-query-stats - source: postgres-source - description: List query statistics from pg_stat_statements, showing performance metrics for queries including execution counts, timing information, and resource usage. Results are ordered by total execution time descending. +kind: tools +name: list_query_stats +type: postgres-list-query-stats +source: postgres-source +description: List query statistics from pg_stat_statements, showing performance metrics for queries including execution counts, timing information, and resource usage. Results are ordered by total execution time descending. ``` The response is a json array with the following elements: @@ -66,6 +66,6 @@ identifying slow queries and understanding query performance patterns. | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|------------------------------------------------------| -| kind | string | true | Must be "postgres-list-query-stats". | +| type | string | true | Must be "postgres-list-query-stats". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/postgres/postgres-list-roles.md b/docs/en/resources/tools/postgres/postgres-list-roles.md index d3de6abdfb..abfaefc84e 100644 --- a/docs/en/resources/tools/postgres/postgres-list-roles.md +++ b/docs/en/resources/tools/postgres/postgres-list-roles.md @@ -26,19 +26,19 @@ takes the following input parameters: ## Example ```yaml -tools: - list_indexes: - kind: postgres-list-roles - source: postgres-source - description: | - Lists all the user-created roles in the instance . It returns the role name, - Object ID, the maximum number of concurrent connections the role can make, - along with boolean indicators for: superuser status, privilege inheritance - from member roles, ability to create roles, ability to create databases, - ability to log in, replication privilege, and the ability to bypass - row-level security, the password expiration timestamp, a list of direct - members belonging to this role, and a list of other roles/groups that this - role is a member of. +kind: tools +name: list_indexes +type: postgres-list-roles +source: postgres-source +description: | + Lists all the user-created roles in the instance . It returns the role name, + Object ID, the maximum number of concurrent connections the role can make, + along with boolean indicators for: superuser status, privilege inheritance + from member roles, ability to create roles, ability to create databases, + ability to log in, replication privilege, and the ability to bypass + row-level security, the password expiration timestamp, a list of direct + members belonging to this role, and a list of other roles/groups that this + role is a member of. ``` The response is a json array with the following elements: @@ -65,6 +65,6 @@ The response is a json array with the following elements: | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|------------------------------------------------------| -| kind | string | true | Must be "postgres-list-roles". | +| type | string | true | Must be "postgres-list-roles". | | source | string | true | Name of the source the SQL should execute on. | | description | string | false | Description of the tool that is passed to the agent. | diff --git a/docs/en/resources/tools/postgres/postgres-list-schemas.md b/docs/en/resources/tools/postgres/postgres-list-schemas.md index 6c0eb9e82a..5933085fe1 100644 --- a/docs/en/resources/tools/postgres/postgres-list-schemas.md +++ b/docs/en/resources/tools/postgres/postgres-list-schemas.md @@ -28,11 +28,11 @@ tool takes the following input parameters: ## Example ```yaml -tools: - list_schemas: - kind: postgres-list-schemas - source: postgres-source - description: "Lists all schemas in the database ordered by schema name and excluding system and temporary schemas. It returns the schema name, schema owner, grants, number of functions, number of tables and number of views within each schema." +kind: tools +name: list_schemas +type: postgres-list-schemas +source: postgres-source +description: "Lists all schemas in the database ordered by schema name and excluding system and temporary schemas. It returns the schema name, schema owner, grants, number of functions, number of tables and number of views within each schema." ``` The response is a json array with the following elements: @@ -52,6 +52,6 @@ The response is a json array with the following elements: | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "postgres-list-schemas". | +| type | string | true | Must be "postgres-list-schemas". | | source | string | true | Name of the source the SQL should execute on. | | description | string | false | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/postgres/postgres-list-sequences.md b/docs/en/resources/tools/postgres/postgres-list-sequences.md index e51915525a..3f5efe853b 100644 --- a/docs/en/resources/tools/postgres/postgres-list-sequences.md +++ b/docs/en/resources/tools/postgres/postgres-list-sequences.md @@ -29,16 +29,16 @@ The tool takes the following input parameters: ## Example ```yaml -tools: - list_indexes: - kind: postgres-list-sequences - source: postgres-source - description: | - Lists all the sequences in the database ordered by sequence name. - Returns sequence name, schema name, sequence owner, data type of the - sequence, starting value, minimum value, maximum value of the sequence, - the value by which the sequence is incremented, and the last value - generated by generated by the sequence in the current session. +kind: tools +name: list_indexes +type: postgres-list-sequences +source: postgres-source +description: | + Lists all the sequences in the database ordered by sequence name. + Returns sequence name, schema name, sequence owner, data type of the + sequence, starting value, minimum value, maximum value of the sequence, + the value by which the sequence is incremented, and the last value + generated by generated by the sequence in the current session. ``` The response is a json array with the following elements: @@ -61,6 +61,6 @@ The response is a json array with the following elements: | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|------------------------------------------------------| -| kind | string | true | Must be "postgres-list-sequences". | +| type | string | true | Must be "postgres-list-sequences". | | source | string | true | Name of the source the SQL should execute on. | | description | string | false | Description of the tool that is passed to the agent. | diff --git a/docs/en/resources/tools/postgres/postgres-list-stored-procedure.md b/docs/en/resources/tools/postgres/postgres-list-stored-procedure.md index ec03365e55..cd6a86aa1f 100644 --- a/docs/en/resources/tools/postgres/postgres-list-stored-procedure.md +++ b/docs/en/resources/tools/postgres/postgres-list-stored-procedure.md @@ -31,11 +31,11 @@ The tool returns a JSON array where each element represents a stored procedure w ## Example ```yaml -tools: - list_stored_procedure: - kind: postgres-list-stored-procedure - source: postgres-source - description: "Retrieves stored procedure metadata including definitions and owners." +kind: tools +name: list_stored_procedure +type: postgres-list-stored-procedure +source: postgres-source +description: "Retrieves stored procedure metadata including definitions and owners." ``` ### Example Requests diff --git a/docs/en/resources/tools/postgres/postgres-list-table-stats.md b/docs/en/resources/tools/postgres/postgres-list-table-stats.md index 666a126aca..cecc8b81d8 100644 --- a/docs/en/resources/tools/postgres/postgres-list-table-stats.md +++ b/docs/en/resources/tools/postgres/postgres-list-table-stats.md @@ -23,11 +23,11 @@ The tool returns a JSON array where each element represents statistics for a tab ## Example ```yaml -tools: - list_table_stats: - kind: postgres-list-table-stats - source: postgres-source - description: "Lists table statistics including size, scans, and bloat metrics." +kind: tools +name: list_table_stats +type: postgres-list-table-stats +source: postgres-source +description: "Lists table statistics including size, scans, and bloat metrics." ``` ### Example Requests diff --git a/docs/en/resources/tools/postgres/postgres-list-tables.md b/docs/en/resources/tools/postgres/postgres-list-tables.md index f40076bd49..04f56cbfaf 100644 --- a/docs/en/resources/tools/postgres/postgres-list-tables.md +++ b/docs/en/resources/tools/postgres/postgres-list-tables.md @@ -31,18 +31,18 @@ constraints, indexes, triggers, owner, comment) as JSON for user-created tables ## Example ```yaml -tools: - postgres_list_tables: - kind: postgres-list-tables - source: postgres-source - description: Use this tool to retrieve schema information for all or - specified tables. Output format can be simple (only table names) or detailed. +kind: tools +name: postgres_list_tables +type: postgres-list-tables +source: postgres-source +description: Use this tool to retrieve schema information for all or + specified tables. Output format can be simple (only table names) or detailed. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|------------------------------------------------------| -| kind | string | true | Must be "postgres-list-tables". | +| type | string | true | Must be "postgres-list-tables". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the agent. | diff --git a/docs/en/resources/tools/postgres/postgres-list-tablespaces.md b/docs/en/resources/tools/postgres/postgres-list-tablespaces.md index bf63f61b8f..5e78bf5cbe 100644 --- a/docs/en/resources/tools/postgres/postgres-list-tablespaces.md +++ b/docs/en/resources/tools/postgres/postgres-list-tablespaces.md @@ -24,15 +24,15 @@ The `postgres-list-tablespaces` tool lists available tablespaces in the database ## Example ```yaml -tools: - list_tablespaces: - kind: postgres-list-tablespaces - source: postgres-source - description: | - Lists all tablespaces in the database. Returns the tablespace name, - owner name, size in bytes(if the current user has CREATE privileges on - the tablespace, otherwise NULL), internal object ID, the access control - list regarding permissions, and any specific tablespace options. +kind: tools +name: list_tablespaces +type: postgres-list-tablespaces +source: postgres-source +description: | + Lists all tablespaces in the database. Returns the tablespace name, + owner name, size in bytes(if the current user has CREATE privileges on + the tablespace, otherwise NULL), internal object ID, the access control + list regarding permissions, and any specific tablespace options. ``` The response is a json array with the following elements: @@ -51,6 +51,6 @@ The response is a json array with the following elements: | **field** | **type** | **required** | **description** | |-------------|:--------:|:-------------:|------------------------------------------------------| -| kind | string | true | Must be "postgres-list-tablespaces". | +| type | string | true | Must be "postgres-list-tablespaces". | | source | string | true | Name of the source the SQL should execute on. | | description | string | false | Description of the tool that is passed to the agent. | diff --git a/docs/en/resources/tools/postgres/postgres-list-triggers.md b/docs/en/resources/tools/postgres/postgres-list-triggers.md index b270894001..5c93e6fc50 100644 --- a/docs/en/resources/tools/postgres/postgres-list-triggers.md +++ b/docs/en/resources/tools/postgres/postgres-list-triggers.md @@ -31,13 +31,12 @@ tool takes the following input parameters: ## Example ```yaml -```yaml -tools: - list_triggers: - kind: postgres-list-triggers - source: postgres-source - description: | - Lists all non-internal triggers in a database. Returns trigger name, schema name, table name, wether its enabled or disabled, timing (e.g BEFORE/AFTER of the event), the events that cause the trigger to fire such as INSERT, UPDATE, or DELETE, whether the trigger activates per ROW or per STATEMENT, the handler function executed by the trigger and full definition. +kind: tools +name: list_triggers +type: postgres-list-triggers +source: postgres-source +description: | + Lists all non-internal triggers in a database. Returns trigger name, schema name, table name, wether its enabled or disabled, timing (e.g BEFORE/AFTER of the event), the events that cause the trigger to fire such as INSERT, UPDATE, or DELETE, whether the trigger activates per ROW or per STATEMENT, the handler function executed by the trigger and full definition. ``` The response is a json array with the following elements: @@ -60,6 +59,6 @@ The response is a json array with the following elements: | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|------------------------------------------------------| -| kind | string | true | Must be "postgres-list-triggers". | +| type | string | true | Must be "postgres-list-triggers". | | source | string | true | Name of the source the SQL should execute on. | | description | string | false | Description of the tool that is passed to the agent. | diff --git a/docs/en/resources/tools/postgres/postgres-list-views.md b/docs/en/resources/tools/postgres/postgres-list-views.md index b6f1687f33..a99b092276 100644 --- a/docs/en/resources/tools/postgres/postgres-list-views.md +++ b/docs/en/resources/tools/postgres/postgres-list-views.md @@ -29,16 +29,16 @@ parameters: ## Example ```yaml -tools: - list_views: - kind: postgres-list-views - source: cloudsql-pg-source +kind: tools +name: list_views +type: postgres-list-views +source: cloudsql-pg-source ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|------------------------------------------------------| -| kind | string | true | Must be "postgres-list-views". | +| type | string | true | Must be "postgres-list-views". | | source | string | true | Name of the source the SQL should execute on. | | description | string | false | Description of the tool that is passed to the agent. | diff --git a/docs/en/resources/tools/postgres/postgres-long-running-transactions.md b/docs/en/resources/tools/postgres/postgres-long-running-transactions.md index 0380ca7c21..fc264bb6ee 100644 --- a/docs/en/resources/tools/postgres/postgres-long-running-transactions.md +++ b/docs/en/resources/tools/postgres/postgres-long-running-transactions.md @@ -60,11 +60,11 @@ LIMIT ## Example ```yaml -tools: - long_running_transactions: - kind: postgres-long-running-transactions - source: postgres-source - description: "Identifies transactions open longer than a threshold and returns details including query text and durations." +kind: tools +name: long_running_transactions +type: postgres-long-running-transactions +source: postgres-source +description: "Identifies transactions open longer than a threshold and returns details including query text and durations." ``` Example response element: diff --git a/docs/en/resources/tools/postgres/postgres-replication-stats.md b/docs/en/resources/tools/postgres/postgres-replication-stats.md index c9dfdc81cb..b257753955 100644 --- a/docs/en/resources/tools/postgres/postgres-replication-stats.md +++ b/docs/en/resources/tools/postgres/postgres-replication-stats.md @@ -23,11 +23,11 @@ This tool takes no parameters. It returns a JSON array; each element represents ## Example ```yaml -tools: - replication_stats: - kind: postgres-replication-stats - source: postgres-source - description: "Lists replication connections and readable WAL lag metrics." +kind: tools +name: replication_stats +type: postgres-replication-stats +source: postgres-source +description: "Lists replication connections and readable WAL lag metrics." ``` Example response element: diff --git a/docs/en/resources/tools/postgres/postgres-sql.md b/docs/en/resources/tools/postgres/postgres-sql.md index 190f9478e3..067386b957 100644 --- a/docs/en/resources/tools/postgres/postgres-sql.md +++ b/docs/en/resources/tools/postgres/postgres-sql.md @@ -34,41 +34,41 @@ of the prepared statement. > names, or other parts of the query. ```yaml -tools: - search_flights_by_number: - kind: postgres-sql - source: my-pg-instance - statement: | - SELECT * FROM flights - WHERE airline = $1 - AND flight_number = $2 - LIMIT 10 - description: | - Use this tool to get information for a specific flight. - Takes an airline code and flight number and returns info on the flight. - Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. - A airline code is a code for an airline service consisting of two-character - airline designator and followed by flight number, which is 1 to 4 digit number. - For example, if given CY 0123, the airline is "CY", and flight_number is "123". - Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". - If the tool returns more than one option choose the date closes to today. - Example: - {{ - "airline": "CY", - "flight_number": "888", - }} - Example: - {{ - "airline": "DL", - "flight_number": "1234", - }} - parameters: - - name: airline - type: string - description: Airline unique 2 letter identifier - - name: flight_number - type: string - description: 1 to 4 digit number +kind: tools +name: search_flights_by_number +type: postgres-sql +source: my-pg-instance +statement: | + SELECT * FROM flights + WHERE airline = $1 + AND flight_number = $2 + LIMIT 10 +description: | + Use this tool to get information for a specific flight. + Takes an airline code and flight number and returns info on the flight. + Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. + A airline code is a code for an airline service consisting of two-character + airline designator and followed by flight number, which is 1 to 4 digit number. + For example, if given CY 0123, the airline is "CY", and flight_number is "123". + Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". + If the tool returns more than one option choose the date closes to today. + Example: + {{ + "airline": "CY", + "flight_number": "888", + }} + Example: + {{ + "airline": "DL", + "flight_number": "1234", + }} +parameters: + - name: airline + type: string + description: Airline unique 2 letter identifier + - name: flight_number + type: string + description: 1 to 4 digit number ``` ### Example with Template Parameters @@ -80,29 +80,29 @@ tools: > [templateParameters](..#template-parameters). ```yaml -tools: - list_table: - kind: postgres-sql - source: my-pg-instance - statement: | - SELECT * FROM {{.tableName}} - description: | - Use this tool to list all information from a specific table. - Example: - {{ - "tableName": "flights", - }} - templateParameters: - - name: tableName - type: string - description: Table to select from +kind: tools +name: list_table +type: postgres-sql +source: my-pg-instance +statement: | + SELECT * FROM {{.tableName}} +description: | + Use this tool to list all information from a specific table. + Example: + {{ + "tableName": "flights", + }} +templateParameters: + - name: tableName + type: string + description: Table to select from ``` ## Reference | **field** | **type** | **required** | **description** | |--------------------|:--------------------------------------------:|:------------:|----------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "postgres-sql". | +| type | string | true | Must be "postgres-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | statement | string | true | SQL statement to execute on. | diff --git a/docs/en/resources/tools/redis/redis.md b/docs/en/resources/tools/redis/redis.md index 53dc344d6a..fade388416 100644 --- a/docs/en/resources/tools/redis/redis.md +++ b/docs/en/resources/tools/redis/redis.md @@ -42,21 +42,21 @@ to be executed after argument expansion will be `[SADD, userNames, Alice, Sid, B ## Example ```yaml -tools: - user_data_tool: - kind: redis - source: my-redis-instance - description: | - Use this tool to interact with user data stored in Redis. - It can set, retrieve, and delete user-specific information. - commands: - - [SADD, userNames, $userNames] # Array will be flattened into multiple arguments. - - [GET, $userId] - parameters: - - name: userId - type: string - description: The unique identifier for the user. - - name: userNames - type: array - description: The user names to be set. +kind: tools +name: user_data_tool +type: redis +source: my-redis-instance +description: | + Use this tool to interact with user data stored in Redis. + It can set, retrieve, and delete user-specific information. +commands: + - [SADD, userNames, $userNames] # Array will be flattened into multiple arguments. + - [GET, $userId] +parameters: + - name: userId + type: string + description: The unique identifier for the user. + - name: userNames + type: array + description: The user names to be set. ``` diff --git a/docs/en/resources/tools/serverless-spark/serverless-spark-cancel-batch.md b/docs/en/resources/tools/serverless-spark/serverless-spark-cancel-batch.md index 7af6f05ed4..61fa321170 100644 --- a/docs/en/resources/tools/serverless-spark/serverless-spark-cancel-batch.md +++ b/docs/en/resources/tools/serverless-spark/serverless-spark-cancel-batch.md @@ -30,11 +30,11 @@ The tool inherits the `project` and `location` from the source configuration. ## Example ```yaml -tools: - cancel_spark_batch: - kind: serverless-spark-cancel-batch - source: my-serverless-spark-source - description: Use this tool to cancel a running serverless spark batch operation. +kind: tools +name: cancel_spark_batch +type: serverless-spark-cancel-batch +source: my-serverless-spark-source +description: Use this tool to cancel a running serverless spark batch operation. ``` ## Response Format @@ -47,7 +47,7 @@ tools: | **field** | **type** | **required** | **description** | | ------------ | :------: | :----------: | -------------------------------------------------- | -| kind | string | true | Must be "serverless-spark-cancel-batch". | +| type | string | true | Must be "serverless-spark-cancel-batch". | | source | string | true | Name of the source the tool should use. | | description | string | true | Description of the tool that is passed to the LLM. | | authRequired | string[] | false | List of auth services required to invoke this tool | diff --git a/docs/en/resources/tools/serverless-spark/serverless-spark-create-pyspark-batch.md b/docs/en/resources/tools/serverless-spark/serverless-spark-create-pyspark-batch.md index b94d386b2d..e0d2a5c097 100644 --- a/docs/en/resources/tools/serverless-spark/serverless-spark-create-pyspark-batch.md +++ b/docs/en/resources/tools/serverless-spark/serverless-spark-create-pyspark-batch.md @@ -43,16 +43,16 @@ prebuilt config. ### Example `tools.yaml` ```yaml -tools: - - name: "serverless-spark-create-pyspark-batch" - kind: "serverless-spark-create-pyspark-batch" - source: "my-serverless-spark-source" - runtimeConfig: - properties: - spark.driver.memory: "1024m" - environmentConfig: - executionConfig: - networkUri: "my-network" +kind: tools +name: serverless-spark-create-pyspark-batch +type: serverless-spark-create-pyspark-batch +source: "my-serverless-spark-source" +runtimeConfig: + properties: + spark.driver.memory: "1024m" +environmentConfig: + executionConfig: + networkUri: "my-network" ``` ## Response Format @@ -89,7 +89,7 @@ detailed information. | **field** | **type** | **required** | **description** | | ----------------- | :------: | :----------: | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -| kind | string | true | Must be "serverless-spark-create-pyspark-batch". | +| type | string | true | Must be "serverless-spark-create-pyspark-batch". | | source | string | true | Name of the source the tool should use. | | description | string | false | Description of the tool that is passed to the LLM. | | runtimeConfig | map | false | [Runtime config](https://docs.cloud.google.com/dataproc-serverless/docs/reference/rest/v1/RuntimeConfig) for all batches created with this tool. | diff --git a/docs/en/resources/tools/serverless-spark/serverless-spark-create-spark-batch.md b/docs/en/resources/tools/serverless-spark/serverless-spark-create-spark-batch.md index 8264be00b0..46a0b87292 100644 --- a/docs/en/resources/tools/serverless-spark/serverless-spark-create-spark-batch.md +++ b/docs/en/resources/tools/serverless-spark/serverless-spark-create-spark-batch.md @@ -48,16 +48,16 @@ prebuilt config. ### Example `tools.yaml` ```yaml -tools: - - name: "serverless-spark-create-spark-batch" - kind: "serverless-spark-create-spark-batch" - source: "my-serverless-spark-source" - runtimeConfig: - properties: - spark.driver.memory: "1024m" - environmentConfig: - executionConfig: - networkUri: "my-network" +kind: tools +name: "serverless-spark-create-spark-batch" +type: "serverless-spark-create-spark-batch" +source: "my-serverless-spark-source" +runtimeConfig: + properties: + spark.driver.memory: "1024m" +environmentConfig: + executionConfig: + networkUri: "my-network" ``` ## Response Format @@ -94,7 +94,7 @@ detailed information. | **field** | **type** | **required** | **description** | | ----------------- | :------: | :----------: | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -| kind | string | true | Must be "serverless-spark-create-spark-batch". | +| type | string | true | Must be "serverless-spark-create-spark-batch". | | source | string | true | Name of the source the tool should use. | | description | string | false | Description of the tool that is passed to the LLM. | | runtimeConfig | map | false | [Runtime config](https://docs.cloud.google.com/dataproc-serverless/docs/reference/rest/v1/RuntimeConfig) for all batches created with this tool. | diff --git a/docs/en/resources/tools/serverless-spark/serverless-spark-get-batch.md b/docs/en/resources/tools/serverless-spark/serverless-spark-get-batch.md index 754aab9fd9..a43d6fdb04 100644 --- a/docs/en/resources/tools/serverless-spark/serverless-spark-get-batch.md +++ b/docs/en/resources/tools/serverless-spark/serverless-spark-get-batch.md @@ -25,11 +25,11 @@ The tool gets the `project` and `location` from the source configuration. ## Example ```yaml -tools: - get_my_batch: - kind: serverless-spark-get-batch - source: my-serverless-spark-source - description: Use this tool to get a serverless spark batch. +kind: tools +name: get_my_batch +type: serverless-spark-get-batch +source: my-serverless-spark-source +description: Use this tool to get a serverless spark batch. ``` ## Response Format @@ -85,7 +85,7 @@ detailed information. | **field** | **type** | **required** | **description** | | ------------ | :------: | :----------: | -------------------------------------------------- | -| kind | string | true | Must be "serverless-spark-get-batch". | +| type | string | true | Must be "serverless-spark-get-batch". | | source | string | true | Name of the source the tool should use. | | description | string | true | Description of the tool that is passed to the LLM. | | authRequired | string[] | false | List of auth services required to invoke this tool | diff --git a/docs/en/resources/tools/serverless-spark/serverless-spark-list-batches.md b/docs/en/resources/tools/serverless-spark/serverless-spark-list-batches.md index 9f0e5f0e7c..7a74006084 100644 --- a/docs/en/resources/tools/serverless-spark/serverless-spark-list-batches.md +++ b/docs/en/resources/tools/serverless-spark/serverless-spark-list-batches.md @@ -33,11 +33,11 @@ The tool gets the `project` and `location` from the source configuration. ## Example ```yaml -tools: - list_spark_batches: - kind: serverless-spark-list-batches - source: my-serverless-spark-source - description: Use this tool to list and filter serverless spark batches. +kind: tools +name: list_spark_batches +type: serverless-spark-list-batches +source: my-serverless-spark-source +description: Use this tool to list and filter serverless spark batches. ``` ## Response Format @@ -72,7 +72,7 @@ tools: | **field** | **type** | **required** | **description** | | ------------ | :------: | :----------: | -------------------------------------------------- | -| kind | string | true | Must be "serverless-spark-list-batches". | +| type | string | true | Must be "serverless-spark-list-batches". | | source | string | true | Name of the source the tool should use. | | description | string | true | Description of the tool that is passed to the LLM. | | authRequired | string[] | false | List of auth services required to invoke this tool | diff --git a/docs/en/resources/tools/singlestore/singlestore-execute-sql.md b/docs/en/resources/tools/singlestore/singlestore-execute-sql.md index c4c007eaf1..fc2e9fbf55 100644 --- a/docs/en/resources/tools/singlestore/singlestore-execute-sql.md +++ b/docs/en/resources/tools/singlestore/singlestore-execute-sql.md @@ -25,17 +25,17 @@ statement against the `source`. ## Example ```yaml -tools: - execute_sql_tool: - kind: singlestore-execute-sql - source: my-s2-instance - description: Use this tool to execute sql statement +kind: tools +name: execute_sql_tool +type: singlestore-execute-sql +source: my-s2-instance +description: Use this tool to execute sql statement ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "singlestore-execute-sql". | +| type | string | true | Must be "singlestore-execute-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/singlestore/singlestore-sql.md b/docs/en/resources/tools/singlestore/singlestore-sql.md index c745e2d9f3..885fbc959f 100644 --- a/docs/en/resources/tools/singlestore/singlestore-sql.md +++ b/docs/en/resources/tools/singlestore/singlestore-sql.md @@ -27,41 +27,41 @@ form of placeholders `?`. > names, or other parts of the query. ```yaml -tools: - search_flights_by_number: - kind: singlestore-sql - source: my-s2-instance - statement: | - SELECT * FROM flights - WHERE airline = ? - AND flight_number = ? - LIMIT 10 - description: | - Use this tool to get information for a specific flight. - Takes an airline code and flight number and returns info on the flight. - Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. - A airline code is a code for an airline service consisting of two-character - airline designator and followed by flight number, which is 1 to 4 digit number. - For example, if given CY 0123, the airline is "CY", and flight_number is "123". - Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". - If the tool returns more than one option choose the date closes to today. - Example: - {{ - "airline": "CY", - "flight_number": "888", - }} - Example: - {{ - "airline": "DL", - "flight_number": "1234", - }} - parameters: - - name: airline - type: string - description: Airline unique 2 letter identifier - - name: flight_number - type: string - description: 1 to 4 digit number +kind: tools +name: search_flights_by_number +type: singlestore-sql +source: my-s2-instance +statement: | + SELECT * FROM flights + WHERE airline = ? + AND flight_number = ? + LIMIT 10 +description: | + Use this tool to get information for a specific flight. + Takes an airline code and flight number and returns info on the flight. + Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. + A airline code is a code for an airline service consisting of two-character + airline designator and followed by flight number, which is 1 to 4 digit number. + For example, if given CY 0123, the airline is "CY", and flight_number is "123". + Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". + If the tool returns more than one option choose the date closes to today. + Example: + {{ + "airline": "CY", + "flight_number": "888", + }} + Example: + {{ + "airline": "DL", + "flight_number": "1234", + }} +parameters: + - name: airline + type: string + description: Airline unique 2 letter identifier + - name: flight_number + type: string + description: 1 to 4 digit number ``` ### Example with Template Parameters @@ -73,29 +73,29 @@ tools: > [templateParameters](..#template-parameters). ```yaml -tools: - list_table: - kind: singlestore-sql - source: my-s2-instance - statement: | - SELECT * FROM {{.tableName}}; - description: | - Use this tool to list all information from a specific table. - Example: - {{ - "tableName": "flights", - }} - templateParameters: - - name: tableName - type: string - description: Table to select from +kind: tools +name: list_table +type: singlestore-sql +source: my-s2-instance +statement: | + SELECT * FROM {{.tableName}}; +description: | + Use this tool to list all information from a specific table. + Example: + {{ + "tableName": "flights", + }} +templateParameters: + - name: tableName + type: string + description: Table to select from ``` ## Reference | **field** | **type** | **required** | **description** | |--------------------|:--------------------------------------------:|:------------:|----------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "singlestore-sql". | +| type | string | true | Must be "singlestore-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | statement | string | true | SQL statement to execute on. | diff --git a/docs/en/resources/tools/snowflake/snowflake-execute-sql.md b/docs/en/resources/tools/snowflake/snowflake-execute-sql.md index 1d6af931bd..b5af0fe63f 100644 --- a/docs/en/resources/tools/snowflake/snowflake-execute-sql.md +++ b/docs/en/resources/tools/snowflake/snowflake-execute-sql.md @@ -23,18 +23,18 @@ statement against the `source`. ## Example ```yaml -tools: - execute_sql_tool: - kind: snowflake-execute-sql - source: my-snowflake-instance - description: Use this tool to execute sql statement. +kind: tools +name: execute_sql_tool +type: snowflake-execute-sql +source: my-snowflake-instance +description: Use this tool to execute sql statement. ``` ## Reference | **field** | **type** | **required** | **description** | |--------------|:-------------:|:------------:|-----------------------------------------------------------| -| kind | string | true | Must be "snowflake-execute-sql". | +| type | string | true | Must be "snowflake-execute-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | authRequired | array[string] | false | List of auth services that are required to use this tool. | diff --git a/docs/en/resources/tools/snowflake/snowflake-sql.md b/docs/en/resources/tools/snowflake/snowflake-sql.md index d55241e32f..b66041cac5 100644 --- a/docs/en/resources/tools/snowflake/snowflake-sql.md +++ b/docs/en/resources/tools/snowflake/snowflake-sql.md @@ -26,41 +26,41 @@ first parameter specified, `:2` will be the second parameter, and so on. ## Example ```yaml -tools: - search_flights_by_number: - kind: snowflake-sql - source: my-snowflake-instance - statement: | - SELECT * FROM flights - WHERE airline = :1 - AND flight_number = :2 - LIMIT 10 - description: | - Use this tool to get information for a specific flight. - Takes an airline code and flight number and returns info on the flight. - Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. - A airline code is a code for an airline service consisting of two-character - airline designator and followed by flight number, which is 1 to 4 digit number. - For example, if given CY 0123, the airline is "CY", and flight_number is "123". - Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". - If the tool returns more than one option choose the date closes to today. - Example: - {{ - "airline": "CY", - "flight_number": "888", - }} - Example: - {{ - "airline": "DL", - "flight_number": "1234", - }} - parameters: - - name: airline - type: string - description: Airline unique 2 letter identifier - - name: flight_number - type: string - description: 1 to 4 digit number +kind: tools +name: search_flights_by_number +type: snowflake-sql +source: my-snowflake-instance +statement: | + SELECT * FROM flights + WHERE airline = :1 + AND flight_number = :2 + LIMIT 10 +description: | + Use this tool to get information for a specific flight. + Takes an airline code and flight number and returns info on the flight. + Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. + A airline code is a code for an airline service consisting of two-character + airline designator and followed by flight number, which is 1 to 4 digit number. + For example, if given CY 0123, the airline is "CY", and flight_number is "123". + Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". + If the tool returns more than one option choose the date closes to today. + Example: + {{ + "airline": "CY", + "flight_number": "888", + }} + Example: + {{ + "airline": "DL", + "flight_number": "1234", + }} +parameters: + - name: airline + type: string + description: Airline unique 2 letter identifier + - name: flight_number + type: string + description: 1 to 4 digit number ``` ### Example with Template Parameters @@ -72,29 +72,29 @@ tools: > [templateParameters](..#template-parameters). ```yaml -tools: - list_table: - kind: snowflake - source: my-snowflake-instance - statement: | - SELECT * FROM {{.tableName}}; - description: | - Use this tool to list all information from a specific table. - Example: - {{ - "tableName": "flights", - }} - templateParameters: - - name: tableName - type: string - description: Table to select from +kind: tools +name: list_table +type: snowflake +source: my-snowflake-instance +statement: | + SELECT * FROM {{.tableName}}; +description: | + Use this tool to list all information from a specific table. + Example: + {{ + "tableName": "flights", + }} +templateParameters: + - name: tableName + type: string + description: Table to select from ``` ## Reference | **field** | **type** | **required** | **description** | |--------------------|:--------------------------------------------:|:------------:|----------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "snowflake-sql". | +| type | string | true | Must be "snowflake-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | statement | string | true | SQL statement to execute on. | diff --git a/docs/en/resources/tools/spanner/spanner-execute-sql.md b/docs/en/resources/tools/spanner/spanner-execute-sql.md index b04e90e34e..b9e5c6c255 100644 --- a/docs/en/resources/tools/spanner/spanner-execute-sql.md +++ b/docs/en/resources/tools/spanner/spanner-execute-sql.md @@ -25,18 +25,18 @@ statement against the `source`. ## Example ```yaml -tools: - execute_sql_tool: - kind: spanner-execute-sql - source: my-spanner-instance - description: Use this tool to execute sql statement. +kind: tools +name: execute_sql_tool +type: spanner-execute-sql +source: my-spanner-instance +description: Use this tool to execute sql statement. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|------------------------------------------------------------------------------------------| -| kind | string | true | Must be "spanner-execute-sql". | +| type | string | true | Must be "spanner-execute-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | readOnly | bool | false | When set to `true`, the `statement` is run as a read-only transaction. Default: `false`. | diff --git a/docs/en/resources/tools/spanner/spanner-list-graphs.md b/docs/en/resources/tools/spanner/spanner-list-graphs.md index e846fdfe77..7d8ae63fbc 100644 --- a/docs/en/resources/tools/spanner/spanner-list-graphs.md +++ b/docs/en/resources/tools/spanner/spanner-list-graphs.md @@ -35,35 +35,35 @@ source dialect, as Spanner Graph isn't available in the PostgreSQL dialect. ### Basic Usage - List All Graphs ```yaml -sources: - my-spanner-db: - kind: spanner - project: ${SPANNER_PROJECT} - instance: ${SPANNER_INSTANCE} - database: ${SPANNER_DATABASE} - dialect: googlesql # wont work for postgresql - -tools: - list_all_graphs: - kind: spanner-list-graphs - source: my-spanner-db - description: Lists all graphs with their complete schema information +kind: sources +name: my-spanner-db +type: spanner +project: ${SPANNER_PROJECT} +instance: ${SPANNER_INSTANCE} +database: ${SPANNER_DATABASE} +dialect: googlesql # wont work for postgresql +--- +kind: tools +name: list_all_graphs +type: spanner-list-graphs +source: my-spanner-db +description: Lists all graphs with their complete schema information ``` ### List Specific Graphs ```yaml -tools: - list_specific_graphs: - kind: spanner-list-graphs - source: my-spanner-db - description: | - Lists schema information for specific graphs. - Example usage: - { - "graph_names": "FinGraph,SocialGraph", - "output_format": "detailed" - } +kind: tools +name: list_specific_graphs +type: spanner-list-graphs +source: my-spanner-db +description: | + Lists schema information for specific graphs. + Example usage: + { + "graph_names": "FinGraph,SocialGraph", + "output_format": "detailed" + } ``` ## Parameters @@ -235,36 +235,36 @@ comprehensive schema information: ## Example with Agent Integration ```yaml -sources: - spanner-db: - kind: spanner - project: my-project - instance: my-instance - database: my-database - dialect: googlesql - -tools: - schema_inspector: - kind: spanner-list-graphs - source: spanner-db - description: | - Use this tool to inspect database schema information. - You can: - - List all graphs by leaving graph_names empty - - Get specific graph schemas by providing comma-separated graph names - - Choose between simple (names only) or detailed (full schema) output - - Examples: - 1. List all graphs with details: {"output_format": "detailed"} - 2. Get specific graphs: {"graph_names": "FinGraph,SocialGraph", "output_format": "detailed"} - 3. Just get graph names: {"output_format": "simple"} +kind: sources +name: spanner-db +type: spanner +project: my-project +instance: my-instance +database: my-database +dialect: googlesql +--- +kind: tools +name: schema_inspector +type: spanner-list-graphs +source: spanner-db +description: | + Use this tool to inspect database schema information. + You can: + - List all graphs by leaving graph_names empty + - Get specific graph schemas by providing comma-separated graph names + - Choose between simple (names only) or detailed (full schema) output + + Examples: + 1. List all graphs with details: {"output_format": "detailed"} + 2. Get specific graphs: {"graph_names": "FinGraph,SocialGraph", "output_format": "detailed"} + 3. Just get graph names: {"output_format": "simple"} ``` ## Reference | **field** | **type** | **required** | **description** | |--------------|:--------:|:------------:|-----------------------------------------------------------------| -| kind | string | true | Must be "spanner-list-graphs" | +| type | string | true | Must be "spanner-list-graphs" | | source | string | true | Name of the Spanner source to query (dialect must be GoogleSQL) | | description | string | false | Description of the tool that is passed to the LLM | | authRequired | string[] | false | List of auth services required to invoke this tool | diff --git a/docs/en/resources/tools/spanner/spanner-list-tables.md b/docs/en/resources/tools/spanner/spanner-list-tables.md index 3a7f6ea48a..d1b196fa9c 100644 --- a/docs/en/resources/tools/spanner/spanner-list-tables.md +++ b/docs/en/resources/tools/spanner/spanner-list-tables.md @@ -36,35 +36,35 @@ syntax. ### Basic Usage - List All Tables ```yaml -sources: - my-spanner-db: - kind: spanner - project: ${SPANNER_PROJECT} - instance: ${SPANNER_INSTANCE} - database: ${SPANNER_DATABASE} - dialect: googlesql # or postgresql - -tools: - list_all_tables: - kind: spanner-list-tables - source: my-spanner-db - description: Lists all tables with their complete schema information +kind: sources +name: my-spanner-db +type: spanner +project: ${SPANNER_PROJECT} +instance: ${SPANNER_INSTANCE} +database: ${SPANNER_DATABASE} +dialect: googlesql # or postgresql +--- +kind: tools +name: list_all_tables +type: spanner-list-tables +source: my-spanner-db +description: Lists all tables with their complete schema information ``` ### List Specific Tables ```yaml -tools: - list_specific_tables: - kind: spanner-list-tables - source: my-spanner-db - description: | - Lists schema information for specific tables. - Example usage: - { - "table_names": "users,orders,products", - "output_format": "detailed" - } +kind: tools +name: list_specific_tables +type: spanner-list-tables +source: my-spanner-db +description: | + Lists schema information for specific tables. + Example usage: + { + "table_names": "users,orders,products", + "output_format": "detailed" + } ``` ## Parameters @@ -177,36 +177,36 @@ comprehensive schema information: ## Example with Agent Integration ```yaml -sources: - spanner-db: - kind: spanner - project: my-project - instance: my-instance - database: my-database - dialect: googlesql - -tools: - schema_inspector: - kind: spanner-list-tables - source: spanner-db - description: | - Use this tool to inspect database schema information. - You can: - - List all tables by leaving table_names empty - - Get specific table schemas by providing comma-separated table names - - Choose between simple (names only) or detailed (full schema) output - - Examples: - 1. List all tables with details: {"output_format": "detailed"} - 2. Get specific tables: {"table_names": "users,orders", "output_format": "detailed"} - 3. Just get table names: {"output_format": "simple"} +kind: sources +name: spanner-db +type: spanner +project: my-project +instance: my-instance +database: my-database +dialect: googlesql +--- +kind: tools +name: schema_inspector +type: spanner-list-tables +source: spanner-db +description: | + Use this tool to inspect database schema information. + You can: + - List all tables by leaving table_names empty + - Get specific table schemas by providing comma-separated table names + - Choose between simple (names only) or detailed (full schema) output + + Examples: + 1. List all tables with details: {"output_format": "detailed"} + 2. Get specific tables: {"table_names": "users,orders", "output_format": "detailed"} + 3. Just get table names: {"output_format": "simple"} ``` ## Reference | **field** | **type** | **required** | **description** | |--------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "spanner-list-tables" | +| type | string | true | Must be "spanner-list-tables" | | source | string | true | Name of the Spanner source to query | | description | string | false | Description of the tool that is passed to the LLM | | authRequired | string[] | false | List of auth services required to invoke this tool | diff --git a/docs/en/resources/tools/spanner/spanner-sql.md b/docs/en/resources/tools/spanner/spanner-sql.md index edf21254b4..221ecc7288 100644 --- a/docs/en/resources/tools/spanner/spanner-sql.md +++ b/docs/en/resources/tools/spanner/spanner-sql.md @@ -50,80 +50,80 @@ the second parameter, and so on. {{< tabpane persist="header" >}} {{< tab header="GoogleSQL" lang="yaml" >}} -tools: - search_flights_by_number: - kind: spanner-sql - source: my-spanner-instance - statement: | - SELECT * FROM flights - WHERE airline = @airline - AND flight_number = @flight_number - LIMIT 10 - description: | - Use this tool to get information for a specific flight. - Takes an airline code and flight number and returns info on the flight. - Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. - A airline code is a code for an airline service consisting of two-character - airline designator and followed by flight number, which is 1 to 4 digit number. - For example, if given CY 0123, the airline is "CY", and flight_number is "123". - Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". - If the tool returns more than one option choose the date closes to today. - Example: - {{ - "airline": "CY", - "flight_number": "888", - }} - Example: - {{ - "airline": "DL", - "flight_number": "1234", - }} - parameters: - - name: airline - type: string - description: Airline unique 2 letter identifier - - name: flight_number - type: string - description: 1 to 4 digit number +kind: tools +name: search_flights_by_number +type: spanner-sql +source: my-spanner-instance +statement: | + SELECT * FROM flights + WHERE airline = @airline + AND flight_number = @flight_number + LIMIT 10 +description: | + Use this tool to get information for a specific flight. + Takes an airline code and flight number and returns info on the flight. + Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. + A airline code is a code for an airline service consisting of two-character + airline designator and followed by flight number, which is 1 to 4 digit number. + For example, if given CY 0123, the airline is "CY", and flight_number is "123". + Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". + If the tool returns more than one option choose the date closes to today. + Example: + {{ + "airline": "CY", + "flight_number": "888", + }} + Example: + {{ + "airline": "DL", + "flight_number": "1234", + }} +parameters: + - name: airline + type: string + description: Airline unique 2 letter identifier + - name: flight_number + type: string + description: 1 to 4 digit number {{< /tab >}} {{< tab header="PostgreSQL" lang="yaml" >}} -tools: - search_flights_by_number: - kind: spanner - source: my-spanner-instance - statement: | - SELECT * FROM flights - WHERE airline = $1 - AND flight_number = $2 - LIMIT 10 - description: | - Use this tool to get information for a specific flight. - Takes an airline code and flight number and returns info on the flight. - Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. - A airline code is a code for an airline service consisting of two-character - airline designator and followed by flight number, which is 1 to 4 digit number. - For example, if given CY 0123, the airline is "CY", and flight_number is "123". - Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". - If the tool returns more than one option choose the date closes to today. - Example: - {{ - "airline": "CY", - "flight_number": "888", - }} - Example: - {{ - "airline": "DL", - "flight_number": "1234", - }} - parameters: - - name: airline - type: string - description: Airline unique 2 letter identifier - - name: flight_number - type: string - description: 1 to 4 digit number +kind: tools +name: search_flights_by_number +type: spanner +source: my-spanner-instance +statement: | + SELECT * FROM flights + WHERE airline = $1 + AND flight_number = $2 + LIMIT 10 +description: | + Use this tool to get information for a specific flight. + Takes an airline code and flight number and returns info on the flight. + Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. + A airline code is a code for an airline service consisting of two-character + airline designator and followed by flight number, which is 1 to 4 digit number. + For example, if given CY 0123, the airline is "CY", and flight_number is "123". + Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". + If the tool returns more than one option choose the date closes to today. + Example: + {{ + "airline": "CY", + "flight_number": "888", + }} + Example: + {{ + "airline": "DL", + "flight_number": "1234", + }} +parameters: + - name: airline + type: string + description: Airline unique 2 letter identifier + - name: flight_number + type: string + description: 1 to 4 digit number {{< /tab >}} {{< /tabpane >}} @@ -137,29 +137,29 @@ tools: > [templateParameters](..#template-parameters). ```yaml -tools: - list_table: - kind: spanner - source: my-spanner-instance - statement: | - SELECT * FROM {{.tableName}}; - description: | - Use this tool to list all information from a specific table. - Example: - {{ - "tableName": "flights", - }} - templateParameters: - - name: tableName - type: string - description: Table to select from +kind: tools +name: list_table +type: spanner +source: my-spanner-instance +statement: | + SELECT * FROM {{.tableName}}; +description: | + Use this tool to list all information from a specific table. + Example: + {{ + "tableName": "flights", + }} +templateParameters: + - name: tableName + type: string + description: Table to select from ``` ## Reference | **field** | **type** | **required** | **description** | |--------------------|:--------------------------------------------:|:------------:|----------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "spanner-sql". | +| type | string | true | Must be "spanner-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | statement | string | true | SQL statement to execute on. | diff --git a/docs/en/resources/tools/sqlite/sqlite-execute-sql.md b/docs/en/resources/tools/sqlite/sqlite-execute-sql.md index 0360154a44..7e5d293641 100644 --- a/docs/en/resources/tools/sqlite/sqlite-execute-sql.md +++ b/docs/en/resources/tools/sqlite/sqlite-execute-sql.md @@ -25,17 +25,17 @@ This tool is designed for direct execution of SQL statements. It takes a single ## Example ```yaml -tools: - execute_sql_tool: - kind: sqlite-execute-sql - source: my-sqlite-db - description: Use this tool to execute a SQL statement. +kind: tools +name: execute_sql_tool +type: sqlite-execute-sql +source: my-sqlite-db +description: Use this tool to execute a SQL statement. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "sqlite-execute-sql". | +| type | string | true | Must be "sqlite-execute-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/sqlite/sqlite-sql.md b/docs/en/resources/tools/sqlite/sqlite-sql.md index ecc714dfb2..de5c9bc48b 100644 --- a/docs/en/resources/tools/sqlite/sqlite-sql.md +++ b/docs/en/resources/tools/sqlite/sqlite-sql.md @@ -30,19 +30,19 @@ DDL statements. > names, or other parts of the query. ```yaml -tools: - search-users: - kind: sqlite-sql - source: my-sqlite-db - description: Search users by name and age - parameters: - - name: name - type: string - description: The name to search for - - name: min_age - type: integer - description: Minimum age - statement: SELECT * FROM users WHERE name LIKE ? AND age >= ? +kind: tools +name: search-users +type: sqlite-sql +source: my-sqlite-db +description: Search users by name and age +parameters: + - name: name + type: string + description: The name to search for + - name: min_age + type: integer + description: Minimum age +statement: SELECT * FROM users WHERE name LIKE ? AND age >= ? ``` ### Example with Template Parameters @@ -54,29 +54,29 @@ tools: > [templateParameters](..#template-parameters). ```yaml -tools: - list_table: - kind: sqlite-sql - source: my-sqlite-db - statement: | - SELECT * FROM {{.tableName}}; - description: | - Use this tool to list all information from a specific table. - Example: - {{ - "tableName": "flights", - }} - templateParameters: - - name: tableName - type: string - description: Table to select from +kind: tools +name: list_table +type: sqlite-sql +source: my-sqlite-db +statement: | + SELECT * FROM {{.tableName}}; +description: | + Use this tool to list all information from a specific table. + Example: + {{ + "tableName": "flights", + }} +templateParameters: + - name: tableName + type: string + description: Table to select from ``` ## Reference | **field** | **type** | **required** | **description** | |--------------------|:--------------------------------------------:|:------------:|----------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "sqlite-sql". | +| type | string | true | Must be "sqlite-sql". | | source | string | true | Name of the source the SQLite source configuration. | | description | string | true | Description of the tool that is passed to the LLM. | | statement | string | true | The SQL statement to execute. | diff --git a/docs/en/resources/tools/tidb/tidb-execute-sql.md b/docs/en/resources/tools/tidb/tidb-execute-sql.md index 8b1e68b8b2..fd36d7a845 100644 --- a/docs/en/resources/tools/tidb/tidb-execute-sql.md +++ b/docs/en/resources/tools/tidb/tidb-execute-sql.md @@ -25,17 +25,17 @@ statement against the `source`. ## Example ```yaml -tools: - execute_sql_tool: - kind: tidb-execute-sql - source: my-tidb-instance - description: Use this tool to execute sql statement. +kind: tools +name: execute_sql_tool +type: tidb-execute-sql +source: my-tidb-instance +description: Use this tool to execute sql statement. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------:|:------------:|----------------------------------------------------| -| kind | string | true | Must be "tidb-execute-sql". | +| type | string | true | Must be "tidb-execute-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/tidb/tidb-sql.md b/docs/en/resources/tools/tidb/tidb-sql.md index 3ec6caff45..8883d7ef42 100644 --- a/docs/en/resources/tools/tidb/tidb-sql.md +++ b/docs/en/resources/tools/tidb/tidb-sql.md @@ -29,41 +29,41 @@ and expects parameters in the SQL query to be in the form of placeholders `?`. > names, or other parts of the query. ```yaml -tools: - search_flights_by_number: - kind: tidb-sql - source: my-tidb-instance - statement: | - SELECT * FROM flights - WHERE airline = ? - AND flight_number = ? - LIMIT 10 - description: | - Use this tool to get information for a specific flight. - Takes an airline code and flight number and returns info on the flight. - Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. - A airline code is a code for an airline service consisting of two-character - airline designator and followed by flight number, which is 1 to 4 digit number. - For example, if given CY 0123, the airline is "CY", and flight_number is "123". - Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". - If the tool returns more than one option choose the date closes to today. - Example: - {{ - "airline": "CY", - "flight_number": "888", - }} - Example: - {{ - "airline": "DL", - "flight_number": "1234", - }} - parameters: - - name: airline - type: string - description: Airline unique 2 letter identifier - - name: flight_number - type: string - description: 1 to 4 digit number +kind: tools +name: search_flights_by_number +type: tidb-sql +source: my-tidb-instance +statement: | + SELECT * FROM flights + WHERE airline = ? + AND flight_number = ? + LIMIT 10 +description: | + Use this tool to get information for a specific flight. + Takes an airline code and flight number and returns info on the flight. + Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. + A airline code is a code for an airline service consisting of two-character + airline designator and followed by flight number, which is 1 to 4 digit number. + For example, if given CY 0123, the airline is "CY", and flight_number is "123". + Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". + If the tool returns more than one option choose the date closes to today. + Example: + {{ + "airline": "CY", + "flight_number": "888", + }} + Example: + {{ + "airline": "DL", + "flight_number": "1234", + }} +parameters: + - name: airline + type: string + description: Airline unique 2 letter identifier + - name: flight_number + type: string + description: 1 to 4 digit number ``` ### Example with Template Parameters @@ -75,29 +75,29 @@ tools: > [templateParameters](..#template-parameters). ```yaml -tools: - list_table: - kind: tidb-sql - source: my-tidb-instance - statement: | - SELECT * FROM {{.tableName}}; - description: | - Use this tool to list all information from a specific table. - Example: - {{ - "tableName": "flights", - }} - templateParameters: - - name: tableName - type: string - description: Table to select from +kind: tools +name: list_table +type: tidb-sql +source: my-tidb-instance +statement: | + SELECT * FROM {{.tableName}}; +description: | + Use this tool to list all information from a specific table. + Example: + {{ + "tableName": "flights", + }} +templateParameters: + - name: tableName + type: string + description: Table to select from ``` ## Reference | **field** | **type** | **required** | **description** | |--------------------|:--------------------------------------------:|:------------:|----------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "tidb-sql". | +| type | string | true | Must be "tidb-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | statement | string | true | SQL statement to execute on. | diff --git a/docs/en/resources/tools/trino/trino-execute-sql.md b/docs/en/resources/tools/trino/trino-execute-sql.md index 3d18cd6ee8..3d07133e03 100644 --- a/docs/en/resources/tools/trino/trino-execute-sql.md +++ b/docs/en/resources/tools/trino/trino-execute-sql.md @@ -25,17 +25,17 @@ statement against the `source`. ## Example ```yaml -tools: - execute_sql_tool: - kind: trino-execute-sql - source: my-trino-instance - description: Use this tool to execute sql statement. +kind: tools +name: execute_sql_tool +type: trino-execute-sql +source: my-trino-instance +description: Use this tool to execute sql statement. ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:------------------------------------------:|:------------:|--------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "trino-execute-sql". | +| type | string | true | Must be "trino-execute-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | diff --git a/docs/en/resources/tools/trino/trino-sql.md b/docs/en/resources/tools/trino/trino-sql.md index 4b0f8b21d5..1ee22b4239 100644 --- a/docs/en/resources/tools/trino/trino-sql.md +++ b/docs/en/resources/tools/trino/trino-sql.md @@ -28,41 +28,41 @@ The specified SQL statement is executed as a [prepared statement][trino-prepare] > names, or other parts of the query. ```yaml -tools: - search_orders_by_region: - kind: trino-sql - source: my-trino-instance - statement: | - SELECT * FROM hive.sales.orders - WHERE region = ? - AND order_date >= DATE(?) - LIMIT 10 - description: | - Use this tool to get information for orders in a specific region. - Takes a region code and date and returns info on the orders. - Do NOT use this tool with an order id. Do NOT guess a region code or date. - A region code is a code for a geographic region consisting of two-character - region designator and followed by optional subregion. - For example, if given US-WEST, the region is "US-WEST". - Another example for this is EU-CENTRAL, the region is "EU-CENTRAL". - If the tool returns more than one option choose the date closest to today. - Example: - {{ - "region": "US-WEST", - "order_date": "2024-01-01", - }} - Example: - {{ - "region": "EU-CENTRAL", - "order_date": "2024-01-15", - }} - parameters: - - name: region - type: string - description: Region unique identifier - - name: order_date - type: string - description: Order date in YYYY-MM-DD format +kind: tools +name: search_orders_by_region +type: trino-sql +source: my-trino-instance +statement: | + SELECT * FROM hive.sales.orders + WHERE region = ? + AND order_date >= DATE(?) + LIMIT 10 +description: | + Use this tool to get information for orders in a specific region. + Takes a region code and date and returns info on the orders. + Do NOT use this tool with an order id. Do NOT guess a region code or date. + A region code is a code for a geographic region consisting of two-character + region designator and followed by optional subregion. + For example, if given US-WEST, the region is "US-WEST". + Another example for this is EU-CENTRAL, the region is "EU-CENTRAL". + If the tool returns more than one option choose the date closest to today. + Example: + {{ + "region": "US-WEST", + "order_date": "2024-01-01", + }} + Example: + {{ + "region": "EU-CENTRAL", + "order_date": "2024-01-15", + }} +parameters: + - name: region + type: string + description: Region unique identifier + - name: order_date + type: string + description: Order date in YYYY-MM-DD format ``` ### Example with Template Parameters @@ -74,29 +74,29 @@ tools: > [templateParameters](..#template-parameters). ```yaml -tools: - list_table: - kind: trino-sql - source: my-trino-instance - statement: | - SELECT * FROM {{.tableName}} - description: | - Use this tool to list all information from a specific table. - Example: - {{ - "tableName": "hive.sales.orders", - }} - templateParameters: - - name: tableName - type: string - description: Table to select from +kind: tools +name: list_table +type: trino-sql +source: my-trino-instance +statement: | + SELECT * FROM {{.tableName}} +description: | + Use this tool to list all information from a specific table. + Example: + {{ + "tableName": "hive.sales.orders", + }} +templateParameters: + - name: tableName + type: string + description: Table to select from ``` ## Reference | **field** | **type** | **required** | **description** | |--------------------|:--------------------------------------------:|:------------:|----------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "trino-sql". | +| type | string | true | Must be "trino-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | statement | string | true | SQL statement to execute on. | diff --git a/docs/en/resources/tools/utility/wait.md b/docs/en/resources/tools/utility/wait.md index 1fde916ce5..c58d69a24b 100644 --- a/docs/en/resources/tools/utility/wait.md +++ b/docs/en/resources/tools/utility/wait.md @@ -24,17 +24,17 @@ and shouldn't be used for production agents. ## Example ```yaml -tools: - wait_for_tool: - kind: wait - description: Use this tool to pause execution for a specified duration. - timeout: 30s +kind: tools +name: wait_for_tool +type: wait +description: Use this tool to pause execution for a specified duration. +timeout: 30s ``` ## Reference | **field** | **type** | **required** | **description** | |-------------|:--------------:|:------------:|-------------------------------------------------------| -| kind | string | true | Must be "wait". | +| type | string | true | Must be "wait". | | description | string | true | Description of the tool that is passed to the LLM. | | timeout | string | true | The default duration the tool can wait for. | diff --git a/docs/en/resources/tools/valkey/valkey.md b/docs/en/resources/tools/valkey/valkey.md index fab9e5e3b1..3b801fcae9 100644 --- a/docs/en/resources/tools/valkey/valkey.md +++ b/docs/en/resources/tools/valkey/valkey.md @@ -38,21 +38,21 @@ to be executed after argument expansion will be `[SADD, userNames, Alice, Sid, B ## Example ```yaml -tools: - user_data_tool: - kind: valkey - source: my-valkey-instance - description: | - Use this tool to interact with user data stored in Valkey. - It can set, retrieve, and delete user-specific information. - commands: - - [SADD, userNames, $userNames] # Array will be flattened into multiple arguments. - - [GET, $userId] - parameters: - - name: userId - type: string - description: The unique identifier for the user. - - name: userNames - type: array - description: The user names to be set. +kind: tools +name: user_data_tool +type: valkey +source: my-valkey-instance +description: | + Use this tool to interact with user data stored in Valkey. + It can set, retrieve, and delete user-specific information. +commands: + - [SADD, userNames, $userNames] # Array will be flattened into multiple arguments. + - [GET, $userId] +parameters: + - name: userId + type: string + description: The unique identifier for the user. + - name: userNames + type: array + description: The user names to be set. ``` diff --git a/docs/en/resources/tools/yuagbytedb/yugabytedb-sql.md b/docs/en/resources/tools/yuagbytedb/yugabytedb-sql.md index e96ab9e6be..82329c42c8 100644 --- a/docs/en/resources/tools/yuagbytedb/yugabytedb-sql.md +++ b/docs/en/resources/tools/yuagbytedb/yugabytedb-sql.md @@ -26,41 +26,41 @@ of the prepared statement. > names, or other parts of the query. ```yaml -tools: - search_flights_by_number: - kind: yugabytedb-sql - source: my-yb-instance - statement: | - SELECT * FROM flights - WHERE airline = $1 - AND flight_number = $2 - LIMIT 10 - description: | - Use this tool to get information for a specific flight. - Takes an airline code and flight number and returns info on the flight. - Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. - A airline code is a code for an airline service consisting of two-character - airline designator and followed by flight number, which is 1 to 4 digit number. - For example, if given CY 0123, the airline is "CY", and flight_number is "123". - Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". - If the tool returns more than one option choose the date closes to today. - Example: - {{ - "airline": "CY", - "flight_number": "888", - }} - Example: - {{ - "airline": "DL", - "flight_number": "1234", - }} - parameters: - - name: airline - type: string - description: Airline unique 2 letter identifier - - name: flight_number - type: string - description: 1 to 4 digit number +kind: tools +name: search_flights_by_number +type: yugabytedb-sql +source: my-yb-instance +statement: | + SELECT * FROM flights + WHERE airline = $1 + AND flight_number = $2 + LIMIT 10 +description: | + Use this tool to get information for a specific flight. + Takes an airline code and flight number and returns info on the flight. + Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. + A airline code is a code for an airline service consisting of two-character + airline designator and followed by flight number, which is 1 to 4 digit number. + For example, if given CY 0123, the airline is "CY", and flight_number is "123". + Another example for this is DL 1234, the airline is "DL", and flight_number is "1234". + If the tool returns more than one option choose the date closes to today. + Example: + {{ + "airline": "CY", + "flight_number": "888", + }} + Example: + {{ + "airline": "DL", + "flight_number": "1234", + }} +parameters: + - name: airline + type: string + description: Airline unique 2 letter identifier + - name: flight_number + type: string + description: 1 to 4 digit number ``` ### Example with Template Parameters @@ -72,29 +72,29 @@ tools: > [templateParameters](..#template-parameters). ```yaml -tools: - list_table: - kind: yugabytedb-sql - source: my-yb-instance - statement: | - SELECT * FROM {{.tableName}} - description: | - Use this tool to list all information from a specific table. - Example: - {{ - "tableName": "flights", - }} - templateParameters: - - name: tableName - type: string - description: Table to select from +kind: tools +name: list_table +type: yugabytedb-sql +source: my-yb-instance +statement: | + SELECT * FROM {{.tableName}} +description: | + Use this tool to list all information from a specific table. + Example: + {{ + "tableName": "flights", + }} +templateParameters: + - name: tableName + type: string + description: Table to select from ``` ## Reference | **field** | **type** | **required** | **description** | |--------------------|:--------------------------------------------:|:------------:|----------------------------------------------------------------------------------------------------------------------------------------| -| kind | string | true | Must be "yugabytedb-sql". | +| type | string | true | Must be "yugabytedb-sql". | | source | string | true | Name of the source the SQL should execute on. | | description | string | true | Description of the tool that is passed to the LLM. | | statement | string | true | SQL statement to execute on. | diff --git a/docs/en/samples/alloydb/ai-nl/alloydb_ai_nl.ipynb b/docs/en/samples/alloydb/ai-nl/alloydb_ai_nl.ipynb index f931a2119b..d5c0b725a4 100644 --- a/docs/en/samples/alloydb/ai-nl/alloydb_ai_nl.ipynb +++ b/docs/en/samples/alloydb/ai-nl/alloydb_ai_nl.ipynb @@ -801,27 +801,30 @@ "# Create a tools file\n", "tools_file_name = \"tools.yml\"\n", "file_content = f\"\"\"\n", - "sources:\n", - " my-alloydb-pg-source:\n", - " kind: alloydb-postgres\n", - " project: {project_id}\n", - " region: {region}\n", - " cluster: {cluster_name}\n", - " instance: {instance_name}\n", - " database: {database_name}\n", - " user: postgres\n", - " password: {password}\n", - "tools:\n", - " ask_questions:\n", - " kind: alloydb-ai-nl\n", - " source: my-alloydb-pg-source\n", - " description: 'Ask any natural language questions about the tables'\n", - " nlConfig: 'nla_demo_cfg'\n", - " basic_sql:\n", - " kind: postgres-sql\n", - " source: my-alloydb-pg-source\n", - " description: 'Check if db is connected'\n", - " statement: SELECT * from nla_demo.products;\n", + "kind: sources\n", + "name: my-alloydb-pg-source\n", + "type: alloydb-postgres\n", + "project: {project_id}\n", + "region: {region}\n", + "cluster: {cluster_name}\n", + "instance: {instance_name}\n", + "database: {database_name}\n", + "user: postgres\n", + "password: {password}\n", + "---\n", + "kind: tools\n", + "name: ask_questions\n", + "type: alloydb-ai-nl\n", + "source: my-alloydb-pg-source\n", + "description: 'Ask any natural language questions about the tables'\n", + "nlConfig: 'nla_demo_cfg'\n", + "---\n", + "kind: tools\n", + "name: basic_sql\n", + "type: postgres-sql\n", + "source: my-alloydb-pg-source\n", + "description: 'Check if db is connected'\n", + "statement: SELECT * from nla_demo.products;\n", "\"\"\"" ] }, diff --git a/docs/en/samples/alloydb/mcp_quickstart.md b/docs/en/samples/alloydb/mcp_quickstart.md index 82bd5198e7..07034a7f33 100644 --- a/docs/en/samples/alloydb/mcp_quickstart.md +++ b/docs/en/samples/alloydb/mcp_quickstart.md @@ -143,16 +143,16 @@ First, define the data source for your tools. This tells Toolbox how to connect to your AlloyDB instance. ```yaml -sources: - alloydb-pg-source: - kind: alloydb-postgres - project: YOUR_PROJECT_ID - region: YOUR_REGION - cluster: YOUR_CLUSTER - instance: YOUR_INSTANCE - database: YOUR_DATABASE - user: YOUR_USER - password: YOUR_PASSWORD +kind: sources +name: alloydb-pg-source +type: alloydb-postgres +project: YOUR_PROJECT_ID +region: YOUR_REGION +cluster: YOUR_CLUSTER +instance: YOUR_INSTANCE +database: YOUR_DATABASE +user: YOUR_USER +password: YOUR_PASSWORD ``` Next, define the tools the agent can use. We will categorize them into three @@ -165,76 +165,77 @@ structured queries like managing a shopping cart. Add the following to your `tools.yaml` file: ```yaml -tools: - - access-cart-information: - kind: postgres-sql - source: alloydb-pg-source - description: >- - List items in customer cart. - Use this tool to list items in a customer cart. This tool requires the cart ID. - parameters: - - name: cart_id - type: integer - description: The id of the cart. - statement: | - SELECT - p.name AS product_name, - ci.quantity, - ci.price AS item_price, - (ci.quantity * ci.price) AS total_item_price, - c.created_at AS cart_created_at, - ci.product_id AS product_id - FROM - cart_items ci JOIN cart c ON ci.cart_id = c.cart_id - JOIN products p ON ci.product_id = p.product_id - WHERE - c.cart_id = $1; - - add-to-cart: - kind: postgres-sql - source: alloydb-pg-source - description: >- - Add items to customer cart using the product ID and product prices from the product list. - Use this tool to add items to a customer cart. - This tool requires the cart ID, product ID, quantity, and price. - parameters: - - name: cart_id - type: integer - description: The id of the cart. - - name: product_id - type: integer - description: The id of the product. - - name: quantity - type: integer - description: The quantity of items to add. - - name: price - type: float - description: The price of items to add. - statement: | - INSERT INTO - cart_items (cart_id, product_id, quantity, price) - VALUES($1,$2,$3,$4); - - delete-from-cart: - kind: postgres-sql - source: alloydb-pg-source - description: >- - Remove products from customer cart. - Use this tool to remove products from a customer cart. - This tool requires the cart ID and product ID. - parameters: - - name: cart_id - type: integer - description: The id of the cart. - - name: product_id - type: integer - description: The id of the product. - statement: | - DELETE FROM - cart_items - WHERE - cart_id = $1 AND product_id = $2; +kind: tools +name: access-cart-information +type: postgres-sql +source: alloydb-pg-source +description: >- + List items in customer cart. + Use this tool to list items in a customer cart. This tool requires the cart ID. +parameters: + - name: cart_id + type: integer + description: The id of the cart. +statement: | + SELECT + p.name AS product_name, + ci.quantity, + ci.price AS item_price, + (ci.quantity * ci.price) AS total_item_price, + c.created_at AS cart_created_at, + ci.product_id AS product_id + FROM + cart_items ci JOIN cart c ON ci.cart_id = c.cart_id + JOIN products p ON ci.product_id = p.product_id + WHERE + c.cart_id = $1; +--- +kind: tools +name: add-to-cart +type: postgres-sql +source: alloydb-pg-source +description: >- + Add items to customer cart using the product ID and product prices from the product list. + Use this tool to add items to a customer cart. + This tool requires the cart ID, product ID, quantity, and price. +parameters: + - name: cart_id + type: integer + description: The id of the cart. + - name: product_id + type: integer + description: The id of the product. + - name: quantity + type: integer + description: The quantity of items to add. + - name: price + type: float + description: The price of items to add. +statement: | + INSERT INTO + cart_items (cart_id, product_id, quantity, price) + VALUES($1,$2,$3,$4); +--- +kind: tools +name: delete-from-cart +type: postgres-sql +source: alloydb-pg-source +description: >- + Remove products from customer cart. + Use this tool to remove products from a customer cart. + This tool requires the cart ID and product ID. +parameters: + - name: cart_id + type: integer + description: The id of the cart. + - name: product_id + type: integer + description: The id of the product. +statement: | + DELETE FROM + cart_items + WHERE + cart_id = $1 AND product_id = $2; ``` ### 2. Semantic Search Tools @@ -244,27 +245,28 @@ meaning of a user's query, rather than just keywords. Append the following tools to the `tools` section in your `tools.yaml`: ```yaml - search-product-recommendations: - kind: postgres-sql - source: alloydb-pg-source - description: >- - Search for products based on user needs. - Use this tool to search for products. This tool requires the user's needs. - parameters: - - name: query - type: string - description: The product characteristics - statement: | - SELECT - product_id, - name, - description, - ROUND(CAST(price AS numeric), 2) as price - FROM - products - ORDER BY - embedding('gemini-embedding-001', $1)::vector <=> embedding - LIMIT 5; +kind: tools +name: search-product-recommendations +type: postgres-sql +source: alloydb-pg-source +description: >- + Search for products based on user needs. + Use this tool to search for products. This tool requires the user's needs. +parameters: + - name: query + type: string + description: The product characteristics +statement: | + SELECT + product_id, + name, + description, + ROUND(CAST(price AS numeric), 2) as price + FROM + products + ORDER BY + embedding('gemini-embedding-001', $1)::vector <=> embedding + LIMIT 5; ``` ### 3. Natural Language to SQL (NL2SQL) Tools @@ -286,27 +288,29 @@ to the `tools` section in your `tools.yaml`: section: ```yaml - ask-questions-about-products: - kind: alloydb-ai-nl - source: alloydb-pg-source - nlConfig: flower_shop - description: >- - Ask questions related to products or brands. - Use this tool to ask questions about products or brands. - Always SELECT the IDs of objects when generating queries. +kind: tools +name: ask-questions-about-products +type: alloydb-ai-nl +source: alloydb-pg-source +nlConfig: flower_shop +description: >- + Ask questions related to products or brands. + Use this tool to ask questions about products or brands. + Always SELECT the IDs of objects when generating queries. ``` Finally, group the tools into a `toolset` to make them available to the model. Add the following to the end of your `tools.yaml` file: ```yaml -toolsets: - flower_shop: - - access-cart-information - - search-product-recommendations - - ask-questions-about-products - - add-to-cart - - delete-from-cart +kind: toolsets +name: flower_shop +tools: + - access-cart-information + - search-product-recommendations + - ask-questions-about-products + - add-to-cart + - delete-from-cart ``` For more info on tools, check out the diff --git a/docs/en/samples/bigquery/colab_quickstart_bigquery.ipynb b/docs/en/samples/bigquery/colab_quickstart_bigquery.ipynb index 9c13b6e86e..d4da45edb0 100644 --- a/docs/en/samples/bigquery/colab_quickstart_bigquery.ipynb +++ b/docs/en/samples/bigquery/colab_quickstart_bigquery.ipynb @@ -273,72 +273,83 @@ "# You can also upload a tools file and use that to run toolbox.\n", "tools_file_name = \"tools.yml\"\n", "file_content = f\"\"\"\n", - "sources:\n", - " my-bigquery-source:\n", - " kind: bigquery\n", - " project: {BIGQUERY_PROJECT}\n", + "kind: sources\n", + "name: my-bigquery-source\n", + "type: bigquery\n", + "project: {BIGQUERY_PROJECT}\n", + "---\n", + "kind: tools\n", + "name: search-hotels-by-name\n", + "type: bigquery-sql\n", + "source: my-bigquery-source\n", + "description: Search for hotels based on name.\n", + "parameters:\n", + " - name: name\n", + " type: string\n", + " description: The name of the hotel.\n", + "statement: SELECT * FROM `{DATASET}.{TABLE_ID}` WHERE LOWER(name) LIKE LOWER(CONCAT('%', @name, '%'));\n", + "---\n", + "kind: tools\n", + "name: search-hotels-by-location\n", + "type: bigquery-sql\n", + "source: my-bigquery-source\n", + "description: Search for hotels based on location.\n", + "parameters:\n", + " - name: location\n", + " type: string\n", + " description: The location of the hotel.\n", + "statement: SELECT * FROM `{DATASET}.{TABLE_ID}` WHERE LOWER(location) LIKE LOWER(CONCAT('%', @location, '%'));\n", + "---\n", + "kind: tools\n", + "name: book-hotel\n", + "type: bigquery-sql\n", + "source: my-bigquery-source\n", + "description: >-\n", + " Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not.\n", + "parameters:\n", + " - name: hotel_id\n", + " type: integer\n", + " description: The ID of the hotel to book.\n", + "statement: UPDATE `{DATASET}.{TABLE_ID}` SET booked = TRUE WHERE id = @hotel_id;\n", + "---\n", + "kind: tools\n", + "name: update-hotel\n", + "type: bigquery-sql\n", + "source: my-bigquery-source\n", + "description: >-\n", + " Update a hotel's check-in and check-out dates by its ID. Returns a message indicating whether the hotel was successfully updated or not.\n", + "parameters:\n", + " - name: checkin_date\n", + " type: string\n", + " description: The new check-in date of the hotel.\n", + " - name: checkout_date\n", + " type: string\n", + " description: The new check-out date of the hotel.\n", + " - name: hotel_id\n", + " type: integer\n", + " description: The ID of the hotel to update.\n", + "statement: >-\n", + " UPDATE `{DATASET}.{TABLE_ID}` SET checkin_date = PARSE_DATE('%Y-%m-%d', @checkin_date), checkout_date = PARSE_DATE('%Y-%m-%d', @checkout_date) WHERE id = @hotel_id;\n", + "---\n", + "kind: tools\n", + "name: cancel-hotel\n", + "type: bigquery-sql\n", + "source: my-bigquery-source\n", + "description: Cancel a hotel by its ID.\n", + "parameters:\n", + " - name: hotel_id\n", + " type: integer\n", + " description: The ID of the hotel to cancel.\n", + "statement: UPDATE `{DATASET}.{TABLE_ID}` SET booked = FALSE WHERE id = @hotel_id;\n", + "---\n", + "kind: toolsets\n", + "name: my-toolset\n", "tools:\n", - " search-hotels-by-name:\n", - " kind: bigquery-sql\n", - " source: my-bigquery-source\n", - " description: Search for hotels based on name.\n", - " parameters:\n", - " - name: name\n", - " type: string\n", - " description: The name of the hotel.\n", - " statement: SELECT * FROM `{DATASET}.{TABLE_ID}` WHERE LOWER(name) LIKE LOWER(CONCAT('%', @name, '%'));\n", - " search-hotels-by-location:\n", - " kind: bigquery-sql\n", - " source: my-bigquery-source\n", - " description: Search for hotels based on location.\n", - " parameters:\n", - " - name: location\n", - " type: string\n", - " description: The location of the hotel.\n", - " statement: SELECT * FROM `{DATASET}.{TABLE_ID}` WHERE LOWER(location) LIKE LOWER(CONCAT('%', @location, '%'));\n", - " book-hotel:\n", - " kind: bigquery-sql\n", - " source: my-bigquery-source\n", - " description: >-\n", - " Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not.\n", - " parameters:\n", - " - name: hotel_id\n", - " type: integer\n", - " description: The ID of the hotel to book.\n", - " statement: UPDATE `{DATASET}.{TABLE_ID}` SET booked = TRUE WHERE id = @hotel_id;\n", - " update-hotel:\n", - " kind: bigquery-sql\n", - " source: my-bigquery-source\n", - " description: >-\n", - " Update a hotel's check-in and check-out dates by its ID. Returns a message indicating whether the hotel was successfully updated or not.\n", - " parameters:\n", - " - name: checkin_date\n", - " type: string\n", - " description: The new check-in date of the hotel.\n", - " - name: checkout_date\n", - " type: string\n", - " description: The new check-out date of the hotel.\n", - " - name: hotel_id\n", - " type: integer\n", - " description: The ID of the hotel to update.\n", - " statement: >-\n", - " UPDATE `{DATASET}.{TABLE_ID}` SET checkin_date = PARSE_DATE('%Y-%m-%d', @checkin_date), checkout_date = PARSE_DATE('%Y-%m-%d', @checkout_date) WHERE id = @hotel_id;\n", - " cancel-hotel:\n", - " kind: bigquery-sql\n", - " source: my-bigquery-source\n", - " description: Cancel a hotel by its ID.\n", - " parameters:\n", - " - name: hotel_id\n", - " type: integer\n", - " description: The ID of the hotel to cancel.\n", - " statement: UPDATE `{DATASET}.{TABLE_ID}` SET booked = FALSE WHERE id = @hotel_id;\n", - "toolsets:\n", - " my-toolset:\n", - " - search-hotels-by-name\n", - " - search-hotels-by-location\n", - " - book-hotel\n", - " - update-hotel\n", - " - cancel-hotel\n", + " - search-hotels-by-name\n", + " - search-hotels-by-location\n", + " - book-hotel\n", + " - update-hotel\n", + " - cancel-hotel\n", "\"\"\"" ] }, diff --git a/docs/en/samples/bigquery/local_quickstart.md b/docs/en/samples/bigquery/local_quickstart.md index 5735a1a515..1216270dd1 100644 --- a/docs/en/samples/bigquery/local_quickstart.md +++ b/docs/en/samples/bigquery/local_quickstart.md @@ -201,66 +201,75 @@ to use BigQuery, and then run the Toolbox server. {{< /notice >}} ```yaml - sources: - my-bigquery-source: - kind: bigquery - project: YOUR_PROJECT_ID - location: us - tools: - search-hotels-by-name: - kind: bigquery-sql - source: my-bigquery-source - description: Search for hotels based on name. - parameters: - - name: name - type: string - description: The name of the hotel. - statement: SELECT * FROM `YOUR_DATASET_NAME.hotels` WHERE LOWER(name) LIKE LOWER(CONCAT('%', @name, '%')); - search-hotels-by-location: - kind: bigquery-sql - source: my-bigquery-source - description: Search for hotels based on location. - parameters: - - name: location - type: string - description: The location of the hotel. - statement: SELECT * FROM `YOUR_DATASET_NAME.hotels` WHERE LOWER(location) LIKE LOWER(CONCAT('%', @location, '%')); - book-hotel: - kind: bigquery-sql - source: my-bigquery-source - description: >- - Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not. - parameters: - - name: hotel_id - type: integer - description: The ID of the hotel to book. - statement: UPDATE `YOUR_DATASET_NAME.hotels` SET booked = TRUE WHERE id = @hotel_id; - update-hotel: - kind: bigquery-sql - source: my-bigquery-source - description: >- - Update a hotel's check-in and check-out dates by its ID. Returns a message indicating whether the hotel was successfully updated or not. - parameters: - - name: checkin_date - type: string - description: The new check-in date of the hotel. - - name: checkout_date - type: string - description: The new check-out date of the hotel. - - name: hotel_id - type: integer - description: The ID of the hotel to update. - statement: >- - UPDATE `YOUR_DATASET_NAME.hotels` SET checkin_date = PARSE_DATE('%Y-%m-%d', @checkin_date), checkout_date = PARSE_DATE('%Y-%m-%d', @checkout_date) WHERE id = @hotel_id; - cancel-hotel: - kind: bigquery-sql - source: my-bigquery-source - description: Cancel a hotel by its ID. - parameters: - - name: hotel_id - type: integer - description: The ID of the hotel to cancel. - statement: UPDATE `YOUR_DATASET_NAME.hotels` SET booked = FALSE WHERE id = @hotel_id; + kind: sources + name: my-bigquery-source + type: bigquery + project: YOUR_PROJECT_ID + location: us + --- + kind: tools + name: search-hotels-by-name + type: bigquery-sql + source: my-bigquery-source + description: Search for hotels based on name. + parameters: + - name: name + type: string + description: The name of the hotel. + statement: SELECT * FROM `YOUR_DATASET_NAME.hotels` WHERE LOWER(name) LIKE LOWER(CONCAT('%', @name, '%')); + --- + kind: tools + name: search-hotels-by-location + type: bigquery-sql + source: my-bigquery-source + description: Search for hotels based on location. + parameters: + - name: location + type: string + description: The location of the hotel. + statement: SELECT * FROM `YOUR_DATASET_NAME.hotels` WHERE LOWER(location) LIKE LOWER(CONCAT('%', @location, '%')); + --- + kind: tools + name: book-hotel + type: bigquery-sql + source: my-bigquery-source + description: >- + Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not. + parameters: + - name: hotel_id + type: integer + description: The ID of the hotel to book. + statement: UPDATE `YOUR_DATASET_NAME.hotels` SET booked = TRUE WHERE id = @hotel_id; + --- + kind: tools + name: update-hotel + type: bigquery-sql + source: my-bigquery-source + description: >- + Update a hotel's check-in and check-out dates by its ID. Returns a message indicating whether the hotel was successfully updated or not. + parameters: + - name: checkin_date + type: string + description: The new check-in date of the hotel. + - name: checkout_date + type: string + description: The new check-out date of the hotel. + - name: hotel_id + type: integer + description: The ID of the hotel to update. + statement: >- + UPDATE `YOUR_DATASET_NAME.hotels` SET checkin_date = PARSE_DATE('%Y-%m-%d', @checkin_date), checkout_date = PARSE_DATE('%Y-%m-%d', @checkout_date) WHERE id = @hotel_id; + --- + kind: tools + name: cancel-hotel + type: bigquery-sql + source: my-bigquery-source + description: Cancel a hotel by its ID. + parameters: + - name: hotel_id + type: integer + description: The ID of the hotel to cancel. + statement: UPDATE `YOUR_DATASET_NAME.hotels` SET booked = FALSE WHERE id = @hotel_id; ``` **Important Note on `toolsets`**: The `tools.yaml` content above does not @@ -272,8 +281,9 @@ to use BigQuery, and then run the Toolbox server. ```yaml # Add this to your tools.yaml if using load_toolset("my-toolset") # Ensure it's at the same indentation level as 'sources:' and 'tools:' - toolsets: - my-toolset: + kind: toolsets + name: my-toolset + tools: - search-hotels-by-name - search-hotels-by-location - book-hotel diff --git a/docs/en/samples/bigquery/mcp_quickstart/_index.md b/docs/en/samples/bigquery/mcp_quickstart/_index.md index 53250e06fd..1216daac7e 100644 --- a/docs/en/samples/bigquery/mcp_quickstart/_index.md +++ b/docs/en/samples/bigquery/mcp_quickstart/_index.md @@ -120,73 +120,84 @@ In this section, we will download Toolbox, configure our tools in a {{< /notice >}} ```yaml - sources: - my-bigquery-source: - kind: bigquery - project: YOUR_PROJECT_ID - location: us + kind: sources + name: my-bigquery-source + type: bigquery + project: YOUR_PROJECT_ID + location: us + --- + kind: tools + name: search-hotels-by-name + type: bigquery-sql + source: my-bigquery-source + description: Search for hotels based on name. + parameters: + - name: name + type: string + description: The name of the hotel. + statement: SELECT * FROM `YOUR_DATASET_NAME.hotels` WHERE LOWER(name) LIKE LOWER(CONCAT('%', @name, '%')); + --- + kind: tools + name: search-hotels-by-location + type: bigquery-sql + source: my-bigquery-source + description: Search for hotels based on location. + parameters: + - name: location + type: string + description: The location of the hotel. + statement: SELECT * FROM `YOUR_DATASET_NAME.hotels` WHERE LOWER(location) LIKE LOWER(CONCAT('%', @location, '%')); + --- + kind: tools + name: book-hotel + type: bigquery-sql + source: my-bigquery-source + description: >- + Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not. + parameters: + - name: hotel_id + type: integer + description: The ID of the hotel to book. + statement: UPDATE `YOUR_DATASET_NAME.hotels` SET booked = TRUE WHERE id = @hotel_id; + --- + kind: tools + name: update-hotel + type: bigquery-sql + source: my-bigquery-source + description: >- + Update a hotel's check-in and check-out dates by its ID. Returns a message indicating whether the hotel was successfully updated or not. + parameters: + - name: checkin_date + type: string + description: The new check-in date of the hotel. + - name: checkout_date + type: string + description: The new check-out date of the hotel. + - name: hotel_id + type: integer + description: The ID of the hotel to update. + statement: >- + UPDATE `YOUR_DATASET_NAME.hotels` SET checkin_date = PARSE_DATE('%Y-%m-%d', @checkin_date), checkout_date = PARSE_DATE('%Y-%m-%d', @checkout_date) WHERE id = @hotel_id; + --- + kind: tools + name: cancel-hotel + type: bigquery-sql + source: my-bigquery-source + description: Cancel a hotel by its ID. + parameters: + - name: hotel_id + type: integer + description: The ID of the hotel to cancel. + statement: UPDATE `YOUR_DATASET_NAME.hotels` SET booked = FALSE WHERE id = @hotel_id; + --- + kind: toolsets + name: my-toolset tools: - search-hotels-by-name: - kind: bigquery-sql - source: my-bigquery-source - description: Search for hotels based on name. - parameters: - - name: name - type: string - description: The name of the hotel. - statement: SELECT * FROM `YOUR_DATASET_NAME.hotels` WHERE LOWER(name) LIKE LOWER(CONCAT('%', @name, '%')); - search-hotels-by-location: - kind: bigquery-sql - source: my-bigquery-source - description: Search for hotels based on location. - parameters: - - name: location - type: string - description: The location of the hotel. - statement: SELECT * FROM `YOUR_DATASET_NAME.hotels` WHERE LOWER(location) LIKE LOWER(CONCAT('%', @location, '%')); - book-hotel: - kind: bigquery-sql - source: my-bigquery-source - description: >- - Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not. - parameters: - - name: hotel_id - type: integer - description: The ID of the hotel to book. - statement: UPDATE `YOUR_DATASET_NAME.hotels` SET booked = TRUE WHERE id = @hotel_id; - update-hotel: - kind: bigquery-sql - source: my-bigquery-source - description: >- - Update a hotel's check-in and check-out dates by its ID. Returns a message indicating whether the hotel was successfully updated or not. - parameters: - - name: checkin_date - type: string - description: The new check-in date of the hotel. - - name: checkout_date - type: string - description: The new check-out date of the hotel. - - name: hotel_id - type: integer - description: The ID of the hotel to update. - statement: >- - UPDATE `YOUR_DATASET_NAME.hotels` SET checkin_date = PARSE_DATE('%Y-%m-%d', @checkin_date), checkout_date = PARSE_DATE('%Y-%m-%d', @checkout_date) WHERE id = @hotel_id; - cancel-hotel: - kind: bigquery-sql - source: my-bigquery-source - description: Cancel a hotel by its ID. - parameters: - - name: hotel_id - type: integer - description: The ID of the hotel to cancel. - statement: UPDATE `YOUR_DATASET_NAME.hotels` SET booked = FALSE WHERE id = @hotel_id; - toolsets: - my-toolset: - - search-hotels-by-name - - search-hotels-by-location - - book-hotel - - update-hotel - - cancel-hotel + - search-hotels-by-name + - search-hotels-by-location + - book-hotel + - update-hotel + - cancel-hotel ``` For more info on tools, check out the diff --git a/docs/en/samples/neo4j/mcp_quickstart.md b/docs/en/samples/neo4j/mcp_quickstart.md index fa36ac6ce3..ebcb70a70e 100644 --- a/docs/en/samples/neo4j/mcp_quickstart.md +++ b/docs/en/samples/neo4j/mcp_quickstart.md @@ -61,37 +61,38 @@ Write the following into a `tools.yaml` file: \+ ```yaml -sources: - my-neo4j-source: - kind: neo4j - uri: bolt://localhost:7687 - user: neo4j - password: my-password # Replace with your actual password - -tools: - search-movies-by-actor: - kind: neo4j-cypher - source: my-neo4j-source - description: "Searches for movies an actor has appeared in based on their name. Useful for questions like 'What movies has Tom Hanks been in?'" - parameters: - - name: actor_name - type: string - description: The full name of the actor to search for. - statement: | - MATCH (p:Person {name: $actor_name}) -[:ACTED_IN]-> (m:Movie) - RETURN m.title AS title, m.year AS year, m.genre AS genre - - get-actor-for-movie: - kind: neo4j-cypher - source: my-neo4j-source - description: "Finds the actors who starred in a specific movie. Useful for questions like 'Who acted in Inception?'" - parameters: - - name: movie_title - type: string - description: The exact title of the movie. - statement: | - MATCH (p:Person) -[:ACTED_IN]-> (m:Movie {title: $movie_title}) - RETURN p.name AS actor +kind: sources +name: my-neo4j-source +type: neo4j +uri: bolt://localhost:7687 +user: neo4j +password: my-password # Replace with your actual password +--- +kind: tools +name: search-movies-by-actor +type: neo4j-cypher +source: my-neo4j-source +description: "Searches for movies an actor has appeared in based on their name. Useful for questions like 'What movies has Tom Hanks been in?'" +parameters: + - name: actor_name + type: string + description: The full name of the actor to search for. +statement: | + MATCH (p:Person {name: $actor_name}) -[:ACTED_IN]-> (m:Movie) + RETURN m.title AS title, m.year AS year, m.genre AS genre +--- +kind: tools +name: get-actor-for-movie +type: neo4j-cypher +source: my-neo4j-source +description: "Finds the actors who starred in a specific movie. Useful for questions like 'Who acted in Inception?'" +parameters: + - name: movie_title + type: string + description: The exact title of the movie. +statement: | + MATCH (p:Person) -[:ACTED_IN]-> (m:Movie {title: $movie_title}) + RETURN p.name AS actor ``` . **Start the Toolbox server.** diff --git a/docs/en/samples/snowflake/_index.md b/docs/en/samples/snowflake/_index.md index 0149544eba..6f3ca05e8d 100644 --- a/docs/en/samples/snowflake/_index.md +++ b/docs/en/samples/snowflake/_index.md @@ -79,32 +79,33 @@ You have two options: Create a `tools.yaml` file and add the following content. You must replace the placeholders with your actual Snowflake configuration. ```yaml -sources: - snowflake-source: - kind: snowflake - account: ${SNOWFLAKE_ACCOUNT} - user: ${SNOWFLAKE_USER} - password: ${SNOWFLAKE_PASSWORD} - database: ${SNOWFLAKE_DATABASE} - schema: ${SNOWFLAKE_SCHEMA} - warehouse: ${SNOWFLAKE_WAREHOUSE} - role: ${SNOWFLAKE_ROLE} - -tools: - execute_sql: - kind: snowflake-execute-sql - source: snowflake-source - description: Use this tool to execute SQL. - - list_tables: - kind: snowflake-sql - source: snowflake-source - description: "Lists detailed schema information for user-created tables." - statement: | - SELECT table_name, table_type - FROM information_schema.tables - WHERE table_schema = current_schema() - ORDER BY table_name; +kind: sources +name: snowflake-source +type: snowflake +account: ${SNOWFLAKE_ACCOUNT} +user: ${SNOWFLAKE_USER} +password: ${SNOWFLAKE_PASSWORD} +database: ${SNOWFLAKE_DATABASE} +schema: ${SNOWFLAKE_SCHEMA} +warehouse: ${SNOWFLAKE_WAREHOUSE} +role: ${SNOWFLAKE_ROLE} +--- +kind: tools +name: execute_sql +type: snowflake-execute-sql +source: snowflake-source +description: Use this tool to execute SQL. +--- +kind: tools +name: list_tables +type: snowflake-sql +source: snowflake-source +description: "Lists detailed schema information for user-created tables." +statement: | + SELECT table_name, table_type + FROM information_schema.tables + WHERE table_schema = current_schema() + ORDER BY table_name; ``` For more info on tools, check out the diff --git a/docs/en/samples/snowflake/snowflake-config.yaml b/docs/en/samples/snowflake/snowflake-config.yaml index 085433e346..29660de2bf 100644 --- a/docs/en/samples/snowflake/snowflake-config.yaml +++ b/docs/en/samples/snowflake/snowflake-config.yaml @@ -12,57 +12,60 @@ # See the License for the specific language governing permissions and # limitations under the License. -sources: - my-snowflake-db: - kind: snowflake - account: ${SNOWFLAKE_ACCOUNT} - user: ${SNOWFLAKE_USER} - password: ${SNOWFLAKE_PASSWORD} - database: ${SNOWFLAKE_DATABASE} - schema: ${SNOWFLAKE_SCHEMA} - warehouse: ${SNOWFLAKE_WAREHOUSE} # Optional, defaults to COMPUTE_WH if not set - role: ${SNOWFLAKE_ROLE} # Optional, defaults to ACCOUNTADMIN if not set - +kind: sources +name: my-snowflake-db +type: snowflake +account: ${SNOWFLAKE_ACCOUNT} +user: ${SNOWFLAKE_USER} +password: ${SNOWFLAKE_PASSWORD} +database: ${SNOWFLAKE_DATABASE} +schema: ${SNOWFLAKE_SCHEMA} +warehouse: ${SNOWFLAKE_WAREHOUSE} # Optional, defaults to COMPUTE_WH if not set +role: ${SNOWFLAKE_ROLE} # Optional, defaults to ACCOUNTADMIN if not set +--- +kind: tools +name: execute_sql +type: snowflake-execute-sql +source: my-snowflake-db +description: Execute arbitrary SQL statements on Snowflake +--- +kind: tools +name: get_customer_orders +type: snowflake-sql +source: my-snowflake-db +description: Get orders for a specific customer +statement: | + SELECT o.order_id, o.order_date, o.total_amount, o.status + FROM orders o + WHERE o.customer_id = $1 + ORDER BY o.order_date DESC +parameters: + - name: customer_id + type: string + description: The customer ID to look up orders for +--- +kind: tools +name: daily_sales_report +type: snowflake-sql +source: my-snowflake-db +description: Generate daily sales report for a specific date +statement: | + SELECT + DATE(order_date) as sales_date, + COUNT(*) as total_orders, + SUM(total_amount) as total_revenue, + AVG(total_amount) as avg_order_value + FROM orders + WHERE DATE(order_date) = $1 + GROUP BY DATE(order_date) +parameters: + - name: report_date + type: string + description: The date to generate report for (YYYY-MM-DD format) +--- +kind: toolsets +name: snowflake-analytics tools: - execute_sql: - kind: snowflake-execute-sql - source: my-snowflake-db - description: Execute arbitrary SQL statements on Snowflake - - get_customer_orders: - kind: snowflake-sql - source: my-snowflake-db - description: Get orders for a specific customer - statement: | - SELECT o.order_id, o.order_date, o.total_amount, o.status - FROM orders o - WHERE o.customer_id = $1 - ORDER BY o.order_date DESC - parameters: - - name: customer_id - type: string - description: The customer ID to look up orders for - - daily_sales_report: - kind: snowflake-sql - source: my-snowflake-db - description: Generate daily sales report for a specific date - statement: | - SELECT - DATE(order_date) as sales_date, - COUNT(*) as total_orders, - SUM(total_amount) as total_revenue, - AVG(total_amount) as avg_order_value - FROM orders - WHERE DATE(order_date) = $1 - GROUP BY DATE(order_date) - parameters: - - name: report_date - type: string - description: The date to generate report for (YYYY-MM-DD format) - -toolsets: - snowflake-analytics: - - execute_sql - - get_customer_orders - - daily_sales_report + - execute_sql + - get_customer_orders + - daily_sales_report diff --git a/internal/auth/auth.go b/internal/auth/auth.go index e8f15e4f11..5fd30d1f45 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -21,13 +21,13 @@ import ( // AuthServiceConfig is the interface for configuring authentication services. type AuthServiceConfig interface { - AuthServiceConfigKind() string + AuthServiceConfigType() string Initialize() (AuthService, error) } // AuthService is the interface for authentication services. type AuthService interface { - AuthServiceKind() string + AuthServiceType() string GetName() string GetClaimsFromHeader(context.Context, http.Header) (map[string]any, error) ToConfig() AuthServiceConfig diff --git a/internal/auth/google/google.go b/internal/auth/google/google.go index 90cb809589..4027950557 100644 --- a/internal/auth/google/google.go +++ b/internal/auth/google/google.go @@ -23,7 +23,7 @@ import ( "google.golang.org/api/idtoken" ) -const AuthServiceKind string = "google" +const AuthServiceType string = "google" // validate interface var _ auth.AuthServiceConfig = Config{} @@ -31,13 +31,13 @@ var _ auth.AuthServiceConfig = Config{} // Auth service configuration type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` ClientID string `yaml:"clientId" validate:"required"` } -// Returns the auth service kind -func (cfg Config) AuthServiceConfigKind() string { - return AuthServiceKind +// Returns the auth service type +func (cfg Config) AuthServiceConfigType() string { + return AuthServiceType } // Initialize a Google auth service @@ -55,9 +55,9 @@ type AuthService struct { Config } -// Returns the auth service kind -func (a AuthService) AuthServiceKind() string { - return AuthServiceKind +// Returns the auth service type +func (a AuthService) AuthServiceType() string { + return AuthServiceType } func (a AuthService) ToConfig() auth.AuthServiceConfig { diff --git a/internal/embeddingmodels/embeddingmodels.go b/internal/embeddingmodels/embeddingmodels.go index d038dd231e..5f82ee32f1 100644 --- a/internal/embeddingmodels/embeddingmodels.go +++ b/internal/embeddingmodels/embeddingmodels.go @@ -22,12 +22,12 @@ import ( // EmbeddingModelConfig is the interface for configuring embedding models. type EmbeddingModelConfig interface { - EmbeddingModelConfigKind() string + EmbeddingModelConfigType() string Initialize(context.Context) (EmbeddingModel, error) } type EmbeddingModel interface { - EmbeddingModelKind() string + EmbeddingModelType() string ToConfig() EmbeddingModelConfig EmbedParameters(context.Context, []string) ([][]float32, error) } diff --git a/internal/embeddingmodels/gemini/gemini.go b/internal/embeddingmodels/gemini/gemini.go index 1a31060e7b..fa63b12acb 100644 --- a/internal/embeddingmodels/gemini/gemini.go +++ b/internal/embeddingmodels/gemini/gemini.go @@ -23,22 +23,22 @@ import ( "google.golang.org/genai" ) -const EmbeddingModelKind string = "gemini" +const EmbeddingModelType string = "gemini" // validate interface var _ embeddingmodels.EmbeddingModelConfig = Config{} type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Model string `yaml:"model" validate:"required"` ApiKey string `yaml:"apiKey"` Dimension int32 `yaml:"dimension"` } -// Returns the embedding model kind -func (cfg Config) EmbeddingModelConfigKind() string { - return EmbeddingModelKind +// Returns the embedding model type +func (cfg Config) EmbeddingModelConfigType() string { + return EmbeddingModelType } // Initialize a Gemini embedding model @@ -69,9 +69,9 @@ type EmbeddingModel struct { Config } -// Returns the embedding model kind -func (m EmbeddingModel) EmbeddingModelKind() string { - return EmbeddingModelKind +// Returns the embedding model type +func (m EmbeddingModel) EmbeddingModelType() string { + return EmbeddingModelType } func (m EmbeddingModel) ToConfig() embeddingmodels.EmbeddingModelConfig { diff --git a/internal/embeddingmodels/gemini/gemini_test.go b/internal/embeddingmodels/gemini/gemini_test.go index c4c3b8dcdc..e04e1df1b6 100644 --- a/internal/embeddingmodels/gemini/gemini_test.go +++ b/internal/embeddingmodels/gemini/gemini_test.go @@ -15,9 +15,9 @@ package gemini_test import ( + "context" "testing" - yaml "github.com/goccy/go-yaml" "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/embeddingmodels" "github.com/googleapis/genai-toolbox/internal/embeddingmodels/gemini" @@ -34,15 +34,15 @@ func TestParseFromYamlGemini(t *testing.T) { { desc: "basic example", in: ` - embeddingModels: - my-gemini-model: - kind: gemini - model: text-embedding-004 + kind: embeddingModels + name: my-gemini-model + type: gemini + model: text-embedding-004 `, want: map[string]embeddingmodels.EmbeddingModelConfig{ "my-gemini-model": gemini.Config{ Name: "my-gemini-model", - Kind: gemini.EmbeddingModelKind, + Type: gemini.EmbeddingModelType, Model: "text-embedding-004", }, }, @@ -50,17 +50,17 @@ func TestParseFromYamlGemini(t *testing.T) { { desc: "full example with optional fields", in: ` - embeddingModels: - complex-gemini: - kind: gemini - model: text-embedding-004 - apiKey: "test-api-key" - dimension: 768 + kind: embeddingModels + name: complex-gemini + type: gemini + model: text-embedding-004 + apiKey: "test-api-key" + dimension: 768 `, want: map[string]embeddingmodels.EmbeddingModelConfig{ "complex-gemini": gemini.Config{ Name: "complex-gemini", - Kind: gemini.EmbeddingModelKind, + Type: gemini.EmbeddingModelType, Model: "text-embedding-004", ApiKey: "test-api-key", Dimension: 768, @@ -70,16 +70,13 @@ func TestParseFromYamlGemini(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Models server.EmbeddingModelConfigs `yaml:"embeddingModels"` - }{} // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, got, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Models) { - t.Fatalf("incorrect parse: %v", cmp.Diff(tc.want, got.Models)) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: %v", cmp.Diff(tc.want, got)) } }) } @@ -93,32 +90,29 @@ func TestFailParseFromYamlGemini(t *testing.T) { { desc: "missing required model field", in: ` - embeddingModels: - bad-model: - kind: gemini + kind: embeddingModels + name: bad-model + type: gemini `, // Removed the specific model name from the prefix to match your output - err: "unable to parse as \"gemini\": Key: 'Config.Model' Error:Field validation for 'Model' failed on the 'required' tag", + err: "error unmarshaling embeddingModels: unable to parse as \"bad-model\": Key: 'Config.Model' Error:Field validation for 'Model' failed on the 'required' tag", }, { desc: "unknown field", in: ` - embeddingModels: - bad-field: - kind: gemini - model: text-embedding-004 - invalid_param: true + kind: embeddingModels + name: bad-field + type: gemini + model: text-embedding-004 + invalid_param: true `, // Updated to match the specific line-starting format of your error output - err: "unable to parse as \"gemini\": [1:1] unknown field \"invalid_param\"\n> 1 | invalid_param: true\n ^\n 2 | kind: gemini\n 3 | model: text-embedding-004", + err: "error unmarshaling embeddingModels: unable to parse as \"bad-field\": [1:1] unknown field \"invalid_param\"\n> 1 | invalid_param: true\n ^\n 2 | model: text-embedding-004\n 3 | name: bad-field\n 4 | type: gemini", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Models server.EmbeddingModelConfigs `yaml:"embeddingModels"` - }{} - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/prompts/custom/custom.go b/internal/prompts/custom/custom.go index 312b53613c..4ed44c4651 100644 --- a/internal/prompts/custom/custom.go +++ b/internal/prompts/custom/custom.go @@ -25,12 +25,12 @@ import ( type Message = prompts.Message -const kind = "custom" +const resourceType = "custom" -// init registers this prompt kind with the prompt framework. +// init registers this prompt type with the prompt framework. func init() { - if !prompts.Register(kind, newConfig) { - panic(fmt.Sprintf("prompt kind %q already registered", kind)) + if !prompts.Register(resourceType, newConfig) { + panic(fmt.Sprintf("prompt type %q already registered", resourceType)) } } @@ -56,8 +56,8 @@ type Config struct { var _ prompts.PromptConfig = Config{} var _ prompts.Prompt = Prompt{} -func (c Config) PromptConfigKind() string { - return kind +func (c Config) PromptConfigType() string { + return resourceType } func (c Config) Initialize() (prompts.Prompt, error) { diff --git a/internal/prompts/custom/custom_test.go b/internal/prompts/custom/custom_test.go index ff411c7b8b..4f9ad565e5 100644 --- a/internal/prompts/custom/custom_test.go +++ b/internal/prompts/custom/custom_test.go @@ -42,7 +42,7 @@ func TestConfig(t *testing.T) { Arguments: testArgs, } - // initialize and check kind + // initialize and check type p, err := cfg.Initialize() if err != nil { t.Fatalf("Initialize() failed: %v", err) @@ -50,8 +50,8 @@ func TestConfig(t *testing.T) { if p == nil { t.Fatal("Initialize() returned a nil prompt") } - if cfg.PromptConfigKind() != "custom" { - t.Errorf("PromptConfigKind() = %q, want %q", cfg.PromptConfigKind(), "custom") + if cfg.PromptConfigType() != "custom" { + t.Errorf("PromptConfigType() = %q, want %q", cfg.PromptConfigType(), "custom") } t.Run("Manifest", func(t *testing.T) { diff --git a/internal/prompts/prompts.go b/internal/prompts/prompts.go index bac784c4c5..ae8312c49e 100644 --- a/internal/prompts/prompts.go +++ b/internal/prompts/prompts.go @@ -30,40 +30,40 @@ var promptRegistry = make(map[string]PromptConfigFactory) // Register allows individual prompt packages to register their configuration // factory function. This is typically called from an init() function in the -// prompt's package. It associates a 'kind' string with a function that can +// prompt's package. It associates a 'type' string with a function that can // produce the specific PromptConfig type. It returns true if the registration was -// successful, and false if a prompt with the same kind was already registered. -func Register(kind string, factory PromptConfigFactory) bool { - if _, exists := promptRegistry[kind]; exists { - // Prompt with this kind already exists, do not overwrite. +// successful, and false if a prompt with the same type was already registered. +func Register(resourceType string, factory PromptConfigFactory) bool { + if _, exists := promptRegistry[resourceType]; exists { + // Prompt with this type already exists, do not overwrite. return false } - promptRegistry[kind] = factory + promptRegistry[resourceType] = factory return true } -// DecodeConfig looks up the registered factory for the given kind and uses it +// DecodeConfig looks up the registered factory for the given type and uses it // to decode the prompt configuration. -func DecodeConfig(ctx context.Context, kind, name string, decoder *yaml.Decoder) (PromptConfig, error) { - factory, found := promptRegistry[kind] - if !found && kind == "" { - kind = "custom" - factory, found = promptRegistry[kind] +func DecodeConfig(ctx context.Context, resourceType, name string, decoder *yaml.Decoder) (PromptConfig, error) { + factory, found := promptRegistry[resourceType] + if !found && resourceType == "" { + resourceType = "custom" + factory, found = promptRegistry[resourceType] } if !found { - return nil, fmt.Errorf("unknown prompt kind: %q", kind) + return nil, fmt.Errorf("unknown prompt type: %q", resourceType) } promptConfig, err := factory(ctx, name, decoder) if err != nil { - return nil, fmt.Errorf("unable to parse prompt %q as kind %q: %w", name, kind, err) + return nil, fmt.Errorf("unable to parse prompt %q as resourceType %q: %w", name, resourceType, err) } return promptConfig, nil } type PromptConfig interface { - PromptConfigKind() string + PromptConfigType() string Initialize() (Prompt, error) } diff --git a/internal/prompts/prompts_test.go b/internal/prompts/prompts_test.go index d0fe0a95f5..72fbe5c3ce 100644 --- a/internal/prompts/prompts_test.go +++ b/internal/prompts/prompts_test.go @@ -29,16 +29,16 @@ import ( type mockPromptConfig struct { name string - kind string + Type string } -func (m *mockPromptConfig) PromptConfigKind() string { return m.kind } +func (m *mockPromptConfig) PromptConfigType() string { return m.Type } func (m *mockPromptConfig) Initialize() (prompts.Prompt, error) { return nil, nil } var errMockFactory = errors.New("mock factory error") func mockFactory(ctx context.Context, name string, decoder *yaml.Decoder) (prompts.PromptConfig, error) { - return &mockPromptConfig{name: name, kind: "mockKind"}, nil + return &mockPromptConfig{name: name, Type: "mockType"}, nil } func mockErrorFactory(ctx context.Context, name string, decoder *yaml.Decoder) (prompts.PromptConfig, error) { @@ -50,17 +50,17 @@ func TestRegistry(t *testing.T) { ctx := context.Background() t.Run("RegisterAndDecodeSuccess", func(t *testing.T) { - kind := "testKindSuccess" - if !prompts.Register(kind, mockFactory) { + resourceType := "testTypeSuccess" + if !prompts.Register(resourceType, mockFactory) { t.Fatal("expected registration to succeed") } // This should fail because we are registering a duplicate - if prompts.Register(kind, mockFactory) { + if prompts.Register(resourceType, mockFactory) { t.Fatal("expected duplicate registration to fail") } decoder := yaml.NewDecoder(strings.NewReader("")) - config, err := prompts.DecodeConfig(ctx, kind, "testPrompt", decoder) + config, err := prompts.DecodeConfig(ctx, resourceType, "testPrompt", decoder) if err != nil { t.Fatalf("expected DecodeConfig to succeed, but got error: %v", err) } @@ -69,25 +69,25 @@ func TestRegistry(t *testing.T) { } }) - t.Run("DecodeUnknownKind", func(t *testing.T) { + t.Run("DecodeUnknownType", func(t *testing.T) { decoder := yaml.NewDecoder(strings.NewReader("")) - _, err := prompts.DecodeConfig(ctx, "unregisteredKind", "testPrompt", decoder) + _, err := prompts.DecodeConfig(ctx, "unregisteredType", "testPrompt", decoder) if err == nil { - t.Fatal("expected an error for unknown kind, but got nil") + t.Fatal("expected an error for unknown type, but got nil") } - if !strings.Contains(err.Error(), "unknown prompt kind") { - t.Errorf("expected error to contain 'unknown prompt kind', but got: %v", err) + if !strings.Contains(err.Error(), "unknown prompt type") { + t.Errorf("expected error to contain 'unknown prompt type', but got: %v", err) } }) t.Run("FactoryReturnsError", func(t *testing.T) { - kind := "testKindError" - if !prompts.Register(kind, mockErrorFactory) { + resourceType := "testTypeError" + if !prompts.Register(resourceType, mockErrorFactory) { t.Fatal("expected registration to succeed") } decoder := yaml.NewDecoder(strings.NewReader("")) - _, err := prompts.DecodeConfig(ctx, kind, "testPrompt", decoder) + _, err := prompts.DecodeConfig(ctx, resourceType, "testPrompt", decoder) if err == nil { t.Fatal("expected an error from the factory, but got nil") } @@ -100,13 +100,13 @@ func TestRegistry(t *testing.T) { decoder := yaml.NewDecoder(strings.NewReader("description: A test prompt")) config, err := prompts.DecodeConfig(ctx, "", "testDefaultPrompt", decoder) if err != nil { - t.Fatalf("expected DecodeConfig with empty kind to succeed, but got error: %v", err) + t.Fatalf("expected DecodeConfig with empty type to succeed, but got error: %v", err) } if config == nil { - t.Fatal("expected a non-nil config for default kind") + t.Fatal("expected a non-nil config for default type") } - if config.PromptConfigKind() != "custom" { - t.Errorf("expected default kind to be 'custom', but got %q", config.PromptConfigKind()) + if config.PromptConfigType() != "custom" { + t.Errorf("expected default type to be 'custom', but got %q", config.PromptConfigType()) } }) } diff --git a/internal/server/config.go b/internal/server/config.go index 652e7547de..48f623b0ea 100644 --- a/internal/server/config.go +++ b/internal/server/config.go @@ -14,8 +14,10 @@ package server import ( + "bytes" "context" "fmt" + "io" "regexp" "strings" @@ -127,315 +129,264 @@ func (s *StringLevel) Type() string { return "stringLevel" } -// SourceConfigs is a type used to allow unmarshal of the data source config map type SourceConfigs map[string]sources.SourceConfig - -// validate interface -var _ yaml.InterfaceUnmarshalerContext = &SourceConfigs{} - -func (c *SourceConfigs) UnmarshalYAML(ctx context.Context, unmarshal func(interface{}) error) error { - *c = make(SourceConfigs) - // Parse the 'kind' fields for each source - var raw map[string]util.DelayedUnmarshaler - if err := unmarshal(&raw); err != nil { - return err - } - - for name, u := range raw { - // Unmarshal to a general type that ensure it capture all fields - var v map[string]any - if err := u.Unmarshal(&v); err != nil { - return fmt.Errorf("unable to unmarshal %q: %w", name, err) - } - - kind, ok := v["kind"] - if !ok { - return fmt.Errorf("missing 'kind' field for source %q", name) - } - kindStr, ok := kind.(string) - if !ok { - return fmt.Errorf("invalid 'kind' field for source %q (must be a string)", name) - } - - yamlDecoder, err := util.NewStrictDecoder(v) - if err != nil { - return fmt.Errorf("error creating YAML decoder for source %q: %w", name, err) - } - - sourceConfig, err := sources.DecodeConfig(ctx, kindStr, name, yamlDecoder) - if err != nil { - return err - } - (*c)[name] = sourceConfig - } - return nil -} - -// AuthServiceConfigs is a type used to allow unmarshal of the data authService config map type AuthServiceConfigs map[string]auth.AuthServiceConfig - -// validate interface -var _ yaml.InterfaceUnmarshalerContext = &AuthServiceConfigs{} - -func (c *AuthServiceConfigs) UnmarshalYAML(ctx context.Context, unmarshal func(interface{}) error) error { - *c = make(AuthServiceConfigs) - // Parse the 'kind' fields for each authService - var raw map[string]util.DelayedUnmarshaler - if err := unmarshal(&raw); err != nil { - return err - } - - for name, u := range raw { - var v map[string]any - if err := u.Unmarshal(&v); err != nil { - return fmt.Errorf("unable to unmarshal %q: %w", name, err) - } - - kind, ok := v["kind"] - if !ok { - return fmt.Errorf("missing 'kind' field for %q", name) - } - - dec, err := util.NewStrictDecoder(v) - if err != nil { - return fmt.Errorf("error creating decoder: %w", err) - } - switch kind { - case google.AuthServiceKind: - actual := google.Config{Name: name} - if err := dec.DecodeContext(ctx, &actual); err != nil { - return fmt.Errorf("unable to parse as %q: %w", kind, err) - } - (*c)[name] = actual - default: - return fmt.Errorf("%q is not a valid kind of auth source", kind) - } - } - return nil -} - -// EmbeddingModelConfigs is a type used to allow unmarshal of the embedding model config map type EmbeddingModelConfigs map[string]embeddingmodels.EmbeddingModelConfig - -// validate interface -var _ yaml.InterfaceUnmarshalerContext = &EmbeddingModelConfigs{} - -func (c *EmbeddingModelConfigs) UnmarshalYAML(ctx context.Context, unmarshal func(interface{}) error) error { - *c = make(EmbeddingModelConfigs) - // Parse the 'kind' fields for each embedding model - var raw map[string]util.DelayedUnmarshaler - if err := unmarshal(&raw); err != nil { - return err - } - - for name, u := range raw { - // Unmarshal to a general type that ensure it capture all fields - var v map[string]any - if err := u.Unmarshal(&v); err != nil { - return fmt.Errorf("unable to unmarshal embedding model %q: %w", name, err) - } - - kind, ok := v["kind"] - if !ok { - return fmt.Errorf("missing 'kind' field for embedding model %q", name) - } - - dec, err := util.NewStrictDecoder(v) - if err != nil { - return fmt.Errorf("error creating decoder: %w", err) - } - switch kind { - case gemini.EmbeddingModelKind: - actual := gemini.Config{Name: name} - if err := dec.DecodeContext(ctx, &actual); err != nil { - return fmt.Errorf("unable to parse as %q: %w", kind, err) - } - (*c)[name] = actual - default: - return fmt.Errorf("%q is not a valid kind of auth source", kind) - } - } - return nil -} - -// ToolConfigs is a type used to allow unmarshal of the tool configs type ToolConfigs map[string]tools.ToolConfig - -// validate interface -var _ yaml.InterfaceUnmarshalerContext = &ToolConfigs{} - -func (c *ToolConfigs) UnmarshalYAML(ctx context.Context, unmarshal func(interface{}) error) error { - *c = make(ToolConfigs) - // Parse the 'kind' fields for each source - var raw map[string]util.DelayedUnmarshaler - if err := unmarshal(&raw); err != nil { - return err - } - - for name, u := range raw { - err := NameValidation(name) - if err != nil { - return err - } - var v map[string]any - if err := u.Unmarshal(&v); err != nil { - return fmt.Errorf("unable to unmarshal %q: %w", name, err) - } - - // `authRequired` and `useClientOAuth` cannot be specified together - if v["authRequired"] != nil && v["useClientOAuth"] == true { - return fmt.Errorf("`authRequired` and `useClientOAuth` are mutually exclusive. Choose only one authentication method") - } - - // Make `authRequired` an empty list instead of nil for Tool manifest - if v["authRequired"] == nil { - v["authRequired"] = []string{} - } - - kindVal, ok := v["kind"] - if !ok { - return fmt.Errorf("missing 'kind' field for tool %q", name) - } - kindStr, ok := kindVal.(string) - if !ok { - return fmt.Errorf("invalid 'kind' field for tool %q (must be a string)", name) - } - - // validify parameter references - if rawParams, ok := v["parameters"]; ok { - if paramsList, ok := rawParams.([]any); ok { - // Turn params into a map - validParamNames := make(map[string]bool) - for _, rawP := range paramsList { - if pMap, ok := rawP.(map[string]any); ok { - if pName, ok := pMap["name"].(string); ok && pName != "" { - validParamNames[pName] = true - } - } - } - - // Validate references - for i, rawP := range paramsList { - pMap, ok := rawP.(map[string]any) - if !ok { - continue - } - - pName, _ := pMap["name"].(string) - refName, _ := pMap["valueFromParam"].(string) - - if refName != "" { - // Check if the referenced parameter exists - if !validParamNames[refName] { - return fmt.Errorf("tool %q config error: parameter %q (index %d) references '%q' in the 'valueFromParam' field, which is not a defined parameter", name, pName, i, refName) - } - - // Check for self-reference - if refName == pName { - return fmt.Errorf("tool %q config error: parameter %q cannot copy value from itself", name, pName) - } - } - } - } - } - yamlDecoder, err := util.NewStrictDecoder(v) - if err != nil { - return fmt.Errorf("error creating YAML decoder for tool %q: %w", name, err) - } - - toolCfg, err := tools.DecodeConfig(ctx, kindStr, name, yamlDecoder) - if err != nil { - return err - } - (*c)[name] = toolCfg - } - return nil -} - -// ToolsetConfigs is a type used to allow unmarshal of the toolset configs type ToolsetConfigs map[string]tools.ToolsetConfig - -// validate interface -var _ yaml.InterfaceUnmarshalerContext = &ToolsetConfigs{} - -func (c *ToolsetConfigs) UnmarshalYAML(ctx context.Context, unmarshal func(interface{}) error) error { - *c = make(ToolsetConfigs) - - var raw map[string][]string - if err := unmarshal(&raw); err != nil { - return err - } - - for name, toolList := range raw { - (*c)[name] = tools.ToolsetConfig{Name: name, ToolNames: toolList} - } - return nil -} - -// PromptConfigs is a type used to allow unmarshal of the prompt configs type PromptConfigs map[string]prompts.PromptConfig - -// validate interface -var _ yaml.InterfaceUnmarshalerContext = &PromptConfigs{} - -func (c *PromptConfigs) UnmarshalYAML(ctx context.Context, unmarshal func(interface{}) error) error { - *c = make(PromptConfigs) - var raw map[string]util.DelayedUnmarshaler - if err := unmarshal(&raw); err != nil { - return err - } - - for name, u := range raw { - var v map[string]any - if err := u.Unmarshal(&v); err != nil { - return fmt.Errorf("unable to unmarshal prompt %q: %w", name, err) - } - - // Look for the 'kind' field. If it's not present, kindStr will be an - // empty string, which prompts.DecodeConfig will correctly default to "custom". - var kindStr string - if kindVal, ok := v["kind"]; ok { - var isString bool - kindStr, isString = kindVal.(string) - if !isString { - return fmt.Errorf("invalid 'kind' field for prompt %q (must be a string)", name) - } - } - - // Create a new, strict decoder for this specific prompt's data. - yamlDecoder, err := util.NewStrictDecoder(v) - if err != nil { - return fmt.Errorf("error creating YAML decoder for prompt %q: %w", name, err) - } - - // Use the central registry to decode the prompt based on its kind. - promptCfg, err := prompts.DecodeConfig(ctx, kindStr, name, yamlDecoder) - if err != nil { - return err - } - (*c)[name] = promptCfg - } - return nil -} - -// PromptsetConfigs is a type used to allow unmarshal of the PromptsetConfigs configs type PromptsetConfigs map[string]prompts.PromptsetConfig -// validate interface -var _ yaml.InterfaceUnmarshalerContext = &PromptsetConfigs{} +func UnmarshalResourceConfig(ctx context.Context, raw []byte) (SourceConfigs, AuthServiceConfigs, EmbeddingModelConfigs, ToolConfigs, ToolsetConfigs, PromptConfigs, error) { + // prepare configs map + var sourceConfigs SourceConfigs + var authServiceConfigs AuthServiceConfigs + var embeddingModelConfigs EmbeddingModelConfigs + var toolConfigs ToolConfigs + var toolsetConfigs ToolsetConfigs + var promptConfigs PromptConfigs + // promptset configs is not yet supported -func (c *PromptsetConfigs) UnmarshalYAML(ctx context.Context, unmarshal func(interface{}) error) error { - *c = make(PromptsetConfigs) + decoder := yaml.NewDecoder(bytes.NewReader(raw)) + // for loop to unmarshal documents with the `---` separator + for { + var resource map[string]any + if err := decoder.DecodeContext(ctx, &resource); err != nil { + if err == io.EOF { + break + } + return nil, nil, nil, nil, nil, nil, fmt.Errorf("unable to decode YAML document: %w", err) + } + var kind, name string + var ok bool + if kind, ok = resource["kind"].(string); !ok { + return nil, nil, nil, nil, nil, nil, fmt.Errorf("missing 'kind' field or it is not a string: %v", resource) + } + if name, ok = resource["name"].(string); !ok { + return nil, nil, nil, nil, nil, nil, fmt.Errorf("missing 'name' field or it is not a string") + } + // remove 'kind' from map for strict unmarshaling + delete(resource, "kind") + switch kind { + case "sources": + c, err := UnmarshalYAMLSourceConfig(ctx, name, resource) + if err != nil { + return nil, nil, nil, nil, nil, nil, fmt.Errorf("error unmarshaling %s: %s", kind, err) + } + if sourceConfigs == nil { + sourceConfigs = make(SourceConfigs) + } + sourceConfigs[name] = c + case "authServices": + c, err := UnmarshalYAMLAuthServiceConfig(ctx, name, resource) + if err != nil { + return nil, nil, nil, nil, nil, nil, fmt.Errorf("error unmarshaling %s: %s", kind, err) + } + if authServiceConfigs == nil { + authServiceConfigs = make(AuthServiceConfigs) + } + authServiceConfigs[name] = c + case "tools": + c, err := UnmarshalYAMLToolConfig(ctx, name, resource) + if err != nil { + return nil, nil, nil, nil, nil, nil, fmt.Errorf("error unmarshaling %s: %s", kind, err) + } + if toolConfigs == nil { + toolConfigs = make(ToolConfigs) + } + toolConfigs[name] = c + case "toolsets": + c, err := UnmarshalYAMLToolsetConfig(ctx, name, resource) + if err != nil { + return nil, nil, nil, nil, nil, nil, fmt.Errorf("error unmarshaling %s: %s", kind, err) + } + if toolsetConfigs == nil { + toolsetConfigs = make(ToolsetConfigs) + } + toolsetConfigs[name] = c + case "embeddingModels": + c, err := UnmarshalYAMLEmbeddingModelConfig(ctx, name, resource) + if err != nil { + return nil, nil, nil, nil, nil, nil, fmt.Errorf("error unmarshaling %s: %s", kind, err) + } + if embeddingModelConfigs == nil { + embeddingModelConfigs = make(EmbeddingModelConfigs) + } + embeddingModelConfigs[name] = c + case "prompts": + c, err := UnmarshalYAMLPromptConfig(ctx, name, resource) + if err != nil { + return nil, nil, nil, nil, nil, nil, fmt.Errorf("error unmarshaling %s: %s", kind, err) + } + if promptConfigs == nil { + promptConfigs = make(PromptConfigs) + } + promptConfigs[name] = c + default: + return nil, nil, nil, nil, nil, nil, fmt.Errorf("invalid kind %s", kind) + } + } + return sourceConfigs, authServiceConfigs, embeddingModelConfigs, toolConfigs, toolsetConfigs, promptConfigs, nil +} + +func UnmarshalYAMLSourceConfig(ctx context.Context, name string, r map[string]any) (sources.SourceConfig, error) { + resourceType, ok := r["type"].(string) + if !ok { + return nil, fmt.Errorf("missing 'type' field or it is not a string") + } + dec, err := util.NewStrictDecoder(r) + if err != nil { + return nil, fmt.Errorf("error creating decoder: %w", err) + } + sourceConfig, err := sources.DecodeConfig(ctx, resourceType, name, dec) + if err != nil { + return nil, err + } + return sourceConfig, nil +} + +func UnmarshalYAMLAuthServiceConfig(ctx context.Context, name string, r map[string]any) (auth.AuthServiceConfig, error) { + resourceType, ok := r["type"].(string) + if !ok { + return nil, fmt.Errorf("missing 'type' field or it is not a string") + } + if resourceType != google.AuthServiceType { + return nil, fmt.Errorf("%s is not a valid type of auth service", resourceType) + } + dec, err := util.NewStrictDecoder(r) + if err != nil { + return nil, fmt.Errorf("error creating decoder: %s", err) + } + actual := google.Config{Name: name} + if err := dec.DecodeContext(ctx, &actual); err != nil { + return nil, fmt.Errorf("unable to parse as %s: %w", name, err) + } + return actual, nil +} + +func UnmarshalYAMLEmbeddingModelConfig(ctx context.Context, name string, r map[string]any) (embeddingmodels.EmbeddingModelConfig, error) { + resourceType, ok := r["type"].(string) + if !ok { + return nil, fmt.Errorf("missing 'type' field or it is not a string") + } + if resourceType != gemini.EmbeddingModelType { + return nil, fmt.Errorf("%s is not a valid type of embedding model", resourceType) + } + dec, err := util.NewStrictDecoder(r) + if err != nil { + return nil, fmt.Errorf("error creating decoder: %s", err) + } + actual := gemini.Config{Name: name} + if err := dec.DecodeContext(ctx, &actual); err != nil { + return nil, fmt.Errorf("unable to parse as %q: %w", name, err) + } + return actual, nil +} + +func UnmarshalYAMLToolConfig(ctx context.Context, name string, r map[string]any) (tools.ToolConfig, error) { + resourceType, ok := r["type"].(string) + if !ok { + return nil, fmt.Errorf("missing 'type' field or it is not a string") + } + // `authRequired` and `useClientOAuth` cannot be specified together + if r["authRequired"] != nil && r["useClientOAuth"] == true { + return nil, fmt.Errorf("`authRequired` and `useClientOAuth` are mutually exclusive. Choose only one authentication method") + } + // Make `authRequired` an empty list instead of nil for Tool manifest + if r["authRequired"] == nil { + r["authRequired"] = []string{} + } + + // validify parameter references + if rawParams, ok := r["parameters"]; ok { + if paramsList, ok := rawParams.([]any); ok { + // Turn params into a map + validParamNames := make(map[string]bool) + for _, rawP := range paramsList { + if pMap, ok := rawP.(map[string]any); ok { + if pName, ok := pMap["name"].(string); ok && pName != "" { + validParamNames[pName] = true + } + } + } + + // Validate references + for i, rawP := range paramsList { + pMap, ok := rawP.(map[string]any) + if !ok { + continue + } + + pName, _ := pMap["name"].(string) + refName, _ := pMap["valueFromParam"].(string) + + if refName != "" { + // Check if the referenced parameter exists + if !validParamNames[refName] { + return nil, fmt.Errorf("tool %q config error: parameter %q (index %d) references '%q' in the 'valueFromParam' field, which is not a defined parameter", name, pName, i, refName) + } + + // Check for self-reference + if refName == pName { + return nil, fmt.Errorf("tool %q config error: parameter %q cannot copy value from itself", name, pName) + } + } + } + } + } + + dec, err := util.NewStrictDecoder(r) + if err != nil { + return nil, fmt.Errorf("error creating decoder: %s", err) + } + toolCfg, err := tools.DecodeConfig(ctx, resourceType, name, dec) + if err != nil { + return nil, err + } + return toolCfg, nil +} + +func UnmarshalYAMLToolsetConfig(ctx context.Context, name string, r map[string]any) (tools.ToolsetConfig, error) { + var toolsetConfig tools.ToolsetConfig + toolList, ok := r["tools"].([]any) + if !ok { + return toolsetConfig, fmt.Errorf("tools is missing or not a list of strings: %v", r) + } + justTools := map[string]any{"tools": toolList} + dec, err := util.NewStrictDecoder(justTools) + if err != nil { + return toolsetConfig, fmt.Errorf("error creating decoder: %s", err) + } var raw map[string][]string - if err := unmarshal(&raw); err != nil { - return err + if err := dec.DecodeContext(ctx, &raw); err != nil { + return toolsetConfig, fmt.Errorf("unable to unmarshal tools: %s", err) + } + return tools.ToolsetConfig{Name: name, ToolNames: raw["tools"]}, nil +} + +func UnmarshalYAMLPromptConfig(ctx context.Context, name string, r map[string]any) (prompts.PromptConfig, error) { + // Look for the 'type' field. If it's not present, typeStr will be an + // empty string, which prompts.DecodeConfig will correctly default to "custom". + var resourceType string + if typeVal, ok := r["type"]; ok { + var isString bool + resourceType, isString = typeVal.(string) + if !isString { + return nil, fmt.Errorf("invalid 'type' field for prompt %q (must be a string)", name) + } + } + dec, err := util.NewStrictDecoder(r) + if err != nil { + return nil, fmt.Errorf("error creating decoder: %s", err) } - for name, promptList := range raw { - (*c)[name] = prompts.PromptsetConfig{Name: name, PromptNames: promptList} + // Use the central registry to decode the prompt based on its type. + promptCfg, err := prompts.DecodeConfig(ctx, resourceType, name, dec) + if err != nil { + return nil, err } - return nil + return promptCfg, nil } // Tools naming validation is added in the MCP v2025-11-25, but we'll be diff --git a/internal/server/resources/resources_test.go b/internal/server/resources/resources_test.go index ad4bfdd326..e0682a27a9 100644 --- a/internal/server/resources/resources_test.go +++ b/internal/server/resources/resources_test.go @@ -32,7 +32,7 @@ func TestUpdateServer(t *testing.T) { "example-source": &alloydbpg.Source{ Config: alloydbpg.Config{ Name: "example-alloydb-source", - Kind: "alloydb-postgres", + Type: "alloydb-postgres", }, }, } @@ -92,7 +92,7 @@ func TestUpdateServer(t *testing.T) { "example-source2": &alloydbpg.Source{ Config: alloydbpg.Config{ Name: "example-alloydb-source2", - Kind: "alloydb-postgres", + Type: "alloydb-postgres", }, }, } diff --git a/internal/server/server.go b/internal/server/server.go index 961ffc48a3..f77c504113 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -86,7 +86,7 @@ func InitializeConfigs(ctx context.Context, cfg ServerConfig) ( childCtx, span := instrumentation.Tracer.Start( ctx, "toolbox/server/source/init", - trace.WithAttributes(attribute.String("source_kind", sc.SourceConfigKind())), + trace.WithAttributes(attribute.String("source_type", sc.SourceConfigType())), trace.WithAttributes(attribute.String("source_name", name)), ) defer span.End() @@ -114,7 +114,7 @@ func InitializeConfigs(ctx context.Context, cfg ServerConfig) ( _, span := instrumentation.Tracer.Start( ctx, "toolbox/server/auth/init", - trace.WithAttributes(attribute.String("auth_kind", sc.AuthServiceConfigKind())), + trace.WithAttributes(attribute.String("auth_type", sc.AuthServiceConfigType())), trace.WithAttributes(attribute.String("auth_name", name)), ) defer span.End() @@ -142,7 +142,7 @@ func InitializeConfigs(ctx context.Context, cfg ServerConfig) ( _, span := instrumentation.Tracer.Start( ctx, "toolbox/server/embeddingmodel/init", - trace.WithAttributes(attribute.String("model_kind", ec.EmbeddingModelConfigKind())), + trace.WithAttributes(attribute.String("model_type", ec.EmbeddingModelConfigType())), trace.WithAttributes(attribute.String("model_name", name)), ) defer span.End() @@ -170,7 +170,7 @@ func InitializeConfigs(ctx context.Context, cfg ServerConfig) ( _, span := instrumentation.Tracer.Start( ctx, "toolbox/server/tool/init", - trace.WithAttributes(attribute.String("tool_kind", tc.ToolConfigKind())), + trace.WithAttributes(attribute.String("tool_type", tc.ToolConfigType())), trace.WithAttributes(attribute.String("tool_name", name)), ) defer span.End() @@ -239,7 +239,7 @@ func InitializeConfigs(ctx context.Context, cfg ServerConfig) ( _, span := instrumentation.Tracer.Start( ctx, "toolbox/server/prompt/init", - trace.WithAttributes(attribute.String("prompt_kind", pc.PromptConfigKind())), + trace.WithAttributes(attribute.String("prompt_type", pc.PromptConfigType())), trace.WithAttributes(attribute.String("prompt_name", name)), ) defer span.End() diff --git a/internal/server/server_test.go b/internal/server/server_test.go index c13df83be4..ab809fc579 100644 --- a/internal/server/server_test.go +++ b/internal/server/server_test.go @@ -141,7 +141,7 @@ func TestUpdateServer(t *testing.T) { "example-source": &alloydbpg.Source{ Config: alloydbpg.Config{ Name: "example-alloydb-source", - Kind: "alloydb-postgres", + Type: "alloydb-postgres", }, }, } diff --git a/internal/sources/alloydbadmin/alloydbadmin.go b/internal/sources/alloydbadmin/alloydbadmin.go index 633c7eb73e..6a9938d936 100644 --- a/internal/sources/alloydbadmin/alloydbadmin.go +++ b/internal/sources/alloydbadmin/alloydbadmin.go @@ -32,14 +32,14 @@ import ( "google.golang.org/api/option" ) -const SourceKind string = "alloydb-admin" +const SourceType string = "alloydb-admin" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -53,13 +53,13 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` DefaultProject string `yaml:"defaultProject"` UseClientOAuth bool `yaml:"useClientOAuth"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -106,8 +106,8 @@ type Source struct { Service *alloydbrestapi.Service } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { diff --git a/internal/sources/alloydbadmin/alloydbadmin_test.go b/internal/sources/alloydbadmin/alloydbadmin_test.go index b8af21c386..ae4fd9b5e1 100644 --- a/internal/sources/alloydbadmin/alloydbadmin_test.go +++ b/internal/sources/alloydbadmin/alloydbadmin_test.go @@ -15,9 +15,9 @@ package alloydbadmin_test import ( + "context" "testing" - 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/sources" @@ -34,14 +34,14 @@ func TestParseFromYamlAlloyDBAdmin(t *testing.T) { { desc: "basic example", in: ` - sources: - my-alloydb-admin-instance: - kind: alloydb-admin + kind: sources + name: my-alloydb-admin-instance + type: alloydb-admin `, want: map[string]sources.SourceConfig{ "my-alloydb-admin-instance": alloydbadmin.Config{ Name: "my-alloydb-admin-instance", - Kind: alloydbadmin.SourceKind, + Type: alloydbadmin.SourceType, UseClientOAuth: false, }, }, @@ -49,15 +49,15 @@ func TestParseFromYamlAlloyDBAdmin(t *testing.T) { { desc: "use client auth example", in: ` - sources: - my-alloydb-admin-instance: - kind: alloydb-admin - useClientOAuth: true + kind: sources + name: my-alloydb-admin-instance + type: alloydb-admin + useClientOAuth: true `, want: map[string]sources.SourceConfig{ "my-alloydb-admin-instance": alloydbadmin.Config{ Name: "my-alloydb-admin-instance", - Kind: alloydbadmin.SourceKind, + Type: alloydbadmin.SourceType, UseClientOAuth: true, }, }, @@ -65,16 +65,13 @@ func TestParseFromYamlAlloyDBAdmin(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -89,30 +86,27 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - my-alloydb-admin-instance: - kind: alloydb-admin - project: test-project + kind: sources + name: my-alloydb-admin-instance + type: alloydb-admin + project: test-project `, - err: "unable to parse source \"my-alloydb-admin-instance\" as \"alloydb-admin\": [2:1] unknown field \"project\"\n 1 | kind: alloydb-admin\n> 2 | project: test-project\n ^\n", + err: "error unmarshaling sources: unable to parse source \"my-alloydb-admin-instance\" as \"alloydb-admin\": [2:1] unknown field \"project\"\n 1 | name: my-alloydb-admin-instance\n> 2 | project: test-project\n ^\n 3 | type: alloydb-admin", }, { desc: "missing required field", in: ` - sources: - my-alloydb-admin-instance: - useClientOAuth: true + kind: sources + name: my-alloydb-admin-instance + useClientOAuth: true `, - err: "missing 'kind' field for source \"my-alloydb-admin-instance\"", + err: "error unmarshaling sources: missing 'type' field or it is not a string", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/alloydbpg/alloydb_pg.go b/internal/sources/alloydbpg/alloydb_pg.go index 58d8600ebd..74c4eb3a26 100644 --- a/internal/sources/alloydbpg/alloydb_pg.go +++ b/internal/sources/alloydbpg/alloydb_pg.go @@ -29,14 +29,14 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "alloydb-postgres" +const SourceType string = "alloydb-postgres" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -50,7 +50,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Project string `yaml:"project" validate:"required"` Region string `yaml:"region" validate:"required"` Cluster string `yaml:"cluster" validate:"required"` @@ -61,8 +61,8 @@ type Config struct { Database string `yaml:"database" validate:"required"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -90,8 +90,8 @@ type Source struct { Pool *pgxpool.Pool } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -183,7 +183,7 @@ func getConnectionConfig(ctx context.Context, user, pass, dbname string) (string func initAlloyDBPgConnectionPool(ctx context.Context, tracer trace.Tracer, name, project, region, cluster, instance, ipType, user, pass, dbname string) (*pgxpool.Pool, error) { //nolint:all // Reassigned ctx - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() dsn, useIAM, err := getConnectionConfig(ctx, user, pass, dbname) diff --git a/internal/sources/alloydbpg/alloydb_pg_test.go b/internal/sources/alloydbpg/alloydb_pg_test.go index f0ddc57ef9..b1b374b6a4 100644 --- a/internal/sources/alloydbpg/alloydb_pg_test.go +++ b/internal/sources/alloydbpg/alloydb_pg_test.go @@ -15,9 +15,9 @@ package alloydbpg_test import ( + "context" "testing" - 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/sources" @@ -34,21 +34,21 @@ func TestParseFromYamlAlloyDBPg(t *testing.T) { { desc: "basic example", in: ` - sources: - my-pg-instance: - kind: alloydb-postgres - project: my-project - region: my-region - cluster: my-cluster - instance: my-instance - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-pg-instance + type: alloydb-postgres + project: my-project + region: my-region + cluster: my-cluster + instance: my-instance + database: my_db + user: my_user + password: my_pass `, want: map[string]sources.SourceConfig{ "my-pg-instance": alloydbpg.Config{ Name: "my-pg-instance", - Kind: alloydbpg.SourceKind, + Type: alloydbpg.SourceType, Project: "my-project", Region: "my-region", Cluster: "my-cluster", @@ -63,22 +63,22 @@ func TestParseFromYamlAlloyDBPg(t *testing.T) { { desc: "public ipType", in: ` - sources: - my-pg-instance: - kind: alloydb-postgres - project: my-project - region: my-region - cluster: my-cluster - instance: my-instance - ipType: Public - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-pg-instance + type: alloydb-postgres + project: my-project + region: my-region + cluster: my-cluster + instance: my-instance + ipType: Public + database: my_db + user: my_user + password: my_pass `, want: map[string]sources.SourceConfig{ "my-pg-instance": alloydbpg.Config{ Name: "my-pg-instance", - Kind: alloydbpg.SourceKind, + Type: alloydbpg.SourceType, Project: "my-project", Region: "my-region", Cluster: "my-cluster", @@ -93,22 +93,22 @@ func TestParseFromYamlAlloyDBPg(t *testing.T) { { desc: "private ipType", in: ` - sources: - my-pg-instance: - kind: alloydb-postgres - project: my-project - region: my-region - cluster: my-cluster - instance: my-instance - ipType: private - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-pg-instance + type: alloydb-postgres + project: my-project + region: my-region + cluster: my-cluster + instance: my-instance + ipType: private + database: my_db + user: my_user + password: my_pass `, want: map[string]sources.SourceConfig{ "my-pg-instance": alloydbpg.Config{ Name: "my-pg-instance", - Kind: alloydbpg.SourceKind, + Type: alloydbpg.SourceType, Project: "my-project", Region: "my-region", Cluster: "my-cluster", @@ -123,16 +123,13 @@ func TestParseFromYamlAlloyDBPg(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -147,60 +144,56 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "invalid ipType", in: ` - sources: - my-pg-instance: - kind: alloydb-postgres - project: my-project - region: my-region - cluster: my-cluster - instance: my-instance - ipType: fail - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-pg-instance + type: alloydb-postgres + project: my-project + region: my-region + cluster: my-cluster + instance: my-instance + ipType: fail + database: my_db + user: my_user + password: my_pass `, - err: "unable to parse source \"my-pg-instance\" as \"alloydb-postgres\": ipType invalid: must be one of \"public\", \"private\", or \"psc\"", + err: "error unmarshaling sources: unable to parse source \"my-pg-instance\" as \"alloydb-postgres\": ipType invalid: must be one of \"public\", \"private\", or \"psc\"", }, { desc: "extra field", in: ` - sources: - my-pg-instance: - kind: alloydb-postgres - project: my-project - region: my-region - cluster: my-cluster - instance: my-instance - database: my_db - user: my_user - password: my_pass - foo: bar + kind: sources + name: my-pg-instance + type: alloydb-postgres + project: my-project + region: my-region + cluster: my-cluster + instance: my-instance + database: my_db + user: my_user + password: my_pass + foo: bar `, - err: "unable to parse source \"my-pg-instance\" as \"alloydb-postgres\": [3:1] unknown field \"foo\"\n 1 | cluster: my-cluster\n 2 | database: my_db\n> 3 | foo: bar\n ^\n 4 | instance: my-instance\n 5 | kind: alloydb-postgres\n 6 | password: my_pass\n 7 | ", + err: "error unmarshaling sources: unable to parse source \"my-pg-instance\" as \"alloydb-postgres\": [3:1] unknown field \"foo\"\n 1 | cluster: my-cluster\n 2 | database: my_db\n> 3 | foo: bar\n ^\n 4 | instance: my-instance\n 5 | name: my-pg-instance\n 6 | password: my_pass\n 7 | ", }, { desc: "missing required field", in: ` - sources: - my-pg-instance: - kind: alloydb-postgres - region: my-region - cluster: my-cluster - instance: my-instance - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-pg-instance + type: alloydb-postgres + region: my-region + cluster: my-cluster + instance: my-instance + database: my_db + user: my_user + password: my_pass `, - err: "unable to parse source \"my-pg-instance\" as \"alloydb-postgres\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-pg-instance\" as \"alloydb-postgres\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/bigquery/bigquery.go b/internal/sources/bigquery/bigquery.go index b24378c858..527c4e0c3b 100644 --- a/internal/sources/bigquery/bigquery.go +++ b/internal/sources/bigquery/bigquery.go @@ -41,7 +41,7 @@ import ( "google.golang.org/api/option" ) -const SourceKind string = "bigquery" +const SourceType string = "bigquery" // CloudPlatformScope is a broad scope for Google Cloud Platform services. const CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform" @@ -65,8 +65,8 @@ type BigQuerySessionProvider func(ctx context.Context) (*Session, error) type DataplexClientCreator func(tokenString string) (*dataplexapi.CatalogClient, error) func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -81,7 +81,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { // BigQuery configs Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Project string `yaml:"project" validate:"required"` Location string `yaml:"location"` WriteMode string `yaml:"writeMode"` @@ -119,9 +119,9 @@ func (s *StringOrStringSlice) UnmarshalYAML(unmarshal func(any) error) error { return fmt.Errorf("cannot unmarshal %T into StringOrStringSlice", v) } -func (r Config) SourceConfigKind() string { - // Returns BigQuery source kind - return SourceKind +func (r Config) SourceConfigType() string { + // Returns BigQuery source type + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { if r.WriteMode == "" { @@ -302,9 +302,9 @@ type Session struct { LastUsed time.Time } -func (s *Source) SourceKind() string { - // Returns BigQuery Google SQL source kind - return SourceKind +func (s *Source) SourceType() string { + // Returns BigQuery Google SQL source type + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -665,7 +665,7 @@ func initBigQueryConnection( impersonateServiceAccount string, scopes []string, ) (*bigqueryapi.Client, *bigqueryrestapi.Service, oauth2.TokenSource, error) { - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() userAgent, err := util.UserAgentFromContext(ctx) @@ -741,7 +741,7 @@ func initBigQueryConnectionWithOAuthToken( tokenString string, wantRestService bool, ) (*bigqueryapi.Client, *bigqueryrestapi.Service, error) { - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() // Construct token source token := &oauth2.Token{ @@ -801,7 +801,7 @@ func initDataplexConnection( var clientCreator DataplexClientCreator var err error - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() userAgent, err := util.UserAgentFromContext(ctx) diff --git a/internal/sources/bigquery/bigquery_test.go b/internal/sources/bigquery/bigquery_test.go index a23f1b47bd..d2883a94f7 100644 --- a/internal/sources/bigquery/bigquery_test.go +++ b/internal/sources/bigquery/bigquery_test.go @@ -15,18 +15,18 @@ package bigquery_test import ( + "context" "math/big" "reflect" "testing" - yaml "github.com/goccy/go-yaml" "github.com/google/go-cmp/cmp" - "go.opentelemetry.io/otel/trace/noop" - "github.com/googleapis/genai-toolbox/internal/server" + "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/bigquery" "github.com/googleapis/genai-toolbox/internal/testutils" "github.com/googleapis/genai-toolbox/internal/util" + "go.opentelemetry.io/otel/trace/noop" ) func TestParseFromYamlBigQuery(t *testing.T) { @@ -38,15 +38,15 @@ func TestParseFromYamlBigQuery(t *testing.T) { { desc: "basic example", in: ` - sources: - my-instance: - kind: bigquery - project: my-project + kind: sources + name: my-instance + type: bigquery + project: my-project `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-instance": bigquery.Config{ Name: "my-instance", - Kind: bigquery.SourceKind, + Type: bigquery.SourceType, Project: "my-project", Location: "", WriteMode: "", @@ -56,17 +56,17 @@ func TestParseFromYamlBigQuery(t *testing.T) { { desc: "all fields specified", in: ` - sources: - my-instance: - kind: bigquery - project: my-project - location: asia - writeMode: blocked + kind: sources + name: my-instance + type: bigquery + project: my-project + location: asia + writeMode: blocked `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-instance": bigquery.Config{ Name: "my-instance", - Kind: bigquery.SourceKind, + Type: bigquery.SourceType, Project: "my-project", Location: "asia", WriteMode: "blocked", @@ -77,17 +77,17 @@ func TestParseFromYamlBigQuery(t *testing.T) { { desc: "use client auth example", in: ` - sources: - my-instance: - kind: bigquery - project: my-project - location: us - useClientOAuth: true + kind: sources + name: my-instance + type: bigquery + project: my-project + location: us + useClientOAuth: true `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-instance": bigquery.Config{ Name: "my-instance", - Kind: bigquery.SourceKind, + Type: bigquery.SourceType, Project: "my-project", Location: "us", UseClientOAuth: true, @@ -97,18 +97,18 @@ func TestParseFromYamlBigQuery(t *testing.T) { { desc: "with allowed datasets example", in: ` - sources: - my-instance: - kind: bigquery - project: my-project - location: us - allowedDatasets: - - my_dataset + kind: sources + name: my-instance + type: bigquery + project: my-project + location: us + allowedDatasets: + - my_dataset `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-instance": bigquery.Config{ Name: "my-instance", - Kind: bigquery.SourceKind, + Type: bigquery.SourceType, Project: "my-project", Location: "us", AllowedDatasets: []string{"my_dataset"}, @@ -118,17 +118,17 @@ func TestParseFromYamlBigQuery(t *testing.T) { { desc: "with service account impersonation example", in: ` - sources: - my-instance: - kind: bigquery - project: my-project - location: us - impersonateServiceAccount: service-account@my-project.iam.gserviceaccount.com + kind: sources + name: my-instance + type: bigquery + project: my-project + location: us + impersonateServiceAccount: service-account@my-project.iam.gserviceaccount.com `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-instance": bigquery.Config{ Name: "my-instance", - Kind: bigquery.SourceKind, + Type: bigquery.SourceType, Project: "my-project", Location: "us", ImpersonateServiceAccount: "service-account@my-project.iam.gserviceaccount.com", @@ -138,19 +138,19 @@ func TestParseFromYamlBigQuery(t *testing.T) { { desc: "with custom scopes example", in: ` - sources: - my-instance: - kind: bigquery - project: my-project - location: us - scopes: - - https://www.googleapis.com/auth/bigquery - - https://www.googleapis.com/auth/cloud-platform + kind: sources + name: my-instance + type: bigquery + project: my-project + location: us + scopes: + - https://www.googleapis.com/auth/bigquery + - https://www.googleapis.com/auth/cloud-platform `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-instance": bigquery.Config{ Name: "my-instance", - Kind: bigquery.SourceKind, + Type: bigquery.SourceType, Project: "my-project", Location: "us", Scopes: []string{"https://www.googleapis.com/auth/bigquery", "https://www.googleapis.com/auth/cloud-platform"}, @@ -160,17 +160,17 @@ func TestParseFromYamlBigQuery(t *testing.T) { { desc: "with max query result rows example", in: ` - sources: - my-instance: - kind: bigquery - project: my-project - location: us - maxQueryResultRows: 10 + kind: sources + name: my-instance + type: bigquery + project: my-project + location: us + maxQueryResultRows: 10 `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-instance": bigquery.Config{ Name: "my-instance", - Kind: bigquery.SourceKind, + Type: bigquery.SourceType, Project: "my-project", Location: "us", MaxQueryResultRows: 10, @@ -180,20 +180,15 @@ func TestParseFromYamlBigQuery(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if diff := cmp.Diff(tc.want, got); diff != "" { + t.Fatalf("incorrect parse (-want +got):\n%s", diff) } }) } - } func TestFailParseFromYaml(t *testing.T) { @@ -205,33 +200,29 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - my-instance: - kind: bigquery - project: my-project - location: us - foo: bar + kind: sources + name: my-instance + type: bigquery + project: my-project + location: us + foo: bar `, - err: "unable to parse source \"my-instance\" as \"bigquery\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | kind: bigquery\n 3 | location: us\n 4 | project: my-project", + err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"bigquery\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | location: us\n 3 | name: my-instance\n 4 | project: my-project\n 5 | ", }, { desc: "missing required field", in: ` - sources: - my-instance: - kind: bigquery - location: us + kind: sources + name: my-instance + type: bigquery + location: us `, - err: "unable to parse source \"my-instance\" as \"bigquery\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"bigquery\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } @@ -260,7 +251,7 @@ func TestInitialize_MaxQueryResultRows(t *testing.T) { desc: "default value", cfg: bigquery.Config{ Name: "test-default", - Kind: bigquery.SourceKind, + Type: bigquery.SourceType, Project: "test-project", UseClientOAuth: true, }, @@ -270,7 +261,7 @@ func TestInitialize_MaxQueryResultRows(t *testing.T) { desc: "configured value", cfg: bigquery.Config{ Name: "test-configured", - Kind: bigquery.SourceKind, + Type: bigquery.SourceType, Project: "test-project", UseClientOAuth: true, MaxQueryResultRows: 100, diff --git a/internal/sources/bigtable/bigtable.go b/internal/sources/bigtable/bigtable.go index 22daf64c37..16b5f30651 100644 --- a/internal/sources/bigtable/bigtable.go +++ b/internal/sources/bigtable/bigtable.go @@ -27,14 +27,14 @@ import ( "google.golang.org/api/option" ) -const SourceKind string = "bigtable" +const SourceType string = "bigtable" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -48,13 +48,13 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Project string `yaml:"project" validate:"required"` Instance string `yaml:"instance" validate:"required"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -77,8 +77,8 @@ type Source struct { Client *bigtable.Client } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -179,7 +179,7 @@ func (s *Source) RunSQL(ctx context.Context, statement string, configParam param func initBigtableClient(ctx context.Context, tracer trace.Tracer, name, project, instance string) (*bigtable.Client, error) { //nolint:all // Reassigned ctx - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() // Set up Bigtable data operations client. diff --git a/internal/sources/bigtable/bigtable_test.go b/internal/sources/bigtable/bigtable_test.go index c3f2a7d3dc..253f6e14ff 100644 --- a/internal/sources/bigtable/bigtable_test.go +++ b/internal/sources/bigtable/bigtable_test.go @@ -15,9 +15,9 @@ package bigtable_test import ( + "context" "testing" - 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/sources" @@ -34,16 +34,16 @@ func TestParseFromYamlBigtableDb(t *testing.T) { { desc: "can configure with a bigtable table", in: ` - sources: - my-bigtable-instance: - kind: bigtable - project: my-project - instance: my-instance + kind: sources + name: my-bigtable-instance + type: bigtable + project: my-project + instance: my-instance `, want: map[string]sources.SourceConfig{ "my-bigtable-instance": bigtable.Config{ Name: "my-bigtable-instance", - Kind: bigtable.SourceKind, + Type: bigtable.SourceType, Project: "my-project", Instance: "my-instance", }, @@ -52,16 +52,12 @@ func TestParseFromYamlBigtableDb(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -77,33 +73,29 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - my-bigtable-instance: - kind: bigtable - project: my-project - instance: my-instance - foo: bar + kind: sources + name: my-bigtable-instance + type: bigtable + project: my-project + instance: my-instance + foo: bar `, - err: "unable to parse source \"my-bigtable-instance\" as \"bigtable\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | instance: my-instance\n 3 | kind: bigtable\n 4 | project: my-project", + err: "error unmarshaling sources: unable to parse source \"my-bigtable-instance\" as \"bigtable\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | instance: my-instance\n 3 | name: my-bigtable-instance\n 4 | project: my-project\n 5 | ", }, { desc: "missing required field", in: ` - sources: - my-bigtable-instance: - kind: bigtable - project: my-project + kind: sources + name: my-bigtable-instance + type: bigtable + project: my-project `, - err: "unable to parse source \"my-bigtable-instance\" as \"bigtable\": Key: 'Config.Instance' Error:Field validation for 'Instance' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-bigtable-instance\" as \"bigtable\": Key: 'Config.Instance' Error:Field validation for 'Instance' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/cassandra/cassandra.go b/internal/sources/cassandra/cassandra.go index 49c070bf06..44d8b362bc 100644 --- a/internal/sources/cassandra/cassandra.go +++ b/internal/sources/cassandra/cassandra.go @@ -25,11 +25,11 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "cassandra" +const SourceType string = "cassandra" func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -43,7 +43,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Hosts []string `yaml:"hosts" validate:"required"` Keyspace string `yaml:"keyspace"` ProtoVersion int `yaml:"protoVersion"` @@ -68,9 +68,9 @@ func (c Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.So return s, nil } -// SourceConfigKind implements sources.SourceConfig. -func (c Config) SourceConfigKind() string { - return SourceKind +// SourceConfigType implements sources.SourceConfig. +func (c Config) SourceConfigType() string { + return SourceType } var _ sources.SourceConfig = Config{} @@ -89,9 +89,9 @@ func (s *Source) ToConfig() sources.SourceConfig { return s.Config } -// SourceKind implements sources.Source. -func (s *Source) SourceKind() string { - return SourceKind +// SourceType implements sources.Source. +func (s *Source) SourceType() string { + return SourceType } func (s *Source) RunSQL(ctx context.Context, statement string, params parameters.ParamValues) (any, error) { @@ -120,7 +120,7 @@ var _ sources.Source = &Source{} func initCassandraSession(ctx context.Context, tracer trace.Tracer, c Config) (*gocql.Session, error) { //nolint:all // Reassigned ctx - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, c.Name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, c.Name) defer span.End() // Validate authentication configuration diff --git a/internal/sources/cassandra/cassandra_test.go b/internal/sources/cassandra/cassandra_test.go index ddcbb3debe..e37e9c846e 100644 --- a/internal/sources/cassandra/cassandra_test.go +++ b/internal/sources/cassandra/cassandra_test.go @@ -15,11 +15,12 @@ package cassandra_test import ( + "context" "testing" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/cassandra" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -33,17 +34,17 @@ func TestParseFromYamlCassandra(t *testing.T) { { desc: "basic example (without optional fields)", in: ` - sources: - my-cassandra-instance: - kind: cassandra - hosts: - - "my-host1" - - "my-host2" + kind: sources + name: my-cassandra-instance + type: cassandra + hosts: + - "my-host1" + - "my-host2" `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-cassandra-instance": cassandra.Config{ Name: "my-cassandra-instance", - Kind: cassandra.SourceKind, + Type: cassandra.SourceType, Hosts: []string{"my-host1", "my-host2"}, Username: "", Password: "", @@ -59,25 +60,25 @@ func TestParseFromYamlCassandra(t *testing.T) { { desc: "with optional fields", in: ` - sources: - my-cassandra-instance: - kind: cassandra - hosts: - - "my-host1" - - "my-host2" - username: "user" - password: "pass" - keyspace: "example_keyspace" - protoVersion: 4 - caPath: "path/to/ca.crt" - certPath: "path/to/cert" - keyPath: "path/to/key" - enableHostVerification: true + kind: sources + name: my-cassandra-instance + type: cassandra + hosts: + - "my-host1" + - "my-host2" + username: "user" + password: "pass" + keyspace: "example_keyspace" + protoVersion: 4 + caPath: "path/to/ca.crt" + certPath: "path/to/cert" + keyPath: "path/to/key" + enableHostVerification: true `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-cassandra-instance": cassandra.Config{ Name: "my-cassandra-instance", - Kind: cassandra.SourceKind, + Type: cassandra.SourceType, Hosts: []string{"my-host1", "my-host2"}, Username: "user", Password: "pass", @@ -93,16 +94,12 @@ func TestParseFromYamlCassandra(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -118,33 +115,29 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - my-cassandra-instance: - kind: cassandra - hosts: - - "my-host" - foo: bar + kind: sources + name: my-cassandra-instance + type: cassandra + hosts: + - "my-host" + foo: bar `, - err: "unable to parse source \"my-cassandra-instance\" as \"cassandra\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | hosts:\n 3 | - my-host\n 4 | kind: cassandra", + err: "error unmarshaling sources: unable to parse source \"my-cassandra-instance\" as \"cassandra\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | hosts:\n 3 | - my-host\n 4 | name: my-cassandra-instance\n 5 | ", }, { desc: "missing required field", in: ` - sources: - my-cassandra-instance: - kind: cassandra + kind: sources + name: my-cassandra-instance + type: cassandra `, - err: "unable to parse source \"my-cassandra-instance\" as \"cassandra\": Key: 'Config.Hosts' Error:Field validation for 'Hosts' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-cassandra-instance\" as \"cassandra\": Key: 'Config.Hosts' Error:Field validation for 'Hosts' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/clickhouse/clickhouse.go b/internal/sources/clickhouse/clickhouse.go index 3f0b6f961b..599522ec1b 100644 --- a/internal/sources/clickhouse/clickhouse.go +++ b/internal/sources/clickhouse/clickhouse.go @@ -28,14 +28,14 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "clickhouse" +const SourceType string = "clickhouse" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -49,7 +49,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Host string `yaml:"host" validate:"required"` Port string `yaml:"port" validate:"required"` Database string `yaml:"database" validate:"required"` @@ -59,8 +59,8 @@ type Config struct { Secure bool `yaml:"secure"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -88,8 +88,8 @@ type Source struct { Pool *sql.DB } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -174,7 +174,7 @@ func validateConfig(protocol string) error { func initClickHouseConnectionPool(ctx context.Context, tracer trace.Tracer, name, host, port, user, pass, dbname, protocol string, secure bool) (*sql.DB, error) { //nolint:all // Reassigned ctx - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() if protocol == "" { diff --git a/internal/sources/clickhouse/clickhouse_test.go b/internal/sources/clickhouse/clickhouse_test.go index 7a1bd321eb..59830d107b 100644 --- a/internal/sources/clickhouse/clickhouse_test.go +++ b/internal/sources/clickhouse/clickhouse_test.go @@ -21,137 +21,113 @@ import ( "github.com/goccy/go-yaml" "github.com/google/go-cmp/cmp" + "github.com/googleapis/genai-toolbox/internal/server" + "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/testutils" "go.opentelemetry.io/otel" ) -func TestConfigSourceConfigKind(t *testing.T) { - config := Config{} - if config.SourceConfigKind() != SourceKind { - t.Errorf("Expected %s, got %s", SourceKind, config.SourceConfigKind()) +func TestParseFromYamlClickhouse(t *testing.T) { + tcs := []struct { + desc string + in string + want server.SourceConfigs + }{ + { + desc: "all fields specified", + in: ` + kind: sources + name: test-clickhouse + type: clickhouse + host: localhost + port: "8443" + user: default + password: "mypass" + database: mydb + protocol: https + secure: true + `, + want: map[string]sources.SourceConfig{ + "test-clickhouse": Config{ + Name: "test-clickhouse", + Type: "clickhouse", + Host: "localhost", + Port: "8443", + User: "default", + Password: "mypass", + Database: "mydb", + Protocol: "https", + Secure: true, + }, + }, + }, + { + desc: "minimal configuration with defaults", + in: ` + kind: sources + name: minimal-clickhouse + type: clickhouse + host: 127.0.0.1 + port: "8123" + user: testuser + database: testdb + `, + want: map[string]sources.SourceConfig{ + "minimal-clickhouse": Config{ + Name: "minimal-clickhouse", + Type: "clickhouse", + Host: "127.0.0.1", + Port: "8123", + User: "testuser", + Password: "", + Database: "testdb", + Protocol: "", + Secure: false, + }, + }, + }, + } + for _, tc := range tcs { + t.Run(tc.desc, func(t *testing.T) { + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) + if err != nil { + t.Fatalf("unable to unmarshal: %s", err) + } + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) + } + }) } } -func TestNewConfig(t *testing.T) { - tests := []struct { - name string - yaml string - expected Config +func TestFailParseFromYaml(t *testing.T) { + tcs := []struct { + desc string + in string + err string }{ { - name: "all fields specified", - yaml: ` - name: test-clickhouse - kind: clickhouse - host: localhost - port: "8443" - user: default - password: "mypass" - database: mydb - protocol: https - secure: true + desc: "extra field", + in: ` + kind: sources + name: test-clickhouse + type: clickhouse + host: localhost + foo: bar `, - expected: Config{ - Name: "test-clickhouse", - Kind: "clickhouse", - Host: "localhost", - Port: "8443", - User: "default", - Password: "mypass", - Database: "mydb", - Protocol: "https", - Secure: true, - }, - }, - { - name: "minimal configuration with defaults", - yaml: ` - name: minimal-clickhouse - kind: clickhouse - host: 127.0.0.1 - port: "8123" - user: testuser - database: testdb - `, - expected: Config{ - Name: "minimal-clickhouse", - Kind: "clickhouse", - Host: "127.0.0.1", - Port: "8123", - User: "testuser", - Password: "", - Database: "testdb", - Protocol: "", - Secure: false, - }, - }, - { - name: "http protocol", - yaml: ` - name: http-clickhouse - kind: clickhouse - host: clickhouse.example.com - port: "8123" - user: analytics - password: "securepass" - database: analytics_db - protocol: http - secure: false - `, - expected: Config{ - Name: "http-clickhouse", - Kind: "clickhouse", - Host: "clickhouse.example.com", - Port: "8123", - User: "analytics", - Password: "securepass", - Database: "analytics_db", - Protocol: "http", - Secure: false, - }, - }, - { - name: "https with secure connection", - yaml: ` - name: secure-clickhouse - kind: clickhouse - host: secure.clickhouse.io - port: "8443" - user: secureuser - password: "verysecure" - database: production - protocol: https - secure: true - `, - expected: Config{ - Name: "secure-clickhouse", - Kind: "clickhouse", - Host: "secure.clickhouse.io", - Port: "8443", - User: "secureuser", - Password: "verysecure", - Database: "production", - Protocol: "https", - Secure: true, - }, + err: "error unmarshaling sources: unable to parse source \"test-clickhouse\" as \"clickhouse\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | host: localhost\n 3 | name: test-clickhouse\n 4 | type: clickhouse", }, } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - decoder := yaml.NewDecoder(strings.NewReader(string(testutils.FormatYaml(tt.yaml)))) - config, err := newConfig(context.Background(), tt.expected.Name, decoder) - if err != nil { - t.Fatalf("Failed to create config: %v", err) + for _, tc := range tcs { + t.Run(tc.desc, func(t *testing.T) { + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) + if err == nil { + t.Fatalf("expect parsing to fail") } - - clickhouseConfig, ok := config.(Config) - if !ok { - t.Fatalf("Expected Config type, got %T", config) - } - - if diff := cmp.Diff(tt.expected, clickhouseConfig); diff != "" { - t.Errorf("Config mismatch (-want +got):\n%s", diff) + errStr := err.Error() + if errStr != tc.err { + t.Fatalf("unexpected error: got %q, want %q", errStr, tc.err) } }) } @@ -167,19 +143,11 @@ func TestNewConfigInvalidYAML(t *testing.T) { name: "invalid yaml syntax", yaml: ` name: test-clickhouse - kind: clickhouse + type: clickhouse host: [invalid `, expectError: true, }, - { - name: "missing required fields", - yaml: ` - name: test-clickhouse - kind: clickhouse - `, - expectError: false, - }, } for _, tt := range tests { @@ -196,10 +164,10 @@ func TestNewConfigInvalidYAML(t *testing.T) { } } -func TestSource_SourceKind(t *testing.T) { +func TestSource_SourceType(t *testing.T) { source := &Source{} - if source.SourceKind() != SourceKind { - t.Errorf("Expected %s, got %s", SourceKind, source.SourceKind()) + if source.SourceType() != SourceType { + t.Errorf("Expected %s, got %s", SourceType, source.SourceType()) } } diff --git a/internal/sources/cloudgda/cloud_gda.go b/internal/sources/cloudgda/cloud_gda.go index 5743991647..80e8df431c 100644 --- a/internal/sources/cloudgda/cloud_gda.go +++ b/internal/sources/cloudgda/cloud_gda.go @@ -29,15 +29,15 @@ import ( "golang.org/x/oauth2/google" ) -const SourceKind string = "cloud-gemini-data-analytics" +const SourceType string = "cloud-gemini-data-analytics" const Endpoint string = "https://geminidataanalytics.googleapis.com" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -51,13 +51,13 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` ProjectID string `yaml:"projectId" validate:"required"` UseClientOAuth bool `yaml:"useClientOAuth"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } // Initialize initializes a Gemini Data Analytics Source instance. @@ -102,8 +102,8 @@ type Source struct { userAgent string } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { diff --git a/internal/sources/cloudgda/cloud_gda_test.go b/internal/sources/cloudgda/cloud_gda_test.go index 30b977729d..6ec771f601 100644 --- a/internal/sources/cloudgda/cloud_gda_test.go +++ b/internal/sources/cloudgda/cloud_gda_test.go @@ -20,7 +20,6 @@ import ( "path/filepath" "testing" - 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/sources" @@ -39,15 +38,15 @@ func TestParseFromYamlCloudGDA(t *testing.T) { { desc: "basic example", in: ` - sources: - my-gda-instance: - kind: cloud-gemini-data-analytics - projectId: test-project-id - `, + kind: sources + name: my-gda-instance + type: cloud-gemini-data-analytics + projectId: test-project-id + `, want: map[string]sources.SourceConfig{ "my-gda-instance": cloudgda.Config{ Name: "my-gda-instance", - Kind: cloudgda.SourceKind, + Type: cloudgda.SourceType, ProjectID: "test-project-id", UseClientOAuth: false, }, @@ -56,16 +55,16 @@ func TestParseFromYamlCloudGDA(t *testing.T) { { desc: "use client auth example", in: ` - sources: - my-gda-instance: - kind: cloud-gemini-data-analytics - projectId: another-project - useClientOAuth: true + kind: sources + name: my-gda-instance + type: cloud-gemini-data-analytics + projectId: another-project + useClientOAuth: true `, want: map[string]sources.SourceConfig{ "my-gda-instance": cloudgda.Config{ Name: "my-gda-instance", - Kind: cloudgda.SourceKind, + Type: cloudgda.SourceType, ProjectID: "another-project", UseClientOAuth: true, }, @@ -76,16 +75,12 @@ func TestParseFromYamlCloudGDA(t *testing.T) { tc := tc t.Run(tc.desc, func(t *testing.T) { t.Parallel() - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -101,22 +96,18 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "missing projectId", in: ` - sources: - my-gda-instance: - kind: cloud-gemini-data-analytics + kind: sources + name: my-gda-instance + type: cloud-gemini-data-analytics `, - err: "unable to parse source \"my-gda-instance\" as \"cloud-gemini-data-analytics\": Key: 'Config.ProjectID' Error:Field validation for 'ProjectID' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-gda-instance\" as \"cloud-gemini-data-analytics\": Key: 'Config.ProjectID' Error:Field validation for 'ProjectID' failed on the 'required' tag", }, } for _, tc := range tcs { tc := tc t.Run(tc.desc, func(t *testing.T) { t.Parallel() - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } @@ -153,12 +144,12 @@ func TestInitialize(t *testing.T) { }{ { desc: "initialize with ADC", - cfg: cloudgda.Config{Name: "test-gda", Kind: cloudgda.SourceKind, ProjectID: "test-proj"}, + cfg: cloudgda.Config{Name: "test-gda", Type: cloudgda.SourceType, ProjectID: "test-proj"}, wantClientOAuth: false, }, { desc: "initialize with client OAuth", - cfg: cloudgda.Config{Name: "test-gda-oauth", Kind: cloudgda.SourceKind, ProjectID: "test-proj", UseClientOAuth: true}, + cfg: cloudgda.Config{Name: "test-gda-oauth", Type: cloudgda.SourceType, ProjectID: "test-proj", UseClientOAuth: true}, wantClientOAuth: true, }, } diff --git a/internal/sources/cloudhealthcare/cloud_healthcare.go b/internal/sources/cloudhealthcare/cloud_healthcare.go index 82cfbd583e..b3c5e3ede8 100644 --- a/internal/sources/cloudhealthcare/cloud_healthcare.go +++ b/internal/sources/cloudhealthcare/cloud_healthcare.go @@ -34,7 +34,7 @@ import ( "google.golang.org/api/option" ) -const SourceKind string = "cloud-healthcare" +const SourceType string = "cloud-healthcare" // validate interface var _ sources.SourceConfig = Config{} @@ -42,8 +42,8 @@ var _ sources.SourceConfig = Config{} type HealthcareServiceCreator func(tokenString string) (*healthcare.Service, error) func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -58,7 +58,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { // Healthcare configs Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Project string `yaml:"project" validate:"required"` Region string `yaml:"region" validate:"required"` Dataset string `yaml:"dataset" validate:"required"` @@ -67,8 +67,8 @@ type Config struct { UseClientOAuth bool `yaml:"useClientOAuth"` } -func (c Config) SourceConfigKind() string { - return SourceKind +func (c Config) SourceConfigType() string { + return SourceType } func (c Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -144,7 +144,7 @@ func newHealthcareServiceCreator(ctx context.Context, tracer trace.Tracer, name } func initHealthcareConnectionWithOAuthToken(ctx context.Context, tracer trace.Tracer, name string, userAgent string, tokenString string) (*healthcare.Service, error) { - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() // Construct token source token := &oauth2.Token{ @@ -162,7 +162,7 @@ func initHealthcareConnectionWithOAuthToken(ctx context.Context, tracer trace.Tr } func initHealthcareConnection(ctx context.Context, tracer trace.Tracer, name string) (*healthcare.Service, oauth2.TokenSource, error) { - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() cred, err := google.FindDefaultCredentials(ctx, healthcare.CloudHealthcareScope) @@ -194,8 +194,8 @@ type Source struct { allowedDICOMStores map[string]struct{} } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -517,14 +517,14 @@ func (s *Source) RetrieveRenderedDICOMInstance(storeID, study, series, sop strin return base64String, nil } -func (s *Source) SearchDICOM(toolKind, storeID, dicomWebPath, tokenStr string, opts []googleapi.CallOption) (any, error) { +func (s *Source) SearchDICOM(toolType, storeID, dicomWebPath, tokenStr string, opts []googleapi.CallOption) (any, error) { svc, err := s.getService(tokenStr) if err != nil { return nil, err } name := fmt.Sprintf("projects/%s/locations/%s/datasets/%s/dicomStores/%s", s.Project(), s.Region(), s.DatasetID(), storeID) var resp *http.Response - switch toolKind { + switch toolType { case "cloud-healthcare-search-dicom-instances": resp, err = svc.Projects.Locations.Datasets.DicomStores.SearchForInstances(name, dicomWebPath).Do(opts...) case "cloud-healthcare-search-dicom-series": @@ -532,7 +532,7 @@ func (s *Source) SearchDICOM(toolKind, storeID, dicomWebPath, tokenStr string, o case "cloud-healthcare-search-dicom-studies": resp, err = svc.Projects.Locations.Datasets.DicomStores.SearchForStudies(name, dicomWebPath).Do(opts...) default: - return nil, fmt.Errorf("incompatible tool kind: %s", toolKind) + return nil, fmt.Errorf("incompatible tool type: %s", toolType) } if err != nil { return nil, fmt.Errorf("failed to search dicom series: %w", err) diff --git a/internal/sources/cloudhealthcare/cloud_healthcare_test.go b/internal/sources/cloudhealthcare/cloud_healthcare_test.go index 688a701cba..4d4e75c9aa 100644 --- a/internal/sources/cloudhealthcare/cloud_healthcare_test.go +++ b/internal/sources/cloudhealthcare/cloud_healthcare_test.go @@ -15,11 +15,12 @@ package cloudhealthcare_test import ( + "context" "testing" - "github.com/goccy/go-yaml" "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" + "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/cloudhealthcare" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -33,17 +34,17 @@ func TestParseFromYamlCloudHealthcare(t *testing.T) { { desc: "basic example", in: ` - sources: - my-instance: - kind: cloud-healthcare - project: my-project - region: us-central1 - dataset: my-dataset + kind: sources + name: my-instance + type: cloud-healthcare + project: my-project + region: us-central1 + dataset: my-dataset `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-instance": cloudhealthcare.Config{ Name: "my-instance", - Kind: cloudhealthcare.SourceKind, + Type: cloudhealthcare.SourceType, Project: "my-project", Region: "us-central1", Dataset: "my-dataset", @@ -54,18 +55,18 @@ func TestParseFromYamlCloudHealthcare(t *testing.T) { { desc: "use client auth example", in: ` - sources: - my-instance: - kind: cloud-healthcare - project: my-project - region: us - dataset: my-dataset - useClientOAuth: true + kind: sources + name: my-instance + type: cloud-healthcare + project: my-project + region: us + dataset: my-dataset + useClientOAuth: true `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-instance": cloudhealthcare.Config{ Name: "my-instance", - Kind: cloudhealthcare.SourceKind, + Type: cloudhealthcare.SourceType, Project: "my-project", Region: "us", Dataset: "my-dataset", @@ -76,22 +77,22 @@ func TestParseFromYamlCloudHealthcare(t *testing.T) { { desc: "with allowed stores example", in: ` - sources: - my-instance: - kind: cloud-healthcare - project: my-project - region: us - dataset: my-dataset - allowedFhirStores: - - my-fhir-store - allowedDicomStores: - - my-dicom-store1 - - my-dicom-store2 + kind: sources + name: my-instance + type: cloud-healthcare + project: my-project + region: us + dataset: my-dataset + allowedFhirStores: + - my-fhir-store + allowedDicomStores: + - my-dicom-store1 + - my-dicom-store2 `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-instance": cloudhealthcare.Config{ Name: "my-instance", - Kind: cloudhealthcare.SourceKind, + Type: cloudhealthcare.SourceType, Project: "my-project", Region: "us", Dataset: "my-dataset", @@ -103,16 +104,12 @@ func TestParseFromYamlCloudHealthcare(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -127,35 +124,31 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - my-instance: - kind: cloud-healthcare - project: my-project - region: us-central1 - dataset: my-dataset - foo: bar + kind: sources + name: my-instance + type: cloud-healthcare + project: my-project + region: us-central1 + dataset: my-dataset + foo: bar `, - err: "unable to parse source \"my-instance\" as \"cloud-healthcare\": [2:1] unknown field \"foo\"\n 1 | dataset: my-dataset\n> 2 | foo: bar\n ^\n 3 | kind: cloud-healthcare\n 4 | project: my-project\n 5 | region: us-central1", + err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"cloud-healthcare\": [2:1] unknown field \"foo\"\n 1 | dataset: my-dataset\n> 2 | foo: bar\n ^\n 3 | name: my-instance\n 4 | project: my-project\n 5 | region: us-central1\n 6 | ", }, { desc: "missing required field", in: ` - sources: - my-instance: - kind: cloud-healthcare - project: my-project - region: us-central1 + kind: sources + name: my-instance + type: cloud-healthcare + project: my-project + region: us-central1 `, - err: `unable to parse source "my-instance" as "cloud-healthcare": Key: 'Config.Dataset' Error:Field validation for 'Dataset' failed on the 'required' tag`, + err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"cloud-healthcare\": Key: 'Config.Dataset' Error:Field validation for 'Dataset' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/cloudmonitoring/cloud_monitoring.go b/internal/sources/cloudmonitoring/cloud_monitoring.go index eb478dce24..e59204a7b6 100644 --- a/internal/sources/cloudmonitoring/cloud_monitoring.go +++ b/internal/sources/cloudmonitoring/cloud_monitoring.go @@ -29,14 +29,14 @@ import ( monitoring "google.golang.org/api/monitoring/v3" ) -const SourceKind string = "cloud-monitoring" +const SourceType string = "cloud-monitoring" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -50,12 +50,12 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` UseClientOAuth bool `yaml:"useClientOAuth"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } // Initialize initializes a Cloud Monitoring Source instance. @@ -99,8 +99,8 @@ type Source struct { userAgent string } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { diff --git a/internal/sources/cloudmonitoring/cloud_monitoring_test.go b/internal/sources/cloudmonitoring/cloud_monitoring_test.go index 329af6a2a4..cd9533929f 100644 --- a/internal/sources/cloudmonitoring/cloud_monitoring_test.go +++ b/internal/sources/cloudmonitoring/cloud_monitoring_test.go @@ -15,9 +15,9 @@ package cloudmonitoring_test import ( + "context" "testing" - 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/sources" @@ -35,14 +35,14 @@ func TestParseFromYamlCloudMonitoring(t *testing.T) { { desc: "basic example", in: ` - sources: - my-cloud-monitoring-instance: - kind: cloud-monitoring + kind: sources + name: my-cloud-monitoring-instance + type: cloud-monitoring `, want: map[string]sources.SourceConfig{ "my-cloud-monitoring-instance": cloudmonitoring.Config{ Name: "my-cloud-monitoring-instance", - Kind: cloudmonitoring.SourceKind, + Type: cloudmonitoring.SourceType, UseClientOAuth: false, }, }, @@ -50,15 +50,15 @@ func TestParseFromYamlCloudMonitoring(t *testing.T) { { desc: "use client auth example", in: ` - sources: - my-cloud-monitoring-instance: - kind: cloud-monitoring - useClientOAuth: true + kind: sources + name: my-cloud-monitoring-instance + type: cloud-monitoring + useClientOAuth: true `, want: map[string]sources.SourceConfig{ "my-cloud-monitoring-instance": cloudmonitoring.Config{ Name: "my-cloud-monitoring-instance", - Kind: cloudmonitoring.SourceKind, + Type: cloudmonitoring.SourceType, UseClientOAuth: true, }, }, @@ -68,16 +68,12 @@ func TestParseFromYamlCloudMonitoring(t *testing.T) { tc := tc t.Run(tc.desc, func(t *testing.T) { t.Parallel() - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -93,36 +89,28 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - my-cloud-monitoring-instance: - kind: cloud-monitoring - project: test-project + kind: sources + name: my-cloud-monitoring-instance + type: cloud-monitoring + project: test-project `, - err: `unable to parse source "my-cloud-monitoring-instance" as "cloud-monitoring": [2:1] unknown field "project" - 1 | kind: cloud-monitoring -> 2 | project: test-project - ^ -`, + err: "error unmarshaling sources: unable to parse source \"my-cloud-monitoring-instance\" as \"cloud-monitoring\": [2:1] unknown field \"project\"\n 1 | name: my-cloud-monitoring-instance\n> 2 | project: test-project\n ^\n 3 | type: cloud-monitoring", }, { desc: "missing required field", in: ` - sources: - my-cloud-monitoring-instance: - useClientOAuth: true + kind: sources + name: my-cloud-monitoring-instance + useClientOAuth: true `, - err: "missing 'kind' field for source \"my-cloud-monitoring-instance\"", + err: "error unmarshaling sources: missing 'type' field or it is not a string", }, } for _, tc := range tcs { tc := tc t.Run(tc.desc, func(t *testing.T) { t.Parallel() - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/cloudsqladmin/cloud_sql_admin.go b/internal/sources/cloudsqladmin/cloud_sql_admin.go index 9e22f56aa1..9f8ea53e30 100644 --- a/internal/sources/cloudsqladmin/cloud_sql_admin.go +++ b/internal/sources/cloudsqladmin/cloud_sql_admin.go @@ -35,7 +35,7 @@ import ( sqladmin "google.golang.org/api/sqladmin/v1" ) -const SourceKind string = "cloud-sql-admin" +const SourceType string = "cloud-sql-admin" var ( targetLinkRegex = regexp.MustCompile(`/projects/([^/]+)/instances/([^/]+)/databases/([^/]+)`) @@ -46,8 +46,8 @@ var ( var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -61,13 +61,13 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` DefaultProject string `yaml:"defaultProject"` UseClientOAuth bool `yaml:"useClientOAuth"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } // Initialize initializes a CloudSQL Admin Source instance. @@ -114,8 +114,8 @@ type Source struct { Service *sqladmin.Service } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { diff --git a/internal/sources/cloudsqladmin/cloud_sql_admin_test.go b/internal/sources/cloudsqladmin/cloud_sql_admin_test.go index 4138a0a7c4..f597de6c37 100644 --- a/internal/sources/cloudsqladmin/cloud_sql_admin_test.go +++ b/internal/sources/cloudsqladmin/cloud_sql_admin_test.go @@ -15,9 +15,9 @@ package cloudsqladmin_test import ( + "context" "testing" - 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/sources" @@ -35,14 +35,14 @@ func TestParseFromYamlCloudSQLAdmin(t *testing.T) { { desc: "basic example", in: ` - sources: - my-cloud-sql-admin-instance: - kind: cloud-sql-admin + kind: sources + name: my-cloud-sql-admin-instance + type: cloud-sql-admin `, want: map[string]sources.SourceConfig{ "my-cloud-sql-admin-instance": cloudsqladmin.Config{ Name: "my-cloud-sql-admin-instance", - Kind: cloudsqladmin.SourceKind, + Type: cloudsqladmin.SourceType, UseClientOAuth: false, }, }, @@ -50,15 +50,15 @@ func TestParseFromYamlCloudSQLAdmin(t *testing.T) { { desc: "use client auth example", in: ` - sources: - my-cloud-sql-admin-instance: - kind: cloud-sql-admin - useClientOAuth: true + kind: sources + name: my-cloud-sql-admin-instance + type: cloud-sql-admin + useClientOAuth: true `, want: map[string]sources.SourceConfig{ "my-cloud-sql-admin-instance": cloudsqladmin.Config{ Name: "my-cloud-sql-admin-instance", - Kind: cloudsqladmin.SourceKind, + Type: cloudsqladmin.SourceType, UseClientOAuth: true, }, }, @@ -68,16 +68,12 @@ func TestParseFromYamlCloudSQLAdmin(t *testing.T) { tc := tc t.Run(tc.desc, func(t *testing.T) { t.Parallel() - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -93,36 +89,28 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - my-cloud-sql-admin-instance: - kind: cloud-sql-admin - project: test-project + kind: sources + name: my-cloud-sql-admin-instance + type: cloud-sql-admin + project: test-project `, - err: `unable to parse source "my-cloud-sql-admin-instance" as "cloud-sql-admin": [2:1] unknown field "project" - 1 | kind: cloud-sql-admin -> 2 | project: test-project - ^ -`, + err: "error unmarshaling sources: unable to parse source \"my-cloud-sql-admin-instance\" as \"cloud-sql-admin\": [2:1] unknown field \"project\"\n 1 | name: my-cloud-sql-admin-instance\n> 2 | project: test-project\n ^\n 3 | type: cloud-sql-admin", }, { desc: "missing required field", in: ` - sources: - my-cloud-sql-admin-instance: - useClientOAuth: true + kind: sources + name: my-cloud-sql-admin-instance + useClientOAuth: true `, - err: "missing 'kind' field for source \"my-cloud-sql-admin-instance\"", + err: "error unmarshaling sources: missing 'type' field or it is not a string", }, } for _, tc := range tcs { tc := tc t.Run(tc.desc, func(t *testing.T) { t.Parallel() - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/cloudsqlmssql/cloud_sql_mssql.go b/internal/sources/cloudsqlmssql/cloud_sql_mssql.go index 02480df326..9ea632b1bb 100644 --- a/internal/sources/cloudsqlmssql/cloud_sql_mssql.go +++ b/internal/sources/cloudsqlmssql/cloud_sql_mssql.go @@ -29,14 +29,14 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "cloud-sql-mssql" +const SourceType string = "cloud-sql-mssql" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -51,7 +51,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { // Cloud SQL MSSQL configs Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Project string `yaml:"project" validate:"required"` Region string `yaml:"region" validate:"required"` Instance string `yaml:"instance" validate:"required"` @@ -62,9 +62,9 @@ type Config struct { Database string `yaml:"database" validate:"required"` } -func (r Config) SourceConfigKind() string { - // Returns Cloud SQL MSSQL source kind - return SourceKind +func (r Config) SourceConfigType() string { + // Returns Cloud SQL MSSQL source type + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -94,9 +94,9 @@ type Source struct { Db *sql.DB } -func (s *Source) SourceKind() string { - // Returns Cloud SQL MSSQL source kind - return SourceKind +func (s *Source) SourceType() string { + // Returns Cloud SQL MSSQL source type + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -152,7 +152,7 @@ func (s *Source) RunSQL(ctx context.Context, statement string, params []any) (an func initCloudSQLMssqlConnection(ctx context.Context, tracer trace.Tracer, name, project, region, instance, ipType, user, pass, dbname string) (*sql.DB, error) { //nolint:all // Reassigned ctx - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() userAgent, err := util.UserAgentFromContext(ctx) diff --git a/internal/sources/cloudsqlmssql/cloud_sql_mssql_test.go b/internal/sources/cloudsqlmssql/cloud_sql_mssql_test.go index 4af46d63ca..3f7b975d38 100644 --- a/internal/sources/cloudsqlmssql/cloud_sql_mssql_test.go +++ b/internal/sources/cloudsqlmssql/cloud_sql_mssql_test.go @@ -15,11 +15,12 @@ package cloudsqlmssql_test import ( + "context" "testing" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlmssql" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -33,20 +34,20 @@ func TestParseFromYamlCloudSQLMssql(t *testing.T) { { desc: "basic example", in: ` - sources: - my-instance: - kind: cloud-sql-mssql - project: my-project - region: my-region - instance: my-instance - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-instance + type: cloud-sql-mssql + project: my-project + region: my-region + instance: my-instance + database: my_db + user: my_user + password: my_pass `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-instance": cloudsqlmssql.Config{ Name: "my-instance", - Kind: cloudsqlmssql.SourceKind, + Type: cloudsqlmssql.SourceType, Project: "my-project", Region: "my-region", Instance: "my-instance", @@ -60,21 +61,21 @@ func TestParseFromYamlCloudSQLMssql(t *testing.T) { { desc: "psc ipType", in: ` - sources: - my-instance: - kind: cloud-sql-mssql - project: my-project - region: my-region - instance: my-instance - database: my_db - user: my_user - password: my_pass - ipType: psc + kind: sources + name: my-instance + type: cloud-sql-mssql + project: my-project + region: my-region + instance: my-instance + database: my_db + user: my_user + password: my_pass + ipType: psc `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-instance": cloudsqlmssql.Config{ Name: "my-instance", - Kind: cloudsqlmssql.SourceKind, + Type: cloudsqlmssql.SourceType, Project: "my-project", Region: "my-region", Instance: "my-instance", @@ -88,21 +89,21 @@ func TestParseFromYamlCloudSQLMssql(t *testing.T) { { desc: "with deprecated ipAddress", in: ` - sources: - my-instance: - kind: cloud-sql-mssql - project: my-project - region: my-region - instance: my-instance - ipAddress: random - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-instance + type: cloud-sql-mssql + project: my-project + region: my-region + instance: my-instance + ipAddress: random + database: my_db + user: my_user + password: my_pass `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-instance": cloudsqlmssql.Config{ Name: "my-instance", - Kind: cloudsqlmssql.SourceKind, + Type: cloudsqlmssql.SourceType, Project: "my-project", Region: "my-region", Instance: "my-instance", @@ -117,16 +118,12 @@ func TestParseFromYamlCloudSQLMssql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect psarse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect psarse: want %v, got %v", tc.want, got) } }) } @@ -142,57 +139,53 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "invalid ipType", in: ` - sources: - my-instance: - kind: cloud-sql-mssql - project: my-project - region: my-region - instance: my-instance - ipType: fail - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-instance + type: cloud-sql-mssql + project: my-project + region: my-region + instance: my-instance + ipType: fail + database: my_db + user: my_user + password: my_pass `, - err: "unable to parse source \"my-instance\" as \"cloud-sql-mssql\": ipType invalid: must be one of \"public\", \"private\", or \"psc\"", + err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"cloud-sql-mssql\": ipType invalid: must be one of \"public\", \"private\", or \"psc\"", }, { desc: "extra field", in: ` - sources: - my-instance: - kind: cloud-sql-mssql - project: my-project - region: my-region - instance: my-instance - database: my_db - user: my_user - password: my_pass - foo: bar + kind: sources + name: my-instance + type: cloud-sql-mssql + project: my-project + region: my-region + instance: my-instance + database: my_db + user: my_user + password: my_pass + foo: bar `, - err: "unable to parse source \"my-instance\" as \"cloud-sql-mssql\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | instance: my-instance\n 4 | kind: cloud-sql-mssql\n 5 | password: my_pass\n 6 | ", + err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"cloud-sql-mssql\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | instance: my-instance\n 4 | name: my-instance\n 5 | password: my_pass\n 6 | ", }, { desc: "missing required field", in: ` - sources: - my-instance: - kind: cloud-sql-mssql - region: my-region - instance: my-instance - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-instance + type: cloud-sql-mssql + region: my-region + instance: my-instance + database: my_db + user: my_user + password: my_pass `, - err: "unable to parse source \"my-instance\" as \"cloud-sql-mssql\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"cloud-sql-mssql\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/cloudsqlmysql/cloud_sql_mysql.go b/internal/sources/cloudsqlmysql/cloud_sql_mysql.go index 759f00af7d..648f817de4 100644 --- a/internal/sources/cloudsqlmysql/cloud_sql_mysql.go +++ b/internal/sources/cloudsqlmysql/cloud_sql_mysql.go @@ -30,14 +30,14 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "cloud-sql-mysql" +const SourceType string = "cloud-sql-mysql" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -51,7 +51,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Project string `yaml:"project" validate:"required"` Region string `yaml:"region" validate:"required"` Instance string `yaml:"instance" validate:"required"` @@ -61,8 +61,8 @@ type Config struct { Database string `yaml:"database" validate:"required"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -90,8 +90,8 @@ type Source struct { Pool *sql.DB } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -184,7 +184,7 @@ func getConnectionConfig(ctx context.Context, user, pass string) (string, string func initCloudSQLMySQLConnectionPool(ctx context.Context, tracer trace.Tracer, name, project, region, instance, ipType, user, pass, dbname string) (*sql.DB, error) { //nolint:all // Reassigned ctx - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() // Configure the driver to connect to the database diff --git a/internal/sources/cloudsqlmysql/cloud_sql_mysql_test.go b/internal/sources/cloudsqlmysql/cloud_sql_mysql_test.go index 74e9d9dd82..9946abab09 100644 --- a/internal/sources/cloudsqlmysql/cloud_sql_mysql_test.go +++ b/internal/sources/cloudsqlmysql/cloud_sql_mysql_test.go @@ -15,11 +15,12 @@ package cloudsqlmysql_test import ( + "context" "testing" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlmysql" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -33,20 +34,20 @@ func TestParseFromYamlCloudSQLMySQL(t *testing.T) { { desc: "basic example", in: ` - sources: - my-mysql-instance: - kind: cloud-sql-mysql - project: my-project - region: my-region - instance: my-instance - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-mysql-instance + type: cloud-sql-mysql + project: my-project + region: my-region + instance: my-instance + database: my_db + user: my_user + password: my_pass `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-mysql-instance": cloudsqlmysql.Config{ Name: "my-mysql-instance", - Kind: cloudsqlmysql.SourceKind, + Type: cloudsqlmysql.SourceType, Project: "my-project", Region: "my-region", Instance: "my-instance", @@ -60,21 +61,21 @@ func TestParseFromYamlCloudSQLMySQL(t *testing.T) { { desc: "public ipType", in: ` - sources: - my-mysql-instance: - kind: cloud-sql-mysql - project: my-project - region: my-region - instance: my-instance - ipType: Public - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-mysql-instance + type: cloud-sql-mysql + project: my-project + region: my-region + instance: my-instance + ipType: Public + database: my_db + user: my_user + password: my_pass `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-mysql-instance": cloudsqlmysql.Config{ Name: "my-mysql-instance", - Kind: cloudsqlmysql.SourceKind, + Type: cloudsqlmysql.SourceType, Project: "my-project", Region: "my-region", Instance: "my-instance", @@ -88,21 +89,21 @@ func TestParseFromYamlCloudSQLMySQL(t *testing.T) { { desc: "private ipType", in: ` - sources: - my-mysql-instance: - kind: cloud-sql-mysql - project: my-project - region: my-region - instance: my-instance - ipType: private - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-mysql-instance + type: cloud-sql-mysql + project: my-project + region: my-region + instance: my-instance + ipType: private + database: my_db + user: my_user + password: my_pass `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-mysql-instance": cloudsqlmysql.Config{ Name: "my-mysql-instance", - Kind: cloudsqlmysql.SourceKind, + Type: cloudsqlmysql.SourceType, Project: "my-project", Region: "my-region", Instance: "my-instance", @@ -116,21 +117,21 @@ func TestParseFromYamlCloudSQLMySQL(t *testing.T) { { desc: "psc ipType", in: ` - sources: - my-mysql-instance: - kind: cloud-sql-mysql - project: my-project - region: my-region - instance: my-instance - ipType: psc - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-mysql-instance + type: cloud-sql-mysql + project: my-project + region: my-region + instance: my-instance + ipType: psc + database: my_db + user: my_user + password: my_pass `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-mysql-instance": cloudsqlmysql.Config{ Name: "my-mysql-instance", - Kind: cloudsqlmysql.SourceKind, + Type: cloudsqlmysql.SourceType, Project: "my-project", Region: "my-region", Instance: "my-instance", @@ -144,16 +145,12 @@ func TestParseFromYamlCloudSQLMySQL(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -169,57 +166,53 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "invalid ipType", in: ` - sources: - my-mysql-instance: - kind: cloud-sql-mysql - project: my-project - region: my-region - instance: my-instance - ipType: fail - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-mysql-instance + type: cloud-sql-mysql + project: my-project + region: my-region + instance: my-instance + ipType: fail + database: my_db + user: my_user + password: my_pass `, - err: "unable to parse source \"my-mysql-instance\" as \"cloud-sql-mysql\": ipType invalid: must be one of \"public\", \"private\", or \"psc\"", + err: "error unmarshaling sources: unable to parse source \"my-mysql-instance\" as \"cloud-sql-mysql\": ipType invalid: must be one of \"public\", \"private\", or \"psc\"", }, { desc: "extra field", in: ` - sources: - my-mysql-instance: - kind: cloud-sql-mysql - project: my-project - region: my-region - instance: my-instance - database: my_db - user: my_user - password: my_pass - foo: bar + kind: sources + name: my-mysql-instance + type: cloud-sql-mysql + project: my-project + region: my-region + instance: my-instance + database: my_db + user: my_user + password: my_pass + foo: bar `, - err: "unable to parse source \"my-mysql-instance\" as \"cloud-sql-mysql\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | instance: my-instance\n 4 | kind: cloud-sql-mysql\n 5 | password: my_pass\n 6 | ", + err: "error unmarshaling sources: unable to parse source \"my-mysql-instance\" as \"cloud-sql-mysql\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | instance: my-instance\n 4 | name: my-mysql-instance\n 5 | password: my_pass\n 6 | ", }, { desc: "missing required field", in: ` - sources: - my-mysql-instance: - kind: cloud-sql-mysql - region: my-region - instance: my-instance - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-mysql-instance + type: cloud-sql-mysql + region: my-region + instance: my-instance + database: my_db + user: my_user + password: my_pass `, - err: "unable to parse source \"my-mysql-instance\" as \"cloud-sql-mysql\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-mysql-instance\" as \"cloud-sql-mysql\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/cloudsqlpg/cloud_sql_pg.go b/internal/sources/cloudsqlpg/cloud_sql_pg.go index dc7e59be3d..3309768892 100644 --- a/internal/sources/cloudsqlpg/cloud_sql_pg.go +++ b/internal/sources/cloudsqlpg/cloud_sql_pg.go @@ -28,14 +28,14 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "cloud-sql-postgres" +const SourceType string = "cloud-sql-postgres" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -49,7 +49,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Project string `yaml:"project" validate:"required"` Region string `yaml:"region" validate:"required"` Instance string `yaml:"instance" validate:"required"` @@ -59,8 +59,8 @@ type Config struct { Password string `yaml:"password"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -88,8 +88,8 @@ type Source struct { Pool *pgxpool.Pool } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -162,7 +162,7 @@ func getConnectionConfig(ctx context.Context, user, pass, dbname string) (string func initCloudSQLPgConnectionPool(ctx context.Context, tracer trace.Tracer, name, project, region, instance, ipType, user, pass, dbname string) (*pgxpool.Pool, error) { //nolint:all // Reassigned ctx - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() // Configure the driver to connect to the database diff --git a/internal/sources/cloudsqlpg/cloud_sql_pg_test.go b/internal/sources/cloudsqlpg/cloud_sql_pg_test.go index 0b833a94e0..2f0f0118d2 100644 --- a/internal/sources/cloudsqlpg/cloud_sql_pg_test.go +++ b/internal/sources/cloudsqlpg/cloud_sql_pg_test.go @@ -15,11 +15,12 @@ package cloudsqlpg_test import ( + "context" "testing" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlpg" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -33,20 +34,20 @@ func TestParseFromYamlCloudSQLPg(t *testing.T) { { desc: "basic example", in: ` - sources: - my-pg-instance: - kind: cloud-sql-postgres - project: my-project - region: my-region - instance: my-instance - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-pg-instance + type: cloud-sql-postgres + project: my-project + region: my-region + instance: my-instance + database: my_db + user: my_user + password: my_pass `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-pg-instance": cloudsqlpg.Config{ Name: "my-pg-instance", - Kind: cloudsqlpg.SourceKind, + Type: cloudsqlpg.SourceType, Project: "my-project", Region: "my-region", Instance: "my-instance", @@ -60,21 +61,21 @@ func TestParseFromYamlCloudSQLPg(t *testing.T) { { desc: "public ipType", in: ` - sources: - my-pg-instance: - kind: cloud-sql-postgres - project: my-project - region: my-region - instance: my-instance - ipType: Public - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-pg-instance + type: cloud-sql-postgres + project: my-project + region: my-region + instance: my-instance + ipType: Public + database: my_db + user: my_user + password: my_pass `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-pg-instance": cloudsqlpg.Config{ Name: "my-pg-instance", - Kind: cloudsqlpg.SourceKind, + Type: cloudsqlpg.SourceType, Project: "my-project", Region: "my-region", Instance: "my-instance", @@ -88,21 +89,21 @@ func TestParseFromYamlCloudSQLPg(t *testing.T) { { desc: "private ipType", in: ` - sources: - my-pg-instance: - kind: cloud-sql-postgres - project: my-project - region: my-region - instance: my-instance - ipType: private - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-pg-instance + type: cloud-sql-postgres + project: my-project + region: my-region + instance: my-instance + ipType: private + database: my_db + user: my_user + password: my_pass `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-pg-instance": cloudsqlpg.Config{ Name: "my-pg-instance", - Kind: cloudsqlpg.SourceKind, + Type: cloudsqlpg.SourceType, Project: "my-project", Region: "my-region", Instance: "my-instance", @@ -116,21 +117,21 @@ func TestParseFromYamlCloudSQLPg(t *testing.T) { { desc: "psc ipType", in: ` - sources: - my-pg-instance: - kind: cloud-sql-postgres - project: my-project - region: my-region - instance: my-instance - ipType: psc - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-pg-instance + type: cloud-sql-postgres + project: my-project + region: my-region + instance: my-instance + ipType: psc + database: my_db + user: my_user + password: my_pass `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-pg-instance": cloudsqlpg.Config{ Name: "my-pg-instance", - Kind: cloudsqlpg.SourceKind, + Type: cloudsqlpg.SourceType, Project: "my-project", Region: "my-region", Instance: "my-instance", @@ -144,16 +145,12 @@ func TestParseFromYamlCloudSQLPg(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -169,57 +166,53 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "invalid ipType", in: ` - sources: - my-pg-instance: - kind: cloud-sql-postgres - project: my-project - region: my-region - instance: my-instance - ipType: fail - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-pg-instance + type: cloud-sql-postgres + project: my-project + region: my-region + instance: my-instance + ipType: fail + database: my_db + user: my_user + password: my_pass `, - err: "unable to parse source \"my-pg-instance\" as \"cloud-sql-postgres\": ipType invalid: must be one of \"public\", \"private\", or \"psc\"", + err: "error unmarshaling sources: unable to parse source \"my-pg-instance\" as \"cloud-sql-postgres\": ipType invalid: must be one of \"public\", \"private\", or \"psc\"", }, { desc: "extra field", in: ` - sources: - my-pg-instance: - kind: cloud-sql-postgres - project: my-project - region: my-region - instance: my-instance - database: my_db - user: my_user - password: my_pass - foo: bar + kind: sources + name: my-pg-instance + type: cloud-sql-postgres + project: my-project + region: my-region + instance: my-instance + database: my_db + user: my_user + password: my_pass + foo: bar `, - err: "unable to parse source \"my-pg-instance\" as \"cloud-sql-postgres\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | instance: my-instance\n 4 | kind: cloud-sql-postgres\n 5 | password: my_pass\n 6 | ", + err: "error unmarshaling sources: unable to parse source \"my-pg-instance\" as \"cloud-sql-postgres\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | instance: my-instance\n 4 | name: my-pg-instance\n 5 | password: my_pass\n 6 | ", }, { desc: "missing required field", in: ` - sources: - my-pg-instance: - kind: cloud-sql-postgres - region: my-region - instance: my-instance - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-pg-instance + type: cloud-sql-postgres + region: my-region + instance: my-instance + database: my_db + user: my_user + password: my_pass `, - err: "unable to parse source \"my-pg-instance\" as \"cloud-sql-postgres\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-pg-instance\" as \"cloud-sql-postgres\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/couchbase/couchbase.go b/internal/sources/couchbase/couchbase.go index c273a47ec0..222acb0f5b 100644 --- a/internal/sources/couchbase/couchbase.go +++ b/internal/sources/couchbase/couchbase.go @@ -29,14 +29,14 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "couchbase" +const SourceType string = "couchbase" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -50,7 +50,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` ConnectionString string `yaml:"connectionString" validate:"required"` Bucket string `yaml:"bucket" validate:"required"` Scope string `yaml:"scope" validate:"required"` @@ -66,8 +66,8 @@ type Config struct { QueryScanConsistency uint `yaml:"queryScanConsistency"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -96,8 +96,8 @@ type Source struct { Scope *gocb.Scope } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { diff --git a/internal/sources/couchbase/couchbase_test.go b/internal/sources/couchbase/couchbase_test.go index 43677333c4..3fb8efc034 100644 --- a/internal/sources/couchbase/couchbase_test.go +++ b/internal/sources/couchbase/couchbase_test.go @@ -15,11 +15,12 @@ package couchbase_test import ( + "context" "testing" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/couchbase" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -33,19 +34,19 @@ func TestParseFromYamlCouchbase(t *testing.T) { { desc: "basic example", in: ` - sources: - my-couchbase-instance: - kind: couchbase - connectionString: localhost - username: Administrator - password: password - bucket: travel-sample - scope: inventory + kind: sources + name: my-couchbase-instance + type: couchbase + connectionString: localhost + username: Administrator + password: password + bucket: travel-sample + scope: inventory `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-couchbase-instance": couchbase.Config{ Name: "my-couchbase-instance", - Kind: couchbase.SourceKind, + Type: couchbase.SourceType, ConnectionString: "localhost", Username: "Administrator", Password: "password", @@ -57,24 +58,24 @@ func TestParseFromYamlCouchbase(t *testing.T) { { desc: "with TLS configuration", in: ` - sources: - my-couchbase-instance: - kind: couchbase - connectionString: couchbases://localhost - bucket: travel-sample - scope: inventory - clientCert: /path/to/cert.pem - clientKey: /path/to/key.pem - clientCertPassword: password - clientKeyPassword: password - caCert: /path/to/ca.pem - noSslVerify: false - queryScanConsistency: 2 + kind: sources + name: my-couchbase-instance + type: couchbase + connectionString: couchbases://localhost + bucket: travel-sample + scope: inventory + clientCert: /path/to/cert.pem + clientKey: /path/to/key.pem + clientCertPassword: password + clientKeyPassword: password + caCert: /path/to/ca.pem + noSslVerify: false + queryScanConsistency: 2 `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-couchbase-instance": couchbase.Config{ Name: "my-couchbase-instance", - Kind: couchbase.SourceKind, + Type: couchbase.SourceType, ConnectionString: "couchbases://localhost", Bucket: "travel-sample", Scope: "inventory", @@ -91,16 +92,12 @@ func TestParseFromYamlCouchbase(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -115,39 +112,35 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - my-couchbase-instance: - kind: couchbase - connectionString: localhost - username: Administrator - password: password - bucket: travel-sample - scope: inventory - foo: bar + kind: sources + name: my-couchbase-instance + type: couchbase + connectionString: localhost + username: Administrator + password: password + bucket: travel-sample + scope: inventory + foo: bar `, - err: "unable to parse source \"my-couchbase-instance\" as \"couchbase\": [3:1] unknown field \"foo\"\n 1 | bucket: travel-sample\n 2 | connectionString: localhost\n> 3 | foo: bar\n ^\n 4 | kind: couchbase\n 5 | password: password\n 6 | scope: inventory\n 7 | ", + err: "error unmarshaling sources: unable to parse source \"my-couchbase-instance\" as \"couchbase\": [3:1] unknown field \"foo\"\n 1 | bucket: travel-sample\n 2 | connectionString: localhost\n> 3 | foo: bar\n ^\n 4 | name: my-couchbase-instance\n 5 | password: password\n 6 | scope: inventory\n 7 | ", }, { desc: "missing required field", in: ` - sources: - my-couchbase-instance: - kind: couchbase - username: Administrator - password: password - bucket: travel-sample - scope: inventory + kind: sources + name: my-couchbase-instance + type: couchbase + username: Administrator + password: password + bucket: travel-sample + scope: inventory `, - err: "unable to parse source \"my-couchbase-instance\" as \"couchbase\": Key: 'Config.ConnectionString' Error:Field validation for 'ConnectionString' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-couchbase-instance\" as \"couchbase\": Key: 'Config.ConnectionString' Error:Field validation for 'ConnectionString' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/dataplex/dataplex.go b/internal/sources/dataplex/dataplex.go index 52d64b194d..3ddeb2ec9f 100644 --- a/internal/sources/dataplex/dataplex.go +++ b/internal/sources/dataplex/dataplex.go @@ -31,14 +31,14 @@ import ( grpcstatus "google.golang.org/grpc/status" ) -const SourceKind string = "dataplex" +const SourceType string = "dataplex" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -53,13 +53,13 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { // Dataplex configs Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Project string `yaml:"project" validate:"required"` } -func (r Config) SourceConfigKind() string { - // Returns Dataplex source kind - return SourceKind +func (r Config) SourceConfigType() string { + // Returns Dataplex source type + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -83,9 +83,9 @@ type Source struct { Client *dataplexapi.CatalogClient } -func (s *Source) SourceKind() string { - // Returns Dataplex source kind - return SourceKind +func (s *Source) SourceType() string { + // Returns Dataplex source type + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -106,7 +106,7 @@ func initDataplexConnection( name string, project string, ) (*dataplexapi.CatalogClient, error) { - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() cred, err := google.FindDefaultCredentials(ctx) diff --git a/internal/sources/dataplex/dataplex_test.go b/internal/sources/dataplex/dataplex_test.go index 0379eba5b4..10b9641c6b 100644 --- a/internal/sources/dataplex/dataplex_test.go +++ b/internal/sources/dataplex/dataplex_test.go @@ -15,11 +15,12 @@ package dataplex_test import ( + "context" "testing" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/dataplex" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -33,15 +34,15 @@ func TestParseFromYamlDataplex(t *testing.T) { { desc: "basic example", in: ` - sources: - my-instance: - kind: dataplex - project: my-project + kind: sources + name: my-instance + type: dataplex + project: my-project `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-instance": dataplex.Config{ Name: "my-instance", - Kind: dataplex.SourceKind, + Type: dataplex.SourceType, Project: "my-project", }, }, @@ -49,16 +50,12 @@ func TestParseFromYamlDataplex(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -74,31 +71,27 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - my-instance: - kind: dataplex - project: my-project - foo: bar + kind: sources + name: my-instance + type: dataplex + project: my-project + foo: bar `, - err: "unable to parse source \"my-instance\" as \"dataplex\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | kind: dataplex\n 3 | project: my-project", + err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"dataplex\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | name: my-instance\n 3 | project: my-project\n 4 | type: dataplex", }, { desc: "missing required field", in: ` - sources: - my-instance: - kind: dataplex + kind: sources + name: my-instance + type: dataplex `, - err: "unable to parse source \"my-instance\" as \"dataplex\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"dataplex\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/dgraph/dgraph.go b/internal/sources/dgraph/dgraph.go index 317779db38..db2bc88d1f 100644 --- a/internal/sources/dgraph/dgraph.go +++ b/internal/sources/dgraph/dgraph.go @@ -30,14 +30,14 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "dgraph" +const SourceType string = "dgraph" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -67,7 +67,7 @@ type DgraphClient struct { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` DgraphUrl string `yaml:"dgraphUrl" validate:"required"` User string `yaml:"user"` Password string `yaml:"password"` @@ -75,8 +75,8 @@ type Config struct { ApiKey string `yaml:"apiKey"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -103,8 +103,8 @@ type Source struct { Client *DgraphClient `yaml:"client"` } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -139,7 +139,7 @@ func (s *Source) RunSQL(statement string, params parameters.ParamValues, isQuery func initDgraphHttpClient(ctx context.Context, tracer trace.Tracer, r Config) (*DgraphClient, error) { //nolint:all // Reassigned ctx - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, r.Name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, r.Name) defer span.End() if r.DgraphUrl == "" { diff --git a/internal/sources/dgraph/dgraph_test.go b/internal/sources/dgraph/dgraph_test.go index d2db006683..4681c0278e 100644 --- a/internal/sources/dgraph/dgraph_test.go +++ b/internal/sources/dgraph/dgraph_test.go @@ -15,11 +15,12 @@ package dgraph_test import ( + "context" "testing" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/dgraph" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -33,19 +34,19 @@ func TestParseFromYamlDgraph(t *testing.T) { { desc: "basic example", in: ` - sources: - my-dgraph-instance: - kind: dgraph - dgraphUrl: https://localhost:8080 - apiKey: abc123 - password: pass@123 - namespace: 0 - user: user123 + kind: sources + name: my-dgraph-instance + type: dgraph + dgraphUrl: https://localhost:8080 + apiKey: abc123 + password: pass@123 + namespace: 0 + user: user123 `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-dgraph-instance": dgraph.Config{ Name: "my-dgraph-instance", - Kind: dgraph.SourceKind, + Type: dgraph.SourceType, DgraphUrl: "https://localhost:8080", ApiKey: "abc123", Password: "pass@123", @@ -57,15 +58,15 @@ func TestParseFromYamlDgraph(t *testing.T) { { desc: "basic example minimal field", in: ` - sources: - my-dgraph-instance: - kind: dgraph - dgraphUrl: https://localhost:8080 + kind: sources + name: my-dgraph-instance + type: dgraph + dgraphUrl: https://localhost:8080 `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-dgraph-instance": dgraph.Config{ Name: "my-dgraph-instance", - Kind: dgraph.SourceKind, + Type: dgraph.SourceType, DgraphUrl: "https://localhost:8080", }, }, @@ -74,16 +75,12 @@ func TestParseFromYamlDgraph(t *testing.T) { for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Sources); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -100,31 +97,27 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - my-dgraph-instance: - kind: dgraph - dgraphUrl: https://localhost:8080 - foo: bar + kind: sources + name: my-dgraph-instance + type: dgraph + dgraphUrl: https://localhost:8080 + foo: bar `, - err: "unable to parse source \"my-dgraph-instance\" as \"dgraph\": [2:1] unknown field \"foo\"\n 1 | dgraphUrl: https://localhost:8080\n> 2 | foo: bar\n ^\n 3 | kind: dgraph", + err: "error unmarshaling sources: unable to parse source \"my-dgraph-instance\" as \"dgraph\": [2:1] unknown field \"foo\"\n 1 | dgraphUrl: https://localhost:8080\n> 2 | foo: bar\n ^\n 3 | name: my-dgraph-instance\n 4 | type: dgraph", }, { desc: "missing required field", in: ` - sources: - my-dgraph-instance: - kind: dgraph + kind: sources + name: my-dgraph-instance + type: dgraph `, - err: "unable to parse source \"my-dgraph-instance\" as \"dgraph\": Key: 'Config.DgraphUrl' Error:Field validation for 'DgraphUrl' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-dgraph-instance\" as \"dgraph\": Key: 'Config.DgraphUrl' Error:Field validation for 'DgraphUrl' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/elasticsearch/elasticsearch.go b/internal/sources/elasticsearch/elasticsearch.go index b5ec915c18..42dd835b23 100644 --- a/internal/sources/elasticsearch/elasticsearch.go +++ b/internal/sources/elasticsearch/elasticsearch.go @@ -30,14 +30,14 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "elasticsearch" +const SourceType string = "elasticsearch" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -51,15 +51,15 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Addresses []string `yaml:"addresses" validate:"required"` Username string `yaml:"username"` Password string `yaml:"password"` APIKey string `yaml:"apikey"` } -func (c Config) SourceConfigKind() string { - return SourceKind +func (c Config) SourceConfigType() string { + return SourceType } type EsClient interface { @@ -139,9 +139,9 @@ func (c Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.So return s, nil } -// SourceKind returns the kind string for this source. -func (s *Source) SourceKind() string { - return SourceKind +// SourceType returns the resourceType string for this source. +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { diff --git a/internal/sources/elasticsearch/elasticsearch_test.go b/internal/sources/elasticsearch/elasticsearch_test.go index 95d941edc4..d3170741f6 100644 --- a/internal/sources/elasticsearch/elasticsearch_test.go +++ b/internal/sources/elasticsearch/elasticsearch_test.go @@ -15,13 +15,15 @@ package elasticsearch_test import ( + "context" "reflect" "testing" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/elasticsearch" + "github.com/googleapis/genai-toolbox/internal/testutils" ) func TestParseFromYamlElasticsearch(t *testing.T) { @@ -33,17 +35,17 @@ func TestParseFromYamlElasticsearch(t *testing.T) { { desc: "basic example", in: ` - sources: - my-es-instance: - kind: elasticsearch - addresses: - - http://localhost:9200 - apikey: somekey - `, - want: server.SourceConfigs{ + kind: sources + name: my-es-instance + type: elasticsearch + addresses: + - http://localhost:9200 + apikey: somekey + `, + want: map[string]sources.SourceConfig{ "my-es-instance": elasticsearch.Config{ Name: "my-es-instance", - Kind: elasticsearch.SourceKind, + Type: elasticsearch.SourceType, Addresses: []string{"http://localhost:9200"}, APIKey: "somekey", }, @@ -52,20 +54,50 @@ func TestParseFromYamlElasticsearch(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - err := yaml.Unmarshal([]byte(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("failed to parse yaml: %v", err) } - if diff := cmp.Diff(tc.want, got.Sources); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Errorf("unexpected config diff (-want +got):\n%s", diff) } }) } } +func TestFailParseFromYaml(t *testing.T) { + tcs := []struct { + desc string + in string + err string + }{ + { + desc: "extra field", + in: ` + kind: sources + name: my-es-instance + type: elasticsearch + addresses: + - http://localhost:9200 + foo: bar + `, + err: "error unmarshaling sources: unable to parse source \"my-es-instance\" as \"elasticsearch\": [3:1] unknown field \"foo\"\n 1 | addresses:\n 2 | - http://localhost:9200\n> 3 | foo: bar\n ^\n 4 | name: my-es-instance\n 5 | type: elasticsearch", + }, + } + for _, tc := range tcs { + t.Run(tc.desc, func(t *testing.T) { + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) + if err == nil { + t.Fatalf("expect parsing to fail") + } + errStr := err.Error() + if errStr != tc.err { + t.Fatalf("unexpected error: got %q, want %q", errStr, tc.err) + } + }) + } +} + func TestTool_esqlToMap(t1 *testing.T) { tests := []struct { name string diff --git a/internal/sources/firebird/firebird.go b/internal/sources/firebird/firebird.go index 4be3d20cac..1d3f224227 100644 --- a/internal/sources/firebird/firebird.go +++ b/internal/sources/firebird/firebird.go @@ -27,13 +27,13 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" ) -const SourceKind string = "firebird" +const SourceType string = "firebird" var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -47,7 +47,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Host string `yaml:"host" validate:"required"` Port string `yaml:"port" validate:"required"` User string `yaml:"user" validate:"required"` @@ -55,8 +55,8 @@ type Config struct { Database string `yaml:"database" validate:"required"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -84,8 +84,8 @@ type Source struct { Db *sql.DB } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -144,7 +144,7 @@ func (s *Source) RunSQL(ctx context.Context, statement string, params []any) (an } func initFirebirdConnectionPool(ctx context.Context, tracer trace.Tracer, name, host, port, user, pass, dbname string) (*sql.DB, error) { - _, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + _, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() // urlExample := "user:password@host:port/path/to/database.fdb" diff --git a/internal/sources/firebird/firebird_test.go b/internal/sources/firebird/firebird_test.go index 0a7e72f66c..71353517a8 100644 --- a/internal/sources/firebird/firebird_test.go +++ b/internal/sources/firebird/firebird_test.go @@ -15,11 +15,12 @@ package firebird_test import ( + "context" "testing" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/firebird" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -33,19 +34,19 @@ func TestParseFromYamlFirebird(t *testing.T) { { desc: "basic example", in: ` - sources: - my-fdb-instance: - kind: firebird - host: my-host - port: my-port - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-fdb-instance + type: firebird + host: my-host + port: my-port + database: my_db + user: my_user + password: my_pass `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-fdb-instance": firebird.Config{ Name: "my-fdb-instance", - Kind: firebird.SourceKind, + Type: firebird.SourceType, Host: "my-host", Port: "my-port", Database: "my_db", @@ -57,16 +58,12 @@ func TestParseFromYamlFirebird(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -82,39 +79,35 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - my-fdb-instance: - kind: firebird - host: my-host - port: my-port - database: my_db - user: my_user - password: my_pass - foo: bar + kind: sources + name: my-fdb-instance + type: firebird + host: my-host + port: my-port + database: my_db + user: my_user + password: my_pass + foo: bar `, - err: "unable to parse source \"my-fdb-instance\" as \"firebird\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: my-host\n 4 | kind: firebird\n 5 | password: my_pass\n 6 | ", + err: "error unmarshaling sources: unable to parse source \"my-fdb-instance\" as \"firebird\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: my-host\n 4 | name: my-fdb-instance\n 5 | password: my_pass\n 6 | ", }, { desc: "missing required field", in: ` - sources: - my-fdb-instance: - kind: firebird - host: my-host - port: my-port - database: my_db - user: my_user + kind: sources + name: my-fdb-instance + type: firebird + host: my-host + port: my-port + database: my_db + user: my_user `, - err: "unable to parse source \"my-fdb-instance\" as \"firebird\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-fdb-instance\" as \"firebird\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/firestore/firestore.go b/internal/sources/firestore/firestore.go index be9f7aa94f..0756f146a2 100644 --- a/internal/sources/firestore/firestore.go +++ b/internal/sources/firestore/firestore.go @@ -31,14 +31,14 @@ import ( "google.golang.org/genproto/googleapis/type/latlng" ) -const SourceKind string = "firestore" +const SourceType string = "firestore" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -53,14 +53,14 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { // Firestore configs Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Project string `yaml:"project" validate:"required"` Database string `yaml:"database"` // Optional, defaults to "(default)" } -func (r Config) SourceConfigKind() string { - // Returns Firestore source kind - return SourceKind +func (r Config) SourceConfigType() string { + // Returns Firestore source type + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -92,9 +92,9 @@ type Source struct { RulesClient *firebaserules.Service } -func (s *Source) SourceKind() string { - // Returns Firestore source kind - return SourceKind +func (s *Source) SourceType() string { + // Returns Firestore source type + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -594,7 +594,7 @@ func initFirestoreConnection( project string, database string, ) (*firestore.Client, error) { - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() userAgent, err := util.UserAgentFromContext(ctx) diff --git a/internal/sources/firestore/firestore_test.go b/internal/sources/firestore/firestore_test.go index 3f15440f13..b65926bda3 100644 --- a/internal/sources/firestore/firestore_test.go +++ b/internal/sources/firestore/firestore_test.go @@ -15,12 +15,13 @@ package firestore_test import ( + "context" "testing" "time" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/firestore" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -34,15 +35,15 @@ func TestParseFromYamlFirestore(t *testing.T) { { desc: "basic example with default database", in: ` - sources: - my-firestore: - kind: firestore - project: my-project + kind: sources + name: my-firestore + type: firestore + project: my-project `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-firestore": firestore.Config{ Name: "my-firestore", - Kind: firestore.SourceKind, + Type: firestore.SourceType, Project: "my-project", Database: "", }, @@ -51,16 +52,16 @@ func TestParseFromYamlFirestore(t *testing.T) { { desc: "with custom database", in: ` - sources: - my-firestore: - kind: firestore - project: my-project - database: my-database + kind: sources + name: my-firestore + type: firestore + project: my-project + database: my-database `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-firestore": firestore.Config{ Name: "my-firestore", - Kind: firestore.SourceKind, + Type: firestore.SourceType, Project: "my-project", Database: "my-database", }, @@ -69,22 +70,18 @@ func TestParseFromYamlFirestore(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } } -func TestFailParseFromYamlFirestore(t *testing.T) { +func TestFailParseFromYaml(t *testing.T) { tcs := []struct { desc string in string @@ -93,32 +90,27 @@ func TestFailParseFromYamlFirestore(t *testing.T) { { desc: "extra field", in: ` - sources: - my-firestore: - kind: firestore - project: my-project - foo: bar + kind: sources + name: my-firestore + type: firestore + project: my-project + foo: bar `, - err: "unable to parse source \"my-firestore\" as \"firestore\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | kind: firestore\n 3 | project: my-project", + err: "error unmarshaling sources: unable to parse source \"my-firestore\" as \"firestore\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | name: my-firestore\n 3 | project: my-project\n 4 | type: firestore", }, { desc: "missing required field", in: ` - sources: - my-firestore: - kind: firestore - database: my-database + kind: sources + name: my-firestore + type: firestore `, - err: "unable to parse source \"my-firestore\" as \"firestore\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-firestore\" as \"firestore\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/http/http.go b/internal/sources/http/http.go index 238c19b607..8a6d58a619 100644 --- a/internal/sources/http/http.go +++ b/internal/sources/http/http.go @@ -29,14 +29,14 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "http" +const SourceType string = "http" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -50,7 +50,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` BaseURL string `yaml:"baseUrl"` Timeout string `yaml:"timeout"` DefaultHeaders map[string]string `yaml:"headers"` @@ -58,8 +58,8 @@ type Config struct { DisableSslVerification bool `yaml:"disableSslVerification"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } // Initialize initializes an HTTP Source instance. @@ -122,8 +122,8 @@ type Source struct { client *http.Client } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { diff --git a/internal/sources/http/http_test.go b/internal/sources/http/http_test.go index 02d8fc6b4d..4332b24fca 100644 --- a/internal/sources/http/http_test.go +++ b/internal/sources/http/http_test.go @@ -15,9 +15,9 @@ package http_test import ( + "context" "testing" - 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/sources" @@ -34,15 +34,15 @@ func TestParseFromYamlHttp(t *testing.T) { { desc: "basic example", in: ` - sources: - my-http-instance: - kind: http - baseUrl: http://test_server/ + kind: sources + name: my-http-instance + type: http + baseUrl: http://test_server/ `, want: map[string]sources.SourceConfig{ "my-http-instance": http.Config{ Name: "my-http-instance", - Kind: http.SourceKind, + Type: http.SourceType, BaseURL: "http://test_server/", Timeout: "30s", DisableSslVerification: false, @@ -52,23 +52,23 @@ func TestParseFromYamlHttp(t *testing.T) { { desc: "advanced example", in: ` - sources: - my-http-instance: - kind: http - baseUrl: http://test_server/ - timeout: 10s - headers: - Authorization: test_header - Custom-Header: custom - queryParams: - api-key: test_api_key - param: param-value - disableSslVerification: true + kind: sources + name: my-http-instance + type: http + baseUrl: http://test_server/ + timeout: 10s + headers: + Authorization: test_header + Custom-Header: custom + queryParams: + api-key: test_api_key + param: param-value + disableSslVerification: true `, want: map[string]sources.SourceConfig{ "my-http-instance": http.Config{ Name: "my-http-instance", - Kind: http.SourceKind, + Type: http.SourceType, BaseURL: "http://test_server/", Timeout: "10s", DefaultHeaders: map[string]string{"Authorization": "test_header", "Custom-Header": "custom"}, @@ -80,16 +80,12 @@ func TestParseFromYamlHttp(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -104,36 +100,32 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - my-http-instance: - kind: http - baseUrl: http://test_server/ - timeout: 10s - headers: - Authorization: test_header - queryParams: - api-key: test_api_key - project: test-project + kind: sources + name: my-http-instance + type: http + baseUrl: http://test_server/ + timeout: 10s + headers: + Authorization: test_header + queryParams: + api-key: test_api_key + project: test-project `, - err: "unable to parse source \"my-http-instance\" as \"http\": [5:1] unknown field \"project\"\n 2 | headers:\n 3 | Authorization: test_header\n 4 | kind: http\n> 5 | project: test-project\n ^\n 6 | queryParams:\n 7 | api-key: test_api_key\n 8 | timeout: 10s", + err: "error unmarshaling sources: unable to parse source \"my-http-instance\" as \"http\": [5:1] unknown field \"project\"\n 2 | headers:\n 3 | Authorization: test_header\n 4 | name: my-http-instance\n> 5 | project: test-project\n ^\n 6 | queryParams:\n 7 | api-key: test_api_key\n 8 | timeout: 10s\n 9 | ", }, { desc: "missing required field", in: ` - sources: - my-http-instance: - baseUrl: http://test_server/ + kind: sources + name: my-http-instance + baseUrl: http://test_server/ `, - err: "missing 'kind' field for source \"my-http-instance\"", + err: "error unmarshaling sources: missing 'type' field or it is not a string", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/looker/looker.go b/internal/sources/looker/looker.go index c7b401b080..e20ec2107d 100644 --- a/internal/sources/looker/looker.go +++ b/internal/sources/looker/looker.go @@ -33,14 +33,14 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const SourceKind string = "looker" +const SourceType string = "looker" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -64,7 +64,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` BaseURL string `yaml:"base_url" validate:"required"` ClientId string `yaml:"client_id"` ClientSecret string `yaml:"client_secret"` @@ -79,8 +79,8 @@ type Config struct { SessionLength int64 `yaml:"sessionLength"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } // Initialize initializes a Looker Source instance. @@ -154,8 +154,8 @@ type Source struct { AuthTokenHeaderName string } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { diff --git a/internal/sources/looker/looker_test.go b/internal/sources/looker/looker_test.go index bd470f0130..95fbf442f3 100644 --- a/internal/sources/looker/looker_test.go +++ b/internal/sources/looker/looker_test.go @@ -15,9 +15,9 @@ package looker_test import ( + "context" "testing" - 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/sources" @@ -34,17 +34,17 @@ func TestParseFromYamlLooker(t *testing.T) { { desc: "basic example", in: ` - sources: - my-looker-instance: - kind: looker - base_url: http://example.looker.com/ - client_id: jasdl;k;tjl - client_secret: sdakl;jgflkasdfkfg + kind: sources + name: my-looker-instance + type: looker + base_url: http://example.looker.com/ + client_id: jasdl;k;tjl + client_secret: sdakl;jgflkasdfkfg `, want: map[string]sources.SourceConfig{ "my-looker-instance": looker.Config{ Name: "my-looker-instance", - Kind: looker.SourceKind, + Type: looker.SourceType, BaseURL: "http://example.looker.com/", ClientId: "jasdl;k;tjl", ClientSecret: "sdakl;jgflkasdfkfg", @@ -62,22 +62,18 @@ func TestParseFromYamlLooker(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } } -func TestFailParseFromYamlLooker(t *testing.T) { +func TestFailParseFromYaml(t *testing.T) { tcs := []struct { desc string in string @@ -86,34 +82,30 @@ func TestFailParseFromYamlLooker(t *testing.T) { { desc: "extra field", in: ` - sources: - my-looker-instance: - kind: looker - base_url: http://example.looker.com/ - client_id: jasdl;k;tjl - client_secret: sdakl;jgflkasdfkfg - schema: test-schema + kind: sources + name: my-looker-instance + type: looker + base_url: http://example.looker.com/ + client_id: jasdl;k;tjl + client_secret: sdakl;jgflkasdfkfg + schema: test-schema `, - err: "unable to parse source \"my-looker-instance\" as \"looker\": [5:1] unknown field \"schema\"\n 2 | client_id: jasdl;k;tjl\n 3 | client_secret: sdakl;jgflkasdfkfg\n 4 | kind: looker\n> 5 | schema: test-schema\n ^\n", + err: "error unmarshaling sources: unable to parse source \"my-looker-instance\" as \"looker\": [5:1] unknown field \"schema\"\n 2 | client_id: jasdl;k;tjl\n 3 | client_secret: sdakl;jgflkasdfkfg\n 4 | name: my-looker-instance\n> 5 | schema: test-schema\n ^\n 6 | type: looker", }, { desc: "missing required field", in: ` - sources: - my-looker-instance: - kind: looker - client_id: jasdl;k;tjl + kind: sources + name: my-looker-instance + type: looker + client_id: jasdl;k;tjl `, - err: "unable to parse source \"my-looker-instance\" as \"looker\": Key: 'Config.BaseURL' Error:Field validation for 'BaseURL' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-looker-instance\" as \"looker\": Key: 'Config.BaseURL' Error:Field validation for 'BaseURL' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/mindsdb/mindsdb.go b/internal/sources/mindsdb/mindsdb.go index 4bb5daac1c..8fde3b6222 100644 --- a/internal/sources/mindsdb/mindsdb.go +++ b/internal/sources/mindsdb/mindsdb.go @@ -27,14 +27,14 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "mindsdb" +const SourceType string = "mindsdb" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -48,7 +48,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Host string `yaml:"host" validate:"required"` Port string `yaml:"port" validate:"required"` User string `yaml:"user" validate:"required"` @@ -57,8 +57,8 @@ type Config struct { QueryTimeout string `yaml:"queryTimeout"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -86,8 +86,8 @@ type Source struct { Pool *sql.DB } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -159,7 +159,7 @@ func (s *Source) RunSQL(ctx context.Context, statement string, params []any) (an func initMindsDBConnectionPool(ctx context.Context, tracer trace.Tracer, name, host, port, user, pass, dbname, queryTimeout string) (*sql.DB, error) { //nolint:all // Reassigned ctx - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() // Configure the driver to connect to the database diff --git a/internal/sources/mindsdb/mindsdb_test.go b/internal/sources/mindsdb/mindsdb_test.go index b80f0bc5a6..9195aa0c1f 100644 --- a/internal/sources/mindsdb/mindsdb_test.go +++ b/internal/sources/mindsdb/mindsdb_test.go @@ -15,11 +15,12 @@ package mindsdb_test import ( + "context" "testing" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/mindsdb" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -33,19 +34,19 @@ func TestParseFromYamlMindsDB(t *testing.T) { { desc: "basic example", in: ` - sources: - my-mindsdb-instance: - kind: mindsdb - host: 0.0.0.0 - port: my-port - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-mindsdb-instance + type: mindsdb + host: 0.0.0.0 + port: my-port + database: my_db + user: my_user + password: my_pass `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-mindsdb-instance": mindsdb.Config{ Name: "my-mindsdb-instance", - Kind: mindsdb.SourceKind, + Type: mindsdb.SourceType, Host: "0.0.0.0", Port: "my-port", Database: "my_db", @@ -57,20 +58,20 @@ func TestParseFromYamlMindsDB(t *testing.T) { { desc: "with query timeout", in: ` - sources: - my-mindsdb-instance: - kind: mindsdb - host: 0.0.0.0 - port: my-port - database: my_db - user: my_user - password: my_pass - queryTimeout: 45s + kind: sources + name: my-mindsdb-instance + type: mindsdb + host: 0.0.0.0 + port: my-port + database: my_db + user: my_user + password: my_pass + queryTimeout: 45s `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-mindsdb-instance": mindsdb.Config{ Name: "my-mindsdb-instance", - Kind: mindsdb.SourceKind, + Type: mindsdb.SourceType, Host: "0.0.0.0", Port: "my-port", Database: "my_db", @@ -83,16 +84,12 @@ func TestParseFromYamlMindsDB(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -108,39 +105,35 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - my-mindsdb-instance: - kind: mindsdb - host: 0.0.0.0 - port: my-port - database: my_db - user: my_user - password: my_pass - foo: bar + kind: sources + name: my-mindsdb-instance + type: mindsdb + host: 0.0.0.0 + port: my-port + database: my_db + user: my_user + password: my_pass + foo: bar `, - err: "unable to parse source \"my-mindsdb-instance\" as \"mindsdb\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | kind: mindsdb\n 5 | password: my_pass\n 6 | ", + err: "error unmarshaling sources: unable to parse source \"my-mindsdb-instance\" as \"mindsdb\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | name: my-mindsdb-instance\n 5 | password: my_pass\n 6 | ", }, { desc: "missing required field", in: ` - sources: - my-mindsdb-instance: - kind: mindsdb - port: my-port - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-mindsdb-instance + type: mindsdb + port: my-port + database: my_db + user: my_user + password: my_pass `, - err: "unable to parse source \"my-mindsdb-instance\" as \"mindsdb\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-mindsdb-instance\" as \"mindsdb\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/mongodb/mongodb.go b/internal/sources/mongodb/mongodb.go index 533e5005d5..297da86c24 100644 --- a/internal/sources/mongodb/mongodb.go +++ b/internal/sources/mongodb/mongodb.go @@ -29,14 +29,14 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "mongodb" +const SourceType string = "mongodb" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -50,12 +50,12 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Uri string `yaml:"uri" validate:"required"` // MongoDB Atlas connection URI } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -84,8 +84,8 @@ type Source struct { Client *mongo.Client } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -293,7 +293,7 @@ func (s *Source) DeleteOne(ctx context.Context, filterString, database, collecti func initMongoDBClient(ctx context.Context, tracer trace.Tracer, name, uri string) (*mongo.Client, error) { // Start a tracing span - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() userAgent, err := util.UserAgentFromContext(ctx) diff --git a/internal/sources/mongodb/mongodb_test.go b/internal/sources/mongodb/mongodb_test.go index 0c882899a4..9fec7ecc74 100644 --- a/internal/sources/mongodb/mongodb_test.go +++ b/internal/sources/mongodb/mongodb_test.go @@ -15,11 +15,12 @@ package mongodb_test import ( + "context" "testing" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/mongodb" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -33,15 +34,15 @@ func TestParseFromYamlMongoDB(t *testing.T) { { desc: "basic example", in: ` - sources: - mongo-db: - kind: "mongodb" - uri: "mongodb+srv://username:password@host/dbname" + kind: sources + name: mongo-db + type: "mongodb" + uri: "mongodb+srv://username:password@host/dbname" `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "mongo-db": mongodb.Config{ Name: "mongo-db", - Kind: mongodb.SourceKind, + Type: mongodb.SourceType, Uri: "mongodb+srv://username:password@host/dbname", }, }, @@ -49,16 +50,12 @@ func TestParseFromYamlMongoDB(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -74,31 +71,27 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - mongo-db: - kind: mongodb - uri: "mongodb+srv://username:password@host/dbname" - foo: bar + kind: sources + name: mongo-db + type: mongodb + uri: "mongodb+srv://username:password@host/dbname" + foo: bar `, - err: "unable to parse source \"mongo-db\" as \"mongodb\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | kind: mongodb\n 3 | uri: mongodb+srv://username:password@host/dbname", + err: "error unmarshaling sources: unable to parse source \"mongo-db\" as \"mongodb\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | name: mongo-db\n 3 | type: mongodb\n 4 | uri: mongodb+srv://username:password@host/dbname", }, { desc: "missing required field", in: ` - sources: - mongo-db: - kind: mongodb + kind: sources + name: mongo-db + type: mongodb `, - err: "unable to parse source \"mongo-db\" as \"mongodb\": Key: 'Config.Uri' Error:Field validation for 'Uri' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"mongo-db\" as \"mongodb\": Key: 'Config.Uri' Error:Field validation for 'Uri' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/mssql/mssql.go b/internal/sources/mssql/mssql.go index 688ccf18c4..e8dd7e824c 100644 --- a/internal/sources/mssql/mssql.go +++ b/internal/sources/mssql/mssql.go @@ -28,14 +28,14 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "mssql" +const SourceType string = "mssql" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -50,7 +50,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { // Cloud SQL MSSQL configs Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Host string `yaml:"host" validate:"required"` Port string `yaml:"port" validate:"required"` User string `yaml:"user" validate:"required"` @@ -59,9 +59,9 @@ type Config struct { Encrypt string `yaml:"encrypt"` } -func (r Config) SourceConfigKind() string { - // Returns Cloud SQL MSSQL source kind - return SourceKind +func (r Config) SourceConfigType() string { + // Returns Cloud SQL MSSQL source type + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -91,9 +91,9 @@ type Source struct { Db *sql.DB } -func (s *Source) SourceKind() string { - // Returns Cloud SQL MSSQL source kind - return SourceKind +func (s *Source) SourceType() string { + // Returns Cloud SQL MSSQL source type + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -156,7 +156,7 @@ func initMssqlConnection( error, ) { //nolint:all // Reassigned ctx - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() userAgent, err := util.UserAgentFromContext(ctx) diff --git a/internal/sources/mssql/mssql_test.go b/internal/sources/mssql/mssql_test.go index b1fa552b46..26b682fafa 100644 --- a/internal/sources/mssql/mssql_test.go +++ b/internal/sources/mssql/mssql_test.go @@ -15,11 +15,12 @@ package mssql_test import ( + "context" "testing" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/mssql" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -33,19 +34,19 @@ func TestParseFromYamlMssql(t *testing.T) { { desc: "basic example", in: ` - sources: - my-mssql-instance: - kind: mssql - host: 0.0.0.0 - port: my-port - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-mssql-instance + type: mssql + host: 0.0.0.0 + port: my-port + database: my_db + user: my_user + password: my_pass `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-mssql-instance": mssql.Config{ Name: "my-mssql-instance", - Kind: mssql.SourceKind, + Type: mssql.SourceType, Host: "0.0.0.0", Port: "my-port", Database: "my_db", @@ -57,20 +58,20 @@ func TestParseFromYamlMssql(t *testing.T) { { desc: "with encrypt field", in: ` - sources: - my-mssql-instance: - kind: mssql - host: 0.0.0.0 - port: my-port - database: my_db - user: my_user - password: my_pass - encrypt: strict + kind: sources + name: my-mssql-instance + type: mssql + host: 0.0.0.0 + port: my-port + database: my_db + user: my_user + password: my_pass + encrypt: strict `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-mssql-instance": mssql.Config{ Name: "my-mssql-instance", - Kind: mssql.SourceKind, + Type: mssql.SourceType, Host: "0.0.0.0", Port: "my-port", Database: "my_db", @@ -83,16 +84,12 @@ func TestParseFromYamlMssql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect psarse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect psarse: want %v, got %v", tc.want, got) } }) } @@ -107,39 +104,35 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - my-mssql-instance: - kind: mssql - host: 0.0.0.0 - port: my-port - database: my_db - user: my_user - password: my_pass - foo: bar + kind: sources + name: my-mssql-instance + type: mssql + host: 0.0.0.0 + port: my-port + database: my_db + user: my_user + password: my_pass + foo: bar `, - err: "unable to parse source \"my-mssql-instance\" as \"mssql\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | kind: mssql\n 5 | password: my_pass\n 6 | ", + err: "error unmarshaling sources: unable to parse source \"my-mssql-instance\" as \"mssql\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | name: my-mssql-instance\n 5 | password: my_pass\n 6 | ", }, { desc: "missing required field", in: ` - sources: - my-mssql-instance: - kind: mssql - host: 0.0.0.0 - port: my-port - database: my_db - user: my_user + kind: sources + name: my-mssql-instance + type: mssql + host: 0.0.0.0 + port: my-port + database: my_db + user: my_user `, - err: "unable to parse source \"my-mssql-instance\" as \"mssql\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-mssql-instance\" as \"mssql\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/mysql/mysql.go b/internal/sources/mysql/mysql.go index b456ec9a3f..626e72c817 100644 --- a/internal/sources/mysql/mysql.go +++ b/internal/sources/mysql/mysql.go @@ -30,14 +30,14 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "mysql" +const SourceType string = "mysql" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -51,7 +51,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Host string `yaml:"host" validate:"required"` Port string `yaml:"port" validate:"required"` User string `yaml:"user" validate:"required"` @@ -61,8 +61,8 @@ type Config struct { QueryParams map[string]string `yaml:"queryParams"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -90,8 +90,8 @@ type Source struct { Pool *sql.DB } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -158,7 +158,7 @@ func (s *Source) RunSQL(ctx context.Context, statement string, params []any) (an func initMySQLConnectionPool(ctx context.Context, tracer trace.Tracer, name, host, port, user, pass, dbname, queryTimeout string, queryParams map[string]string) (*sql.DB, error) { //nolint:all // Reassigned ctx - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() // Build query parameters via url.Values for deterministic order and proper escaping. diff --git a/internal/sources/mysql/mysql_test.go b/internal/sources/mysql/mysql_test.go index 2cbce3bc50..fc6dd348c7 100644 --- a/internal/sources/mysql/mysql_test.go +++ b/internal/sources/mysql/mysql_test.go @@ -19,12 +19,12 @@ import ( "strings" "testing" - yaml "github.com/goccy/go-yaml" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "go.opentelemetry.io/otel/trace/noop" "github.com/googleapis/genai-toolbox/internal/server" + "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/sources/mysql" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -38,19 +38,19 @@ func TestParseFromYamlCloudSQLMySQL(t *testing.T) { { desc: "basic example", in: ` - sources: - my-mysql-instance: - kind: mysql - host: 0.0.0.0 - port: my-port - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-mysql-instance + type: mysql + host: 0.0.0.0 + port: my-port + database: my_db + user: my_user + password: my_pass `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-mysql-instance": mysql.Config{ Name: "my-mysql-instance", - Kind: mysql.SourceKind, + Type: mysql.SourceType, Host: "0.0.0.0", Port: "my-port", Database: "my_db", @@ -62,20 +62,20 @@ func TestParseFromYamlCloudSQLMySQL(t *testing.T) { { desc: "with query timeout", in: ` - sources: - my-mysql-instance: - kind: mysql - host: 0.0.0.0 - port: my-port - database: my_db - user: my_user - password: my_pass - queryTimeout: 45s + kind: sources + name: my-mysql-instance + type: mysql + host: 0.0.0.0 + port: my-port + database: my_db + user: my_user + password: my_pass + queryTimeout: 45s `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-mysql-instance": mysql.Config{ Name: "my-mysql-instance", - Kind: mysql.SourceKind, + Type: mysql.SourceType, Host: "0.0.0.0", Port: "my-port", Database: "my_db", @@ -88,22 +88,22 @@ func TestParseFromYamlCloudSQLMySQL(t *testing.T) { { desc: "with query params", in: ` - sources: - my-mysql-instance: - kind: mysql - host: 0.0.0.0 - port: my-port - database: my_db - user: my_user - password: my_pass - queryParams: - tls: preferred - charset: utf8mb4 + kind: sources + name: my-mysql-instance + type: mysql + host: 0.0.0.0 + port: my-port + database: my_db + user: my_user + password: my_pass + queryParams: + tls: preferred + charset: utf8mb4 `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-mysql-instance": mysql.Config{ Name: "my-mysql-instance", - Kind: mysql.SourceKind, + Type: mysql.SourceType, Host: "0.0.0.0", Port: "my-port", Database: "my_db", @@ -120,15 +120,11 @@ func TestParseFromYamlCloudSQLMySQL(t *testing.T) { for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { t.Parallel() - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Sources, cmpopts.EquateEmpty()); diff != "" { + if diff := cmp.Diff(tc.want, got, cmpopts.EquateEmpty()); diff != "" { t.Fatalf("mismatch (-want +got):\n%s", diff) } }) @@ -145,55 +141,51 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - my-mysql-instance: - kind: mysql - host: 0.0.0.0 - port: my-port - database: my_db - user: my_user - password: my_pass - foo: bar + kind: sources + name: my-mysql-instance + type: mysql + host: 0.0.0.0 + port: my-port + database: my_db + user: my_user + password: my_pass + foo: bar `, - err: "unknown field \"foo\"", + err: "error unmarshaling sources: unable to parse source \"my-mysql-instance\" as \"mysql\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | name: my-mysql-instance\n 5 | password: my_pass\n 6 | ", }, { desc: "missing required field", in: ` - sources: - my-mysql-instance: - kind: mysql - port: my-port - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-mysql-instance + type: mysql + port: my-port + database: my_db + user: my_user + password: my_pass `, - err: "Field validation for 'Host' failed", + err: "error unmarshaling sources: unable to parse source \"my-mysql-instance\" as \"mysql\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag", }, { desc: "invalid query params type", in: ` - sources: - my-mysql-instance: - kind: mysql - host: 0.0.0.0 - port: 3306 - database: my_db - user: my_user - password: my_pass - queryParams: not-a-map + kind: sources + name: my-mysql-instance + type: mysql + host: 0.0.0.0 + port: 3306 + database: my_db + user: my_user + password: my_pass + queryParams: not-a-map `, - err: "string was used where mapping is expected", + err: "error unmarshaling sources: unable to parse source \"my-mysql-instance\" as \"mysql\": [6:14] string was used where mapping is expected\n 3 | name: my-mysql-instance\n 4 | password: my_pass\n 5 | port: 3306\n> 6 | queryParams: not-a-map\n ^\n 7 | type: mysql\n 8 | user: my_user", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { t.Parallel() - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } @@ -211,7 +203,7 @@ func TestFailInitialization(t *testing.T) { cfg := mysql.Config{ Name: "instance", - Kind: "mysql", + Type: "mysql", Host: "localhost", Port: "3306", Database: "db", diff --git a/internal/sources/neo4j/neo4j.go b/internal/sources/neo4j/neo4j.go index 70cc21ae14..79af308cbf 100644 --- a/internal/sources/neo4j/neo4j.go +++ b/internal/sources/neo4j/neo4j.go @@ -29,7 +29,7 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "neo4j" +const SourceType string = "neo4j" var sourceClassifier *classifier.QueryClassifier = classifier.NewQueryClassifier() @@ -37,8 +37,8 @@ var sourceClassifier *classifier.QueryClassifier = classifier.NewQueryClassifier var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -52,15 +52,15 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Uri string `yaml:"uri" validate:"required"` User string `yaml:"user" validate:"required"` Password string `yaml:"password" validate:"required"` Database string `yaml:"database" validate:"required"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -91,8 +91,8 @@ type Source struct { Driver neo4j.DriverWithContext } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -182,7 +182,7 @@ func addPlanChildren(p neo4j.Plan) []map[string]any { func initNeo4jDriver(ctx context.Context, tracer trace.Tracer, uri, user, password, name string) (neo4j.DriverWithContext, error) { //nolint:all // Reassigned ctx - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() auth := neo4j.BasicAuth(user, password, "") diff --git a/internal/sources/neo4j/neo4j_test.go b/internal/sources/neo4j/neo4j_test.go index 2ac8aab534..35e3e87d50 100644 --- a/internal/sources/neo4j/neo4j_test.go +++ b/internal/sources/neo4j/neo4j_test.go @@ -15,11 +15,12 @@ package neo4j_test import ( + "context" "testing" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/neo4j" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -33,18 +34,18 @@ func TestParseFromYamlNeo4j(t *testing.T) { { desc: "basic example", in: ` - sources: - my-neo4j-instance: - kind: neo4j - uri: neo4j+s://my-host:7687 - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-neo4j-instance + type: neo4j + uri: neo4j+s://my-host:7687 + database: my_db + user: my_user + password: my_pass `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-neo4j-instance": neo4j.Config{ Name: "my-neo4j-instance", - Kind: neo4j.SourceKind, + Type: neo4j.SourceType, Uri: "neo4j+s://my-host:7687", Database: "my_db", User: "my_user", @@ -55,16 +56,12 @@ func TestParseFromYamlNeo4j(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -80,37 +77,33 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - my-neo4j-instance: - kind: neo4j - uri: neo4j+s://my-host:7687 - database: my_db - user: my_user - password: my_pass - foo: bar + kind: sources + name: my-neo4j-instance + type: neo4j + uri: neo4j+s://my-host:7687 + database: my_db + user: my_user + password: my_pass + foo: bar `, - err: "unable to parse source \"my-neo4j-instance\" as \"neo4j\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | kind: neo4j\n 4 | password: my_pass\n 5 | uri: neo4j+s://my-host:7687\n 6 | ", + err: "error unmarshaling sources: unable to parse source \"my-neo4j-instance\" as \"neo4j\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | name: my-neo4j-instance\n 4 | password: my_pass\n 5 | type: neo4j\n 6 | ", }, { desc: "missing required field", in: ` - sources: - my-neo4j-instance: - kind: neo4j - uri: neo4j+s://my-host:7687 - database: my_db - user: my_user + kind: sources + name: my-neo4j-instance + type: neo4j + uri: neo4j+s://my-host:7687 + database: my_db + user: my_user `, - err: "unable to parse source \"my-neo4j-instance\" as \"neo4j\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-neo4j-instance\" as \"neo4j\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/oceanbase/oceanbase.go b/internal/sources/oceanbase/oceanbase.go index 27a989ae3d..0138838f64 100644 --- a/internal/sources/oceanbase/oceanbase.go +++ b/internal/sources/oceanbase/oceanbase.go @@ -27,14 +27,14 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "oceanbase" +const SourceType string = "oceanbase" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -48,7 +48,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Host string `yaml:"host" validate:"required"` Port string `yaml:"port" validate:"required"` User string `yaml:"user" validate:"required"` @@ -57,8 +57,8 @@ type Config struct { QueryTimeout string `yaml:"queryTimeout"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -86,8 +86,8 @@ type Source struct { Pool *sql.DB } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -153,7 +153,7 @@ func (s *Source) RunSQL(ctx context.Context, statement string, params []any) (an } func initOceanBaseConnectionPool(ctx context.Context, tracer trace.Tracer, name, host, port, user, pass, dbname, queryTimeout string) (*sql.DB, error) { - _, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + _, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?parseTime=true", user, pass, host, port, dbname) diff --git a/internal/sources/oceanbase/oceanbase_test.go b/internal/sources/oceanbase/oceanbase_test.go index a21a5e0655..bfde68da95 100644 --- a/internal/sources/oceanbase/oceanbase_test.go +++ b/internal/sources/oceanbase/oceanbase_test.go @@ -15,11 +15,12 @@ package oceanbase_test import ( + "context" "testing" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/oceanbase" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -34,19 +35,19 @@ func TestParseFromYamlOceanBase(t *testing.T) { { desc: "basic example", in: ` - sources: - my-oceanbase-instance: - kind: oceanbase - host: 0.0.0.0 - port: 2881 - database: ob_db - user: ob_user - password: ob_pass + kind: sources + name: my-oceanbase-instance + type: oceanbase + host: 0.0.0.0 + port: 2881 + database: ob_db + user: ob_user + password: ob_pass `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-oceanbase-instance": oceanbase.Config{ Name: "my-oceanbase-instance", - Kind: oceanbase.SourceKind, + Type: oceanbase.SourceType, Host: "0.0.0.0", Port: "2881", Database: "ob_db", @@ -58,20 +59,20 @@ func TestParseFromYamlOceanBase(t *testing.T) { { desc: "with query timeout", in: ` - sources: - my-oceanbase-instance: - kind: oceanbase - host: 0.0.0.0 - port: 2881 - database: ob_db - user: ob_user - password: ob_pass - queryTimeout: 30s + kind: sources + name: my-oceanbase-instance + type: oceanbase + host: 0.0.0.0 + port: 2881 + database: ob_db + user: ob_user + password: ob_pass + queryTimeout: 30s `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-oceanbase-instance": oceanbase.Config{ Name: "my-oceanbase-instance", - Kind: oceanbase.SourceKind, + Type: oceanbase.SourceType, Host: "0.0.0.0", Port: "2881", Database: "ob_db", @@ -84,16 +85,12 @@ func TestParseFromYamlOceanBase(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -109,39 +106,35 @@ func TestFailParseFromYamlOceanBase(t *testing.T) { { desc: "extra field", in: ` - sources: - my-oceanbase-instance: - kind: oceanbase - host: 0.0.0.0 - port: 2881 - database: ob_db - user: ob_user - password: ob_pass - foo: bar + kind: sources + name: my-oceanbase-instance + type: oceanbase + host: 0.0.0.0 + port: 2881 + database: ob_db + user: ob_user + password: ob_pass + foo: bar `, - err: "unable to parse source \"my-oceanbase-instance\" as \"oceanbase\": [2:1] unknown field \"foo\"\n 1 | database: ob_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | kind: oceanbase\n 5 | password: ob_pass\n 6 | ", + err: "error unmarshaling sources: unable to parse source \"my-oceanbase-instance\" as \"oceanbase\": [2:1] unknown field \"foo\"\n 1 | database: ob_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | name: my-oceanbase-instance\n 5 | password: ob_pass\n 6 | ", }, { desc: "missing required field", in: ` - sources: - my-oceanbase-instance: - kind: oceanbase - port: 2881 - database: ob_db - user: ob_user - password: ob_pass + kind: sources + name: my-oceanbase-instance + type: oceanbase + port: 2881 + database: ob_db + user: ob_user + password: ob_pass `, - err: "unable to parse source \"my-oceanbase-instance\" as \"oceanbase\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-oceanbase-instance\" as \"oceanbase\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/oracle/oracle.go b/internal/sources/oracle/oracle.go index 29d78cc706..f9202323ce 100644 --- a/internal/sources/oracle/oracle.go +++ b/internal/sources/oracle/oracle.go @@ -18,14 +18,14 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "oracle" +const SourceType string = "oracle" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -45,7 +45,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` ConnectionString string `yaml:"connectionString,omitempty"` TnsAlias string `yaml:"tnsAlias,omitempty"` TnsAdmin string `yaml:"tnsAdmin,omitempty"` @@ -95,8 +95,8 @@ func (c Config) validate() error { return nil } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -124,8 +124,8 @@ type Source struct { DB *sql.DB } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -239,7 +239,7 @@ func (s *Source) RunSQL(ctx context.Context, statement string, params []any) (an func initOracleConnection(ctx context.Context, tracer trace.Tracer, config Config) (*sql.DB, error) { //nolint:all // Reassigned ctx - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, config.Name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, config.Name) defer span.End() logger, err := util.LoggerFromContext(ctx) diff --git a/internal/sources/oracle/oracle_test.go b/internal/sources/oracle/oracle_test.go index 3d8f4c7ba5..dc9875341b 100644 --- a/internal/sources/oracle/oracle_test.go +++ b/internal/sources/oracle/oracle_test.go @@ -3,12 +3,13 @@ package oracle_test import ( + "context" "strings" "testing" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/oracle" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -22,18 +23,18 @@ func TestParseFromYamlOracle(t *testing.T) { { desc: "connection string and useOCI=true", in: ` - sources: - my-oracle-cs: - kind: oracle - connectionString: "my-host:1521/XEPDB1" - user: my_user - password: my_pass - useOCI: true - `, - want: server.SourceConfigs{ + kind: sources + name: my-oracle-cs + type: oracle + connectionString: "my-host:1521/XEPDB1" + user: my_user + password: my_pass + useOCI: true + `, + want: map[string]sources.SourceConfig{ "my-oracle-cs": oracle.Config{ Name: "my-oracle-cs", - Kind: oracle.SourceKind, + Type: oracle.SourceType, ConnectionString: "my-host:1521/XEPDB1", User: "my_user", Password: "my_pass", @@ -44,19 +45,19 @@ func TestParseFromYamlOracle(t *testing.T) { { desc: "host/port/serviceName and default useOCI=false", in: ` - sources: - my-oracle-host: - kind: oracle - host: my-host - port: 1521 - serviceName: ORCLPDB - user: my_user - password: my_pass - `, - want: server.SourceConfigs{ + kind: sources + name: my-oracle-host + type: oracle + host: my-host + port: 1521 + serviceName: ORCLPDB + user: my_user + password: my_pass + `, + want: map[string]sources.SourceConfig{ "my-oracle-host": oracle.Config{ Name: "my-oracle-host", - Kind: oracle.SourceKind, + Type: oracle.SourceType, Host: "my-host", Port: 1521, ServiceName: "ORCLPDB", @@ -69,19 +70,19 @@ func TestParseFromYamlOracle(t *testing.T) { { desc: "tnsAlias and TnsAdmin specified with explicit useOCI=true", in: ` - sources: - my-oracle-tns-oci: - kind: oracle - tnsAlias: FINANCE_DB - tnsAdmin: /opt/oracle/network/admin - user: my_user - password: my_pass - useOCI: true - `, - want: server.SourceConfigs{ + kind: sources + name: my-oracle-tns-oci + type: oracle + tnsAlias: FINANCE_DB + tnsAdmin: /opt/oracle/network/admin + user: my_user + password: my_pass + useOCI: true + `, + want: map[string]sources.SourceConfig{ "my-oracle-tns-oci": oracle.Config{ Name: "my-oracle-tns-oci", - Kind: oracle.SourceKind, + Type: oracle.SourceType, TnsAlias: "FINANCE_DB", TnsAdmin: "/opt/oracle/network/admin", User: "my_user", @@ -93,22 +94,18 @@ func TestParseFromYamlOracle(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse:\nwant: %v\ngot: %v\ndiff: %s", tc.want, got.Sources, cmp.Diff(tc.want, got.Sources)) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse:\nwant: %v\ngot: %v\ndiff: %s", tc.want, got, cmp.Diff(tc.want, got)) } }) } } -func TestFailParseFromYamlOracle(t *testing.T) { +func TestFailParseFromYaml(t *testing.T) { tcs := []struct { desc string in string @@ -117,76 +114,72 @@ func TestFailParseFromYamlOracle(t *testing.T) { { desc: "extra field", in: ` - sources: - my-oracle-instance: - kind: oracle - host: my-host - serviceName: ORCL - user: my_user - password: my_pass - extraField: value + kind: sources + name: my-oracle-instance + type: oracle + host: my-host + serviceName: ORCL + user: my_user + password: my_pass + extraField: value `, - err: "unable to parse source \"my-oracle-instance\" as \"oracle\": [1:1] unknown field \"extraField\"\n> 1 | extraField: value\n ^\n 2 | host: my-host\n 3 | kind: oracle\n 4 | password: my_pass\n 5 | ", + err: "error unmarshaling sources: unable to parse source \"my-oracle-instance\" as \"oracle\": [1:1] unknown field \"extraField\"\n> 1 | extraField: value\n ^\n 2 | host: my-host\n 3 | name: my-oracle-instance\n 4 | password: my_pass\n 5 | ", }, { desc: "missing required password field", in: ` - sources: - my-oracle-instance: - kind: oracle - host: my-host - serviceName: ORCL - user: my_user - `, - err: "unable to parse source \"my-oracle-instance\" as \"oracle\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag", + kind: sources + name: my-oracle-instance + type: oracle + host: my-host + serviceName: ORCL + user: my_user + `, + err: "error unmarshaling sources: unable to parse source \"my-oracle-instance\" as \"oracle\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag", }, { desc: "missing connection method fields (validate fails)", in: ` - sources: - my-oracle-instance: - kind: oracle - user: my_user - password: my_pass - `, - err: "unable to parse source \"my-oracle-instance\" as \"oracle\": invalid Oracle configuration: must provide one of: 'tns_alias', 'connection_string', or both 'host' and 'service_name'", + kind: sources + name: my-oracle-instance + type: oracle + user: my_user + password: my_pass + `, + err: "error unmarshaling sources: unable to parse source \"my-oracle-instance\" as \"oracle\": invalid Oracle configuration: must provide one of: 'tns_alias', 'connection_string', or both 'host' and 'service_name'", }, { desc: "multiple connection methods provided (validate fails)", in: ` - sources: - my-oracle-instance: - kind: oracle - host: my-host - serviceName: ORCL - connectionString: "my-host:1521/XEPDB1" - user: my_user - password: my_pass - `, - err: "unable to parse source \"my-oracle-instance\" as \"oracle\": invalid Oracle configuration: provide only one connection method: 'tns_alias', 'connection_string', or 'host'+'service_name'", + kind: sources + name: my-oracle-instance + type: oracle + host: my-host + serviceName: ORCL + connectionString: "my-host:1521/XEPDB1" + user: my_user + password: my_pass + `, + err: "error unmarshaling sources: unable to parse source \"my-oracle-instance\" as \"oracle\": invalid Oracle configuration: provide only one connection method: 'tns_alias', 'connection_string', or 'host'+'service_name'", }, { desc: "fail on tnsAdmin with useOCI=false", in: ` - sources: - my-oracle-fail: - kind: oracle - tnsAlias: FINANCE_DB - tnsAdmin: /opt/oracle/network/admin - user: my_user - password: my_pass - useOCI: false + kind: sources + name: my-oracle-fail + type: oracle + tnsAlias: FINANCE_DB + tnsAdmin: /opt/oracle/network/admin + user: my_user + password: my_pass + useOCI: false `, - err: "unable to parse source \"my-oracle-fail\" as \"oracle\": invalid Oracle configuration: `tnsAdmin` can only be used when `UseOCI` is true, or use `walletLocation` instead", + err: "error unmarshaling sources: unable to parse source \"my-oracle-fail\" as \"oracle\": invalid Oracle configuration: `tnsAdmin` can only be used when `UseOCI` is true, or use `walletLocation` instead", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/postgres/postgres.go b/internal/sources/postgres/postgres.go index d23721fc06..65d7a17b75 100644 --- a/internal/sources/postgres/postgres.go +++ b/internal/sources/postgres/postgres.go @@ -28,14 +28,14 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "postgres" +const SourceType string = "postgres" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -49,7 +49,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Host string `yaml:"host" validate:"required"` Port string `yaml:"port" validate:"required"` User string `yaml:"user" validate:"required"` @@ -58,8 +58,8 @@ type Config struct { QueryParams map[string]string `yaml:"queryParams"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -87,8 +87,8 @@ type Source struct { Pool *pgxpool.Pool } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -128,7 +128,7 @@ func (s *Source) RunSQL(ctx context.Context, statement string, params []any) (an func initPostgresConnectionPool(ctx context.Context, tracer trace.Tracer, name, host, port, user, pass, dbname string, queryParams map[string]string) (*pgxpool.Pool, error) { //nolint:all // Reassigned ctx - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() userAgent, err := util.UserAgentFromContext(ctx) if err != nil { diff --git a/internal/sources/postgres/postgres_test.go b/internal/sources/postgres/postgres_test.go index b9d8872c3a..4bcde0420e 100644 --- a/internal/sources/postgres/postgres_test.go +++ b/internal/sources/postgres/postgres_test.go @@ -1,4 +1,4 @@ -// Copyright 2024 Google LLC +// Copyright 2025 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,13 +15,14 @@ package postgres_test import ( + "context" "sort" "strings" "testing" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/postgres" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -35,19 +36,19 @@ func TestParseFromYamlPostgres(t *testing.T) { { desc: "basic example", in: ` - sources: - my-pg-instance: - kind: postgres - host: my-host - port: my-port - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-pg-instance + type: postgres + host: my-host + port: my-port + database: my_db + user: my_user + password: my_pass `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-pg-instance": postgres.Config{ Name: "my-pg-instance", - Kind: postgres.SourceKind, + Type: postgres.SourceType, Host: "my-host", Port: "my-port", Database: "my_db", @@ -59,22 +60,22 @@ func TestParseFromYamlPostgres(t *testing.T) { { desc: "example with query params", in: ` - sources: - my-pg-instance: - kind: postgres - host: my-host - port: my-port - database: my_db - user: my_user - password: my_pass - queryParams: - sslmode: verify-full - sslrootcert: /tmp/ca.crt + kind: sources + name: my-pg-instance + type: postgres + host: my-host + port: my-port + database: my_db + user: my_user + password: my_pass + queryParams: + sslmode: verify-full + sslrootcert: /tmp/ca.crt `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-pg-instance": postgres.Config{ Name: "my-pg-instance", - Kind: postgres.SourceKind, + Type: postgres.SourceType, Host: "my-host", Port: "my-port", Database: "my_db", @@ -90,16 +91,12 @@ func TestParseFromYamlPostgres(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -115,39 +112,35 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - my-pg-instance: - kind: postgres - host: my-host - port: my-port - database: my_db - user: my_user - password: my_pass - foo: bar + kind: sources + name: my-pg-instance + type: postgres + host: my-host + port: my-port + database: my_db + user: my_user + password: my_pass + foo: bar `, - err: "unable to parse source \"my-pg-instance\" as \"postgres\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: my-host\n 4 | kind: postgres\n 5 | password: my_pass\n 6 | ", + err: "error unmarshaling sources: unable to parse source \"my-pg-instance\" as \"postgres\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: my-host\n 4 | name: my-pg-instance\n 5 | password: my_pass\n 6 | ", }, { desc: "missing required field", in: ` - sources: - my-pg-instance: - kind: postgres - host: my-host - port: my-port - database: my_db - user: my_user + kind: sources + name: my-pg-instance + type: postgres + host: my-host + port: my-port + database: my_db + user: my_user `, - err: "unable to parse source \"my-pg-instance\" as \"postgres\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-pg-instance\" as \"postgres\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/redis/redis.go b/internal/sources/redis/redis.go index f8e4bfa40e..e2a28c52a7 100644 --- a/internal/sources/redis/redis.go +++ b/internal/sources/redis/redis.go @@ -24,14 +24,14 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "redis" +const SourceType string = "redis" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -45,7 +45,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Address []string `yaml:"address" validate:"required"` Username string `yaml:"username"` Password string `yaml:"password"` @@ -54,8 +54,8 @@ type Config struct { ClusterEnabled bool `yaml:"clusterEnabled"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } // RedisClient is an interface for `redis.Client` and `redis.ClusterClient @@ -141,8 +141,8 @@ type Source struct { Client RedisClient } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { diff --git a/internal/sources/redis/redis_test.go b/internal/sources/redis/redis_test.go index 4fe944b924..63e2d01bee 100644 --- a/internal/sources/redis/redis_test.go +++ b/internal/sources/redis/redis_test.go @@ -15,12 +15,13 @@ package redis_test import ( + "context" "strings" "testing" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/redis" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -34,16 +35,16 @@ func TestParseFromYamlRedis(t *testing.T) { { desc: "default setting", in: ` - sources: - my-redis-instance: - kind: redis - address: - - 127.0.0.1 + kind: sources + name: my-redis-instance + type: redis + address: + - 127.0.0.1 `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-redis-instance": redis.Config{ Name: "my-redis-instance", - Kind: redis.SourceKind, + Type: redis.SourceType, Address: []string{"127.0.0.1"}, ClusterEnabled: false, UseGCPIAM: false, @@ -53,20 +54,20 @@ func TestParseFromYamlRedis(t *testing.T) { { desc: "advanced example", in: ` - sources: - my-redis-instance: - kind: redis - address: - - 127.0.0.1 - password: my-pass - database: 1 - useGCPIAM: true - clusterEnabled: true + kind: sources + name: my-redis-instance + type: redis + address: + - 127.0.0.1 + password: my-pass + database: 1 + useGCPIAM: true + clusterEnabled: true `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-redis-instance": redis.Config{ Name: "my-redis-instance", - Kind: redis.SourceKind, + Type: redis.SourceType, Address: []string{"127.0.0.1"}, Password: "my-pass", Database: 1, @@ -78,16 +79,12 @@ func TestParseFromYamlRedis(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -103,48 +100,43 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "invalid database", in: ` - sources: - my-redis-instance: - kind: redis - project: my-project - address: - - 127.0.0.1 - password: my-pass - database: data + kind: sources + name: my-redis-instance + type: redis + address: + - 127.0.0.1 + password: my-pass + database: data `, - err: "cannot unmarshal string into Go struct field .Sources of type int", + err: "error unmarshaling sources: unable to parse source \"my-redis-instance\" as \"redis\": [3:11] cannot unmarshal string into Go struct field Config.Database of type int\n 1 | address:\n 2 | - 127.0.0.1\n> 3 | database: data\n ^\n 4 | name: my-redis-instance\n 5 | password: my-pass\n 6 | type: redis", }, { desc: "extra field", in: ` - sources: - my-redis-instance: - kind: redis - project: my-project - address: - - 127.0.0.1 - password: my-pass - database: 1 + kind: sources + name: my-redis-instance + type: redis + project: my-project + address: + - 127.0.0.1 + password: my-pass + database: 1 `, - err: "unable to parse source \"my-redis-instance\" as \"redis\": [6:1] unknown field \"project\"", + err: "error unmarshaling sources: unable to parse source \"my-redis-instance\" as \"redis\": [6:1] unknown field \"project\"\n 3 | database: 1\n 4 | name: my-redis-instance\n 5 | password: my-pass\n> 6 | project: my-project\n ^\n 7 | type: redis", }, { desc: "missing required field", in: ` - sources: - my-redis-instance: - kind: redis + kind: sources + name: my-redis-instance + type: redis `, - err: "unable to parse source \"my-redis-instance\" as \"redis\": Key: 'Config.Address' Error:Field validation for 'Address' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-redis-instance\" as \"redis\": Key: 'Config.Address' Error:Field validation for 'Address' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/serverlessspark/serverlessspark.go b/internal/sources/serverlessspark/serverlessspark.go index f6968f9bae..a6edb82a48 100644 --- a/internal/sources/serverlessspark/serverlessspark.go +++ b/internal/sources/serverlessspark/serverlessspark.go @@ -33,14 +33,14 @@ import ( "google.golang.org/protobuf/encoding/protojson" ) -const SourceKind string = "serverless-spark" +const SourceType string = "serverless-spark" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -54,13 +54,13 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Project string `yaml:"project" validate:"required"` Location string `yaml:"location" validate:"required"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -94,8 +94,8 @@ type Source struct { OpsClient *longrunning.OperationsClient } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { diff --git a/internal/sources/serverlessspark/serverlessspark_test.go b/internal/sources/serverlessspark/serverlessspark_test.go index 3162f259ef..7e81449905 100644 --- a/internal/sources/serverlessspark/serverlessspark_test.go +++ b/internal/sources/serverlessspark/serverlessspark_test.go @@ -15,11 +15,12 @@ package serverlessspark_test import ( + "context" "testing" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/serverlessspark" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -33,16 +34,16 @@ func TestParseFromYamlServerlessSpark(t *testing.T) { { desc: "basic example", in: ` - sources: - my-instance: - kind: serverless-spark - project: my-project - location: my-location + kind: sources + name: my-instance + type: serverless-spark + project: my-project + location: my-location `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-instance": serverlessspark.Config{ Name: "my-instance", - Kind: serverlessspark.SourceKind, + Type: serverlessspark.SourceType, Project: "my-project", Location: "my-location", }, @@ -51,16 +52,12 @@ func TestParseFromYamlServerlessSpark(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -76,43 +73,39 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - my-instance: - kind: serverless-spark - project: my-project - location: my-location - foo: bar + kind: sources + name: my-instance + type: serverless-spark + project: my-project + location: my-location + foo: bar `, - err: "unable to parse source \"my-instance\" as \"serverless-spark\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | kind: serverless-spark\n 3 | location: my-location\n 4 | project: my-project", + err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"serverless-spark\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | location: my-location\n 3 | name: my-instance\n 4 | project: my-project\n 5 | ", }, { desc: "missing required field project", in: ` - sources: - my-instance: - kind: serverless-spark - location: my-location + kind: sources + name: my-instance + type: serverless-spark + location: my-location `, - err: "unable to parse source \"my-instance\" as \"serverless-spark\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"serverless-spark\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag", }, { desc: "missing required field location", in: ` - sources: - my-instance: - kind: serverless-spark - project: my-project + kind: sources + name: my-instance + type: serverless-spark + project: my-project `, - err: "unable to parse source \"my-instance\" as \"serverless-spark\": Key: 'Config.Location' Error:Field validation for 'Location' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"serverless-spark\": Key: 'Config.Location' Error:Field validation for 'Location' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/singlestore/singlestore.go b/internal/sources/singlestore/singlestore.go index ebcede392e..2d6f1c7807 100644 --- a/internal/sources/singlestore/singlestore.go +++ b/internal/sources/singlestore/singlestore.go @@ -29,15 +29,15 @@ import ( "go.opentelemetry.io/otel/trace" ) -// SourceKind for SingleStore source -const SourceKind string = "singlestore" +// SourceType for SingleStore source +const SourceType string = "singlestore" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -52,7 +52,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources // Config holds the configuration parameters for connecting to a SingleStore database. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Host string `yaml:"host" validate:"required"` Port string `yaml:"port" validate:"required"` User string `yaml:"user" validate:"required"` @@ -61,9 +61,9 @@ type Config struct { QueryTimeout string `yaml:"queryTimeout"` } -// SourceConfigKind returns the kind of the source configuration. -func (r Config) SourceConfigKind() string { - return SourceKind +// SourceConfigType returns the type of the source configuration. +func (r Config) SourceConfigType() string { + return SourceType } // Initialize sets up the SingleStore connection pool and returns a Source. @@ -93,9 +93,9 @@ type Source struct { Pool *sql.DB } -// SourceKind returns the kind of the source configuration. -func (s *Source) SourceKind() string { - return SourceKind +// SourceType returns the type of the source configuration. +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -162,7 +162,7 @@ func (s *Source) RunSQL(ctx context.Context, statement string, params []any) (an func initSingleStoreConnectionPool(ctx context.Context, tracer trace.Tracer, name, host, port, user, pass, dbname, queryTimeout string) (*sql.DB, error) { //nolint:all // Reassigned ctx - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() // Configure the driver to connect to the database diff --git a/internal/sources/singlestore/singlestore_test.go b/internal/sources/singlestore/singlestore_test.go index 101df5300a..f996921db0 100644 --- a/internal/sources/singlestore/singlestore_test.go +++ b/internal/sources/singlestore/singlestore_test.go @@ -1,5 +1,3 @@ -package singlestore_test - // Copyright 2025 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,12 +12,15 @@ package singlestore_test // See the License for the specific language governing permissions and // limitations under the License. +package singlestore_test + import ( + "context" "testing" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/singlestore" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -33,19 +34,19 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - sources: - my-s2-instance: - kind: singlestore - host: 0.0.0.0 - port: my-port - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-s2-instance + type: singlestore + host: 0.0.0.0 + port: my-port + database: my_db + user: my_user + password: my_pass `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-s2-instance": singlestore.Config{ Name: "my-s2-instance", - Kind: singlestore.SourceKind, + Type: singlestore.SourceType, Host: "0.0.0.0", Port: "my-port", Database: "my_db", @@ -57,20 +58,20 @@ func TestParseFromYaml(t *testing.T) { { desc: "with query timeout", in: ` - sources: - my-s2-instance: - kind: singlestore - host: 0.0.0.0 - port: my-port - database: my_db - user: my_user - password: my_pass - queryTimeout: 45s + kind: sources + name: my-s2-instance + type: singlestore + host: 0.0.0.0 + port: my-port + database: my_db + user: my_user + password: my_pass + queryTimeout: 45s `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-s2-instance": singlestore.Config{ Name: "my-s2-instance", - Kind: singlestore.SourceKind, + Type: singlestore.SourceType, Host: "0.0.0.0", Port: "my-port", Database: "my_db", @@ -83,16 +84,12 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -108,39 +105,35 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - my-s2-instance: - kind: singlestore - host: 0.0.0.0 - port: my-port - database: my_db - user: my_user - password: my_pass - foo: bar + kind: sources + name: my-s2-instance + type: singlestore + host: 0.0.0.0 + port: my-port + database: my_db + user: my_user + password: my_pass + foo: bar `, - err: "unable to parse source \"my-s2-instance\" as \"singlestore\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | kind: singlestore\n 5 | password: my_pass\n 6 | ", + err: "error unmarshaling sources: unable to parse source \"my-s2-instance\" as \"singlestore\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | name: my-s2-instance\n 5 | password: my_pass\n 6 | ", }, { desc: "missing required field", in: ` - sources: - my-s2-instance: - kind: singlestore - port: my-port - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-s2-instance + type: singlestore + port: my-port + database: my_db + user: my_user + password: my_pass `, - err: "unable to parse source \"my-s2-instance\" as \"singlestore\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-s2-instance\" as \"singlestore\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/snowflake/snowflake.go b/internal/sources/snowflake/snowflake.go index af44eb2ece..b08f0580b3 100644 --- a/internal/sources/snowflake/snowflake.go +++ b/internal/sources/snowflake/snowflake.go @@ -25,14 +25,14 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "snowflake" +const SourceType string = "snowflake" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -46,7 +46,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Account string `yaml:"account" validate:"required"` User string `yaml:"user" validate:"required"` Password string `yaml:"password" validate:"required"` @@ -56,8 +56,8 @@ type Config struct { Role string `yaml:"role"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -85,8 +85,8 @@ type Source struct { DB *sqlx.DB } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -137,7 +137,7 @@ func (s *Source) RunSQL(ctx context.Context, statement string, params []any) (an func initSnowflakeConnection(ctx context.Context, tracer trace.Tracer, name, account, user, password, database, schema, warehouse, role string) (*sqlx.DB, error) { //nolint:all // Reassigned ctx - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() // Set defaults for optional parameters diff --git a/internal/sources/snowflake/snowflake_test.go b/internal/sources/snowflake/snowflake_test.go index 54d7114849..f9437ec49c 100644 --- a/internal/sources/snowflake/snowflake_test.go +++ b/internal/sources/snowflake/snowflake_test.go @@ -15,11 +15,12 @@ package snowflake_test import ( + "context" "testing" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/snowflake" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -33,19 +34,19 @@ func TestParseFromYamlSnowflake(t *testing.T) { { desc: "basic example", in: ` - sources: - my-snowflake-instance: - kind: snowflake - account: my-account - user: my_user - password: my_pass - database: my_db - schema: my_schema + kind: sources + name: my-snowflake-instance + type: snowflake + account: my-account + user: my_user + password: my_pass + database: my_db + schema: my_schema `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-snowflake-instance": snowflake.Config{ Name: "my-snowflake-instance", - Kind: snowflake.SourceKind, + Type: snowflake.SourceType, Account: "my-account", User: "my_user", Password: "my_pass", @@ -59,16 +60,12 @@ func TestParseFromYamlSnowflake(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -84,39 +81,35 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - my-snowflake-instance: - kind: snowflake - account: my-account - user: my_user - password: my_pass - database: my_db - schema: my_schema - foo: bar + kind: sources + name: my-snowflake-instance + type: snowflake + account: my-account + user: my_user + password: my_pass + database: my_db + schema: my_schema + foo: bar `, - err: "unable to parse source \"my-snowflake-instance\" as \"snowflake\": [3:1] unknown field \"foo\"\n 1 | account: my-account\n 2 | database: my_db\n> 3 | foo: bar\n ^\n 4 | kind: snowflake\n 5 | password: my_pass\n 6 | schema: my_schema\n 7 | ", + err: "error unmarshaling sources: unable to parse source \"my-snowflake-instance\" as \"snowflake\": [3:1] unknown field \"foo\"\n 1 | account: my-account\n 2 | database: my_db\n> 3 | foo: bar\n ^\n 4 | name: my-snowflake-instance\n 5 | password: my_pass\n 6 | schema: my_schema\n 7 | ", }, { desc: "missing required field", in: ` - sources: - my-snowflake-instance: - kind: snowflake - account: my-account - user: my_user - password: my_pass - database: my_db + kind: sources + name: my-snowflake-instance + type: snowflake + account: my-account + user: my_user + password: my_pass + database: my_db `, - err: "unable to parse source \"my-snowflake-instance\" as \"snowflake\": Key: 'Config.Schema' Error:Field validation for 'Schema' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-snowflake-instance\" as \"snowflake\": Key: 'Config.Schema' Error:Field validation for 'Schema' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/sources.go b/internal/sources/sources.go index 10e6d57e17..93ae0233b1 100644 --- a/internal/sources/sources.go +++ b/internal/sources/sources.go @@ -29,48 +29,48 @@ type SourceConfigFactory func(ctx context.Context, name string, decoder *yaml.De var sourceRegistry = make(map[string]SourceConfigFactory) -// Register registers a new source kind with its factory. -// It returns false if the kind is already registered. -func Register(kind string, factory SourceConfigFactory) bool { - if _, exists := sourceRegistry[kind]; exists { - // Source with this kind already exists, do not overwrite. +// Register registers a new source type with its factory. +// It returns false if the type is already registered. +func Register(sourceType string, factory SourceConfigFactory) bool { + if _, exists := sourceRegistry[sourceType]; exists { + // Source with this type already exists, do not overwrite. return false } - sourceRegistry[kind] = factory + sourceRegistry[sourceType] = factory return true } -// DecodeConfig decodes a source configuration using the registered factory for the given kind. -func DecodeConfig(ctx context.Context, kind string, name string, decoder *yaml.Decoder) (SourceConfig, error) { - factory, found := sourceRegistry[kind] +// DecodeConfig decodes a source configuration using the registered factory for the given type. +func DecodeConfig(ctx context.Context, sourceType string, name string, decoder *yaml.Decoder) (SourceConfig, error) { + factory, found := sourceRegistry[sourceType] if !found { - return nil, fmt.Errorf("unknown source kind: %q", kind) + return nil, fmt.Errorf("unknown source type: %q", sourceType) } sourceConfig, err := factory(ctx, name, decoder) if err != nil { - return nil, fmt.Errorf("unable to parse source %q as %q: %w", name, kind, err) + return nil, fmt.Errorf("unable to parse source %q as %q: %w", name, sourceType, err) } return sourceConfig, err } // SourceConfig is the interface for configuring a source. type SourceConfig interface { - SourceConfigKind() string + SourceConfigType() string Initialize(ctx context.Context, tracer trace.Tracer) (Source, error) } // Source is the interface for the source itself. type Source interface { - SourceKind() string + SourceType() string ToConfig() SourceConfig } // InitConnectionSpan adds a span for database pool connection initialization -func InitConnectionSpan(ctx context.Context, tracer trace.Tracer, sourceKind, sourceName string) (context.Context, trace.Span) { +func InitConnectionSpan(ctx context.Context, tracer trace.Tracer, sourceType, sourceName string) (context.Context, trace.Span) { ctx, span := tracer.Start( ctx, "toolbox/server/source/connect", - trace.WithAttributes(attribute.String("source_kind", sourceKind)), + trace.WithAttributes(attribute.String("source_type", sourceType)), trace.WithAttributes(attribute.String("source_name", sourceName)), ) return ctx, span diff --git a/internal/sources/spanner/spanner.go b/internal/sources/spanner/spanner.go index d6a6967e12..7c2f3c1464 100644 --- a/internal/sources/spanner/spanner.go +++ b/internal/sources/spanner/spanner.go @@ -28,14 +28,14 @@ import ( "google.golang.org/api/iterator" ) -const SourceKind string = "spanner" +const SourceType string = "spanner" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -49,15 +49,15 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Project string `yaml:"project" validate:"required"` Instance string `yaml:"instance" validate:"required"` Dialect sources.Dialect `yaml:"dialect" validate:"required"` Database string `yaml:"database" validate:"required"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -80,8 +80,8 @@ type Source struct { Client *spanner.Client } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -171,7 +171,7 @@ func (s *Source) RunSQL(ctx context.Context, readOnly bool, statement string, pa func initSpannerClient(ctx context.Context, tracer trace.Tracer, name, project, instance, dbname string) (*spanner.Client, error) { //nolint:all // Reassigned ctx - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() // Configure the connection to the database diff --git a/internal/sources/spanner/spanner_test.go b/internal/sources/spanner/spanner_test.go index af0ac6a9fe..788a3fcccd 100644 --- a/internal/sources/spanner/spanner_test.go +++ b/internal/sources/spanner/spanner_test.go @@ -15,9 +15,9 @@ package spanner_test import ( + "context" "testing" - 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/sources" @@ -34,17 +34,17 @@ func TestParseFromYamlSpannerDb(t *testing.T) { { desc: "basic example", in: ` - sources: - my-spanner-instance: - kind: spanner - project: my-project - instance: my-instance - database: my_db + kind: sources + name: my-spanner-instance + type: spanner + project: my-project + instance: my-instance + database: my_db `, want: map[string]sources.SourceConfig{ "my-spanner-instance": spanner.Config{ Name: "my-spanner-instance", - Kind: spanner.SourceKind, + Type: spanner.SourceType, Project: "my-project", Instance: "my-instance", Dialect: "googlesql", @@ -55,18 +55,18 @@ func TestParseFromYamlSpannerDb(t *testing.T) { { desc: "gsql dialect", in: ` - sources: - my-spanner-instance: - kind: spanner - project: my-project - instance: my-instance - dialect: Googlesql - database: my_db + kind: sources + name: my-spanner-instance + type: spanner + project: my-project + instance: my-instance + dialect: Googlesql + database: my_db `, want: map[string]sources.SourceConfig{ "my-spanner-instance": spanner.Config{ Name: "my-spanner-instance", - Kind: spanner.SourceKind, + Type: spanner.SourceType, Project: "my-project", Instance: "my-instance", Dialect: "googlesql", @@ -77,18 +77,18 @@ func TestParseFromYamlSpannerDb(t *testing.T) { { desc: "postgresql dialect", in: ` - sources: - my-spanner-instance: - kind: spanner - project: my-project - instance: my-instance - dialect: postgresql - database: my_db + kind: sources + name: my-spanner-instance + type: spanner + project: my-project + instance: my-instance + dialect: postgresql + database: my_db `, want: map[string]sources.SourceConfig{ "my-spanner-instance": spanner.Config{ Name: "my-spanner-instance", - Kind: spanner.SourceKind, + Type: spanner.SourceType, Project: "my-project", Instance: "my-instance", Dialect: "postgresql", @@ -99,16 +99,12 @@ func TestParseFromYamlSpannerDb(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -124,48 +120,44 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "invalid dialect", in: ` - sources: - my-spanner-instance: - kind: spanner - project: my-project - instance: my-instance - dialect: fail - database: my_db + kind: sources + name: my-spanner-instance + type: spanner + project: my-project + instance: my-instance + dialect: fail + database: my_db `, - err: "unable to parse source \"my-spanner-instance\" as \"spanner\": dialect invalid: must be one of \"googlesql\", or \"postgresql\"", + err: "error unmarshaling sources: unable to parse source \"my-spanner-instance\" as \"spanner\": dialect invalid: must be one of \"googlesql\", or \"postgresql\"", }, { desc: "extra field", in: ` - sources: - my-spanner-instance: - kind: spanner - project: my-project - instance: my-instance - database: my_db - foo: bar + kind: sources + name: my-spanner-instance + type: spanner + project: my-project + instance: my-instance + database: my_db + foo: bar `, - err: "unable to parse source \"my-spanner-instance\" as \"spanner\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | instance: my-instance\n 4 | kind: spanner\n 5 | project: my-project", + err: "error unmarshaling sources: unable to parse source \"my-spanner-instance\" as \"spanner\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | instance: my-instance\n 4 | name: my-spanner-instance\n 5 | project: my-project\n 6 | ", }, { desc: "missing required field", in: ` - sources: - my-spanner-instance: - kind: spanner - project: my-project - instance: my-instance + kind: sources + name: my-spanner-instance + type: spanner + project: my-project + instance: my-instance `, - err: "unable to parse source \"my-spanner-instance\" as \"spanner\": Key: 'Config.Database' Error:Field validation for 'Database' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-spanner-instance\" as \"spanner\": Key: 'Config.Database' Error:Field validation for 'Database' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/sqlite/sqlite.go b/internal/sources/sqlite/sqlite.go index f2afc57f9c..c90b932dea 100644 --- a/internal/sources/sqlite/sqlite.go +++ b/internal/sources/sqlite/sqlite.go @@ -27,14 +27,14 @@ import ( _ "modernc.org/sqlite" // Pure Go SQLite driver ) -const SourceKind string = "sqlite" +const SourceType string = "sqlite" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -48,12 +48,12 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Database string `yaml:"database" validate:"required"` // Path to SQLite database file } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -81,8 +81,8 @@ type Source struct { Db *sql.DB } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -155,7 +155,7 @@ func (s *Source) RunSQL(ctx context.Context, statement string, params []any) (an func initSQLiteConnection(ctx context.Context, tracer trace.Tracer, name, dbPath string) (*sql.DB, error) { //nolint:all // Reassigned ctx - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() // Open database connection diff --git a/internal/sources/sqlite/sqlite_test.go b/internal/sources/sqlite/sqlite_test.go index 0367679063..7ccf10a0f1 100644 --- a/internal/sources/sqlite/sqlite_test.go +++ b/internal/sources/sqlite/sqlite_test.go @@ -15,9 +15,9 @@ package sqlite_test import ( + "context" "testing" - 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/sources" @@ -34,15 +34,15 @@ func TestParseFromYamlSQLite(t *testing.T) { { desc: "basic example", in: ` - sources: - my-sqlite-db: - kind: sqlite - database: /path/to/database.db + kind: sources + name: my-sqlite-db + type: sqlite + database: /path/to/database.db `, want: map[string]sources.SourceConfig{ "my-sqlite-db": sqlite.Config{ Name: "my-sqlite-db", - Kind: sqlite.SourceKind, + Type: sqlite.SourceType, Database: "/path/to/database.db", }, }, @@ -50,16 +50,53 @@ func TestParseFromYamlSQLite(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) + } + }) + } +} + +func TestFailParseFromYaml(t *testing.T) { + tcs := []struct { + desc string + in string + err string + }{ + { + desc: "extra field", + in: ` + kind: sources + name: my-sqlite-db + type: sqlite + database: /path/to/database.db + foo: bar + `, + err: "error unmarshaling sources: unable to parse source \"my-sqlite-db\" as \"sqlite\": [2:1] unknown field \"foo\"\n 1 | database: /path/to/database.db\n> 2 | foo: bar\n ^\n 3 | name: my-sqlite-db\n 4 | type: sqlite", + }, + { + desc: "missing required field", + in: ` + kind: sources + name: my-sqlite-db + type: sqlite + `, + err: "error unmarshaling sources: unable to parse source \"my-sqlite-db\" as \"sqlite\": Key: 'Config.Database' Error:Field validation for 'Database' failed on the 'required' tag", + }, + } + for _, tc := range tcs { + t.Run(tc.desc, func(t *testing.T) { + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) + if err == nil { + t.Fatalf("expect parsing to fail") + } + errStr := err.Error() + if errStr != tc.err { + t.Fatalf("unexpected error: got %q, want %q", errStr, tc.err) } }) } diff --git a/internal/sources/tidb/tidb.go b/internal/sources/tidb/tidb.go index 617da6969d..006e999e93 100644 --- a/internal/sources/tidb/tidb.go +++ b/internal/sources/tidb/tidb.go @@ -27,15 +27,15 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "tidb" +const SourceType string = "tidb" const TiDBCloudHostPattern string = `gateway\d{2}\.(.+)\.(prod|dev|staging)\.(.+)\.tidbcloud\.com` // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -55,7 +55,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Host string `yaml:"host" validate:"required"` Port string `yaml:"port" validate:"required"` User string `yaml:"user" validate:"required"` @@ -64,8 +64,8 @@ type Config struct { UseSSL bool `yaml:"ssl"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -93,8 +93,8 @@ type Source struct { Pool *sql.DB } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -189,7 +189,7 @@ func IsTiDBCloudHost(host string) bool { func initTiDBConnectionPool(ctx context.Context, tracer trace.Tracer, name, host, port, user, pass, dbname string, useSSL bool) (*sql.DB, error) { //nolint:all // Reassigned ctx - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() // Configure the driver to connect to the database diff --git a/internal/sources/tidb/tidb_test.go b/internal/sources/tidb/tidb_test.go index f9b8b8ffd1..9b18f52b06 100644 --- a/internal/sources/tidb/tidb_test.go +++ b/internal/sources/tidb/tidb_test.go @@ -15,11 +15,12 @@ package tidb_test import ( + "context" "testing" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/tidb" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -33,19 +34,19 @@ func TestParseFromYamlTiDB(t *testing.T) { { desc: "basic example", in: ` - sources: - my-tidb-instance: - kind: tidb - host: 0.0.0.0 - port: my-port - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-tidb-instance + type: tidb + host: 0.0.0.0 + port: my-port + database: my_db + user: my_user + password: my_pass `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-tidb-instance": tidb.Config{ Name: "my-tidb-instance", - Kind: tidb.SourceKind, + Type: tidb.SourceType, Host: "0.0.0.0", Port: "my-port", Database: "my_db", @@ -58,20 +59,20 @@ func TestParseFromYamlTiDB(t *testing.T) { { desc: "with SSL enabled", in: ` - sources: - my-tidb-cloud: - kind: tidb - host: gateway01.us-west-2.prod.aws.tidbcloud.com - port: 4000 - database: test_db - user: cloud_user - password: cloud_pass - ssl: true + kind: sources + name: my-tidb-cloud + type: tidb + host: gateway01.us-west-2.prod.aws.tidbcloud.com + port: 4000 + database: test_db + user: cloud_user + password: cloud_pass + ssl: true `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-tidb-cloud": tidb.Config{ Name: "my-tidb-cloud", - Kind: tidb.SourceKind, + Type: tidb.SourceType, Host: "gateway01.us-west-2.prod.aws.tidbcloud.com", Port: "4000", Database: "test_db", @@ -84,19 +85,19 @@ func TestParseFromYamlTiDB(t *testing.T) { { desc: "Change SSL enabled due to TiDB Cloud host", in: ` - sources: - my-tidb-cloud: - kind: tidb - host: gateway01.us-west-2.prod.aws.tidbcloud.com - port: 4000 - database: test_db - user: cloud_user - password: cloud_pass + kind: sources + name: my-tidb-cloud + type: tidb + host: gateway01.us-west-2.prod.aws.tidbcloud.com + port: 4000 + database: test_db + user: cloud_user + password: cloud_pass `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-tidb-cloud": tidb.Config{ Name: "my-tidb-cloud", - Kind: tidb.SourceKind, + Type: tidb.SourceType, Host: "gateway01.us-west-2.prod.aws.tidbcloud.com", Port: "4000", Database: "test_db", @@ -109,16 +110,12 @@ func TestParseFromYamlTiDB(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -134,41 +131,37 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "extra field", in: ` - sources: - my-tidb-instance: - kind: tidb - host: 0.0.0.0 - port: my-port - database: my_db - user: my_user - password: my_pass - ssl: false - foo: bar + kind: sources + name: my-tidb-instance + type: tidb + host: 0.0.0.0 + port: my-port + database: my_db + user: my_user + password: my_pass + ssl: false + foo: bar `, - err: "unable to parse source \"my-tidb-instance\" as \"tidb\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | kind: tidb\n 5 | password: my_pass\n 6 | ", + err: "error unmarshaling sources: unable to parse source \"my-tidb-instance\" as \"tidb\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | name: my-tidb-instance\n 5 | password: my_pass\n 6 | ", }, { desc: "missing required field", in: ` - sources: - my-tidb-instance: - kind: tidb - port: my-port - database: my_db - user: my_user - password: my_pass - ssl: false + kind: sources + name: my-tidb-instance + type: tidb + port: my-port + database: my_db + user: my_user + password: my_pass + ssl: false `, - err: "unable to parse source \"my-tidb-instance\" as \"tidb\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-tidb-instance\" as \"tidb\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/trino/trino.go b/internal/sources/trino/trino.go index ed99dc3c19..6d468a27e8 100644 --- a/internal/sources/trino/trino.go +++ b/internal/sources/trino/trino.go @@ -30,14 +30,14 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "trino" +const SourceType string = "trino" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -51,7 +51,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Host string `yaml:"host" validate:"required"` Port string `yaml:"port" validate:"required"` User string `yaml:"user"` @@ -67,8 +67,8 @@ type Config struct { DisableSslVerification bool `yaml:"disableSslVerification"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -96,8 +96,8 @@ type Source struct { Pool *sql.DB } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -160,7 +160,7 @@ func (s *Source) RunSQL(ctx context.Context, statement string, params []any) (an func initTrinoConnectionPool(ctx context.Context, tracer trace.Tracer, name, host, port, user, password, catalog, schema, queryTimeout, accessToken string, kerberosEnabled, sslEnabled bool, sslCertPath, sslCert string, disableSslVerification bool) (*sql.DB, error) { //nolint:all // Reassigned ctx - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() // Build Trino DSN diff --git a/internal/sources/trino/trino_test.go b/internal/sources/trino/trino_test.go index f59679c86b..236ad68fe2 100644 --- a/internal/sources/trino/trino_test.go +++ b/internal/sources/trino/trino_test.go @@ -15,11 +15,12 @@ package trino import ( + "context" "testing" - "github.com/goccy/go-yaml" "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" + "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -153,19 +154,19 @@ func TestParseFromYamlTrino(t *testing.T) { { desc: "basic example", in: ` - sources: - my-trino-instance: - kind: trino - host: localhost - port: "8080" - user: testuser - catalog: hive - schema: default + kind: sources + name: my-trino-instance + type: trino + host: localhost + port: "8080" + user: testuser + catalog: hive + schema: default `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-trino-instance": Config{ Name: "my-trino-instance", - Kind: SourceKind, + Type: SourceType, Host: "localhost", Port: "8080", User: "testuser", @@ -177,24 +178,24 @@ func TestParseFromYamlTrino(t *testing.T) { { desc: "example with optional fields", in: ` - sources: - my-trino-instance: - kind: trino - host: localhost - port: "8443" - user: testuser - password: testpass - catalog: hive - schema: default - queryTimeout: "30m" - accessToken: "jwt-token-here" - kerberosEnabled: true - sslEnabled: true + kind: sources + name: my-trino-instance + type: trino + host: localhost + port: "8443" + user: testuser + password: testpass + catalog: hive + schema: default + queryTimeout: "30m" + accessToken: "jwt-token-here" + kerberosEnabled: true + sslEnabled: true `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-trino-instance": Config{ Name: "my-trino-instance", - Kind: SourceKind, + Type: SourceType, Host: "localhost", Port: "8443", User: "testuser", @@ -211,18 +212,18 @@ func TestParseFromYamlTrino(t *testing.T) { { desc: "anonymous access without user", in: ` - sources: - my-trino-anonymous: - kind: trino - host: localhost - port: "8080" - catalog: hive - schema: default + kind: sources + name: my-trino-anonymous + type: trino + host: localhost + port: "8080" + catalog: hive + schema: default `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-trino-anonymous": Config{ Name: "my-trino-anonymous", - Kind: SourceKind, + Type: SourceType, Host: "localhost", Port: "8080", Catalog: "hive", @@ -233,26 +234,26 @@ func TestParseFromYamlTrino(t *testing.T) { { desc: "example with SSL cert path and cert", in: ` - sources: - my-trino-ssl-cert: - kind: trino - host: localhost - port: "8443" - user: testuser - catalog: hive - schema: default - sslEnabled: true - sslCertPath: /path/to/cert.pem - sslCert: |- + kind: sources + name: my-trino-ssl-cert + type: trino + host: localhost + port: "8443" + user: testuser + catalog: hive + schema: default + sslEnabled: true + sslCertPath: /path/to/cert.pem + sslCert: |- -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- - disableSslVerification: true + disableSslVerification: true `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-trino-ssl-cert": Config{ Name: "my-trino-ssl-cert", - Kind: SourceKind, + Type: SourceType, Host: "localhost", Port: "8443", User: "testuser", @@ -268,16 +269,12 @@ func TestParseFromYamlTrino(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } diff --git a/internal/sources/valkey/valkey.go b/internal/sources/valkey/valkey.go index 58ed2356d3..fe56c3f5d2 100644 --- a/internal/sources/valkey/valkey.go +++ b/internal/sources/valkey/valkey.go @@ -24,14 +24,14 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "valkey" +const SourceType string = "valkey" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -45,7 +45,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Address []string `yaml:"address" validate:"required"` Username string `yaml:"username"` Password string `yaml:"password"` @@ -54,8 +54,8 @@ type Config struct { DisableCache bool `yaml:"disableCache"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -114,8 +114,8 @@ type Source struct { Client valkey.Client } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { diff --git a/internal/sources/valkey/valkey_test.go b/internal/sources/valkey/valkey_test.go index 58a0cc0017..7e9ba2f396 100644 --- a/internal/sources/valkey/valkey_test.go +++ b/internal/sources/valkey/valkey_test.go @@ -15,10 +15,10 @@ package valkey_test import ( + "context" "strings" "testing" - 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/sources" @@ -35,16 +35,16 @@ func TestParseFromYamlValkey(t *testing.T) { { desc: "default setting", in: ` - sources: - my-valkey-instance: - kind: valkey - address: - - 127.0.0.1 + kind: sources + name: my-valkey-instance + type: valkey + address: + - 127.0.0.1 `, want: map[string]sources.SourceConfig{ "my-valkey-instance": valkey.Config{ Name: "my-valkey-instance", - Kind: valkey.SourceKind, + Type: valkey.SourceType, Address: []string{"127.0.0.1"}, Username: "", Password: "", @@ -57,21 +57,21 @@ func TestParseFromYamlValkey(t *testing.T) { { desc: "advanced example", in: ` - sources: - my-valkey-instance: - kind: valkey - address: - - 127.0.0.1 - database: 1 - username: user - password: pass - useGCPIAM: true - disableCache: true + kind: sources + name: my-valkey-instance + type: valkey + address: + - 127.0.0.1 + database: 1 + username: user + password: pass + useGCPIAM: true + disableCache: true `, want: map[string]sources.SourceConfig{ "my-valkey-instance": valkey.Config{ Name: "my-valkey-instance", - Kind: valkey.SourceKind, + Type: valkey.SourceType, Address: []string{"127.0.0.1"}, Username: "user", Password: "pass", @@ -84,16 +84,12 @@ func TestParseFromYamlValkey(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -109,47 +105,42 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "invalid database", in: ` - sources: - my-valkey-instance: - kind: valkey - project: my-project - address: - - 127.0.0.1 - database: my-db - useGCPIAM: false + kind: sources + name: my-valkey-instance + type: valkey + address: + - 127.0.0.1 + database: my-db + useGCPIAM: false `, - err: "cannot unmarshal string into Go struct field .Sources of type int", + err: "error unmarshaling sources: unable to parse source \"my-valkey-instance\" as \"valkey\": [3:11] cannot unmarshal string into Go struct field Config.Database of type int\n 1 | address:\n 2 | - 127.0.0.1\n> 3 | database: my-db\n ^\n 4 | name: my-valkey-instance\n 5 | type: valkey\n 6 | useGCPIAM: false", }, { desc: "extra field", in: ` - sources: - my-valkey-instance: - kind: valkey - address: - - 127.0.0.1 - project: proj - database: 1 + kind: sources + name: my-valkey-instance + type: valkey + address: + - 127.0.0.1 + project: proj + database: 1 `, - err: "unable to parse source \"my-valkey-instance\" as \"valkey\": [5:1] unknown field \"project\"", + err: "error unmarshaling sources: unable to parse source \"my-valkey-instance\" as \"valkey\": [5:1] unknown field \"project\"\n 2 | - 127.0.0.1\n 3 | database: 1\n 4 | name: my-valkey-instance\n> 5 | project: proj\n ^\n 6 | type: valkey", }, { desc: "missing required field", in: ` - sources: - my-valkey-instance: - kind: valkey + kind: sources + name: my-valkey-instance + type: valkey `, - err: "unable to parse source \"my-valkey-instance\" as \"valkey\": Key: 'Config.Address' Error:Field validation for 'Address' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-valkey-instance\" as \"valkey\": Key: 'Config.Address' Error:Field validation for 'Address' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/sources/yugabytedb/yugabytedb.go b/internal/sources/yugabytedb/yugabytedb.go index 830e3ae7fe..8c5b1144c4 100644 --- a/internal/sources/yugabytedb/yugabytedb.go +++ b/internal/sources/yugabytedb/yugabytedb.go @@ -24,14 +24,14 @@ import ( "go.opentelemetry.io/otel/trace" ) -const SourceKind string = "yugabytedb" +const SourceType string = "yugabytedb" // validate interface var _ sources.SourceConfig = Config{} func init() { - if !sources.Register(SourceKind, newConfig) { - panic(fmt.Sprintf("source kind %q already registered", SourceKind)) + if !sources.Register(SourceType, newConfig) { + panic(fmt.Sprintf("source type %q already registered", SourceType)) } } @@ -45,7 +45,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Host string `yaml:"host" validate:"required"` Port string `yaml:"port" validate:"required"` User string `yaml:"user" validate:"required"` @@ -58,8 +58,8 @@ type Config struct { FailedHostReconnectDelaySeconds string `yaml:"failedHostReconnectDelaySecs"` } -func (r Config) SourceConfigKind() string { - return SourceKind +func (r Config) SourceConfigType() string { + return SourceType } func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { @@ -87,8 +87,8 @@ type Source struct { Pool *pgxpool.Pool } -func (s *Source) SourceKind() string { - return SourceKind +func (s *Source) SourceType() string { + return SourceType } func (s *Source) ToConfig() sources.SourceConfig { @@ -130,7 +130,7 @@ func (s *Source) RunSQL(ctx context.Context, statement string, params []any) (an func initYugabyteDBConnectionPool(ctx context.Context, tracer trace.Tracer, name, host, port, user, pass, dbname, loadBalance, topologyKeys, refreshInterval, explicitFallback, failedHostTTL string) (*pgxpool.Pool, error) { //nolint:all // Reassigned ctx - ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) + ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name) defer span.End() // urlExample := "postgres://username:password@localhost:5433/database_name" i := fmt.Sprintf("postgres://%s:%s@%s:%s/%s", user, pass, host, port, dbname) diff --git a/internal/sources/yugabytedb/yugabytedb_test.go b/internal/sources/yugabytedb/yugabytedb_test.go index 32eda8b642..4a14e53d93 100644 --- a/internal/sources/yugabytedb/yugabytedb_test.go +++ b/internal/sources/yugabytedb/yugabytedb_test.go @@ -15,13 +15,14 @@ package yugabytedb_test import ( + "context" "testing" "strings" - 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/sources" "github.com/googleapis/genai-toolbox/internal/sources/yugabytedb" "github.com/googleapis/genai-toolbox/internal/testutils" ) @@ -36,20 +37,19 @@ func TestParseFromYamlYugabyteDB(t *testing.T) { { desc: "only required fields", in: ` - sources: - my-yb-instance: - kind: yugabytedb - name: my-yb-instance - host: yb-host - port: yb-port - user: yb_user - password: yb_pass - database: yb_db + kind: sources + name: my-yb-instance + type: yugabytedb + host: yb-host + port: yb-port + user: yb_user + password: yb_pass + database: yb_db `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-yb-instance": yugabytedb.Config{ Name: "my-yb-instance", - Kind: "yugabytedb", + Type: "yugabytedb", Host: "yb-host", Port: "yb-port", User: "yb_user", @@ -61,21 +61,20 @@ func TestParseFromYamlYugabyteDB(t *testing.T) { { desc: "with loadBalance only", in: ` - sources: - my-yb-instance: - kind: yugabytedb - name: my-yb-instance - host: yb-host - port: yb-port - user: yb_user - password: yb_pass - database: yb_db - loadBalance: true + kind: sources + name: my-yb-instance + type: yugabytedb + host: yb-host + port: yb-port + user: yb_user + password: yb_pass + database: yb_db + loadBalance: true `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-yb-instance": yugabytedb.Config{ Name: "my-yb-instance", - Kind: "yugabytedb", + Type: "yugabytedb", Host: "yb-host", Port: "yb-port", User: "yb_user", @@ -88,22 +87,21 @@ func TestParseFromYamlYugabyteDB(t *testing.T) { { desc: "loadBalance with topologyKeys", in: ` - sources: - my-yb-instance: - kind: yugabytedb - name: my-yb-instance - host: yb-host - port: yb-port - user: yb_user - password: yb_pass - database: yb_db - loadBalance: true - topologyKeys: zone1,zone2 + kind: sources + name: my-yb-instance + type: yugabytedb + host: yb-host + port: yb-port + user: yb_user + password: yb_pass + database: yb_db + loadBalance: true + topologyKeys: zone1,zone2 `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-yb-instance": yugabytedb.Config{ Name: "my-yb-instance", - Kind: "yugabytedb", + Type: "yugabytedb", Host: "yb-host", Port: "yb-port", User: "yb_user", @@ -117,23 +115,22 @@ func TestParseFromYamlYugabyteDB(t *testing.T) { { desc: "with fallback only", in: ` - sources: - my-yb-instance: - kind: yugabytedb - name: my-yb-instance - host: yb-host - port: yb-port - user: yb_user - password: yb_pass - database: yb_db - loadBalance: true - topologyKeys: zone1 - fallbackToTopologyKeysOnly: true + kind: sources + name: my-yb-instance + type: yugabytedb + host: yb-host + port: yb-port + user: yb_user + password: yb_pass + database: yb_db + loadBalance: true + topologyKeys: zone1 + fallbackToTopologyKeysOnly: true `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-yb-instance": yugabytedb.Config{ Name: "my-yb-instance", - Kind: "yugabytedb", + Type: "yugabytedb", Host: "yb-host", Port: "yb-port", User: "yb_user", @@ -148,23 +145,22 @@ func TestParseFromYamlYugabyteDB(t *testing.T) { { desc: "with refresh interval and reconnect delay", in: ` - sources: - my-yb-instance: - kind: yugabytedb - name: my-yb-instance - host: yb-host - port: yb-port - user: yb_user - password: yb_pass - database: yb_db - loadBalance: true - ybServersRefreshInterval: 20 - failedHostReconnectDelaySecs: 5 + kind: sources + name: my-yb-instance + type: yugabytedb + host: yb-host + port: yb-port + user: yb_user + password: yb_pass + database: yb_db + loadBalance: true + ybServersRefreshInterval: 20 + failedHostReconnectDelaySecs: 5 `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-yb-instance": yugabytedb.Config{ Name: "my-yb-instance", - Kind: "yugabytedb", + Type: "yugabytedb", Host: "yb-host", Port: "yb-port", User: "yb_user", @@ -179,25 +175,24 @@ func TestParseFromYamlYugabyteDB(t *testing.T) { { desc: "all fields set", in: ` - sources: - my-yb-instance: - kind: yugabytedb - name: my-yb-instance - host: yb-host - port: yb-port - user: yb_user - password: yb_pass - database: yb_db - loadBalance: true - topologyKeys: zone1,zone2 - fallbackToTopologyKeysOnly: true - ybServersRefreshInterval: 30 - failedHostReconnectDelaySecs: 10 + kind: sources + name: my-yb-instance + type: yugabytedb + host: yb-host + port: yb-port + user: yb_user + password: yb_pass + database: yb_db + loadBalance: true + topologyKeys: zone1,zone2 + fallbackToTopologyKeysOnly: true + ybServersRefreshInterval: 30 + failedHostReconnectDelaySecs: 10 `, - want: server.SourceConfigs{ + want: map[string]sources.SourceConfig{ "my-yb-instance": yugabytedb.Config{ Name: "my-yb-instance", - Kind: "yugabytedb", + Type: "yugabytedb", Host: "yb-host", Port: "yb-port", User: "yb_user", @@ -215,16 +210,12 @@ func TestParseFromYamlYugabyteDB(t *testing.T) { for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse (-want +got):\n%s", cmp.Diff(tc.want, got.Sources)) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse (-want +got):\n%s", cmp.Diff(tc.want, got)) } }) } @@ -239,54 +230,48 @@ func TestFailParseFromYamlYugabyteDB(t *testing.T) { { desc: "extra field", in: ` - sources: - my-yb-source: - kind: yugabytedb - name: my-yb-source - host: yb-host - port: yb-port - database: yb_db - user: yb_user - password: yb_pass - foo: bar + kind: sources + name: my-yb-source + type: yugabytedb + host: yb-host + port: yb-port + database: yb_db + user: yb_user + password: yb_pass + foo: bar `, - err: "unable to parse source \"my-yb-source\" as \"yugabytedb\": [2:1] unknown field \"foo\"", + err: "error unmarshaling sources: unable to parse source \"my-yb-source\" as \"yugabytedb\": [2:1] unknown field \"foo\"\n 1 | database: yb_db\n> 2 | foo: bar\n ^\n 3 | host: yb-host\n 4 | name: my-yb-source\n 5 | password: yb_pass\n 6 | ", }, { desc: "missing required field (password)", in: ` - sources: - my-yb-source: - kind: yugabytedb - name: my-yb-source - host: yb-host - port: yb-port - database: yb_db - user: yb_user + kind: sources + name: my-yb-source + type: yugabytedb + host: yb-host + port: yb-port + database: yb_db + user: yb_user `, - err: "unable to parse source \"my-yb-source\" as \"yugabytedb\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-yb-source\" as \"yugabytedb\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag", }, { desc: "missing required field (host)", in: ` - sources: - my-yb-source: - kind: yugabytedb - name: my-yb-source - port: yb-port - database: yb_db - user: yb_user - password: yb_pass + kind: sources + name: my-yb-source + type: yugabytedb + port: yb-port + database: yb_db + user: yb_user + password: yb_pass `, - err: "unable to parse source \"my-yb-source\" as \"yugabytedb\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag", + err: "error unmarshaling sources: unable to parse source \"my-yb-source\" as \"yugabytedb\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expected parsing to fail") } diff --git a/internal/tools/alloydb/alloydbcreatecluster/alloydbcreatecluster.go b/internal/tools/alloydb/alloydbcreatecluster/alloydbcreatecluster.go index dcc540b856..f11e13bc0d 100644 --- a/internal/tools/alloydb/alloydbcreatecluster/alloydbcreatecluster.go +++ b/internal/tools/alloydb/alloydbcreatecluster/alloydbcreatecluster.go @@ -25,11 +25,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "alloydb-create-cluster" +const resourceType string = "alloydb-create-cluster" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { // Configuration for the create-cluster tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -59,9 +59,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -73,7 +73,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } project := s.GetDefaultProject() @@ -123,7 +123,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool's logic. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -187,7 +187,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/alloydb/alloydbcreatecluster/alloydbcreatecluster_test.go b/internal/tools/alloydb/alloydbcreatecluster/alloydbcreatecluster_test.go index b97dc8487e..2daed2e625 100644 --- a/internal/tools/alloydb/alloydbcreatecluster/alloydbcreatecluster_test.go +++ b/internal/tools/alloydb/alloydbcreatecluster/alloydbcreatecluster_test.go @@ -17,7 +17,6 @@ package alloydbcreatecluster_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - create-my-cluster: - kind: alloydb-create-cluster - source: my-alloydb-admin-source - description: some description + kind: tools + name: create-my-cluster + type: alloydb-create-cluster + source: my-alloydb-admin-source + description: some description `, want: server.ToolConfigs{ "create-my-cluster": alloydbcreatecluster.Config{ Name: "create-my-cluster", - Kind: "alloydb-create-cluster", + Type: "alloydb-create-cluster", Source: "my-alloydb-admin-source", Description: "some description", AuthRequired: []string{}, @@ -56,19 +55,19 @@ func TestParseFromYaml(t *testing.T) { { desc: "with auth required", in: ` - tools: - create-my-cluster-auth: - kind: alloydb-create-cluster - source: my-alloydb-admin-source - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: create-my-cluster-auth + type: alloydb-create-cluster + source: my-alloydb-admin-source + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "create-my-cluster-auth": alloydbcreatecluster.Config{ Name: "create-my-cluster-auth", - Kind: "alloydb-create-cluster", + Type: "alloydb-create-cluster", Source: "my-alloydb-admin-source", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -78,15 +77,12 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/alloydb/alloydbcreateinstance/alloydbcreateinstance.go b/internal/tools/alloydb/alloydbcreateinstance/alloydbcreateinstance.go index ceec57d4f9..aa0723d190 100644 --- a/internal/tools/alloydb/alloydbcreateinstance/alloydbcreateinstance.go +++ b/internal/tools/alloydb/alloydbcreateinstance/alloydbcreateinstance.go @@ -25,11 +25,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "alloydb-create-instance" +const resourceType string = "alloydb-create-instance" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { // Configuration for the create-instance tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -59,9 +59,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -73,7 +73,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } project := s.GetDefaultProject() @@ -124,7 +124,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool's logic. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -193,7 +193,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/alloydb/alloydbcreateinstance/alloydbcreateinstance_test.go b/internal/tools/alloydb/alloydbcreateinstance/alloydbcreateinstance_test.go index 499a23c051..820492d825 100644 --- a/internal/tools/alloydb/alloydbcreateinstance/alloydbcreateinstance_test.go +++ b/internal/tools/alloydb/alloydbcreateinstance/alloydbcreateinstance_test.go @@ -17,7 +17,6 @@ package alloydbcreateinstance_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - create-my-instance: - kind: alloydb-create-instance - source: my-alloydb-admin-source - description: some description + kind: tools + name: create-my-instance + type: alloydb-create-instance + source: my-alloydb-admin-source + description: some description `, want: server.ToolConfigs{ "create-my-instance": alloydbcreateinstance.Config{ Name: "create-my-instance", - Kind: "alloydb-create-instance", + Type: "alloydb-create-instance", Source: "my-alloydb-admin-source", Description: "some description", AuthRequired: []string{}, @@ -56,19 +55,19 @@ func TestParseFromYaml(t *testing.T) { { desc: "with auth required", in: ` - tools: - create-my-instance-auth: - kind: alloydb-create-instance - source: my-alloydb-admin-source - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: create-my-instance-auth + type: alloydb-create-instance + source: my-alloydb-admin-source + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "create-my-instance-auth": alloydbcreateinstance.Config{ Name: "create-my-instance-auth", - Kind: "alloydb-create-instance", + Type: "alloydb-create-instance", Source: "my-alloydb-admin-source", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -78,15 +77,12 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/alloydb/alloydbcreateuser/alloydbcreateuser.go b/internal/tools/alloydb/alloydbcreateuser/alloydbcreateuser.go index 5ee8793ec4..fc5ebdf83f 100644 --- a/internal/tools/alloydb/alloydbcreateuser/alloydbcreateuser.go +++ b/internal/tools/alloydb/alloydbcreateuser/alloydbcreateuser.go @@ -25,11 +25,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "alloydb-create-user" +const resourceType string = "alloydb-create-user" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { // Configuration for the create-user tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -59,9 +59,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -73,7 +73,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } project := s.GetDefaultProject() @@ -123,7 +123,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool's logic. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -198,7 +198,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/alloydb/alloydbcreateuser/alloydbcreateuser_test.go b/internal/tools/alloydb/alloydbcreateuser/alloydbcreateuser_test.go index 1a35b3093e..234a9d35b8 100644 --- a/internal/tools/alloydb/alloydbcreateuser/alloydbcreateuser_test.go +++ b/internal/tools/alloydb/alloydbcreateuser/alloydbcreateuser_test.go @@ -17,7 +17,6 @@ package alloydbcreateuser_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - create-my-user: - kind: alloydb-create-user - source: my-alloydb-admin-source - description: some description + kind: tools + name: create-my-user + type: alloydb-create-user + source: my-alloydb-admin-source + description: some description `, want: server.ToolConfigs{ "create-my-user": alloydbcreateuser.Config{ Name: "create-my-user", - Kind: "alloydb-create-user", + Type: "alloydb-create-user", Source: "my-alloydb-admin-source", Description: "some description", AuthRequired: []string{}, @@ -56,19 +55,19 @@ func TestParseFromYaml(t *testing.T) { { desc: "with auth required", in: ` - tools: - create-my-user-auth: - kind: alloydb-create-user - source: my-alloydb-admin-source - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: create-my-user-auth + type: alloydb-create-user + source: my-alloydb-admin-source + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "create-my-user-auth": alloydbcreateuser.Config{ Name: "create-my-user-auth", - Kind: "alloydb-create-user", + Type: "alloydb-create-user", Source: "my-alloydb-admin-source", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -78,15 +77,12 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/alloydb/alloydbgetcluster/alloydbgetcluster.go b/internal/tools/alloydb/alloydbgetcluster/alloydbgetcluster.go index 8d3b294325..a2d853962f 100644 --- a/internal/tools/alloydb/alloydbgetcluster/alloydbgetcluster.go +++ b/internal/tools/alloydb/alloydbgetcluster/alloydbgetcluster.go @@ -25,11 +25,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "alloydb-get-cluster" +const resourceType string = "alloydb-get-cluster" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { // Configuration for the get-cluster tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -60,9 +60,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -74,7 +74,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } project := s.GetDefaultProject() @@ -121,7 +121,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool's logic. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -169,7 +169,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/alloydb/alloydbgetcluster/alloydbgetcluster_test.go b/internal/tools/alloydb/alloydbgetcluster/alloydbgetcluster_test.go index d30a335cd0..7ae2d11fee 100644 --- a/internal/tools/alloydb/alloydbgetcluster/alloydbgetcluster_test.go +++ b/internal/tools/alloydb/alloydbgetcluster/alloydbgetcluster_test.go @@ -17,7 +17,6 @@ package alloydbgetcluster_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - get-my-cluster: - kind: alloydb-get-cluster - source: my-alloydb-admin-source - description: some description - `, + kind: tools + name: get-my-cluster + type: alloydb-get-cluster + source: my-alloydb-admin-source + description: some description + `, want: server.ToolConfigs{ "get-my-cluster": alloydbgetcluster.Config{ Name: "get-my-cluster", - Kind: "alloydb-get-cluster", + Type: "alloydb-get-cluster", Source: "my-alloydb-admin-source", Description: "some description", AuthRequired: []string{}, @@ -56,19 +55,19 @@ func TestParseFromYaml(t *testing.T) { { desc: "with auth required", in: ` - tools: - get-my-cluster-auth: - kind: alloydb-get-cluster - source: my-alloydb-admin-source - description: some description - authRequired: - - my-google-auth-service - - other-auth-service - `, + kind: tools + name: get-my-cluster-auth + type: alloydb-get-cluster + source: my-alloydb-admin-source + description: some description + authRequired: + - my-google-auth-service + - other-auth-service + `, want: server.ToolConfigs{ "get-my-cluster-auth": alloydbgetcluster.Config{ Name: "get-my-cluster-auth", - Kind: "alloydb-get-cluster", + Type: "alloydb-get-cluster", Source: "my-alloydb-admin-source", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -78,15 +77,12 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/alloydb/alloydbgetinstance/alloydbgetinstance.go b/internal/tools/alloydb/alloydbgetinstance/alloydbgetinstance.go index 0163481bdf..d3b31f1565 100644 --- a/internal/tools/alloydb/alloydbgetinstance/alloydbgetinstance.go +++ b/internal/tools/alloydb/alloydbgetinstance/alloydbgetinstance.go @@ -25,11 +25,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "alloydb-get-instance" +const resourceType string = "alloydb-get-instance" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { // Configuration for the get-instance tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -60,9 +60,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -74,7 +74,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } project := s.GetDefaultProject() @@ -121,7 +121,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool's logic. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -173,7 +173,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/alloydb/alloydbgetinstance/alloydbgetinstance_test.go b/internal/tools/alloydb/alloydbgetinstance/alloydbgetinstance_test.go index 62e9339222..498934fdfd 100644 --- a/internal/tools/alloydb/alloydbgetinstance/alloydbgetinstance_test.go +++ b/internal/tools/alloydb/alloydbgetinstance/alloydbgetinstance_test.go @@ -17,7 +17,6 @@ package alloydbgetinstance_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - get-my-instance: - kind: alloydb-get-instance - source: my-alloydb-admin-source - description: some description - `, + kind: tools + name: get-my-instance + type: alloydb-get-instance + source: my-alloydb-admin-source + description: some description + `, want: server.ToolConfigs{ "get-my-instance": alloydbgetinstance.Config{ Name: "get-my-instance", - Kind: "alloydb-get-instance", + Type: "alloydb-get-instance", Source: "my-alloydb-admin-source", Description: "some description", AuthRequired: []string{}, @@ -56,19 +55,19 @@ func TestParseFromYaml(t *testing.T) { { desc: "with auth required", in: ` - tools: - get-my-instance-auth: - kind: alloydb-get-instance - source: my-alloydb-admin-source - description: some description - authRequired: - - my-google-auth-service - - other-auth-service - `, + kind: tools + name: get-my-instance-auth + type: alloydb-get-instance + source: my-alloydb-admin-source + description: some description + authRequired: + - my-google-auth-service + - other-auth-service + `, want: server.ToolConfigs{ "get-my-instance-auth": alloydbgetinstance.Config{ Name: "get-my-instance-auth", - Kind: "alloydb-get-instance", + Type: "alloydb-get-instance", Source: "my-alloydb-admin-source", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -78,15 +77,12 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/alloydb/alloydbgetuser/alloydbgetuser.go b/internal/tools/alloydb/alloydbgetuser/alloydbgetuser.go index cf6798455b..debc1bc54e 100644 --- a/internal/tools/alloydb/alloydbgetuser/alloydbgetuser.go +++ b/internal/tools/alloydb/alloydbgetuser/alloydbgetuser.go @@ -25,11 +25,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "alloydb-get-user" +const resourceType string = "alloydb-get-user" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { // Configuration for the get-user tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -60,9 +60,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -74,7 +74,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } project := s.GetDefaultProject() @@ -121,7 +121,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool's logic. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -173,7 +173,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/alloydb/alloydbgetuser/alloydbgetuser_test.go b/internal/tools/alloydb/alloydbgetuser/alloydbgetuser_test.go index 0d20ea3259..f601dc30d2 100644 --- a/internal/tools/alloydb/alloydbgetuser/alloydbgetuser_test.go +++ b/internal/tools/alloydb/alloydbgetuser/alloydbgetuser_test.go @@ -17,7 +17,6 @@ package alloydbgetuser_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - get-my-user: - kind: alloydb-get-user - source: my-alloydb-admin-source - description: some description - `, + kind: tools + name: get-my-user + type: alloydb-get-user + source: my-alloydb-admin-source + description: some description + `, want: server.ToolConfigs{ "get-my-user": alloydbgetuser.Config{ Name: "get-my-user", - Kind: "alloydb-get-user", + Type: "alloydb-get-user", Source: "my-alloydb-admin-source", Description: "some description", AuthRequired: []string{}, @@ -56,19 +55,19 @@ func TestParseFromYaml(t *testing.T) { { desc: "with auth required", in: ` - tools: - get-my-user-auth: - kind: alloydb-get-user - source: my-alloydb-admin-source - description: some description - authRequired: - - my-google-auth-service - - other-auth-service - `, + kind: tools + name: get-my-user-auth + type: alloydb-get-user + source: my-alloydb-admin-source + description: some description + authRequired: + - my-google-auth-service + - other-auth-service + `, want: server.ToolConfigs{ "get-my-user-auth": alloydbgetuser.Config{ Name: "get-my-user-auth", - Kind: "alloydb-get-user", + Type: "alloydb-get-user", Source: "my-alloydb-admin-source", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -78,15 +77,12 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/alloydb/alloydblistclusters/alloydblistclusters.go b/internal/tools/alloydb/alloydblistclusters/alloydblistclusters.go index 8036ce51a9..e689cb44c5 100644 --- a/internal/tools/alloydb/alloydblistclusters/alloydblistclusters.go +++ b/internal/tools/alloydb/alloydblistclusters/alloydblistclusters.go @@ -25,11 +25,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "alloydb-list-clusters" +const resourceType string = "alloydb-list-clusters" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { // Configuration for the list-clusters tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -60,9 +60,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -74,7 +74,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } project := s.GetDefaultProject() @@ -119,7 +119,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool's logic. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -163,7 +163,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/alloydb/alloydblistclusters/alloydblistclusters_test.go b/internal/tools/alloydb/alloydblistclusters/alloydblistclusters_test.go index b60a11db20..17429df5de 100644 --- a/internal/tools/alloydb/alloydblistclusters/alloydblistclusters_test.go +++ b/internal/tools/alloydb/alloydblistclusters/alloydblistclusters_test.go @@ -17,7 +17,6 @@ package alloydblistclusters_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - list-my-clusters: - kind: alloydb-list-clusters - source: my-alloydb-admin-source - description: some description - `, + kind: tools + name: list-my-clusters + type: alloydb-list-clusters + source: my-alloydb-admin-source + description: some description + `, want: server.ToolConfigs{ "list-my-clusters": alloydblistclusters.Config{ Name: "list-my-clusters", - Kind: "alloydb-list-clusters", + Type: "alloydb-list-clusters", Source: "my-alloydb-admin-source", Description: "some description", AuthRequired: []string{}, @@ -56,19 +55,19 @@ func TestParseFromYaml(t *testing.T) { { desc: "with auth required", in: ` - tools: - list-my-clusters-auth: - kind: alloydb-list-clusters - source: my-alloydb-admin-source - description: some description - authRequired: - - my-google-auth-service - - other-auth-service - `, + kind: tools + name: list-my-clusters-auth + type: alloydb-list-clusters + source: my-alloydb-admin-source + description: some description + authRequired: + - my-google-auth-service + - other-auth-service + `, want: server.ToolConfigs{ "list-my-clusters-auth": alloydblistclusters.Config{ Name: "list-my-clusters-auth", - Kind: "alloydb-list-clusters", + Type: "alloydb-list-clusters", Source: "my-alloydb-admin-source", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -78,15 +77,12 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/alloydb/alloydblistinstances/alloydblistinstances.go b/internal/tools/alloydb/alloydblistinstances/alloydblistinstances.go index 567e4c8e7d..223179bf72 100644 --- a/internal/tools/alloydb/alloydblistinstances/alloydblistinstances.go +++ b/internal/tools/alloydb/alloydblistinstances/alloydblistinstances.go @@ -25,11 +25,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "alloydb-list-instances" +const resourceType string = "alloydb-list-instances" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { // Configuration for the list-instances tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -60,9 +60,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -74,7 +74,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } project := s.GetDefaultProject() @@ -120,7 +120,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool's logic. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -168,7 +168,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/alloydb/alloydblistinstances/alloydblistinstances_test.go b/internal/tools/alloydb/alloydblistinstances/alloydblistinstances_test.go index aa667d9563..c1f95b964a 100644 --- a/internal/tools/alloydb/alloydblistinstances/alloydblistinstances_test.go +++ b/internal/tools/alloydb/alloydblistinstances/alloydblistinstances_test.go @@ -17,7 +17,6 @@ package alloydblistinstances_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - list-my-instances: - kind: alloydb-list-instances - source: my-alloydb-admin-source - description: some description - `, + kind: tools + name: list-my-instances + type: alloydb-list-instances + source: my-alloydb-admin-source + description: some description + `, want: server.ToolConfigs{ "list-my-instances": alloydblistinstances.Config{ Name: "list-my-instances", - Kind: "alloydb-list-instances", + Type: "alloydb-list-instances", Source: "my-alloydb-admin-source", Description: "some description", AuthRequired: []string{}, @@ -56,19 +55,19 @@ func TestParseFromYaml(t *testing.T) { { desc: "with auth required", in: ` - tools: - list-my-instances-auth: - kind: alloydb-list-instances - source: my-alloydb-admin-source - description: some description - authRequired: - - my-google-auth-service - - other-auth-service - `, + kind: tools + name: list-my-instances-auth + type: alloydb-list-instances + source: my-alloydb-admin-source + description: some description + authRequired: + - my-google-auth-service + - other-auth-service + `, want: server.ToolConfigs{ "list-my-instances-auth": alloydblistinstances.Config{ Name: "list-my-instances-auth", - Kind: "alloydb-list-instances", + Type: "alloydb-list-instances", Source: "my-alloydb-admin-source", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -78,15 +77,12 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/alloydb/alloydblistusers/alloydblistusers.go b/internal/tools/alloydb/alloydblistusers/alloydblistusers.go index cdfd60e47f..8f6e685cec 100644 --- a/internal/tools/alloydb/alloydblistusers/alloydblistusers.go +++ b/internal/tools/alloydb/alloydblistusers/alloydblistusers.go @@ -25,11 +25,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "alloydb-list-users" +const resourceType string = "alloydb-list-users" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { // Configuration for the list-users tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -60,9 +60,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -74,7 +74,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } project := s.GetDefaultProject() @@ -120,7 +120,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool's logic. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -168,7 +168,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/alloydb/alloydblistusers/alloydblistusers_test.go b/internal/tools/alloydb/alloydblistusers/alloydblistusers_test.go index d2d0672684..6c92fcab53 100644 --- a/internal/tools/alloydb/alloydblistusers/alloydblistusers_test.go +++ b/internal/tools/alloydb/alloydblistusers/alloydblistusers_test.go @@ -17,7 +17,6 @@ package alloydblistusers_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - list-my-users: - kind: alloydb-list-users - source: my-alloydb-admin-source - description: some description - `, + kind: tools + name: list-my-users + type: alloydb-list-users + source: my-alloydb-admin-source + description: some description + `, want: server.ToolConfigs{ "list-my-users": alloydblistusers.Config{ Name: "list-my-users", - Kind: "alloydb-list-users", + Type: "alloydb-list-users", Source: "my-alloydb-admin-source", Description: "some description", AuthRequired: []string{}, @@ -56,19 +55,19 @@ func TestParseFromYaml(t *testing.T) { { desc: "with auth required", in: ` - tools: - list-my-users-auth: - kind: alloydb-list-users - source: my-alloydb-admin-source - description: some description - authRequired: - - my-google-auth-service - - other-auth-service - `, + kind: tools + name: list-my-users-auth + type: alloydb-list-users + source: my-alloydb-admin-source + description: some description + authRequired: + - my-google-auth-service + - other-auth-service + `, want: server.ToolConfigs{ "list-my-users-auth": alloydblistusers.Config{ Name: "list-my-users-auth", - Kind: "alloydb-list-users", + Type: "alloydb-list-users", Source: "my-alloydb-admin-source", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -78,15 +77,12 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/alloydb/alloydbwaitforoperation/alloydbwaitforoperation.go b/internal/tools/alloydb/alloydbwaitforoperation/alloydbwaitforoperation.go index 1670914d4a..3c5d6d367c 100644 --- a/internal/tools/alloydb/alloydbwaitforoperation/alloydbwaitforoperation.go +++ b/internal/tools/alloydb/alloydbwaitforoperation/alloydbwaitforoperation.go @@ -27,7 +27,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "alloydb-wait-for-operation" +const resourceType string = "alloydb-wait-for-operation" var alloyDBConnectionMessageTemplate = `Your AlloyDB resource is ready. @@ -73,8 +73,8 @@ Please refer to the official documentation for guidance on deploying the toolbox ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -95,7 +95,7 @@ type compatibleSource interface { // Config defines the configuration for the wait-for-operation tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -110,9 +110,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -124,7 +124,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } project := s.GetDefaultProject() @@ -214,7 +214,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool's logic. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -292,7 +292,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/alloydb/alloydbwaitforoperation/alloydbwaitforoperation_test.go b/internal/tools/alloydb/alloydbwaitforoperation/alloydbwaitforoperation_test.go index 68f92d39d6..ad9961f1b6 100644 --- a/internal/tools/alloydb/alloydbwaitforoperation/alloydbwaitforoperation_test.go +++ b/internal/tools/alloydb/alloydbwaitforoperation/alloydbwaitforoperation_test.go @@ -17,7 +17,6 @@ package alloydbwaitforoperation_test import ( "testing" - 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" @@ -37,20 +36,20 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - wait-for-thing: - kind: alloydb-wait-for-operation - source: some-source - description: some description - delay: 1s - maxDelay: 5s - multiplier: 1.5 - maxRetries: 5 - `, + kind: tools + name: wait-for-thing + type: alloydb-wait-for-operation + source: some-source + description: some description + delay: 1s + maxDelay: 5s + multiplier: 1.5 + maxRetries: 5 + `, want: server.ToolConfigs{ "wait-for-thing": alloydbwaitforoperation.Config{ Name: "wait-for-thing", - Kind: "alloydb-wait-for-operation", + Type: "alloydb-wait-for-operation", Source: "some-source", Description: "some description", AuthRequired: []string{}, @@ -64,15 +63,12 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/alloydbainl/alloydbainl.go b/internal/tools/alloydbainl/alloydbainl.go index 7c80dab902..6b4573e31a 100644 --- a/internal/tools/alloydbainl/alloydbainl.go +++ b/internal/tools/alloydbainl/alloydbainl.go @@ -27,11 +27,11 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "alloydb-ai-nl" +const resourceType string = "alloydb-ai-nl" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` NLConfig string `yaml:"nlConfig" validate:"required"` @@ -61,8 +61,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -128,7 +128,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/alloydbainl/alloydbainl_test.go b/internal/tools/alloydbainl/alloydbainl_test.go index 2e618e66cc..42dc54fa2f 100644 --- a/internal/tools/alloydbainl/alloydbainl_test.go +++ b/internal/tools/alloydbainl/alloydbainl_test.go @@ -17,7 +17,6 @@ package alloydbainl_test import ( "testing" - 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" @@ -38,26 +37,26 @@ func TestParseFromYamlAlloyDBNLA(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: alloydb-ai-nl - source: my-alloydb-instance - description: AlloyDB natural language query tool - nlConfig: 'my_nl_config' - authRequired: - - my-google-auth-service - nlConfigParameters: - - name: user_id - type: string - description: user_id to use - authServices: - - name: my-google-auth-service - field: sub - `, + kind: tools + name: example_tool + type: alloydb-ai-nl + source: my-alloydb-instance + description: AlloyDB natural language query tool + nlConfig: 'my_nl_config' + authRequired: + - my-google-auth-service + nlConfigParameters: + - name: user_id + type: string + description: user_id to use + authServices: + - name: my-google-auth-service + field: sub + `, want: server.ToolConfigs{ "example_tool": alloydbainl.Config{ Name: "example_tool", - Kind: "alloydb-ai-nl", + Type: "alloydb-ai-nl", Source: "my-alloydb-instance", Description: "AlloyDB natural language query tool", NLConfig: "my_nl_config", @@ -72,33 +71,33 @@ func TestParseFromYamlAlloyDBNLA(t *testing.T) { { desc: "with multiple parameters", in: ` - tools: - complex_tool: - kind: alloydb-ai-nl - source: my-alloydb-instance - description: AlloyDB natural language query tool with multiple parameters - nlConfig: 'complex_nl_config' - authRequired: - - my-google-auth-service - - other-auth-service - nlConfigParameters: - - name: user_id - type: string - description: user_id to use - authServices: - - name: my-google-auth-service - field: sub - - name: user_email - type: string - description: user_email to use - authServices: - - name: my-google-auth-service - field: user_email - `, + kind: tools + name: complex_tool + type: alloydb-ai-nl + source: my-alloydb-instance + description: AlloyDB natural language query tool with multiple parameters + nlConfig: 'complex_nl_config' + authRequired: + - my-google-auth-service + - other-auth-service + nlConfigParameters: + - name: user_id + type: string + description: user_id to use + authServices: + - name: my-google-auth-service + field: sub + - name: user_email + type: string + description: user_email to use + authServices: + - name: my-google-auth-service + field: user_email + `, want: server.ToolConfigs{ "complex_tool": alloydbainl.Config{ Name: "complex_tool", - Kind: "alloydb-ai-nl", + Type: "alloydb-ai-nl", Source: "my-alloydb-instance", Description: "AlloyDB natural language query tool with multiple parameters", NLConfig: "complex_nl_config", @@ -115,15 +114,12 @@ func TestParseFromYamlAlloyDBNLA(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/bigquery/bigqueryanalyzecontribution/bigqueryanalyzecontribution.go b/internal/tools/bigquery/bigqueryanalyzecontribution/bigqueryanalyzecontribution.go index f4329d0913..73b80fc152 100644 --- a/internal/tools/bigquery/bigqueryanalyzecontribution/bigqueryanalyzecontribution.go +++ b/internal/tools/bigquery/bigqueryanalyzecontribution/bigqueryanalyzecontribution.go @@ -31,11 +31,11 @@ import ( bigqueryrestapi "google.golang.org/api/bigquery/v2" ) -const kind string = "bigquery-analyze-contribution" +const resourceType string = "bigquery-analyze-contribution" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -59,7 +59,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -68,8 +68,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -82,7 +82,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } allowedDatasets := s.BigQueryAllowedDatasets() @@ -155,7 +155,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke runs the contribution analysis. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -329,7 +329,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/bigquery/bigqueryanalyzecontribution/bigqueryanalyzecontribution_test.go b/internal/tools/bigquery/bigqueryanalyzecontribution/bigqueryanalyzecontribution_test.go index 7409acd14e..ceaa41035e 100644 --- a/internal/tools/bigquery/bigqueryanalyzecontribution/bigqueryanalyzecontribution_test.go +++ b/internal/tools/bigquery/bigqueryanalyzecontribution/bigqueryanalyzecontribution_test.go @@ -17,7 +17,6 @@ package bigqueryanalyzecontribution_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlBigQueryAnalyzeContribution(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: bigquery-analyze-contribution - source: my-instance - description: some description - `, + kind: tools + name: example_tool + type: bigquery-analyze-contribution + source: my-instance + description: some description + `, want: server.ToolConfigs{ "example_tool": bigqueryanalyzecontribution.Config{ Name: "example_tool", - Kind: "bigquery-analyze-contribution", + Type: "bigquery-analyze-contribution", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlBigQueryAnalyzeContribution(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/bigquery/bigqueryconversationalanalytics/bigqueryconversationalanalytics.go b/internal/tools/bigquery/bigqueryconversationalanalytics/bigqueryconversationalanalytics.go index ecc8d87931..e139c119bd 100644 --- a/internal/tools/bigquery/bigqueryconversationalanalytics/bigqueryconversationalanalytics.go +++ b/internal/tools/bigquery/bigqueryconversationalanalytics/bigqueryconversationalanalytics.go @@ -33,7 +33,7 @@ import ( "golang.org/x/oauth2" ) -const kind string = "bigquery-conversational-analytics" +const resourceType string = "bigquery-conversational-analytics" const instructions = `**INSTRUCTIONS - FOLLOW THESE RULES:** 1. **CONTENT:** Your answer should present the supporting data and then provide a conclusion based on that data. @@ -41,8 +41,8 @@ const instructions = `**INSTRUCTIONS - FOLLOW THESE RULES:** 3. **NO CHARTS:** You are STRICTLY FORBIDDEN from generating any charts, graphs, images, or any other form of visualization.` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -107,7 +107,7 @@ type CAPayload struct { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -116,8 +116,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -130,7 +130,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } allowedDatasets := s.BigQueryAllowedDatasets() @@ -173,7 +173,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -285,7 +285,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/bigquery/bigqueryconversationalanalytics/bigqueryconversationalanalytics_test.go b/internal/tools/bigquery/bigqueryconversationalanalytics/bigqueryconversationalanalytics_test.go index aadbbbe4b4..153d656e5b 100644 --- a/internal/tools/bigquery/bigqueryconversationalanalytics/bigqueryconversationalanalytics_test.go +++ b/internal/tools/bigquery/bigqueryconversationalanalytics/bigqueryconversationalanalytics_test.go @@ -17,7 +17,6 @@ package bigqueryconversationalanalytics_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlBigQueryConversationalAnalytics(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: bigquery-conversational-analytics - source: my-instance - description: some description - `, + kind: tools + name: example_tool + type: bigquery-conversational-analytics + source: my-instance + description: some description + `, want: server.ToolConfigs{ "example_tool": bigqueryconversationalanalytics.Config{ Name: "example_tool", - Kind: "bigquery-conversational-analytics", + Type: "bigquery-conversational-analytics", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlBigQueryConversationalAnalytics(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/bigquery/bigqueryexecutesql/bigqueryexecutesql.go b/internal/tools/bigquery/bigqueryexecutesql/bigqueryexecutesql.go index 38558ac389..2b03bf79b0 100644 --- a/internal/tools/bigquery/bigqueryexecutesql/bigqueryexecutesql.go +++ b/internal/tools/bigquery/bigqueryexecutesql/bigqueryexecutesql.go @@ -32,11 +32,11 @@ import ( bigqueryrestapi "google.golang.org/api/bigquery/v2" ) -const kind string = "bigquery-execute-sql" +const resourceType string = "bigquery-execute-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -61,7 +61,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -70,8 +70,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -84,7 +84,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } var sqlDescriptionBuilder strings.Builder @@ -153,7 +153,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -277,7 +277,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para if err != nil { return nil, fmt.Errorf("error getting logger: %s", err) } - logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", kind, sql)) + logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", resourceType, sql)) return source.RunSQL(ctx, bqClient, sql, statementType, nil, connProps) } @@ -302,7 +302,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/bigquery/bigqueryexecutesql/bigqueryexecutesql_test.go b/internal/tools/bigquery/bigqueryexecutesql/bigqueryexecutesql_test.go index 0b5d11879c..e341cee0ac 100644 --- a/internal/tools/bigquery/bigqueryexecutesql/bigqueryexecutesql_test.go +++ b/internal/tools/bigquery/bigqueryexecutesql/bigqueryexecutesql_test.go @@ -17,7 +17,6 @@ package bigqueryexecutesql_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlBigQueryExecuteSql(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: bigquery-execute-sql - source: my-instance - description: some description - `, + kind: tools + name: example_tool + type: bigquery-execute-sql + source: my-instance + description: some description + `, want: server.ToolConfigs{ "example_tool": bigqueryexecutesql.Config{ Name: "example_tool", - Kind: "bigquery-execute-sql", + Type: "bigquery-execute-sql", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlBigQueryExecuteSql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/bigquery/bigqueryforecast/bigqueryforecast.go b/internal/tools/bigquery/bigqueryforecast/bigqueryforecast.go index fa62763569..c5128d3245 100644 --- a/internal/tools/bigquery/bigqueryforecast/bigqueryforecast.go +++ b/internal/tools/bigquery/bigqueryforecast/bigqueryforecast.go @@ -31,11 +31,11 @@ import ( bigqueryrestapi "google.golang.org/api/bigquery/v2" ) -const kind string = "bigquery-forecast" +const resourceType string = "bigquery-forecast" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -59,7 +59,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -68,8 +68,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -82,7 +82,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } allowedDatasets := s.BigQueryAllowedDatasets() @@ -134,7 +134,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -266,7 +266,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para if err != nil { return nil, fmt.Errorf("error getting logger: %s", err) } - logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", kind, sql)) + logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", resourceType, sql)) return source.RunSQL(ctx, bqClient, sql, "SELECT", nil, connProps) } @@ -292,7 +292,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/bigquery/bigqueryforecast/bigqueryforecast_test.go b/internal/tools/bigquery/bigqueryforecast/bigqueryforecast_test.go index 48de140b18..0257668e36 100644 --- a/internal/tools/bigquery/bigqueryforecast/bigqueryforecast_test.go +++ b/internal/tools/bigquery/bigqueryforecast/bigqueryforecast_test.go @@ -17,7 +17,6 @@ package bigqueryforecast_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlBigQueryForecast(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: bigquery-forecast - source: my-instance - description: some description - `, + kind: tools + name: example_tool + type: bigquery-forecast + source: my-instance + description: some description + `, want: server.ToolConfigs{ "example_tool": bigqueryforecast.Config{ Name: "example_tool", - Kind: "bigquery-forecast", + Type: "bigquery-forecast", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlBigQueryForecast(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/bigquery/bigquerygetdatasetinfo/bigquerygetdatasetinfo.go b/internal/tools/bigquery/bigquerygetdatasetinfo/bigquerygetdatasetinfo.go index 65354404be..5a66b745ee 100644 --- a/internal/tools/bigquery/bigquerygetdatasetinfo/bigquerygetdatasetinfo.go +++ b/internal/tools/bigquery/bigquerygetdatasetinfo/bigquerygetdatasetinfo.go @@ -28,13 +28,13 @@ import ( bigqueryrestapi "google.golang.org/api/bigquery/v2" ) -const kind string = "bigquery-get-dataset-info" +const resourceType string = "bigquery-get-dataset-info" const projectKey string = "project" const datasetKey string = "dataset" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -56,7 +56,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -65,8 +65,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -79,7 +79,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } defaultProjectID := s.BigQueryProject() @@ -122,7 +122,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -178,7 +178,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/bigquery/bigquerygetdatasetinfo/bigquerygetdatasetinfo_test.go b/internal/tools/bigquery/bigquerygetdatasetinfo/bigquerygetdatasetinfo_test.go index bb4fa8890f..5a18b9fe1f 100644 --- a/internal/tools/bigquery/bigquerygetdatasetinfo/bigquerygetdatasetinfo_test.go +++ b/internal/tools/bigquery/bigquerygetdatasetinfo/bigquerygetdatasetinfo_test.go @@ -17,7 +17,6 @@ package bigquerygetdatasetinfo_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlBigQueryGetDatasetInfo(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: bigquery-get-dataset-info - source: my-instance - description: some description - `, + kind: tools + name: example_tool + type: bigquery-get-dataset-info + source: my-instance + description: some description + `, want: server.ToolConfigs{ "example_tool": bigquerygetdatasetinfo.Config{ Name: "example_tool", - Kind: "bigquery-get-dataset-info", + Type: "bigquery-get-dataset-info", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlBigQueryGetDatasetInfo(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/bigquery/bigquerygettableinfo/bigquerygettableinfo.go b/internal/tools/bigquery/bigquerygettableinfo/bigquerygettableinfo.go index c7fe0c0e91..b29559206f 100644 --- a/internal/tools/bigquery/bigquerygettableinfo/bigquerygettableinfo.go +++ b/internal/tools/bigquery/bigquerygettableinfo/bigquerygettableinfo.go @@ -28,14 +28,14 @@ import ( bigqueryrestapi "google.golang.org/api/bigquery/v2" ) -const kind string = "bigquery-get-table-info" +const resourceType string = "bigquery-get-table-info" const projectKey string = "project" const datasetKey string = "dataset" const tableKey string = "table" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -57,7 +57,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -66,8 +66,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -80,7 +80,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } defaultProjectID := s.BigQueryProject() @@ -126,7 +126,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -188,7 +188,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/bigquery/bigquerygettableinfo/bigquerygettableinfo_test.go b/internal/tools/bigquery/bigquerygettableinfo/bigquerygettableinfo_test.go index 992dc4d843..c196ff3a0c 100644 --- a/internal/tools/bigquery/bigquerygettableinfo/bigquerygettableinfo_test.go +++ b/internal/tools/bigquery/bigquerygettableinfo/bigquerygettableinfo_test.go @@ -17,7 +17,6 @@ package bigquerygettableinfo_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlBigQueryGetTableInfo(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: bigquery-get-table-info - source: my-instance - description: some description - `, + kind: tools + name: example_tool + type: bigquery-get-table-info + source: my-instance + description: some description + `, want: server.ToolConfigs{ "example_tool": bigquerygettableinfo.Config{ Name: "example_tool", - Kind: "bigquery-get-table-info", + Type: "bigquery-get-table-info", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlBigQueryGetTableInfo(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/bigquery/bigquerylistdatasetids/bigquerylistdatasetids.go b/internal/tools/bigquery/bigquerylistdatasetids/bigquerylistdatasetids.go index 8fbfd67019..f3609978f9 100644 --- a/internal/tools/bigquery/bigquerylistdatasetids/bigquerylistdatasetids.go +++ b/internal/tools/bigquery/bigquerylistdatasetids/bigquerylistdatasetids.go @@ -28,12 +28,12 @@ import ( "google.golang.org/api/iterator" ) -const kind string = "bigquery-list-dataset-ids" +const resourceType string = "bigquery-list-dataset-ids" const projectKey string = "project" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -54,7 +54,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -63,8 +63,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -77,7 +77,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } var projectParameter parameters.Parameter @@ -121,7 +121,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -184,7 +184,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/bigquery/bigquerylistdatasetids/bigquerylistdatasetids_test.go b/internal/tools/bigquery/bigquerylistdatasetids/bigquerylistdatasetids_test.go index 546410431b..21de3f9918 100644 --- a/internal/tools/bigquery/bigquerylistdatasetids/bigquerylistdatasetids_test.go +++ b/internal/tools/bigquery/bigquerylistdatasetids/bigquerylistdatasetids_test.go @@ -17,7 +17,6 @@ package bigquerylistdatasetids_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlBigQueryListDatasetIds(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: bigquery-list-dataset-ids - source: my-instance - description: some description - `, + kind: tools + name: example_tool + type: bigquery-list-dataset-ids + source: my-instance + description: some description + `, want: server.ToolConfigs{ "example_tool": bigquerylistdatasetids.Config{ Name: "example_tool", - Kind: "bigquery-list-dataset-ids", + Type: "bigquery-list-dataset-ids", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlBigQueryListDatasetIds(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/bigquery/bigquerylisttableids/bigquerylisttableids.go b/internal/tools/bigquery/bigquerylisttableids/bigquerylisttableids.go index efeff21465..0c5d6eb1a8 100644 --- a/internal/tools/bigquery/bigquerylisttableids/bigquerylisttableids.go +++ b/internal/tools/bigquery/bigquerylisttableids/bigquerylisttableids.go @@ -29,13 +29,13 @@ import ( "google.golang.org/api/iterator" ) -const kind string = "bigquery-list-table-ids" +const resourceType string = "bigquery-list-table-ids" const projectKey string = "project" const datasetKey string = "dataset" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -57,7 +57,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -66,8 +66,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -80,7 +80,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } defaultProjectID := s.BigQueryProject() @@ -125,7 +125,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -195,7 +195,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/bigquery/bigquerylisttableids/bigquerylisttableids_test.go b/internal/tools/bigquery/bigquerylisttableids/bigquerylisttableids_test.go index 8e5076ce0f..7056764ccc 100644 --- a/internal/tools/bigquery/bigquerylisttableids/bigquerylisttableids_test.go +++ b/internal/tools/bigquery/bigquerylisttableids/bigquerylisttableids_test.go @@ -17,7 +17,6 @@ package bigquerylisttableids_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlBigQueryListTableIds(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: bigquery-list-table-ids - source: my-instance - description: some description - `, + kind: tools + name: example_tool + type: bigquery-list-table-ids + source: my-instance + description: some description + `, want: server.ToolConfigs{ "example_tool": bigquerylisttableids.Config{ Name: "example_tool", - Kind: "bigquery-list-table-ids", + Type: "bigquery-list-table-ids", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlBigQueryListTableIds(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/bigquery/bigquerysearchcatalog/bigquerysearchcatalog.go b/internal/tools/bigquery/bigquerysearchcatalog/bigquerysearchcatalog.go index 518a92e3b3..e93bc48aec 100644 --- a/internal/tools/bigquery/bigquerysearchcatalog/bigquerysearchcatalog.go +++ b/internal/tools/bigquery/bigquerysearchcatalog/bigquerysearchcatalog.go @@ -30,11 +30,11 @@ import ( "google.golang.org/api/iterator" ) -const kind string = "bigquery-search-catalog" +const resourceType string = "bigquery-search-catalog" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -54,7 +54,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -63,8 +63,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -110,7 +110,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -187,7 +187,7 @@ func ExtractType(resourceString string) string { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/bigquery/bigquerysearchcatalog/bigquerysearchcatalog_test.go b/internal/tools/bigquery/bigquerysearchcatalog/bigquerysearchcatalog_test.go index 2885aecafb..bb218a9cd1 100644 --- a/internal/tools/bigquery/bigquerysearchcatalog/bigquerysearchcatalog_test.go +++ b/internal/tools/bigquery/bigquerysearchcatalog/bigquerysearchcatalog_test.go @@ -17,7 +17,6 @@ package bigquerysearchcatalog_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlBigQuerySearch(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: bigquery-search-catalog - source: my-instance - description: some description - `, + kind: tools + name: example_tool + type: bigquery-search-catalog + source: my-instance + description: some description + `, want: server.ToolConfigs{ "example_tool": bigquerysearchcatalog.Config{ Name: "example_tool", - Kind: "bigquery-search-catalog", + Type: "bigquery-search-catalog", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlBigQuerySearch(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/bigquery/bigquerysql/bigquerysql.go b/internal/tools/bigquery/bigquerysql/bigquerysql.go index f8961c0d68..4770dff4a1 100644 --- a/internal/tools/bigquery/bigquerysql/bigquerysql.go +++ b/internal/tools/bigquery/bigquerysql/bigquerysql.go @@ -31,11 +31,11 @@ import ( bigqueryrestapi "google.golang.org/api/bigquery/v2" ) -const kind string = "bigquery-sql" +const resourceType string = "bigquery-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -56,7 +56,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Statement string `yaml:"statement" validate:"required"` @@ -68,8 +68,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -105,7 +105,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -234,7 +234,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/bigquery/bigquerysql/bigquerysql_test.go b/internal/tools/bigquery/bigquerysql/bigquerysql_test.go index 967fd418cd..d646facad2 100644 --- a/internal/tools/bigquery/bigquerysql/bigquerysql_test.go +++ b/internal/tools/bigquery/bigquerysql/bigquerysql_test.go @@ -17,7 +17,6 @@ package bigquerysql_test import ( "testing" - 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" @@ -38,22 +37,22 @@ func TestParseFromYamlBigQuery(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: bigquery-sql - source: my-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - parameters: - - name: country - type: string - description: some description - `, + kind: tools + name: example_tool + type: bigquery-sql + source: my-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + parameters: + - name: country + type: string + description: some description + `, want: server.ToolConfigs{ "example_tool": bigquerysql.Config{ Name: "example_tool", - Kind: "bigquery-sql", + Type: "bigquery-sql", Source: "my-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -67,20 +66,16 @@ func TestParseFromYamlBigQuery(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) } - } func TestParseFromYamlWithTemplateBigQuery(t *testing.T) { @@ -96,33 +91,33 @@ func TestParseFromYamlWithTemplateBigQuery(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: bigquery-sql - source: my-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - parameters: - - name: country - type: string - description: some description - templateParameters: - - name: tableName - type: string - description: The table to select hotels from. - - name: fieldArray - type: array - description: The columns to return for the query. - items: - name: column - type: string - description: A column name that will be returned from the query. - `, + kind: tools + name: example_tool + type: bigquery-sql + source: my-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + parameters: + - name: country + type: string + description: some description + templateParameters: + - name: tableName + type: string + description: The table to select hotels from. + - name: fieldArray + type: array + description: The columns to return for the query. + items: + name: column + type: string + description: A column name that will be returned from the query. + `, want: server.ToolConfigs{ "example_tool": bigquerysql.Config{ Name: "example_tool", - Kind: "bigquery-sql", + Type: "bigquery-sql", Source: "my-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -140,18 +135,14 @@ func TestParseFromYamlWithTemplateBigQuery(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) } - } diff --git a/internal/tools/bigtable/bigtable.go b/internal/tools/bigtable/bigtable.go index e224c36f38..653e1148af 100644 --- a/internal/tools/bigtable/bigtable.go +++ b/internal/tools/bigtable/bigtable.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "bigtable-sql" +const resourceType string = "bigtable-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Statement string `yaml:"statement" validate:"required"` @@ -61,8 +61,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -98,7 +98,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/bigtable/bigtable_test.go b/internal/tools/bigtable/bigtable_test.go index 6d12b341e2..7344e9fa21 100644 --- a/internal/tools/bigtable/bigtable_test.go +++ b/internal/tools/bigtable/bigtable_test.go @@ -17,7 +17,6 @@ package bigtable_test import ( "testing" - 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" @@ -38,22 +37,22 @@ func TestParseFromYamlBigtable(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: bigtable-sql - source: my-pg-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - parameters: - - name: country - type: string - description: some description + kind: tools + name: example_tool + type: bigtable-sql + source: my-pg-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + parameters: + - name: country + type: string + description: some description `, want: server.ToolConfigs{ "example_tool": bigtable.Config{ Name: "example_tool", - Kind: "bigtable-sql", + Type: "bigtable-sql", Source: "my-pg-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -67,15 +66,11 @@ func TestParseFromYamlBigtable(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -96,33 +91,33 @@ func TestParseFromYamlWithTemplateBigtable(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: bigtable-sql - source: my-pg-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - parameters: - - name: country - type: string - description: some description - templateParameters: - - name: tableName - type: string - description: The table to select hotels from. - - name: fieldArray - type: array - description: The columns to return for the query. - items: - name: column - type: string - description: A column name that will be returned from the query. + kind: tools + name: example_tool + type: bigtable-sql + source: my-pg-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + parameters: + - name: country + type: string + description: some description + templateParameters: + - name: tableName + type: string + description: The table to select hotels from. + - name: fieldArray + type: array + description: The columns to return for the query. + items: + name: column + type: string + description: A column name that will be returned from the query. `, want: server.ToolConfigs{ "example_tool": bigtable.Config{ Name: "example_tool", - Kind: "bigtable-sql", + Type: "bigtable-sql", Source: "my-pg-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -140,15 +135,11 @@ func TestParseFromYamlWithTemplateBigtable(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cassandra/cassandracql/cassandracql.go b/internal/tools/cassandra/cassandracql/cassandracql.go index ca21b8facc..83fc261e80 100644 --- a/internal/tools/cassandra/cassandracql/cassandracql.go +++ b/internal/tools/cassandra/cassandracql/cassandracql.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "cassandra-cql" +const resourceType string = "cassandra-cql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Statement string `yaml:"statement" validate:"required"` @@ -60,9 +60,9 @@ type Config struct { var _ tools.ToolConfig = Config{} -// ToolConfigKind implements tools.ToolConfig. -func (c Config) ToolConfigKind() string { - return kind +// ToolConfigType implements tools.ToolConfig. +func (c Config) ToolConfigType() string { + return resourceType } // Initialize implements tools.ToolConfig. @@ -108,7 +108,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { // Invoke implements tools.Tool. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/cassandra/cassandracql/cassandracql_test.go b/internal/tools/cassandra/cassandracql/cassandracql_test.go index 3ed76b33f2..bcf6e128be 100644 --- a/internal/tools/cassandra/cassandracql/cassandracql_test.go +++ b/internal/tools/cassandra/cassandracql/cassandracql_test.go @@ -17,7 +17,6 @@ package cassandracql_test import ( "testing" - 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" @@ -38,30 +37,30 @@ func TestParseFromYamlCassandra(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: cassandra-cql - source: my-cassandra-instance - description: some description - statement: | - SELECT * FROM CQL_STATEMENT; - authRequired: - - my-google-auth-service - - other-auth-service - parameters: - - name: country - type: string - description: some description - authServices: - - name: my-google-auth-service - field: user_id - - name: other-auth-service - field: user_id - `, + kind: tools + type: cassandra-cql + name: example_tool + source: my-cassandra-instance + description: some description + statement: | + SELECT * FROM CQL_STATEMENT; + authRequired: + - my-google-auth-service + - other-auth-service + parameters: + - name: country + type: string + description: some description + authServices: + - name: my-google-auth-service + field: user_id + - name: other-auth-service + field: user_id + `, want: server.ToolConfigs{ "example_tool": cassandracql.Config{ Name: "example_tool", - Kind: "cassandra-cql", + Type: "cassandra-cql", Source: "my-cassandra-instance", Description: "some description", Statement: "SELECT * FROM CQL_STATEMENT;\n", @@ -77,41 +76,41 @@ func TestParseFromYamlCassandra(t *testing.T) { { desc: "with template parameters", in: ` - tools: - example_tool: - kind: cassandra-cql - source: my-cassandra-instance - description: some description - statement: | - SELECT * FROM CQL_STATEMENT; - authRequired: - - my-google-auth-service - - other-auth-service - parameters: - - name: country - type: string - description: some description - authServices: - - name: my-google-auth-service - field: user_id - - name: other-auth-service - field: user_id - templateParameters: - - name: tableName - type: string - description: some description. - - name: fieldArray - type: array - description: The columns to return for the query. - items: - name: column - type: string - description: A column name that will be returned from the query. - `, + kind: tools + type: cassandra-cql + name: example_tool + source: my-cassandra-instance + description: some description + statement: | + SELECT * FROM CQL_STATEMENT; + authRequired: + - my-google-auth-service + - other-auth-service + parameters: + - name: country + type: string + description: some description + authServices: + - name: my-google-auth-service + field: user_id + - name: other-auth-service + field: user_id + templateParameters: + - name: tableName + type: string + description: some description. + - name: fieldArray + type: array + description: The columns to return for the query. + items: + name: column + type: string + description: A column name that will be returned from the query. + `, want: server.ToolConfigs{ "example_tool": cassandracql.Config{ Name: "example_tool", - Kind: "cassandra-cql", + Type: "cassandra-cql", Source: "my-cassandra-instance", Description: "some description", Statement: "SELECT * FROM CQL_STATEMENT;\n", @@ -131,18 +130,18 @@ func TestParseFromYamlCassandra(t *testing.T) { { desc: "without optional fields", in: ` - tools: - example_tool: - kind: cassandra-cql - source: my-cassandra-instance - description: some description - statement: | - SELECT * FROM CQL_STATEMENT; - `, + kind: tools + type: cassandra-cql + name: example_tool + source: my-cassandra-instance + description: some description + statement: | + SELECT * FROM CQL_STATEMENT; + `, want: server.ToolConfigs{ "example_tool": cassandracql.Config{ Name: "example_tool", - Kind: "cassandra-cql", + Type: "cassandra-cql", Source: "my-cassandra-instance", Description: "some description", Statement: "SELECT * FROM CQL_STATEMENT;\n", @@ -155,15 +154,12 @@ func TestParseFromYamlCassandra(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/clickhouse/clickhouseexecutesql/clickhouseexecutesql.go b/internal/tools/clickhouse/clickhouseexecutesql/clickhouseexecutesql.go index 8b34049d36..0e1e8121e0 100644 --- a/internal/tools/clickhouse/clickhouseexecutesql/clickhouseexecutesql.go +++ b/internal/tools/clickhouse/clickhouseexecutesql/clickhouseexecutesql.go @@ -25,11 +25,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const executeSQLKind string = "clickhouse-execute-sql" +const executeSQLType string = "clickhouse-execute-sql" func init() { - if !tools.Register(executeSQLKind, newExecuteSQLConfig) { - panic(fmt.Sprintf("tool kind %q already registered", executeSQLKind)) + if !tools.Register(executeSQLType, newExecuteSQLConfig) { + panic(fmt.Sprintf("tool type %q already registered", executeSQLType)) } } @@ -47,7 +47,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -55,8 +55,8 @@ type Config struct { var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return executeSQLKind +func (cfg Config) ToolConfigType() string { + return executeSQLType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -88,7 +88,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, token tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/clickhouse/clickhouseexecutesql/clickhouseexecutesql_test.go b/internal/tools/clickhouse/clickhouseexecutesql/clickhouseexecutesql_test.go index 9bc0e8716d..47e5da5279 100644 --- a/internal/tools/clickhouse/clickhouseexecutesql/clickhouseexecutesql_test.go +++ b/internal/tools/clickhouse/clickhouseexecutesql/clickhouseexecutesql_test.go @@ -17,7 +17,6 @@ package clickhouse import ( "testing" - 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" @@ -36,16 +35,16 @@ func TestParseFromYamlClickHouseExecuteSQL(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: clickhouse-execute-sql - source: my-instance - description: some description - `, + kind: tools + name: example_tool + type: clickhouse-execute-sql + source: my-instance + description: some description + `, want: server.ToolConfigs{ "example_tool": Config{ Name: "example_tool", - Kind: "clickhouse-execute-sql", + Type: "clickhouse-execute-sql", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -55,14 +54,12 @@ func TestParseFromYamlClickHouseExecuteSQL(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + // Parse contents + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/clickhouse/clickhouselistdatabases/clickhouselistdatabases.go b/internal/tools/clickhouse/clickhouselistdatabases/clickhouselistdatabases.go index 57804b7fee..c83a0875d6 100644 --- a/internal/tools/clickhouse/clickhouselistdatabases/clickhouselistdatabases.go +++ b/internal/tools/clickhouse/clickhouselistdatabases/clickhouselistdatabases.go @@ -25,11 +25,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const listDatabasesKind string = "clickhouse-list-databases" +const listDatabasesType string = "clickhouse-list-databases" func init() { - if !tools.Register(listDatabasesKind, newListDatabasesConfig) { - panic(fmt.Sprintf("tool kind %q already registered", listDatabasesKind)) + if !tools.Register(listDatabasesType, newListDatabasesConfig) { + panic(fmt.Sprintf("tool type %q already registered", listDatabasesType)) } } @@ -47,7 +47,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -56,8 +56,8 @@ type Config struct { var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return listDatabasesKind +func (cfg Config) ToolConfigType() string { + return listDatabasesType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -87,7 +87,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, token tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/clickhouse/clickhouselistdatabases/clickhouselistdatabases_test.go b/internal/tools/clickhouse/clickhouselistdatabases/clickhouselistdatabases_test.go index ca6d9b21b7..4f02cd5bfc 100644 --- a/internal/tools/clickhouse/clickhouselistdatabases/clickhouselistdatabases_test.go +++ b/internal/tools/clickhouse/clickhouselistdatabases/clickhouselistdatabases_test.go @@ -17,17 +17,16 @@ package clickhouse import ( "testing" - 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/util/parameters" ) -func TestListDatabasesConfigToolConfigKind(t *testing.T) { +func TestListDatabasesConfigToolConfigType(t *testing.T) { cfg := Config{} - if cfg.ToolConfigKind() != listDatabasesKind { - t.Errorf("expected %q, got %q", listDatabasesKind, cfg.ToolConfigKind()) + if cfg.ToolConfigType() != listDatabasesType { + t.Errorf("expected %q, got %q", listDatabasesType, cfg.ToolConfigType()) } } @@ -44,16 +43,16 @@ func TestParseFromYamlClickHouseListDatabases(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: clickhouse-list-databases - source: my-instance - description: some description - `, + kind: tools + name: example_tool + type: clickhouse-list-databases + source: my-instance + description: some description + `, want: server.ToolConfigs{ "example_tool": Config{ Name: "example_tool", - Kind: "clickhouse-list-databases", + Type: "clickhouse-list-databases", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -63,14 +62,12 @@ func TestParseFromYamlClickHouseListDatabases(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + // Parse contents + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/clickhouse/clickhouselisttables/clickhouselisttables.go b/internal/tools/clickhouse/clickhouselisttables/clickhouselisttables.go index 338f48d886..89dd914973 100644 --- a/internal/tools/clickhouse/clickhouselisttables/clickhouselisttables.go +++ b/internal/tools/clickhouse/clickhouselisttables/clickhouselisttables.go @@ -25,12 +25,12 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const listTablesKind string = "clickhouse-list-tables" +const listTablesType string = "clickhouse-list-tables" const databaseKey string = "database" func init() { - if !tools.Register(listTablesKind, newListTablesConfig) { - panic(fmt.Sprintf("tool kind %q already registered", listTablesKind)) + if !tools.Register(listTablesType, newListTablesConfig) { + panic(fmt.Sprintf("tool type %q already registered", listTablesType)) } } @@ -48,7 +48,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -57,8 +57,8 @@ type Config struct { var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return listTablesKind +func (cfg Config) ToolConfigType() string { + return listTablesType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -91,7 +91,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, token tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/clickhouse/clickhouselisttables/clickhouselisttables_test.go b/internal/tools/clickhouse/clickhouselisttables/clickhouselisttables_test.go index 4500dac099..cfe2952f27 100644 --- a/internal/tools/clickhouse/clickhouselisttables/clickhouselisttables_test.go +++ b/internal/tools/clickhouse/clickhouselisttables/clickhouselisttables_test.go @@ -17,17 +17,16 @@ package clickhouse import ( "testing" - 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/util/parameters" ) -func TestListTablesConfigToolConfigKind(t *testing.T) { +func TestListTablesConfigToolConfigType(t *testing.T) { cfg := Config{} - if cfg.ToolConfigKind() != listTablesKind { - t.Errorf("expected %q, got %q", listTablesKind, cfg.ToolConfigKind()) + if cfg.ToolConfigType() != listTablesType { + t.Errorf("expected %q, got %q", listTablesType, cfg.ToolConfigType()) } } @@ -44,16 +43,16 @@ func TestParseFromYamlClickHouseListTables(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: clickhouse-list-tables - source: my-instance - description: some description - `, + kind: tools + name: example_tool + type: clickhouse-list-tables + source: my-instance + description: some description + `, want: server.ToolConfigs{ "example_tool": Config{ Name: "example_tool", - Kind: "clickhouse-list-tables", + Type: "clickhouse-list-tables", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -63,14 +62,12 @@ func TestParseFromYamlClickHouseListTables(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + // Parse contents + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/clickhouse/clickhousesql/clickhousesql.go b/internal/tools/clickhouse/clickhousesql/clickhousesql.go index d5c2888721..ca9608acce 100644 --- a/internal/tools/clickhouse/clickhousesql/clickhousesql.go +++ b/internal/tools/clickhouse/clickhousesql/clickhousesql.go @@ -25,11 +25,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const sqlKind string = "clickhouse-sql" +const sqlType string = "clickhouse-sql" func init() { - if !tools.Register(sqlKind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", sqlKind)) + if !tools.Register(sqlType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", sqlType)) } } @@ -47,7 +47,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Statement string `yaml:"statement" validate:"required"` @@ -58,8 +58,8 @@ type Config struct { var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return sqlKind +func (cfg Config) ToolConfigType() string { + return sqlType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -89,7 +89,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, token tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/clickhouse/clickhousesql/clickhousesql_test.go b/internal/tools/clickhouse/clickhousesql/clickhousesql_test.go index 3c50305e28..e7f38a1f6b 100644 --- a/internal/tools/clickhouse/clickhousesql/clickhousesql_test.go +++ b/internal/tools/clickhouse/clickhousesql/clickhousesql_test.go @@ -17,7 +17,6 @@ package clickhouse import ( "testing" - "github.com/goccy/go-yaml" "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/sources" @@ -27,10 +26,10 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -func TestConfigToolConfigKind(t *testing.T) { +func TestConfigToolConfigType(t *testing.T) { config := Config{} - if config.ToolConfigKind() != sqlKind { - t.Errorf("Expected %s, got %s", sqlKind, config.ToolConfigKind()) + if config.ToolConfigType() != sqlType { + t.Errorf("Expected %s, got %s", sqlType, config.ToolConfigType()) } } @@ -47,17 +46,17 @@ func TestParseFromYamlClickHouseSQL(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: clickhouse-sql - source: my-instance - description: some description - statement: SELECT 1 + kind: tools + name: example_tool + type: clickhouse-sql + source: my-instance + description: some description + statement: SELECT 1 `, want: server.ToolConfigs{ "example_tool": Config{ Name: "example_tool", - Kind: "clickhouse-sql", + Type: "clickhouse-sql", Source: "my-instance", Description: "some description", Statement: "SELECT 1", @@ -68,21 +67,21 @@ func TestParseFromYamlClickHouseSQL(t *testing.T) { { desc: "with parameters", in: ` - tools: - param_tool: - kind: clickhouse-sql - source: test-source - description: Test ClickHouse tool - statement: SELECT * FROM test_table WHERE id = $1 - parameters: - - name: id - type: string - description: Test ID + kind: tools + name: param_tool + type: clickhouse-sql + source: test-source + description: Test ClickHouse tool + statement: SELECT * FROM test_table WHERE id = $1 + parameters: + - name: id + type: string + description: Test ID `, want: server.ToolConfigs{ "param_tool": Config{ Name: "param_tool", - Kind: "clickhouse-sql", + Type: "clickhouse-sql", Source: "test-source", Description: "Test ClickHouse tool", Statement: "SELECT * FROM test_table WHERE id = $1", @@ -96,14 +95,11 @@ func TestParseFromYamlClickHouseSQL(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -113,7 +109,7 @@ func TestParseFromYamlClickHouseSQL(t *testing.T) { func TestSQLConfigInitializeValidSource(t *testing.T) { config := Config{ Name: "test-tool", - Kind: sqlKind, + Type: sqlType, Source: "test-clickhouse", Description: "Test tool", Statement: "SELECT 1", diff --git a/internal/tools/cloudgda/cloudgda.go b/internal/tools/cloudgda/cloudgda.go index d0ff461a9b..3c444065bd 100644 --- a/internal/tools/cloudgda/cloudgda.go +++ b/internal/tools/cloudgda/cloudgda.go @@ -26,7 +26,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "cloud-gemini-data-analytics-query" +const resourceType string = "cloud-gemini-data-analytics-query" // Guidance is the tool guidance string. const Guidance = `Tool guidance: @@ -44,8 +44,8 @@ Usage guidance: 2. If ` + "`natural_language_answer`" + ` is produced, use ` + "`intent_explanation`" + ` and ` + "`generated_query`" + ` to see if you need to clarify any assumptions for the user.` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -65,7 +65,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Location string `yaml:"location" validate:"required"` @@ -77,8 +77,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -121,7 +121,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool logic func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -180,7 +180,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudgda/cloudgda_test.go b/internal/tools/cloudgda/cloudgda_test.go index 2e92c56213..d5e73658ea 100644 --- a/internal/tools/cloudgda/cloudgda_test.go +++ b/internal/tools/cloudgda/cloudgda_test.go @@ -23,7 +23,6 @@ import ( "net/http/httptest" "testing" - 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/server/resources" @@ -36,6 +35,10 @@ import ( ) func TestParseFromYaml(t *testing.T) { + ctx, err := testutils.ContextWithNewLogger() + if err != nil { + t.Fatalf("unexpected error: %s", err) + } t.Parallel() tcs := []struct { desc string @@ -45,30 +48,30 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - my-gda-query-tool: - kind: cloud-gemini-data-analytics-query - source: gda-api-source - description: Test Description - location: us-central1 - context: - datasourceReferences: - spannerReference: - databaseReference: - projectId: "cloud-db-nl2sql" - region: "us-central1" - instanceId: "evalbench" - databaseId: "financial" - engine: "GOOGLE_SQL" - agentContextReference: - contextSetId: "projects/cloud-db-nl2sql/locations/us-east1/contextSets/bdf_gsql_gemini_all_templates" - generationOptions: - generateQueryResult: true + kind: tools + name: my-gda-query-tool + type: cloud-gemini-data-analytics-query + source: gda-api-source + description: Test Description + location: us-central1 + context: + datasourceReferences: + spannerReference: + databaseReference: + projectId: "cloud-db-nl2sql" + region: "us-central1" + instanceId: "evalbench" + databaseId: "financial" + engine: "GOOGLE_SQL" + agentContextReference: + contextSetId: "projects/cloud-db-nl2sql/locations/us-east1/contextSets/bdf_gsql_gemini_all_templates" + generationOptions: + generateQueryResult: true `, want: map[string]tools.ToolConfig{ "my-gda-query-tool": cloudgdatool.Config{ Name: "my-gda-query-tool", - Kind: "cloud-gemini-data-analytics-query", + Type: "cloud-gemini-data-analytics-query", Source: "gda-api-source", Description: "Test Description", Location: "us-central1", @@ -100,16 +103,12 @@ func TestParseFromYaml(t *testing.T) { tc := tc t.Run(tc.desc, func(t *testing.T) { t.Parallel() - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Tools) { - t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Tools) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: want %v, got %v", tc.want, got) } }) } @@ -135,13 +134,13 @@ func (rt *authRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) } type mockSource struct { - kind string + Type string client *http.Client // Can be used to inject a specific client baseURL string // BaseURL is needed to implement sources.Source.BaseURL config cloudgdasrc.Config // to return from ToConfig } -func (m *mockSource) SourceKind() string { return m.kind } +func (m *mockSource) SourceType() string { return m.Type } func (m *mockSource) ToConfig() sources.SourceConfig { return m.config } func (m *mockSource) GetClient(ctx context.Context, token string) (*http.Client, error) { if m.client != nil { @@ -166,7 +165,7 @@ func TestInitialize(t *testing.T) { srcs := map[string]sources.Source{ "gda-api-source": &cloudgdasrc.Source{ - Config: cloudgdasrc.Config{Name: "gda-api-source", Kind: cloudgdasrc.SourceKind, ProjectID: "test-project"}, + Config: cloudgdasrc.Config{Name: "gda-api-source", Type: cloudgdasrc.SourceType, ProjectID: "test-project"}, Client: &http.Client{}, BaseURL: cloudgdasrc.Endpoint, }, @@ -180,7 +179,7 @@ func TestInitialize(t *testing.T) { desc: "successful initialization", cfg: cloudgdatool.Config{ Name: "my-gda-query-tool", - Kind: "cloud-gemini-data-analytics-query", + Type: "cloud-gemini-data-analytics-query", Source: "gda-api-source", Description: "Test Description", Location: "us-central1", @@ -189,7 +188,7 @@ func TestInitialize(t *testing.T) { } // Add an incompatible source for testing - srcs["incompatible-source"] = &mockSource{kind: "another-kind"} + srcs["incompatible-source"] = &mockSource{Type: "another-type"} for _, tc := range tcs { tc := tc @@ -287,7 +286,7 @@ func TestInvoke(t *testing.T) { // Create a real cloudgdasrc.Source but inject the authenticated client mockGdaSource := &cloudgdasrc.Source{ - Config: cloudgdasrc.Config{Name: "mock-gda-source", Kind: cloudgdasrc.SourceKind, ProjectID: "test-project"}, + Config: cloudgdasrc.Config{Name: "mock-gda-source", Type: cloudgdasrc.SourceType, ProjectID: "test-project"}, Client: authClient, BaseURL: mockServer.URL, } @@ -298,7 +297,7 @@ func TestInvoke(t *testing.T) { // Initialize the tool config with context toolCfg := cloudgdatool.Config{ Name: "query-data-tool", - Kind: "cloud-gemini-data-analytics-query", + Type: "cloud-gemini-data-analytics-query", Source: "mock-gda-source", Description: "Query Gemini Data Analytics", Location: "us-central1", // Set location for the test diff --git a/internal/tools/cloudhealthcare/cloudhealthcarefhirfetchpage/cloudhealthcarefhirfetchpage.go b/internal/tools/cloudhealthcare/cloudhealthcarefhirfetchpage/cloudhealthcarefhirfetchpage.go index d874c6b778..6b807c8322 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcarefhirfetchpage/cloudhealthcarefhirfetchpage.go +++ b/internal/tools/cloudhealthcare/cloudhealthcarefhirfetchpage/cloudhealthcarefhirfetchpage.go @@ -25,14 +25,14 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "cloud-healthcare-fhir-fetch-page" +const resourceType string = "cloud-healthcare-fhir-fetch-page" const ( pageURLKey = "pageURL" ) func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -51,7 +51,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -60,8 +60,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -94,7 +94,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -134,7 +134,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudhealthcare/cloudhealthcarefhirfetchpage/cloudhealthcarefhirfetchpage_test.go b/internal/tools/cloudhealthcare/cloudhealthcarefhirfetchpage/cloudhealthcarefhirfetchpage_test.go index de85dd8674..1b5d6816bc 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcarefhirfetchpage/cloudhealthcarefhirfetchpage_test.go +++ b/internal/tools/cloudhealthcare/cloudhealthcarefhirfetchpage/cloudhealthcarefhirfetchpage_test.go @@ -17,7 +17,6 @@ package fhirfetchpage_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlHealthcareFHIRFetchPage(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: cloud-healthcare-fhir-fetch-page - source: my-instance - description: some description + kind: tools + name: example_tool + type: cloud-healthcare-fhir-fetch-page + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": fhirfetchpage.Config{ Name: "example_tool", - Kind: "cloud-healthcare-fhir-fetch-page", + Type: "cloud-healthcare-fhir-fetch-page", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlHealthcareFHIRFetchPage(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudhealthcare/cloudhealthcarefhirpatienteverything/cloudhealthcarefhirpatienteverything.go b/internal/tools/cloudhealthcare/cloudhealthcarefhirpatienteverything/cloudhealthcarefhirpatienteverything.go index 3aea841d46..44fbe95538 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcarefhirpatienteverything/cloudhealthcarefhirpatienteverything.go +++ b/internal/tools/cloudhealthcare/cloudhealthcarefhirpatienteverything/cloudhealthcarefhirpatienteverything.go @@ -28,7 +28,7 @@ import ( "google.golang.org/api/googleapi" ) -const kind string = "cloud-healthcare-fhir-patient-everything" +const resourceType string = "cloud-healthcare-fhir-patient-everything" const ( patientIDKey = "patientID" typeFilterKey = "resourceTypesFilter" @@ -36,8 +36,8 @@ const ( ) func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -57,7 +57,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -66,8 +66,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -80,7 +80,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } idParameter := parameters.NewStringParameter(patientIDKey, "The ID of the patient FHIR resource for which the information is required") @@ -117,7 +117,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -186,7 +186,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudhealthcare/cloudhealthcarefhirpatienteverything/cloudhealthcarefhirpatienteverything_test.go b/internal/tools/cloudhealthcare/cloudhealthcarefhirpatienteverything/cloudhealthcarefhirpatienteverything_test.go index 703fd0c2d3..d6caf089ff 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcarefhirpatienteverything/cloudhealthcarefhirpatienteverything_test.go +++ b/internal/tools/cloudhealthcare/cloudhealthcarefhirpatienteverything/cloudhealthcarefhirpatienteverything_test.go @@ -17,7 +17,6 @@ package fhirpatienteverything_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlHealthcareFHIRPatientEverything(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: cloud-healthcare-fhir-patient-everything - source: my-instance - description: some description + kind: tools + name: example_tool + type: cloud-healthcare-fhir-patient-everything + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": fhirpatienteverything.Config{ Name: "example_tool", - Kind: "cloud-healthcare-fhir-patient-everything", + Type: "cloud-healthcare-fhir-patient-everything", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlHealthcareFHIRPatientEverything(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudhealthcare/cloudhealthcarefhirpatientsearch/cloudhealthcarefhirpatientsearch.go b/internal/tools/cloudhealthcare/cloudhealthcarefhirpatientsearch/cloudhealthcarefhirpatientsearch.go index 50ab952ee9..0638a00536 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcarefhirpatientsearch/cloudhealthcarefhirpatientsearch.go +++ b/internal/tools/cloudhealthcare/cloudhealthcarefhirpatientsearch/cloudhealthcarefhirpatientsearch.go @@ -28,7 +28,7 @@ import ( "google.golang.org/api/googleapi" ) -const kind string = "cloud-healthcare-fhir-patient-search" +const resourceType string = "cloud-healthcare-fhir-patient-search" const ( activeKey = "active" cityKey = "city" @@ -52,8 +52,8 @@ const ( ) func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -73,7 +73,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -82,8 +82,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -96,7 +96,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } params := parameters.Parameters{ @@ -151,7 +151,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -259,7 +259,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudhealthcare/cloudhealthcarefhirpatientsearch/cloudhealthcarefhirpatientsearch_test.go b/internal/tools/cloudhealthcare/cloudhealthcarefhirpatientsearch/cloudhealthcarefhirpatientsearch_test.go index 072fbc02d4..1d59af3b23 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcarefhirpatientsearch/cloudhealthcarefhirpatientsearch_test.go +++ b/internal/tools/cloudhealthcare/cloudhealthcarefhirpatientsearch/cloudhealthcarefhirpatientsearch_test.go @@ -17,7 +17,6 @@ package fhirpatientsearch_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlHealthcareFHIRPatientSearch(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: cloud-healthcare-fhir-patient-search - source: my-instance - description: some description + kind: tools + name: example_tool + type: cloud-healthcare-fhir-patient-search + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": fhirpatientsearch.Config{ Name: "example_tool", - Kind: "cloud-healthcare-fhir-patient-search", + Type: "cloud-healthcare-fhir-patient-search", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlHealthcareFHIRPatientSearch(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudhealthcare/cloudhealthcaregetdataset/cloudhealthcaregetdataset.go b/internal/tools/cloudhealthcare/cloudhealthcaregetdataset/cloudhealthcaregetdataset.go index 1f19adb52d..8ae0daa418 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaregetdataset/cloudhealthcaregetdataset.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaregetdataset/cloudhealthcaregetdataset.go @@ -26,11 +26,11 @@ import ( "google.golang.org/api/healthcare/v1" ) -const kind string = "cloud-healthcare-get-dataset" +const resourceType string = "cloud-healthcare-get-dataset" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -58,8 +58,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -91,7 +91,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -126,7 +126,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudhealthcare/cloudhealthcaregetdataset/cloudhealthcaregetdataset_test.go b/internal/tools/cloudhealthcare/cloudhealthcaregetdataset/cloudhealthcaregetdataset_test.go index 3e56f2e9e4..e36b6b5d2d 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaregetdataset/cloudhealthcaregetdataset_test.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaregetdataset/cloudhealthcaregetdataset_test.go @@ -17,7 +17,6 @@ package gethealthcaredataset_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlGetHealthcareDataset(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: cloud-healthcare-get-dataset - source: my-instance - description: some description + kind: tools + name: example_tool + type: cloud-healthcare-get-dataset + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": getdataset.Config{ Name: "example_tool", - Kind: "cloud-healthcare-get-dataset", + Type: "cloud-healthcare-get-dataset", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlGetHealthcareDataset(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstore/cloudhealthcaregetdicomstore.go b/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstore/cloudhealthcaregetdicomstore.go index ac57481f24..529ee8b00c 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstore/cloudhealthcaregetdicomstore.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstore/cloudhealthcaregetdicomstore.go @@ -27,11 +27,11 @@ import ( "google.golang.org/api/healthcare/v1" ) -const kind string = "cloud-healthcare-get-dicom-store" +const resourceType string = "cloud-healthcare-get-dicom-store" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -51,7 +51,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -60,8 +60,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -74,7 +74,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } params := parameters.Parameters{} @@ -108,7 +108,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -147,7 +147,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstore/cloudhealthcaregetdicomstore_test.go b/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstore/cloudhealthcaregetdicomstore_test.go index af87f20b9b..37ba8923e2 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstore/cloudhealthcaregetdicomstore_test.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstore/cloudhealthcaregetdicomstore_test.go @@ -17,7 +17,6 @@ package getdicomstore_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlHealthcareGetDICOMStore(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: cloud-healthcare-get-dicom-store - source: my-instance - description: some description + kind: tools + name: example_tool + type: cloud-healthcare-get-dicom-store + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": getdicomstore.Config{ Name: "example_tool", - Kind: "cloud-healthcare-get-dicom-store", + Type: "cloud-healthcare-get-dicom-store", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlHealthcareGetDICOMStore(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstoremetrics/cloudhealthcaregetdicomstoremetrics.go b/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstoremetrics/cloudhealthcaregetdicomstoremetrics.go index c7cb4f055f..0e5a4aaf9d 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstoremetrics/cloudhealthcaregetdicomstoremetrics.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstoremetrics/cloudhealthcaregetdicomstoremetrics.go @@ -27,11 +27,11 @@ import ( "google.golang.org/api/healthcare/v1" ) -const kind string = "cloud-healthcare-get-dicom-store-metrics" +const resourceType string = "cloud-healthcare-get-dicom-store-metrics" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -51,7 +51,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -60,8 +60,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -74,7 +74,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } params := parameters.Parameters{} @@ -108,7 +108,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -147,7 +147,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstoremetrics/cloudhealthcaregetdicomstoremetrics_test.go b/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstoremetrics/cloudhealthcaregetdicomstoremetrics_test.go index 43523f7b85..f421a42a73 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstoremetrics/cloudhealthcaregetdicomstoremetrics_test.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstoremetrics/cloudhealthcaregetdicomstoremetrics_test.go @@ -17,7 +17,6 @@ package getdicomstoremetrics_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlHealthcareGetDICOMStoreMetrics(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: cloud-healthcare-get-dicom-store-metrics - source: my-instance - description: some description + kind: tools + name: example_tool + type: cloud-healthcare-get-dicom-store-metrics + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": getdicomstoremetrics.Config{ Name: "example_tool", - Kind: "cloud-healthcare-get-dicom-store-metrics", + Type: "cloud-healthcare-get-dicom-store-metrics", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlHealthcareGetDICOMStoreMetrics(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudhealthcare/cloudhealthcaregetfhirresource/cloudhealthcaregetfhirresource.go b/internal/tools/cloudhealthcare/cloudhealthcaregetfhirresource/cloudhealthcaregetfhirresource.go index 79e42c35f6..f51527188f 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaregetfhirresource/cloudhealthcaregetfhirresource.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaregetfhirresource/cloudhealthcaregetfhirresource.go @@ -26,15 +26,15 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "cloud-healthcare-get-fhir-resource" +const resourceType string = "cloud-healthcare-get-fhir-resource" const ( typeKey = "resourceType" idKey = "resourceID" ) func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -54,7 +54,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -63,8 +63,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -77,7 +77,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } typeParameter := parameters.NewStringParameter(typeKey, "The FHIR resource type to retrieve (e.g., Patient, Observation).") @@ -113,7 +113,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -161,7 +161,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudhealthcare/cloudhealthcaregetfhirresource/cloudhealthcaregetfhirresource_test.go b/internal/tools/cloudhealthcare/cloudhealthcaregetfhirresource/cloudhealthcaregetfhirresource_test.go index 7c2ba5277f..a1ec0fd5c8 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaregetfhirresource/cloudhealthcaregetfhirresource_test.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaregetfhirresource/cloudhealthcaregetfhirresource_test.go @@ -17,7 +17,6 @@ package getfhirresource_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlHealthcareGetFHIRResource(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: cloud-healthcare-get-fhir-resource - source: my-instance - description: some description + kind: tools + name: example_tool + type: cloud-healthcare-get-fhir-resource + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": getfhirresource.Config{ Name: "example_tool", - Kind: "cloud-healthcare-get-fhir-resource", + Type: "cloud-healthcare-get-fhir-resource", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlHealthcareGetFHIRResource(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstore/cloudhealthcaregetfhirstore.go b/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstore/cloudhealthcaregetfhirstore.go index ce60e5a2cc..e6b791c2fd 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstore/cloudhealthcaregetfhirstore.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstore/cloudhealthcaregetfhirstore.go @@ -27,11 +27,11 @@ import ( "google.golang.org/api/healthcare/v1" ) -const kind string = "cloud-healthcare-get-fhir-store" +const resourceType string = "cloud-healthcare-get-fhir-store" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -51,7 +51,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -60,8 +60,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -74,7 +74,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } params := parameters.Parameters{} @@ -108,7 +108,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -147,7 +147,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstore/cloudhealthcaregetfhirstore_test.go b/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstore/cloudhealthcaregetfhirstore_test.go index bcf3d54e51..007b186f3b 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstore/cloudhealthcaregetfhirstore_test.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstore/cloudhealthcaregetfhirstore_test.go @@ -17,7 +17,6 @@ package getfhirstore_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlHealthcareGetFHIRStore(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: cloud-healthcare-get-fhir-store - source: my-instance - description: some description + kind: tools + name: example_tool + type: cloud-healthcare-get-fhir-store + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": getfhirstore.Config{ Name: "example_tool", - Kind: "cloud-healthcare-get-fhir-store", + Type: "cloud-healthcare-get-fhir-store", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlHealthcareGetFHIRStore(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstoremetrics/cloudhealthcaregetfhirstoremetrics.go b/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstoremetrics/cloudhealthcaregetfhirstoremetrics.go index f0b4263a6f..379ec2c553 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstoremetrics/cloudhealthcaregetfhirstoremetrics.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstoremetrics/cloudhealthcaregetfhirstoremetrics.go @@ -27,11 +27,11 @@ import ( "google.golang.org/api/healthcare/v1" ) -const kind string = "cloud-healthcare-get-fhir-store-metrics" +const resourceType string = "cloud-healthcare-get-fhir-store-metrics" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -51,7 +51,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -60,8 +60,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -74,7 +74,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } params := parameters.Parameters{} @@ -108,7 +108,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -147,7 +147,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstoremetrics/cloudhealthcaregetfhirstoremetrics_test.go b/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstoremetrics/cloudhealthcaregetfhirstoremetrics_test.go index bd112bb00d..36964ab7d9 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstoremetrics/cloudhealthcaregetfhirstoremetrics_test.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstoremetrics/cloudhealthcaregetfhirstoremetrics_test.go @@ -17,7 +17,6 @@ package getfhirstoremetrics_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlHealthcareGetFHIRStoreMetrics(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: cloud-healthcare-get-fhir-store-metrics - source: my-instance - description: some description + kind: tools + name: example_tool + type: cloud-healthcare-get-fhir-store-metrics + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": getfhirstoremetrics.Config{ Name: "example_tool", - Kind: "cloud-healthcare-get-fhir-store-metrics", + Type: "cloud-healthcare-get-fhir-store-metrics", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlHealthcareGetFHIRStoreMetrics(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudhealthcare/cloudhealthcarelistdicomstores/cloudhealthcarelistdicomstores.go b/internal/tools/cloudhealthcare/cloudhealthcarelistdicomstores/cloudhealthcarelistdicomstores.go index 490541f1bc..7c58c4bb1b 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcarelistdicomstores/cloudhealthcarelistdicomstores.go +++ b/internal/tools/cloudhealthcare/cloudhealthcarelistdicomstores/cloudhealthcarelistdicomstores.go @@ -26,11 +26,11 @@ import ( "google.golang.org/api/healthcare/v1" ) -const kind string = "cloud-healthcare-list-dicom-stores" +const resourceType string = "cloud-healthcare-list-dicom-stores" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -58,8 +58,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -91,7 +91,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -126,7 +126,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudhealthcare/cloudhealthcarelistdicomstores/cloudhealthcarelistdicomstores_test.go b/internal/tools/cloudhealthcare/cloudhealthcarelistdicomstores/cloudhealthcarelistdicomstores_test.go index f9e874b2d9..6967f346f1 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcarelistdicomstores/cloudhealthcarelistdicomstores_test.go +++ b/internal/tools/cloudhealthcare/cloudhealthcarelistdicomstores/cloudhealthcarelistdicomstores_test.go @@ -17,7 +17,6 @@ package listdicomstores_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlHealthcareListDICOMStores(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: cloud-healthcare-list-dicom-stores - source: my-instance - description: some description + kind: tools + name: example_tool + type: cloud-healthcare-list-dicom-stores + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": listdicomstores.Config{ Name: "example_tool", - Kind: "cloud-healthcare-list-dicom-stores", + Type: "cloud-healthcare-list-dicom-stores", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlHealthcareListDICOMStores(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudhealthcare/cloudhealthcarelistfhirstores/cloudhealthcarelistfhirstores.go b/internal/tools/cloudhealthcare/cloudhealthcarelistfhirstores/cloudhealthcarelistfhirstores.go index 7dc83c177f..8bea1273d9 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcarelistfhirstores/cloudhealthcarelistfhirstores.go +++ b/internal/tools/cloudhealthcare/cloudhealthcarelistfhirstores/cloudhealthcarelistfhirstores.go @@ -26,11 +26,11 @@ import ( "google.golang.org/api/healthcare/v1" ) -const kind string = "cloud-healthcare-list-fhir-stores" +const resourceType string = "cloud-healthcare-list-fhir-stores" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -58,8 +58,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -91,7 +91,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -126,7 +126,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudhealthcare/cloudhealthcarelistfhirstores/cloudhealthcarelistfhirstores_test.go b/internal/tools/cloudhealthcare/cloudhealthcarelistfhirstores/cloudhealthcarelistfhirstores_test.go index dc7d8d891e..70414613ea 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcarelistfhirstores/cloudhealthcarelistfhirstores_test.go +++ b/internal/tools/cloudhealthcare/cloudhealthcarelistfhirstores/cloudhealthcarelistfhirstores_test.go @@ -17,7 +17,6 @@ package listfhirstores_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlHealthcareListFHIRStores(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: cloud-healthcare-list-fhir-stores - source: my-instance - description: some description + kind: tools + name: example_tool + type: cloud-healthcare-list-fhir-stores + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": listfhirstores.Config{ Name: "example_tool", - Kind: "cloud-healthcare-list-fhir-stores", + Type: "cloud-healthcare-list-fhir-stores", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlHealthcareListFHIRStores(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudhealthcare/cloudhealthcareretrieverendereddicominstance/cloudhealthcareretrieverendereddicominstance.go b/internal/tools/cloudhealthcare/cloudhealthcareretrieverendereddicominstance/cloudhealthcareretrieverendereddicominstance.go index 5f76593a50..f2cc29a02a 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcareretrieverendereddicominstance/cloudhealthcareretrieverendereddicominstance.go +++ b/internal/tools/cloudhealthcare/cloudhealthcareretrieverendereddicominstance/cloudhealthcareretrieverendereddicominstance.go @@ -26,7 +26,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "cloud-healthcare-retrieve-rendered-dicom-instance" +const resourceType string = "cloud-healthcare-retrieve-rendered-dicom-instance" const ( studyInstanceUIDKey = "StudyInstanceUID" seriesInstanceUIDKey = "SeriesInstanceUID" @@ -35,8 +35,8 @@ const ( ) func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -56,7 +56,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -65,8 +65,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -79,7 +79,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } params := parameters.Parameters{ @@ -118,7 +118,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -174,7 +174,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudhealthcare/cloudhealthcareretrieverendereddicominstance/cloudhealthcareretrieverendereddicominstance_test.go b/internal/tools/cloudhealthcare/cloudhealthcareretrieverendereddicominstance/cloudhealthcareretrieverendereddicominstance_test.go index 1522c3d8c3..adf6005529 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcareretrieverendereddicominstance/cloudhealthcareretrieverendereddicominstance_test.go +++ b/internal/tools/cloudhealthcare/cloudhealthcareretrieverendereddicominstance/cloudhealthcareretrieverendereddicominstance_test.go @@ -17,7 +17,6 @@ package retrieverendereddicominstance_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlHealthcareRetrieveRenderedDICOMInstance(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: cloud-healthcare-retrieve-rendered-dicom-instance - source: my-instance - description: some description + kind: tools + name: example_tool + type: cloud-healthcare-retrieve-rendered-dicom-instance + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": retrieverendereddicominstance.Config{ Name: "example_tool", - Kind: "cloud-healthcare-retrieve-rendered-dicom-instance", + Type: "cloud-healthcare-retrieve-rendered-dicom-instance", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlHealthcareRetrieveRenderedDICOMInstance(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudhealthcare/cloudhealthcaresearchdicominstances/cloudhealthcaresearchdicominstances.go b/internal/tools/cloudhealthcare/cloudhealthcaresearchdicominstances/cloudhealthcaresearchdicominstances.go index 07ba84ebb7..b359c74046 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaresearchdicominstances/cloudhealthcaresearchdicominstances.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaresearchdicominstances/cloudhealthcaresearchdicominstances.go @@ -28,7 +28,7 @@ import ( "google.golang.org/api/googleapi" ) -const kind string = "cloud-healthcare-search-dicom-instances" +const resourceType string = "cloud-healthcare-search-dicom-instances" const ( studyInstanceUIDKey = "StudyInstanceUID" patientNameKey = "PatientName" @@ -42,8 +42,8 @@ const ( ) func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -63,7 +63,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -72,8 +72,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -86,7 +86,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } params := parameters.Parameters{ @@ -132,7 +132,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -176,7 +176,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para } } } - return source.SearchDICOM(t.Kind, storeID, dicomWebPath, tokenStr, opts) + return source.SearchDICOM(t.Type, storeID, dicomWebPath, tokenStr, opts) } func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { @@ -200,7 +200,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudhealthcare/cloudhealthcaresearchdicominstances/cloudhealthcaresearchdicominstances_test.go b/internal/tools/cloudhealthcare/cloudhealthcaresearchdicominstances/cloudhealthcaresearchdicominstances_test.go index e28c6c1dd2..83a3ff5de3 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaresearchdicominstances/cloudhealthcaresearchdicominstances_test.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaresearchdicominstances/cloudhealthcaresearchdicominstances_test.go @@ -17,7 +17,6 @@ package searchdicominstances_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlHealthcareSearchDICOMInstances(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: cloud-healthcare-search-dicom-instances - source: my-instance - description: some description + kind: tools + name: example_tool + type: cloud-healthcare-search-dicom-instances + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": searchdicominstances.Config{ Name: "example_tool", - Kind: "cloud-healthcare-search-dicom-instances", + Type: "cloud-healthcare-search-dicom-instances", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlHealthcareSearchDICOMInstances(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomseries/cloudhealthcaresearchdicomseries.go b/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomseries/cloudhealthcaresearchdicomseries.go index 6ec39d3f0d..35f37cb5a1 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomseries/cloudhealthcaresearchdicomseries.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomseries/cloudhealthcaresearchdicomseries.go @@ -27,7 +27,7 @@ import ( "google.golang.org/api/googleapi" ) -const kind string = "cloud-healthcare-search-dicom-series" +const resourceType string = "cloud-healthcare-search-dicom-series" const ( studyInstanceUIDKey = "StudyInstanceUID" patientNameKey = "PatientName" @@ -40,8 +40,8 @@ const ( ) func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -61,7 +61,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -70,8 +70,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -84,7 +84,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } params := parameters.Parameters{ @@ -129,7 +129,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -161,7 +161,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para dicomWebPath = fmt.Sprintf("studies/%s/series", id) } } - return source.SearchDICOM(t.Kind, storeID, dicomWebPath, tokenStr, opts) + return source.SearchDICOM(t.Type, storeID, dicomWebPath, tokenStr, opts) } func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { @@ -185,7 +185,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomseries/cloudhealthcaresearchdicomseries_test.go b/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomseries/cloudhealthcaresearchdicomseries_test.go index 7558adcadf..e46eb0cb0f 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomseries/cloudhealthcaresearchdicomseries_test.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomseries/cloudhealthcaresearchdicomseries_test.go @@ -17,7 +17,6 @@ package searchdicomseries_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlHealthcareSearchDICOMSeries(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: cloud-healthcare-search-dicom-series - source: my-instance - description: some description + kind: tools + name: example_tool + type: cloud-healthcare-search-dicom-series + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": searchdicomseries.Config{ Name: "example_tool", - Kind: "cloud-healthcare-search-dicom-series", + Type: "cloud-healthcare-search-dicom-series", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlHealthcareSearchDICOMSeries(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomstudies/cloudhealthcaresearchdicomstudies.go b/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomstudies/cloudhealthcaresearchdicomstudies.go index 097e906362..e2b02248d8 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomstudies/cloudhealthcaresearchdicomstudies.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomstudies/cloudhealthcaresearchdicomstudies.go @@ -27,7 +27,7 @@ import ( "google.golang.org/api/googleapi" ) -const kind string = "cloud-healthcare-search-dicom-studies" +const resourceType string = "cloud-healthcare-search-dicom-studies" const ( studyInstanceUIDKey = "StudyInstanceUID" patientNameKey = "PatientName" @@ -38,8 +38,8 @@ const ( ) func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -59,7 +59,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -68,8 +68,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -82,7 +82,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } params := parameters.Parameters{ @@ -125,7 +125,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -145,7 +145,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para return nil, err } dicomWebPath := "studies" - return source.SearchDICOM(t.Kind, storeID, dicomWebPath, tokenStr, opts) + return source.SearchDICOM(t.Type, storeID, dicomWebPath, tokenStr, opts) } func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) { @@ -169,7 +169,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomstudies/cloudhealthcaresearchdicomstudies_test.go b/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomstudies/cloudhealthcaresearchdicomstudies_test.go index 483f37e61b..6415eaedd2 100644 --- a/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomstudies/cloudhealthcaresearchdicomstudies_test.go +++ b/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomstudies/cloudhealthcaresearchdicomstudies_test.go @@ -17,7 +17,6 @@ package searchdicomstudies_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlHealthcareSearchDICOMStudies(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: cloud-healthcare-search-dicom-studies - source: my-instance - description: some description + kind: tools + name: example_tool + type: cloud-healthcare-search-dicom-studies + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": searchdicomstudies.Config{ Name: "example_tool", - Kind: "cloud-healthcare-search-dicom-studies", + Type: "cloud-healthcare-search-dicom-studies", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYamlHealthcareSearchDICOMStudies(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudmonitoring/cloudmonitoring.go b/internal/tools/cloudmonitoring/cloudmonitoring.go index 9a8f60c2e7..0d2e9b6cec 100644 --- a/internal/tools/cloudmonitoring/cloudmonitoring.go +++ b/internal/tools/cloudmonitoring/cloudmonitoring.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "cloud-monitoring-query-prometheus" +const resourceType string = "cloud-monitoring-query-prometheus" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -58,8 +58,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -94,7 +94,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/cloudmonitoring/cloudmonitoring_test.go b/internal/tools/cloudmonitoring/cloudmonitoring_test.go index 51c4d00c21..30b143444e 100644 --- a/internal/tools/cloudmonitoring/cloudmonitoring_test.go +++ b/internal/tools/cloudmonitoring/cloudmonitoring_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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/sources" @@ -29,12 +28,12 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -// mockIncompatibleSource is a source of a different kind to test error paths. +// mockIncompatibleSource is a source of a different type to test error paths. type mockIncompatibleSource struct{ sources.Source } func TestInitialize(t *testing.T) { t.Parallel() - testSource := &cloudmonitoringsrc.Source{Config: cloudmonitoringsrc.Config{Kind: "cloud-monitoring"}} + testSource := &cloudmonitoringsrc.Source{Config: cloudmonitoringsrc.Config{Type: "cloud-monitoring"}} srcs := map[string]sources.Source{ "my-monitoring-source": testSource, "incompatible-source": &mockIncompatibleSource{}, @@ -55,7 +54,7 @@ func TestInitialize(t *testing.T) { desc: "Success case with nil authRequired", cfg: cloudmonitoring.Config{ Name: "test-tool", - Kind: "cloud-monitoring-query-prometheus", + Type: "cloud-monitoring-query-prometheus", Source: "my-monitoring-source", Description: "A test description.", AuthRequired: nil, @@ -70,7 +69,7 @@ func TestInitialize(t *testing.T) { desc: "Success case with specified authRequired", cfg: cloudmonitoring.Config{ Name: "test-tool-with-auth", - Kind: "cloud-monitoring-query-prometheus", + Type: "cloud-monitoring-query-prometheus", Source: "my-monitoring-source", Description: "Another test description.", AuthRequired: []string{"google-auth-service"}, @@ -122,16 +121,16 @@ func TestParseFromYamlCloudMonitoring(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: cloud-monitoring-query-prometheus - source: my-instance - description: some description - `, + kind: tools + name: example_tool + type: cloud-monitoring-query-prometheus + source: my-instance + description: some description + `, want: server.ToolConfigs{ "example_tool": cloudmonitoring.Config{ Name: "example_tool", - Kind: "cloud-monitoring-query-prometheus", + Type: "cloud-monitoring-query-prometheus", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -141,19 +140,19 @@ func TestParseFromYamlCloudMonitoring(t *testing.T) { { desc: "advanced example", in: ` - tools: - example_tool: - kind: cloud-monitoring-query-prometheus - source: my-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: cloud-monitoring-query-prometheus + source: my-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": cloudmonitoring.Config{ Name: "example_tool", - Kind: "cloud-monitoring-query-prometheus", + Type: "cloud-monitoring-query-prometheus", Source: "my-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -163,15 +162,11 @@ func TestParseFromYamlCloudMonitoring(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools, cmp.AllowUnexported(cloudmonitoring.Config{})); diff != "" { + if diff := cmp.Diff(tc.want, got, cmp.AllowUnexported(cloudmonitoring.Config{})); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -189,44 +184,40 @@ func TestFailParseFromYamlCloudMonitoring(t *testing.T) { err string }{ { - desc: "Invalid kind", + desc: "Invalid type", in: ` - tools: - example_tool: - kind: invalid-kind - source: my-instance - description: some description + kind: tools + name: example_tool + type: invalid-type + source: my-instance + description: some description `, - err: `unknown tool kind: "invalid-kind"`, + err: `unknown tool type: "invalid-type"`, }, { desc: "missing source", in: ` - tools: - example_tool: - kind: cloud-monitoring-query-prometheus - description: some description + kind: tools + name: example_tool + type: cloud-monitoring-query-prometheus + description: some description `, err: `Key: 'Config.Source' Error:Field validation for 'Source' failed on the 'required' tag`, }, { desc: "missing description", in: ` - tools: - example_tool: - kind: cloud-monitoring-query-prometheus - source: my-instance + kind: tools + name: example_tool + type: cloud-monitoring-query-prometheus + source: my-instance `, err: `Key: 'Config.Description' Error:Field validation for 'Description' failed on the 'required' tag`, }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/cloudsql/cloudsqlcloneinstance/cloudsqlcloneinstance.go b/internal/tools/cloudsql/cloudsqlcloneinstance/cloudsqlcloneinstance.go index 1bc94d5108..f11520f960 100644 --- a/internal/tools/cloudsql/cloudsqlcloneinstance/cloudsqlcloneinstance.go +++ b/internal/tools/cloudsql/cloudsqlcloneinstance/cloudsqlcloneinstance.go @@ -26,11 +26,11 @@ import ( sqladmin "google.golang.org/api/sqladmin/v1" ) -const kind string = "cloud-sql-clone-instance" +const resourceType string = "cloud-sql-clone-instance" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -52,7 +52,7 @@ type compatibleSource interface { // Config defines the configuration for the clone-instance tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Description string `yaml:"description"` Source string `yaml:"source" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -61,9 +61,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -74,7 +74,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source kind must be `cloud-sql-admin`", kind) + return nil, fmt.Errorf("invalid source for %q tool: source type must be `cloud-sql-admin`", resourceType) } project := s.GetDefaultProject() @@ -125,7 +125,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool's logic. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -176,7 +176,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudsql/cloudsqlcloneinstance/cloudsqlcloneinstance_test.go b/internal/tools/cloudsql/cloudsqlcloneinstance/cloudsqlcloneinstance_test.go index 42fb94406d..2cb93c60b1 100644 --- a/internal/tools/cloudsql/cloudsqlcloneinstance/cloudsqlcloneinstance_test.go +++ b/internal/tools/cloudsql/cloudsqlcloneinstance/cloudsqlcloneinstance_test.go @@ -18,7 +18,6 @@ import ( //"context" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - clone-instance-tool: - kind: cloud-sql-clone-instance - description: a test description - source: a-source + kind: tools + name: clone-instance-tool + type: cloud-sql-clone-instance + description: a test description + source: a-source `, want: server.ToolConfigs{ "clone-instance-tool": cloudsqlcloneinstance.Config{ Name: "clone-instance-tool", - Kind: "cloud-sql-clone-instance", + Type: "cloud-sql-clone-instance", Description: "a test description", Source: "a-source", AuthRequired: []string{}, @@ -57,15 +56,11 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudsql/cloudsqlcreatebackup/cloudsqlcreatebackup.go b/internal/tools/cloudsql/cloudsqlcreatebackup/cloudsqlcreatebackup.go index a5c4f22c79..ab1f8d3e18 100644 --- a/internal/tools/cloudsql/cloudsqlcreatebackup/cloudsqlcreatebackup.go +++ b/internal/tools/cloudsql/cloudsqlcreatebackup/cloudsqlcreatebackup.go @@ -26,7 +26,7 @@ import ( "google.golang.org/api/sqladmin/v1" ) -const kind string = "cloud-sql-create-backup" +const resourceType string = "cloud-sql-create-backup" var _ tools.ToolConfig = Config{} @@ -40,15 +40,15 @@ type compatibleSource interface { // Config defines the configuration for the create-backup tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Description string `yaml:"description"` Source string `yaml:"source" validate:"required"` AuthRequired []string `yaml:"authRequired"` } func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -60,9 +60,9 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.T return actual, nil } -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -73,7 +73,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } project := s.GetDefaultProject() @@ -121,7 +121,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -167,7 +167,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudsql/cloudsqlcreatebackup/cloudsqlcreatebackup_test.go b/internal/tools/cloudsql/cloudsqlcreatebackup/cloudsqlcreatebackup_test.go index f3f46a470d..3136729817 100644 --- a/internal/tools/cloudsql/cloudsqlcreatebackup/cloudsqlcreatebackup_test.go +++ b/internal/tools/cloudsql/cloudsqlcreatebackup/cloudsqlcreatebackup_test.go @@ -17,7 +17,6 @@ package cloudsqlcreatebackup_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - create-backup-tool: - kind: cloud-sql-create-backup - description: a test description - source: a-source + kind: tools + name: create-backup-tool + type: cloud-sql-create-backup + description: a test description + source: a-source `, want: server.ToolConfigs{ "create-backup-tool": cloudsqlcreatebackup.Config{ Name: "create-backup-tool", - Kind: "cloud-sql-create-backup", + Type: "cloud-sql-create-backup", Description: "a test description", Source: "a-source", AuthRequired: []string{}, @@ -56,15 +55,11 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudsql/cloudsqlcreatedatabase/cloudsqlcreatedatabase.go b/internal/tools/cloudsql/cloudsqlcreatedatabase/cloudsqlcreatedatabase.go index 3f43e87045..e5373a771d 100644 --- a/internal/tools/cloudsql/cloudsqlcreatedatabase/cloudsqlcreatedatabase.go +++ b/internal/tools/cloudsql/cloudsqlcreatedatabase/cloudsqlcreatedatabase.go @@ -25,11 +25,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "cloud-sql-create-database" +const resourceType string = "cloud-sql-create-database" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { // Config defines the configuration for the create-database tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -59,9 +59,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -72,7 +72,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source kind must be `cloud-sql-admin`", kind) + return nil, fmt.Errorf("invalid source for %q tool: source type must be `cloud-sql-admin`", resourceType) } project := s.GetDefaultProject() @@ -118,7 +118,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool's logic. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -165,7 +165,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudsql/cloudsqlcreatedatabase/cloudsqlcreatedatabase_test.go b/internal/tools/cloudsql/cloudsqlcreatedatabase/cloudsqlcreatedatabase_test.go index 8630c916b6..7986d05850 100644 --- a/internal/tools/cloudsql/cloudsqlcreatedatabase/cloudsqlcreatedatabase_test.go +++ b/internal/tools/cloudsql/cloudsqlcreatedatabase/cloudsqlcreatedatabase_test.go @@ -17,7 +17,6 @@ package cloudsqlcreatedatabase_test import ( "testing" - "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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - create-database: - kind: cloud-sql-create-database - source: my-source - description: some description + kind: tools + name: create-database + type: cloud-sql-create-database + source: my-source + description: some description `, want: server.ToolConfigs{ "create-database": cloudsqlcreatedatabase.Config{ Name: "create-database", - Kind: "cloud-sql-create-database", + Type: "cloud-sql-create-database", Source: "my-source", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,11 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudsql/cloudsqlcreateusers/cloudsqlcreateusers.go b/internal/tools/cloudsql/cloudsqlcreateusers/cloudsqlcreateusers.go index 1eea0db1ff..40690b9dba 100644 --- a/internal/tools/cloudsql/cloudsqlcreateusers/cloudsqlcreateusers.go +++ b/internal/tools/cloudsql/cloudsqlcreateusers/cloudsqlcreateusers.go @@ -25,11 +25,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "cloud-sql-create-users" +const resourceType string = "cloud-sql-create-users" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { // Config defines the configuration for the create-user tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -59,9 +59,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -72,7 +72,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source kind must be `cloud-sql-admin`", kind) + return nil, fmt.Errorf("invalid source for %q tool: source type must be `cloud-sql-admin`", resourceType) } project := s.GetDefaultProject() @@ -120,7 +120,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool's logic. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -170,7 +170,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudsql/cloudsqlcreateusers/cloudsqlcreateusers_test.go b/internal/tools/cloudsql/cloudsqlcreateusers/cloudsqlcreateusers_test.go index 594b5215cb..6ea0ed59c1 100644 --- a/internal/tools/cloudsql/cloudsqlcreateusers/cloudsqlcreateusers_test.go +++ b/internal/tools/cloudsql/cloudsqlcreateusers/cloudsqlcreateusers_test.go @@ -17,7 +17,6 @@ package cloudsqlcreateusers_test import ( "testing" - "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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - create-user: - kind: cloud-sql-create-users - source: my-source - description: some description + kind: tools + name: create-user + type: cloud-sql-create-users + source: my-source + description: some description `, want: server.ToolConfigs{ "create-user": cloudsqlcreateusers.Config{ Name: "create-user", - Kind: "cloud-sql-create-users", + Type: "cloud-sql-create-users", Source: "my-source", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,11 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudsql/cloudsqlgetinstances/cloudsqlgetinstances.go b/internal/tools/cloudsql/cloudsqlgetinstances/cloudsqlgetinstances.go index 1cbd79fe8e..401c61e757 100644 --- a/internal/tools/cloudsql/cloudsqlgetinstances/cloudsqlgetinstances.go +++ b/internal/tools/cloudsql/cloudsqlgetinstances/cloudsqlgetinstances.go @@ -25,11 +25,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "cloud-sql-get-instance" +const resourceType string = "cloud-sql-get-instance" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { // Config defines the configuration for the get-instances tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Description string `yaml:"description"` Source string `yaml:"source" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -59,9 +59,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -73,7 +73,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source kind must be `cloud-sql-admin`", kind) + return nil, fmt.Errorf("invalid source for %q tool: source type must be `cloud-sql-admin`", resourceType) } project := s.GetDefaultProject() @@ -118,7 +118,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool's logic. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -161,7 +161,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudsql/cloudsqlgetinstances/cloudsqlgetinstances_test.go b/internal/tools/cloudsql/cloudsqlgetinstances/cloudsqlgetinstances_test.go index 809ecfa815..249f4e2015 100644 --- a/internal/tools/cloudsql/cloudsqlgetinstances/cloudsqlgetinstances_test.go +++ b/internal/tools/cloudsql/cloudsqlgetinstances/cloudsqlgetinstances_test.go @@ -17,7 +17,6 @@ package cloudsqlgetinstances_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - get-instances: - kind: cloud-sql-get-instance - description: "A tool to get cloud sql instances" - source: "my-gcp-source" + kind: tools + name: get-instances + type: cloud-sql-get-instance + description: "A tool to get cloud sql instances" + source: "my-gcp-source" `, want: server.ToolConfigs{ "get-instances": cloudsqlgetinstances.Config{ Name: "get-instances", - Kind: "cloud-sql-get-instance", + Type: "cloud-sql-get-instance", Description: "A tool to get cloud sql instances", Source: "my-gcp-source", AuthRequired: []string{}, @@ -56,15 +55,11 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudsql/cloudsqllistdatabases/cloudsqllistdatabases.go b/internal/tools/cloudsql/cloudsqllistdatabases/cloudsqllistdatabases.go index 556270c542..9eb8eda844 100644 --- a/internal/tools/cloudsql/cloudsqllistdatabases/cloudsqllistdatabases.go +++ b/internal/tools/cloudsql/cloudsqllistdatabases/cloudsqllistdatabases.go @@ -25,11 +25,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "cloud-sql-list-databases" +const resourceType string = "cloud-sql-list-databases" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { // Config defines the configuration for the list-databases tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -59,9 +59,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -72,7 +72,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source kind must be `cloud-sql-admin`", kind) + return nil, fmt.Errorf("invalid source for %q tool: source type must be `cloud-sql-admin`", resourceType) } project := s.GetDefaultProject() @@ -117,7 +117,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool's logic. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -160,7 +160,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudsql/cloudsqllistdatabases/cloudsqllistdatabases_test.go b/internal/tools/cloudsql/cloudsqllistdatabases/cloudsqllistdatabases_test.go index f7c1d49380..4717110f73 100644 --- a/internal/tools/cloudsql/cloudsqllistdatabases/cloudsqllistdatabases_test.go +++ b/internal/tools/cloudsql/cloudsqllistdatabases/cloudsqllistdatabases_test.go @@ -17,7 +17,6 @@ package cloudsqllistdatabases_test import ( "testing" - "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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - list-my-databases: - kind: cloud-sql-list-databases - description: some description - source: some-source + kind: tools + name: list-my-databases + type: cloud-sql-list-databases + description: some description + source: some-source `, want: server.ToolConfigs{ "list-my-databases": cloudsqllistdatabases.Config{ Name: "list-my-databases", - Kind: "cloud-sql-list-databases", + Type: "cloud-sql-list-databases", Description: "some description", AuthRequired: []string{}, Source: "some-source", @@ -56,15 +55,11 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudsql/cloudsqllistinstances/cloudsqllistinstances.go b/internal/tools/cloudsql/cloudsqllistinstances/cloudsqllistinstances.go index 0e48075211..441fbf00ea 100644 --- a/internal/tools/cloudsql/cloudsqllistinstances/cloudsqllistinstances.go +++ b/internal/tools/cloudsql/cloudsqllistinstances/cloudsqllistinstances.go @@ -25,11 +25,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "cloud-sql-list-instances" +const resourceType string = "cloud-sql-list-instances" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { // Config defines the configuration for the list-instance tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -59,9 +59,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -72,7 +72,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source kind must be `cloud-sql-admin`", kind) + return nil, fmt.Errorf("invalid source for %q tool: source type must be `cloud-sql-admin`", resourceType) } project := s.GetDefaultProject() @@ -116,7 +116,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool's logic. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -155,7 +155,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudsql/cloudsqllistinstances/cloudsqllistinstances_test.go b/internal/tools/cloudsql/cloudsqllistinstances/cloudsqllistinstances_test.go index bf7eabfc09..0ef4ce1b6e 100644 --- a/internal/tools/cloudsql/cloudsqllistinstances/cloudsqllistinstances_test.go +++ b/internal/tools/cloudsql/cloudsqllistinstances/cloudsqllistinstances_test.go @@ -17,7 +17,6 @@ package cloudsqllistinstances import ( "testing" - "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" @@ -36,16 +35,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - list-my-instances: - kind: cloud-sql-list-instances - description: some description - source: some-source + kind: tools + name: list-my-instances + type: cloud-sql-list-instances + description: some description + source: some-source `, want: server.ToolConfigs{ "list-my-instances": Config{ Name: "list-my-instances", - Kind: "cloud-sql-list-instances", + Type: "cloud-sql-list-instances", Description: "some description", AuthRequired: []string{}, Source: "some-source", @@ -55,15 +54,11 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudsql/cloudsqlrestorebackup/cloudsqlrestorebackup.go b/internal/tools/cloudsql/cloudsqlrestorebackup/cloudsqlrestorebackup.go index 63b025d861..bc17692cf5 100644 --- a/internal/tools/cloudsql/cloudsqlrestorebackup/cloudsqlrestorebackup.go +++ b/internal/tools/cloudsql/cloudsqlrestorebackup/cloudsqlrestorebackup.go @@ -26,7 +26,7 @@ import ( "google.golang.org/api/sqladmin/v1" ) -const kind string = "cloud-sql-restore-backup" +const resourceType string = "cloud-sql-restore-backup" var _ tools.ToolConfig = Config{} @@ -40,15 +40,15 @@ type compatibleSource interface { // Config defines the configuration for the restore-backup tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Description string `yaml:"description"` Source string `yaml:"source" validate:"required"` AuthRequired []string `yaml:"authRequired"` } func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -60,9 +60,9 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.T return actual, nil } -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -73,7 +73,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } project := s.GetDefaultProject() @@ -121,7 +121,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -170,7 +170,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudsql/cloudsqlrestorebackup/cloudsqlrestorebackup_test.go b/internal/tools/cloudsql/cloudsqlrestorebackup/cloudsqlrestorebackup_test.go index 7ed49142ed..27c4bd7467 100644 --- a/internal/tools/cloudsql/cloudsqlrestorebackup/cloudsqlrestorebackup_test.go +++ b/internal/tools/cloudsql/cloudsqlrestorebackup/cloudsqlrestorebackup_test.go @@ -17,7 +17,6 @@ package cloudsqlrestorebackup_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - restore-backup-tool: - kind: cloud-sql-restore-backup - description: a test description - source: a-source + kind: tools + name: restore-backup-tool + type: cloud-sql-restore-backup + description: a test description + source: a-source `, want: server.ToolConfigs{ "restore-backup-tool": cloudsqlrestorebackup.Config{ Name: "restore-backup-tool", - Kind: "cloud-sql-restore-backup", + Type: "cloud-sql-restore-backup", Description: "a test description", Source: "a-source", AuthRequired: []string{}, @@ -56,14 +55,11 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudsql/cloudsqlwaitforoperation/cloudsqlwaitforoperation.go b/internal/tools/cloudsql/cloudsqlwaitforoperation/cloudsqlwaitforoperation.go index 6deafd64ef..841e4d6a97 100644 --- a/internal/tools/cloudsql/cloudsqlwaitforoperation/cloudsqlwaitforoperation.go +++ b/internal/tools/cloudsql/cloudsqlwaitforoperation/cloudsqlwaitforoperation.go @@ -27,7 +27,7 @@ import ( "google.golang.org/api/sqladmin/v1" ) -const kind string = "cloud-sql-wait-for-operation" +const resourceType string = "cloud-sql-wait-for-operation" var cloudSQLConnectionMessageTemplate = `Your Cloud SQL resource is ready. @@ -71,8 +71,8 @@ Please refer to the official documentation for guidance on deploying the toolbox ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -94,7 +94,7 @@ type compatibleSource interface { // Config defines the configuration for the wait-for-operation tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -110,9 +110,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -124,7 +124,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source kind must be `cloud-sql-admin`", kind) + return nil, fmt.Errorf("invalid source for %q tool: source type must be `cloud-sql-admin`", resourceType) } project := s.GetDefaultProject() @@ -211,7 +211,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool's logic. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -290,7 +290,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudsql/cloudsqlwaitforoperation/cloudsqlwaitforoperation_test.go b/internal/tools/cloudsql/cloudsqlwaitforoperation/cloudsqlwaitforoperation_test.go index 580ee5a4f4..994cd87bb4 100644 --- a/internal/tools/cloudsql/cloudsqlwaitforoperation/cloudsqlwaitforoperation_test.go +++ b/internal/tools/cloudsql/cloudsqlwaitforoperation/cloudsqlwaitforoperation_test.go @@ -17,7 +17,6 @@ package cloudsqlwaitforoperation_test import ( "testing" - 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" @@ -37,20 +36,20 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - wait-for-thing: - kind: cloud-sql-wait-for-operation - source: some-source - description: some description - delay: 1s - maxDelay: 5s - multiplier: 1.5 - maxRetries: 5 + kind: tools + name: wait-for-thing + type: cloud-sql-wait-for-operation + source: some-source + description: some description + delay: 1s + maxDelay: 5s + multiplier: 1.5 + maxRetries: 5 `, want: server.ToolConfigs{ "wait-for-thing": cloudsqlwaitforoperation.Config{ Name: "wait-for-thing", - Kind: "cloud-sql-wait-for-operation", + Type: "cloud-sql-wait-for-operation", Source: "some-source", Description: "some description", AuthRequired: []string{}, @@ -64,15 +63,11 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudsqlmssql/cloudsqlmssqlcreateinstance/cloudsqlmssqlcreateinstance.go b/internal/tools/cloudsqlmssql/cloudsqlmssqlcreateinstance/cloudsqlmssqlcreateinstance.go index 36cecf97fc..fb512316ad 100644 --- a/internal/tools/cloudsqlmssql/cloudsqlmssqlcreateinstance/cloudsqlmssqlcreateinstance.go +++ b/internal/tools/cloudsqlmssql/cloudsqlmssqlcreateinstance/cloudsqlmssqlcreateinstance.go @@ -27,11 +27,11 @@ import ( "google.golang.org/api/sqladmin/v1" ) -const kind string = "cloud-sql-mssql-create-instance" +const resourceType string = "cloud-sql-mssql-create-instance" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -52,7 +52,7 @@ type compatibleSource interface { // Config defines the configuration for the create-instances tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Description string `yaml:"description"` Source string `yaml:"source" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -61,9 +61,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -74,7 +74,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source kind must be `cloud-sql-admin`", kind) + return nil, fmt.Errorf("invalid source for %q tool: source type must be `cloud-sql-admin`", resourceType) } project := s.GetDefaultProject() @@ -122,7 +122,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool's logic. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -194,7 +194,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudsqlmssql/cloudsqlmssqlcreateinstance/cloudsqlmssqlcreateinstance_test.go b/internal/tools/cloudsqlmssql/cloudsqlmssqlcreateinstance/cloudsqlmssqlcreateinstance_test.go index 54b381ae62..01928e87cd 100644 --- a/internal/tools/cloudsqlmssql/cloudsqlmssqlcreateinstance/cloudsqlmssqlcreateinstance_test.go +++ b/internal/tools/cloudsqlmssql/cloudsqlmssqlcreateinstance/cloudsqlmssqlcreateinstance_test.go @@ -17,7 +17,6 @@ package cloudsqlmssqlcreateinstance_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - create-instance-tool: - kind: cloud-sql-mssql-create-instance - description: a test description - source: a-source + kind: tools + name: create-instance-tool + type: cloud-sql-mssql-create-instance + description: a test description + source: a-source `, want: server.ToolConfigs{ "create-instance-tool": cloudsqlmssqlcreateinstance.Config{ Name: "create-instance-tool", - Kind: "cloud-sql-mssql-create-instance", + Type: "cloud-sql-mssql-create-instance", Description: "a test description", Source: "a-source", AuthRequired: []string{}, @@ -56,15 +55,11 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudsqlmysql/cloudsqlmysqlcreateinstance/cloudsqlmysqlcreateinstance.go b/internal/tools/cloudsqlmysql/cloudsqlmysqlcreateinstance/cloudsqlmysqlcreateinstance.go index 4c6f2b6263..722cf86b34 100644 --- a/internal/tools/cloudsqlmysql/cloudsqlmysqlcreateinstance/cloudsqlmysqlcreateinstance.go +++ b/internal/tools/cloudsqlmysql/cloudsqlmysqlcreateinstance/cloudsqlmysqlcreateinstance.go @@ -27,11 +27,11 @@ import ( sqladmin "google.golang.org/api/sqladmin/v1" ) -const kind string = "cloud-sql-mysql-create-instance" +const resourceType string = "cloud-sql-mysql-create-instance" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -52,7 +52,7 @@ type compatibleSource interface { // Config defines the configuration for the create-instances tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Description string `yaml:"description"` Source string `yaml:"source" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -61,9 +61,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -74,7 +74,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source kind must be `cloud-sql-admin`", kind) + return nil, fmt.Errorf("invalid source for %q tool: source type must be `cloud-sql-admin`", resourceType) } project := s.GetDefaultProject() @@ -122,7 +122,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool's logic. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -196,7 +196,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudsqlmysql/cloudsqlmysqlcreateinstance/cloudsqlmysqlcreateinstance_test.go b/internal/tools/cloudsqlmysql/cloudsqlmysqlcreateinstance/cloudsqlmysqlcreateinstance_test.go index eb961412c8..88b4ea087d 100644 --- a/internal/tools/cloudsqlmysql/cloudsqlmysqlcreateinstance/cloudsqlmysqlcreateinstance_test.go +++ b/internal/tools/cloudsqlmysql/cloudsqlmysqlcreateinstance/cloudsqlmysqlcreateinstance_test.go @@ -17,7 +17,6 @@ package cloudsqlmysqlcreateinstance_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - create-instance-tool: - kind: cloud-sql-mysql-create-instance - description: a test description - source: a-source + kind: tools + name: create-instance-tool + type: cloud-sql-mysql-create-instance + description: a test description + source: a-source `, want: server.ToolConfigs{ "create-instance-tool": cloudsqlmysqlcreateinstance.Config{ Name: "create-instance-tool", - Kind: "cloud-sql-mysql-create-instance", + Type: "cloud-sql-mysql-create-instance", Description: "a test description", Source: "a-source", AuthRequired: []string{}, @@ -56,15 +55,11 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudsqlpg/cloudsqlpgcreateinstances/cloudsqlpgcreateinstances.go b/internal/tools/cloudsqlpg/cloudsqlpgcreateinstances/cloudsqlpgcreateinstances.go index b65055089d..2b9fb97653 100644 --- a/internal/tools/cloudsqlpg/cloudsqlpgcreateinstances/cloudsqlpgcreateinstances.go +++ b/internal/tools/cloudsqlpg/cloudsqlpgcreateinstances/cloudsqlpgcreateinstances.go @@ -27,11 +27,11 @@ import ( sqladmin "google.golang.org/api/sqladmin/v1" ) -const kind string = "cloud-sql-postgres-create-instance" +const resourceType string = "cloud-sql-postgres-create-instance" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -52,7 +52,7 @@ type compatibleSource interface { // Config defines the configuration for the create-instances tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Description string `yaml:"description"` Source string `yaml:"source" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -61,9 +61,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -74,7 +74,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) } s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source kind must be `cloud-sql-admin`", kind) + return nil, fmt.Errorf("invalid source for %q tool: source type must be `cloud-sql-admin`", resourceType) } project := s.GetDefaultProject() @@ -122,7 +122,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool's logic. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -195,7 +195,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudsqlpg/cloudsqlpgcreateinstances/cloudsqlpgcreateinstances_test.go b/internal/tools/cloudsqlpg/cloudsqlpgcreateinstances/cloudsqlpgcreateinstances_test.go index 950ba8b2de..12dca82574 100644 --- a/internal/tools/cloudsqlpg/cloudsqlpgcreateinstances/cloudsqlpgcreateinstances_test.go +++ b/internal/tools/cloudsqlpg/cloudsqlpgcreateinstances/cloudsqlpgcreateinstances_test.go @@ -17,7 +17,6 @@ package cloudsqlpgcreateinstances_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - create-instance-tool: - kind: cloud-sql-postgres-create-instance - description: a test description - source: a-source + kind: tools + name: create-instance-tool + type: cloud-sql-postgres-create-instance + description: a test description + source: a-source `, want: server.ToolConfigs{ "create-instance-tool": cloudsqlpgcreateinstances.Config{ Name: "create-instance-tool", - Kind: "cloud-sql-postgres-create-instance", + Type: "cloud-sql-postgres-create-instance", Description: "a test description", Source: "a-source", AuthRequired: []string{}, @@ -56,15 +55,11 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/cloudsqlpg/cloudsqlpgupgradeprecheck/cloudsqlpgupgradeprecheck.go b/internal/tools/cloudsqlpg/cloudsqlpgupgradeprecheck/cloudsqlpgupgradeprecheck.go index 3f1cdb5340..16c65063ce 100644 --- a/internal/tools/cloudsqlpg/cloudsqlpgupgradeprecheck/cloudsqlpgupgradeprecheck.go +++ b/internal/tools/cloudsqlpg/cloudsqlpgupgradeprecheck/cloudsqlpgupgradeprecheck.go @@ -27,11 +27,11 @@ import ( sqladmin "google.golang.org/api/sqladmin/v1" ) -const kind string = "postgres-upgrade-precheck" +const resourceType string = "postgres-upgrade-precheck" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -51,7 +51,7 @@ type compatibleSource interface { // Config defines the configuration for the precheck-upgrade tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Description string `yaml:"description"` Source string `yaml:"source" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -60,9 +60,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize initializes the tool from the configuration. @@ -133,7 +133,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the tool's logic. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -231,7 +231,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } diff --git a/internal/tools/cloudsqlpg/cloudsqlpgupgradeprecheck/cloudsqlpgupgradeprecheck_test.go b/internal/tools/cloudsqlpg/cloudsqlpgupgradeprecheck/cloudsqlpgupgradeprecheck_test.go index 27a117e1ba..790676cd70 100644 --- a/internal/tools/cloudsqlpg/cloudsqlpgupgradeprecheck/cloudsqlpgupgradeprecheck_test.go +++ b/internal/tools/cloudsqlpg/cloudsqlpgupgradeprecheck/cloudsqlpgupgradeprecheck_test.go @@ -17,7 +17,6 @@ package cloudsqlpgupgradeprecheck_test import ( "testing" - 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" @@ -37,18 +36,18 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic precheck example", in: ` - tools: - precheck-upgrade-tool: - kind: postgres-upgrade-precheck - description: a precheck test description - source: some-admin-source - authRequired: - - https://www.googleapis.com/auth/cloud-platform + kind: tools + name: precheck-upgrade-tool + type: postgres-upgrade-precheck + description: a precheck test description + source: some-admin-source + authRequired: + - https://www.googleapis.com/auth/cloud-platform `, want: server.ToolConfigs{ "precheck-upgrade-tool": cloudsqlpgupgradeprecheck.Config{ Name: "precheck-upgrade-tool", - Kind: "postgres-upgrade-precheck", + Type: "postgres-upgrade-precheck", Description: "a precheck test description", Source: "some-admin-source", AuthRequired: []string{"https://www.googleapis.com/auth/cloud-platform"}, @@ -58,16 +57,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "precheck example with no auth", in: ` - tools: - precheck-upgrade-tool-no-auth: - kind: postgres-upgrade-precheck - description: a precheck test description no auth - source: other-admin-source + kind: tools + name: precheck-upgrade-tool-no-auth + type: postgres-upgrade-precheck + description: a precheck test description no auth + source: other-admin-source `, want: server.ToolConfigs{ "precheck-upgrade-tool-no-auth": cloudsqlpgupgradeprecheck.Config{ Name: "precheck-upgrade-tool-no-auth", - Kind: "postgres-upgrade-precheck", + Type: "postgres-upgrade-precheck", Description: "a precheck test description no auth", Source: "other-admin-source", AuthRequired: []string{}, @@ -77,15 +76,11 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff (-want +got):\n%s", diff) } }) diff --git a/internal/tools/couchbase/couchbase.go b/internal/tools/couchbase/couchbase.go index 824b9cab58..35880d5ca5 100644 --- a/internal/tools/couchbase/couchbase.go +++ b/internal/tools/couchbase/couchbase.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "couchbase-sql" +const resourceType string = "couchbase-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Statement string `yaml:"statement" validate:"required"` @@ -61,8 +61,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -97,7 +97,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/couchbase/couchbase_test.go b/internal/tools/couchbase/couchbase_test.go index 6f8f2bc459..554c871c0d 100644 --- a/internal/tools/couchbase/couchbase_test.go +++ b/internal/tools/couchbase/couchbase_test.go @@ -20,73 +20,12 @@ import ( "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" ) -func TestParseFromYamlCouchbase(t *testing.T) { - tcs := []struct { - desc string - in string - want server.ToolConfigs - }{ - { - desc: "basic example", - in: ` - tools: - example_tool: - kind: couchbase-sql - source: my-couchbase-instance - description: some tool description - statement: | - select * from hotel WHERE name = $hotel; - parameters: - - name: hotel - type: string - description: hotel parameter description - `, - want: server.ToolConfigs{ - "example_tool": couchbase.Config{ - Name: "example_tool", - Kind: "couchbase-sql", - AuthRequired: []string{}, - Source: "my-couchbase-instance", - Description: "some tool description", - Statement: "select * from hotel WHERE name = $hotel;\n", - Parameters: []parameters.Parameter{ - parameters.NewStringParameter("hotel", "hotel parameter description"), - }, - }, - }, - }, - } - for _, tc := range tcs { - t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - - // Create a context with a logger - ctx, err := testutils.ContextWithNewLogger() - if err != nil { - t.Fatalf("unable to create context with logger: %s", err) - } - - // Parse contents with context - err = yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) - if err != nil { - t.Fatalf("unable to unmarshal: %s", err) - } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { - t.Fatalf("incorrect parse: diff %v", diff) - } - }) - } -} - -func TestParseFromYamlWithTemplateMssql(t *testing.T) { +func TestParseFromYaml(t *testing.T) { ctx, err := testutils.ContextWithNewLogger() if err != nil { t.Fatalf("unexpected error: %s", err) @@ -99,26 +38,55 @@ func TestParseFromYamlWithTemplateMssql(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: couchbase-sql - source: my-couchbase-instance - description: some tool description - statement: | - select * from {{.tableName}} WHERE name = $hotel; - parameters: - - name: hotel - type: string - description: hotel parameter description - templateParameters: - - name: tableName - type: string - description: The table to select hotels from. + kind: tools + name: example_tool + type: couchbase-sql + source: my-couchbase-instance + description: some tool description + statement: | + select * from hotel WHERE name = $hotel; + parameters: + - name: hotel + type: string + description: hotel parameter description `, want: server.ToolConfigs{ "example_tool": couchbase.Config{ Name: "example_tool", - Kind: "couchbase-sql", + Type: "couchbase-sql", + AuthRequired: []string{}, + Source: "my-couchbase-instance", + Description: "some tool description", + Statement: "select * from hotel WHERE name = $hotel;\n", + Parameters: []parameters.Parameter{ + parameters.NewStringParameter("hotel", "hotel parameter description"), + }, + }, + }, + }, + { + desc: "with template", + in: ` + kind: tools + name: example_tool + type: couchbase-sql + source: my-couchbase-instance + description: some tool description + statement: | + select * from {{.tableName}} WHERE name = $hotel; + parameters: + - name: hotel + type: string + description: hotel parameter description + templateParameters: + - name: tableName + type: string + description: The table to select hotels from. + `, + want: server.ToolConfigs{ + "example_tool": couchbase.Config{ + Name: "example_tool", + Type: "couchbase-sql", AuthRequired: []string{}, Source: "my-couchbase-instance", Description: "some tool description", @@ -135,15 +103,11 @@ func TestParseFromYamlWithTemplateMssql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/dataform/dataformcompilelocal/dataformcompilelocal.go b/internal/tools/dataform/dataformcompilelocal/dataformcompilelocal.go index 3f04042c66..bd8d1071f6 100644 --- a/internal/tools/dataform/dataformcompilelocal/dataformcompilelocal.go +++ b/internal/tools/dataform/dataformcompilelocal/dataformcompilelocal.go @@ -27,11 +27,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "dataform-compile-local" +const resourceType string = "dataform-compile-local" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -45,15 +45,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"` + Type string `yaml:"type" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` } var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { diff --git a/internal/tools/dataform/dataformcompilelocal/dataformcompilelocal_test.go b/internal/tools/dataform/dataformcompilelocal/dataformcompilelocal_test.go index 40b85f0363..89cb950aea 100644 --- a/internal/tools/dataform/dataformcompilelocal/dataformcompilelocal_test.go +++ b/internal/tools/dataform/dataformcompilelocal/dataformcompilelocal_test.go @@ -17,7 +17,6 @@ package dataformcompilelocal_test import ( "testing" - 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" @@ -37,15 +36,15 @@ func TestParseFromYamlDataformCompile(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: dataform-compile-local - description: some description + kind: tools + name: example_tool + type: dataform-compile-local + description: some description `, want: server.ToolConfigs{ "example_tool": dataformcompilelocal.Config{ Name: "example_tool", - Kind: "dataform-compile-local", + Type: "dataform-compile-local", Description: "some description", AuthRequired: []string{}, }, @@ -54,15 +53,11 @@ func TestParseFromYamlDataformCompile(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/dataplex/dataplexlookupentry/dataplexlookupentry.go b/internal/tools/dataplex/dataplexlookupentry/dataplexlookupentry.go index 08d3c965f8..1eb4d2fb38 100644 --- a/internal/tools/dataplex/dataplexlookupentry/dataplexlookupentry.go +++ b/internal/tools/dataplex/dataplexlookupentry/dataplexlookupentry.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "dataplex-lookup-entry" +const resourceType string = "dataplex-lookup-entry" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -48,7 +48,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -58,8 +58,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -111,7 +111,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/dataplex/dataplexlookupentry/dataplexlookupentry_test.go b/internal/tools/dataplex/dataplexlookupentry/dataplexlookupentry_test.go index 8c3d5942c2..514125d512 100644 --- a/internal/tools/dataplex/dataplexlookupentry/dataplexlookupentry_test.go +++ b/internal/tools/dataplex/dataplexlookupentry/dataplexlookupentry_test.go @@ -17,7 +17,6 @@ package dataplexlookupentry_test import ( "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlDataplexLookupEntry(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: dataplex-lookup-entry - source: my-instance - description: some description - `, + kind: tools + name: example_tool + type: dataplex-lookup-entry + source: my-instance + description: some description + `, want: server.ToolConfigs{ "example_tool": dataplexlookupentry.Config{ Name: "example_tool", - Kind: "dataplex-lookup-entry", + Type: "dataplex-lookup-entry", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,34 +56,34 @@ func TestParseFromYamlDataplexLookupEntry(t *testing.T) { { desc: "advanced example", in: ` - tools: - example_tool: - kind: dataplex-lookup-entry - source: my-instance - description: some description - parameters: - - name: name - type: string - description: some name description - - name: view - type: string - description: some view description - - name: aspectTypes - type: array - description: some aspect types description - default: [] - items: - name: aspectType - type: string - description: some aspect type description - - name: entry - type: string - description: some entry description - `, + kind: tools + name: example_tool + type: dataplex-lookup-entry + source: my-instance + description: some description + parameters: + - name: name + type: string + description: some name description + - name: view + type: string + description: some view description + - name: aspectTypes + type: array + description: some aspect types description + default: [] + items: + name: aspectType + type: string + description: some aspect type description + - name: entry + type: string + description: some entry description + `, want: server.ToolConfigs{ "example_tool": dataplexlookupentry.Config{ Name: "example_tool", - Kind: "dataplex-lookup-entry", + Type: "dataplex-lookup-entry", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -100,18 +99,14 @@ func TestParseFromYamlDataplexLookupEntry(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) } - } diff --git a/internal/tools/dataplex/dataplexsearchaspecttypes/dataplexsearchaspecttypes.go b/internal/tools/dataplex/dataplexsearchaspecttypes/dataplexsearchaspecttypes.go index fd879bc1d6..9384aed578 100644 --- a/internal/tools/dataplex/dataplexsearchaspecttypes/dataplexsearchaspecttypes.go +++ b/internal/tools/dataplex/dataplexsearchaspecttypes/dataplexsearchaspecttypes.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "dataplex-search-aspect-types" +const resourceType string = "dataplex-search-aspect-types" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -48,7 +48,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -57,8 +57,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -94,7 +94,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/dataplex/dataplexsearchaspecttypes/dataplexsearchaspecttypes_test.go b/internal/tools/dataplex/dataplexsearchaspecttypes/dataplexsearchaspecttypes_test.go index 963091b03d..cb081ca45f 100644 --- a/internal/tools/dataplex/dataplexsearchaspecttypes/dataplexsearchaspecttypes_test.go +++ b/internal/tools/dataplex/dataplexsearchaspecttypes/dataplexsearchaspecttypes_test.go @@ -17,7 +17,6 @@ package dataplexsearchaspecttypes_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlDataplexSearchAspectTypes(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: dataplex-search-aspect-types - source: my-instance - description: some description - `, + kind: tools + name: example_tool + type: dataplex-search-aspect-types + source: my-instance + description: some description + `, want: server.ToolConfigs{ "example_tool": dataplexsearchaspecttypes.Config{ Name: "example_tool", - Kind: "dataplex-search-aspect-types", + Type: "dataplex-search-aspect-types", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,18 +55,14 @@ func TestParseFromYamlDataplexSearchAspectTypes(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) } - } diff --git a/internal/tools/dataplex/dataplexsearchentries/dataplexsearchentries.go b/internal/tools/dataplex/dataplexsearchentries/dataplexsearchentries.go index 39a22bba02..a848145746 100644 --- a/internal/tools/dataplex/dataplexsearchentries/dataplexsearchentries.go +++ b/internal/tools/dataplex/dataplexsearchentries/dataplexsearchentries.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "dataplex-search-entries" +const resourceType string = "dataplex-search-entries" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -48,7 +48,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -57,8 +57,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -94,7 +94,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/dataplex/dataplexsearchentries/dataplexsearchentries_test.go b/internal/tools/dataplex/dataplexsearchentries/dataplexsearchentries_test.go index f916c82f74..e8b80883ac 100644 --- a/internal/tools/dataplex/dataplexsearchentries/dataplexsearchentries_test.go +++ b/internal/tools/dataplex/dataplexsearchentries/dataplexsearchentries_test.go @@ -17,7 +17,6 @@ package dataplexsearchentries_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlDataplexSearchEntries(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: dataplex-search-entries - source: my-instance - description: some description - `, + kind: tools + name: example_tool + type: dataplex-search-entries + source: my-instance + description: some description + `, want: server.ToolConfigs{ "example_tool": dataplexsearchentries.Config{ Name: "example_tool", - Kind: "dataplex-search-entries", + Type: "dataplex-search-entries", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,18 +55,14 @@ func TestParseFromYamlDataplexSearchEntries(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) } - } diff --git a/internal/tools/dgraph/dgraph.go b/internal/tools/dgraph/dgraph.go index be1e733e38..37296c1f9a 100644 --- a/internal/tools/dgraph/dgraph.go +++ b/internal/tools/dgraph/dgraph.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "dgraph-dql" +const resourceType string = "dgraph-dql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Statement string `yaml:"statement" validate:"required"` @@ -62,8 +62,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -92,7 +92,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/dgraph/dgraph_test.go b/internal/tools/dgraph/dgraph_test.go index cb4f672ff3..08ea32e2e4 100644 --- a/internal/tools/dgraph/dgraph_test.go +++ b/internal/tools/dgraph/dgraph_test.go @@ -17,7 +17,6 @@ package dgraph_test import ( "testing" - 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" @@ -37,20 +36,20 @@ func TestParseFromYamlDgraph(t *testing.T) { { desc: "basic query example", in: ` - tools: - example_tool: - kind: dgraph-dql - source: my-dgraph-instance - description: some tool description - isQuery: true - timeout: 20s - statement: | - query {q(func: eq(email, "example@email.com")) {email}} + kind: tools + name: example_tool + type: dgraph-dql + source: my-dgraph-instance + description: some tool description + isQuery: true + timeout: 20s + statement: | + query {q(func: eq(email, "example@email.com")) {email}} `, want: server.ToolConfigs{ "example_tool": dgraph.Config{ Name: "example_tool", - Kind: "dgraph-dql", + Type: "dgraph-dql", Source: "my-dgraph-instance", AuthRequired: []string{}, Description: "some tool description", @@ -63,18 +62,18 @@ func TestParseFromYamlDgraph(t *testing.T) { { desc: "basic mutation example", in: ` - tools: - example_tool: - kind: dgraph-dql - source: my-dgraph-instance - description: some tool description - statement: | - mutation {set { _:a "a@email.com" . _:b "b@email.com" .}} + kind: tools + name: example_tool + type: dgraph-dql + source: my-dgraph-instance + description: some tool description + statement: | + mutation {set { _:a "a@email.com" . _:b "b@email.com" .}} `, want: server.ToolConfigs{ "example_tool": dgraph.Config{ Name: "example_tool", - Kind: "dgraph-dql", + Type: "dgraph-dql", Source: "my-dgraph-instance", Description: "some tool description", AuthRequired: []string{}, @@ -85,15 +84,11 @@ func TestParseFromYamlDgraph(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/elasticsearch/elasticsearchesql/elasticsearchesql.go b/internal/tools/elasticsearch/elasticsearchesql/elasticsearchesql.go index 03ca370345..d386d6174d 100644 --- a/internal/tools/elasticsearch/elasticsearchesql/elasticsearchesql.go +++ b/internal/tools/elasticsearch/elasticsearchesql/elasticsearchesql.go @@ -28,11 +28,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" ) -const kind string = "elasticsearch-esql" +const resourceType string = "elasticsearch-esql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -43,7 +43,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired" validate:"required"` @@ -55,8 +55,8 @@ type Config struct { var _ tools.ToolConfig = Config{} -func (c Config) ToolConfigKind() string { - return kind +func (c Config) ToolConfigType() string { + return resourceType } func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.ToolConfig, error) { @@ -90,7 +90,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/elasticsearch/elasticsearchesql/elasticsearchesql_test.go b/internal/tools/elasticsearch/elasticsearchesql/elasticsearchesql_test.go index ec65d2842a..aca93acdb4 100644 --- a/internal/tools/elasticsearch/elasticsearchesql/elasticsearchesql_test.go +++ b/internal/tools/elasticsearch/elasticsearchesql/elasticsearchesql_test.go @@ -17,7 +17,6 @@ package elasticsearchesql import ( "testing" - "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" @@ -37,19 +36,19 @@ func TestParseFromYamlElasticsearchEsql(t *testing.T) { { desc: "basic search example", in: ` - tools: - example_tool: - kind: elasticsearch-esql - source: my-elasticsearch-instance - description: Elasticsearch ES|QL tool - query: | - FROM my-index - | KEEP first_name, last_name + kind: tools + name: example_tool + type: elasticsearch-esql + source: my-elasticsearch-instance + description: Elasticsearch ES|QL tool + query: | + FROM my-index + | KEEP first_name, last_name `, want: server.ToolConfigs{ "example_tool": Config{ Name: "example_tool", - Kind: "elasticsearch-esql", + Type: "elasticsearch-esql", Source: "my-elasticsearch-instance", Description: "Elasticsearch ES|QL tool", AuthRequired: []string{}, @@ -60,23 +59,23 @@ func TestParseFromYamlElasticsearchEsql(t *testing.T) { { desc: "search with customizable limit parameter", in: ` - tools: - example_tool: - kind: elasticsearch-esql - source: my-elasticsearch-instance - description: Elasticsearch ES|QL tool with customizable limit - parameters: - - name: limit - type: integer - description: Limit the number of results - query: | - FROM my-index - | LIMIT ?limit + kind: tools + name: example_tool + type: elasticsearch-esql + source: my-elasticsearch-instance + description: Elasticsearch ES|QL tool with customizable limit + parameters: + - name: limit + type: integer + description: Limit the number of results + query: | + FROM my-index + | LIMIT ?limit `, want: server.ToolConfigs{ "example_tool": Config{ Name: "example_tool", - Kind: "elasticsearch-esql", + Type: "elasticsearch-esql", Source: "my-elasticsearch-instance", Description: "Elasticsearch ES|QL tool with customizable limit", AuthRequired: []string{}, @@ -91,15 +90,12 @@ func TestParseFromYamlElasticsearchEsql(t *testing.T) { for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/firebird/firebirdexecutesql/firebirdexecutesql.go b/internal/tools/firebird/firebirdexecutesql/firebirdexecutesql.go index ea4923a316..e96a99d0cc 100644 --- a/internal/tools/firebird/firebirdexecutesql/firebirdexecutesql.go +++ b/internal/tools/firebird/firebirdexecutesql/firebirdexecutesql.go @@ -27,11 +27,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "firebird-execute-sql" +const resourceType string = "firebird-execute-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -58,8 +58,8 @@ type Config struct { var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -91,7 +91,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -107,7 +107,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para if err != nil { return nil, fmt.Errorf("error getting logger: %s", err) } - logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", kind, sql)) + logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", resourceType, sql)) return source.RunSQL(ctx, sql, nil) } diff --git a/internal/tools/firebird/firebirdexecutesql/firebirdexecutesql_test.go b/internal/tools/firebird/firebirdexecutesql/firebirdexecutesql_test.go index a2f8f02355..b91e68eb19 100644 --- a/internal/tools/firebird/firebirdexecutesql/firebirdexecutesql_test.go +++ b/internal/tools/firebird/firebirdexecutesql/firebirdexecutesql_test.go @@ -17,7 +17,6 @@ package firebirdexecutesql_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlExecuteSql(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: firebird-execute-sql - source: my-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: firebird-execute-sql + source: my-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": firebirdexecutesql.Config{ Name: "example_tool", - Kind: "firebird-execute-sql", + Type: "firebird-execute-sql", Source: "my-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,15 +58,12 @@ func TestParseFromYamlExecuteSql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/firebird/firebirdsql/firebirdsql.go b/internal/tools/firebird/firebirdsql/firebirdsql.go index b6c1585e93..1973167f9b 100644 --- a/internal/tools/firebird/firebirdsql/firebirdsql.go +++ b/internal/tools/firebird/firebirdsql/firebirdsql.go @@ -27,11 +27,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "firebird-sql" +const resourceType string = "firebird-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Statement string `yaml:"statement" validate:"required"` @@ -62,8 +62,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -99,7 +99,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/firebird/firebirdsql/firebirdsql_test.go b/internal/tools/firebird/firebirdsql/firebirdsql_test.go index 5530699035..e329d237ac 100644 --- a/internal/tools/firebird/firebirdsql/firebirdsql_test.go +++ b/internal/tools/firebird/firebirdsql/firebirdsql_test.go @@ -17,7 +17,6 @@ package firebirdsql_test import ( "testing" - 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" @@ -38,30 +37,30 @@ func TestParseFromYamlFirebird(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: firebird-sql - source: my-fdb-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - authRequired: - - my-google-auth-service - - other-auth-service - parameters: - - name: country - type: string - description: some description - authServices: - - name: my-google-auth-service - field: user_id - - name: other-auth-service - field: user_id + kind: tools + name: example_tool + type: firebird-sql + source: my-fdb-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + authRequired: + - my-google-auth-service + - other-auth-service + parameters: + - name: country + type: string + description: some description + authServices: + - name: my-google-auth-service + field: user_id + - name: other-auth-service + field: user_id `, want: server.ToolConfigs{ "example_tool": firebirdsql.Config{ Name: "example_tool", - Kind: "firebird-sql", + Type: "firebird-sql", Source: "my-fdb-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -77,15 +76,12 @@ func TestParseFromYamlFirebird(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -106,33 +102,33 @@ func TestParseFromYamlWithTemplateParamsFirebird(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: firebird-sql - source: my-fdb-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - parameters: - - name: name - type: string - description: some description - templateParameters: - - name: tableName - type: string - description: The table to select hotels from. - - name: fieldArray - type: array - description: The columns to return for the query. - items: - name: column - type: string - description: A column name that will be returned from the query. + kind: tools + name: example_tool + type: firebird-sql + source: my-fdb-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + parameters: + - name: name + type: string + description: some description + templateParameters: + - name: tableName + type: string + description: The table to select hotels from. + - name: fieldArray + type: array + description: The columns to return for the query. + items: + name: column + type: string + description: A column name that will be returned from the query. `, want: server.ToolConfigs{ "example_tool": firebirdsql.Config{ Name: "example_tool", - Kind: "firebird-sql", + Type: "firebird-sql", Source: "my-fdb-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -150,15 +146,12 @@ func TestParseFromYamlWithTemplateParamsFirebird(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/firestore/firestoreadddocuments/firestoreadddocuments.go b/internal/tools/firestore/firestoreadddocuments/firestoreadddocuments.go index d2817f9bcd..dc884328bf 100644 --- a/internal/tools/firestore/firestoreadddocuments/firestoreadddocuments.go +++ b/internal/tools/firestore/firestoreadddocuments/firestoreadddocuments.go @@ -27,14 +27,14 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "firestore-add-documents" +const resourceType string = "firestore-add-documents" const collectionPathKey string = "collectionPath" const documentDataKey string = "documentData" const returnDocumentDataKey string = "returnData" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -53,7 +53,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -62,8 +62,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -129,7 +129,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/firestore/firestoreadddocuments/firestoreadddocuments_test.go b/internal/tools/firestore/firestoreadddocuments/firestoreadddocuments_test.go index 5e743714f1..62ad017c7d 100644 --- a/internal/tools/firestore/firestoreadddocuments/firestoreadddocuments_test.go +++ b/internal/tools/firestore/firestoreadddocuments/firestoreadddocuments_test.go @@ -17,7 +17,6 @@ package firestoreadddocuments_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlFirestoreAddDocuments(t *testing.T) { { desc: "basic example", in: ` - tools: - add_docs_tool: - kind: firestore-add-documents - source: my-firestore-instance - description: Add documents to Firestore collections + kind: tools + name: add_docs_tool + type: firestore-add-documents + source: my-firestore-instance + description: Add documents to Firestore collections `, want: server.ToolConfigs{ "add_docs_tool": firestoreadddocuments.Config{ Name: "add_docs_tool", - Kind: "firestore-add-documents", + Type: "firestore-add-documents", Source: "my-firestore-instance", Description: "Add documents to Firestore collections", AuthRequired: []string{}, @@ -56,19 +55,19 @@ func TestParseFromYamlFirestoreAddDocuments(t *testing.T) { { desc: "with auth requirements", in: ` - tools: - secure_add_docs: - kind: firestore-add-documents - source: prod-firestore - description: Add documents with authentication - authRequired: - - google-auth-service - - api-key-service + kind: tools + name: secure_add_docs + type: firestore-add-documents + source: prod-firestore + description: Add documents with authentication + authRequired: + - google-auth-service + - api-key-service `, want: server.ToolConfigs{ "secure_add_docs": firestoreadddocuments.Config{ Name: "secure_add_docs", - Kind: "firestore-add-documents", + Type: "firestore-add-documents", Source: "prod-firestore", Description: "Add documents with authentication", AuthRequired: []string{"google-auth-service", "api-key-service"}, @@ -78,15 +77,11 @@ func TestParseFromYamlFirestoreAddDocuments(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -99,58 +94,57 @@ func TestParseFromYamlMultipleTools(t *testing.T) { t.Fatalf("unexpected error: %s", err) } in := ` - tools: - add_user_docs: - kind: firestore-add-documents - source: users-firestore - description: Add user documents - authRequired: - - user-auth - add_product_docs: - kind: firestore-add-documents - source: products-firestore - description: Add product documents - add_order_docs: - kind: firestore-add-documents - source: orders-firestore - description: Add order documents - authRequired: - - user-auth - - admin-auth + kind: tools + name: add_user_docs + type: firestore-add-documents + source: users-firestore + description: Add user documents + authRequired: + - user-auth +--- + kind: tools + name: add_product_docs + type: firestore-add-documents + source: products-firestore + description: Add product documents +--- + kind: tools + name: add_order_docs + type: firestore-add-documents + source: orders-firestore + description: Add order documents + authRequired: + - user-auth + - admin-auth ` want := server.ToolConfigs{ "add_user_docs": firestoreadddocuments.Config{ Name: "add_user_docs", - Kind: "firestore-add-documents", + Type: "firestore-add-documents", Source: "users-firestore", Description: "Add user documents", AuthRequired: []string{"user-auth"}, }, "add_product_docs": firestoreadddocuments.Config{ Name: "add_product_docs", - Kind: "firestore-add-documents", + Type: "firestore-add-documents", Source: "products-firestore", Description: "Add product documents", AuthRequired: []string{}, }, "add_order_docs": firestoreadddocuments.Config{ Name: "add_order_docs", - Kind: "firestore-add-documents", + Type: "firestore-add-documents", Source: "orders-firestore", Description: "Add order documents", AuthRequired: []string{"user-auth", "admin-auth"}, }, } - - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err = yaml.UnmarshalContext(ctx, testutils.FormatYaml(in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(want, got.Tools); diff != "" { + if diff := cmp.Diff(want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } } diff --git a/internal/tools/firestore/firestoredeletedocuments/firestoredeletedocuments.go b/internal/tools/firestore/firestoredeletedocuments/firestoredeletedocuments.go index 98d89c3d7c..f0a3bd0c80 100644 --- a/internal/tools/firestore/firestoredeletedocuments/firestoredeletedocuments.go +++ b/internal/tools/firestore/firestoredeletedocuments/firestoredeletedocuments.go @@ -27,12 +27,12 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "firestore-delete-documents" +const resourceType string = "firestore-delete-documents" const documentPathsKey string = "documentPaths" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -51,7 +51,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -60,8 +60,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -95,7 +95,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/firestore/firestoredeletedocuments/firestoredeletedocuments_test.go b/internal/tools/firestore/firestoredeletedocuments/firestoredeletedocuments_test.go index 15cfce822c..fe02e2d6c2 100644 --- a/internal/tools/firestore/firestoredeletedocuments/firestoredeletedocuments_test.go +++ b/internal/tools/firestore/firestoredeletedocuments/firestoredeletedocuments_test.go @@ -17,7 +17,6 @@ package firestoredeletedocuments_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlFirestoreDeleteDocuments(t *testing.T) { { desc: "basic example", in: ` - tools: - delete_docs_tool: - kind: firestore-delete-documents - source: my-firestore-instance - description: Delete documents from Firestore by paths + kind: tools + name: delete_docs_tool + type: firestore-delete-documents + source: my-firestore-instance + description: Delete documents from Firestore by paths `, want: server.ToolConfigs{ "delete_docs_tool": firestoredeletedocuments.Config{ Name: "delete_docs_tool", - Kind: "firestore-delete-documents", + Type: "firestore-delete-documents", Source: "my-firestore-instance", Description: "Delete documents from Firestore by paths", AuthRequired: []string{}, @@ -56,19 +55,19 @@ func TestParseFromYamlFirestoreDeleteDocuments(t *testing.T) { { desc: "with auth requirements", in: ` - tools: - secure_delete_docs: - kind: firestore-delete-documents - source: prod-firestore - description: Delete documents with authentication - authRequired: - - google-auth-service - - api-key-service + kind: tools + name: secure_delete_docs + type: firestore-delete-documents + source: prod-firestore + description: Delete documents with authentication + authRequired: + - google-auth-service + - api-key-service `, want: server.ToolConfigs{ "secure_delete_docs": firestoredeletedocuments.Config{ Name: "secure_delete_docs", - Kind: "firestore-delete-documents", + Type: "firestore-delete-documents", Source: "prod-firestore", Description: "Delete documents with authentication", AuthRequired: []string{"google-auth-service", "api-key-service"}, @@ -78,15 +77,11 @@ func TestParseFromYamlFirestoreDeleteDocuments(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -99,58 +94,58 @@ func TestParseFromYamlMultipleTools(t *testing.T) { t.Fatalf("unexpected error: %s", err) } in := ` - tools: - delete_user_docs: - kind: firestore-delete-documents - source: users-firestore - description: Delete user documents - authRequired: - - user-auth - delete_product_docs: - kind: firestore-delete-documents - source: products-firestore - description: Delete product documents - delete_order_docs: - kind: firestore-delete-documents - source: orders-firestore - description: Delete order documents - authRequired: - - user-auth - - admin-auth + kind: tools + name: delete_user_docs + type: firestore-delete-documents + source: users-firestore + description: Delete user documents + authRequired: + - user-auth +--- + kind: tools + name: delete_product_docs + type: firestore-delete-documents + source: products-firestore + description: Delete product documents +--- + kind: tools + name: delete_order_docs + type: firestore-delete-documents + source: orders-firestore + description: Delete order documents + authRequired: + - user-auth + - admin-auth ` want := server.ToolConfigs{ "delete_user_docs": firestoredeletedocuments.Config{ Name: "delete_user_docs", - Kind: "firestore-delete-documents", + Type: "firestore-delete-documents", Source: "users-firestore", Description: "Delete user documents", AuthRequired: []string{"user-auth"}, }, "delete_product_docs": firestoredeletedocuments.Config{ Name: "delete_product_docs", - Kind: "firestore-delete-documents", + Type: "firestore-delete-documents", Source: "products-firestore", Description: "Delete product documents", AuthRequired: []string{}, }, "delete_order_docs": firestoredeletedocuments.Config{ Name: "delete_order_docs", - Kind: "firestore-delete-documents", + Type: "firestore-delete-documents", Source: "orders-firestore", Description: "Delete order documents", AuthRequired: []string{"user-auth", "admin-auth"}, }, } - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err = yaml.UnmarshalContext(ctx, testutils.FormatYaml(in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(want, got.Tools); diff != "" { + if diff := cmp.Diff(want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } } diff --git a/internal/tools/firestore/firestoregetdocuments/firestoregetdocuments.go b/internal/tools/firestore/firestoregetdocuments/firestoregetdocuments.go index 9cba741eb9..3d68c4170b 100644 --- a/internal/tools/firestore/firestoregetdocuments/firestoregetdocuments.go +++ b/internal/tools/firestore/firestoregetdocuments/firestoregetdocuments.go @@ -27,12 +27,12 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "firestore-get-documents" +const resourceType string = "firestore-get-documents" const documentPathsKey string = "documentPaths" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -51,7 +51,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -60,8 +60,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -95,7 +95,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/firestore/firestoregetdocuments/firestoregetdocuments_test.go b/internal/tools/firestore/firestoregetdocuments/firestoregetdocuments_test.go index 4cc6ab6245..5a44b9d687 100644 --- a/internal/tools/firestore/firestoregetdocuments/firestoregetdocuments_test.go +++ b/internal/tools/firestore/firestoregetdocuments/firestoregetdocuments_test.go @@ -17,7 +17,6 @@ package firestoregetdocuments_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlFirestoreGetDocuments(t *testing.T) { { desc: "basic example", in: ` - tools: - get_docs_tool: - kind: firestore-get-documents - source: my-firestore-instance - description: Retrieve documents from Firestore by paths + kind: tools + name: get_docs_tool + type: firestore-get-documents + source: my-firestore-instance + description: Retrieve documents from Firestore by paths `, want: server.ToolConfigs{ "get_docs_tool": firestoregetdocuments.Config{ Name: "get_docs_tool", - Kind: "firestore-get-documents", + Type: "firestore-get-documents", Source: "my-firestore-instance", Description: "Retrieve documents from Firestore by paths", AuthRequired: []string{}, @@ -56,19 +55,19 @@ func TestParseFromYamlFirestoreGetDocuments(t *testing.T) { { desc: "with auth requirements", in: ` - tools: - secure_get_docs: - kind: firestore-get-documents - source: prod-firestore - description: Get documents with authentication - authRequired: - - google-auth-service - - api-key-service + kind: tools + name: secure_get_docs + type: firestore-get-documents + source: prod-firestore + description: Get documents with authentication + authRequired: + - google-auth-service + - api-key-service `, want: server.ToolConfigs{ "secure_get_docs": firestoregetdocuments.Config{ Name: "secure_get_docs", - Kind: "firestore-get-documents", + Type: "firestore-get-documents", Source: "prod-firestore", Description: "Get documents with authentication", AuthRequired: []string{"google-auth-service", "api-key-service"}, @@ -78,15 +77,11 @@ func TestParseFromYamlFirestoreGetDocuments(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -99,58 +94,58 @@ func TestParseFromYamlMultipleTools(t *testing.T) { t.Fatalf("unexpected error: %s", err) } in := ` - tools: - get_user_docs: - kind: firestore-get-documents - source: users-firestore - description: Get user documents - authRequired: - - user-auth - get_product_docs: - kind: firestore-get-documents - source: products-firestore - description: Get product documents - get_order_docs: - kind: firestore-get-documents - source: orders-firestore - description: Get order documents - authRequired: - - user-auth - - admin-auth + kind: tools + name: get_user_docs + type: firestore-get-documents + source: users-firestore + description: Get user documents + authRequired: + - user-auth +--- + kind: tools + name: get_product_docs + type: firestore-get-documents + source: products-firestore + description: Get product documents +--- + kind: tools + name: get_order_docs + type: firestore-get-documents + source: orders-firestore + description: Get order documents + authRequired: + - user-auth + - admin-auth ` want := server.ToolConfigs{ "get_user_docs": firestoregetdocuments.Config{ Name: "get_user_docs", - Kind: "firestore-get-documents", + Type: "firestore-get-documents", Source: "users-firestore", Description: "Get user documents", AuthRequired: []string{"user-auth"}, }, "get_product_docs": firestoregetdocuments.Config{ Name: "get_product_docs", - Kind: "firestore-get-documents", + Type: "firestore-get-documents", Source: "products-firestore", Description: "Get product documents", AuthRequired: []string{}, }, "get_order_docs": firestoregetdocuments.Config{ Name: "get_order_docs", - Kind: "firestore-get-documents", + Type: "firestore-get-documents", Source: "orders-firestore", Description: "Get order documents", AuthRequired: []string{"user-auth", "admin-auth"}, }, } - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err = yaml.UnmarshalContext(ctx, testutils.FormatYaml(in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(want, got.Tools); diff != "" { + if diff := cmp.Diff(want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } } diff --git a/internal/tools/firestore/firestoregetrules/firestoregetrules.go b/internal/tools/firestore/firestoregetrules/firestoregetrules.go index cac04c49a3..bfa8b08ba2 100644 --- a/internal/tools/firestore/firestoregetrules/firestoregetrules.go +++ b/internal/tools/firestore/firestoregetrules/firestoregetrules.go @@ -26,11 +26,11 @@ import ( "google.golang.org/api/firebaserules/v1" ) -const kind string = "firestore-get-rules" +const resourceType string = "firestore-get-rules" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -58,8 +58,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -93,7 +93,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/firestore/firestoregetrules/firestoregetrules_test.go b/internal/tools/firestore/firestoregetrules/firestoregetrules_test.go index 405eb1377a..c4a7dfb6bb 100644 --- a/internal/tools/firestore/firestoregetrules/firestoregetrules_test.go +++ b/internal/tools/firestore/firestoregetrules/firestoregetrules_test.go @@ -17,7 +17,6 @@ package firestoregetrules_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlFirestoreGetRules(t *testing.T) { { desc: "basic example", in: ` - tools: - get_rules_tool: - kind: firestore-get-rules - source: my-firestore-instance - description: Retrieves the active Firestore security rules for the current project + kind: tools + name: get_rules_tool + type: firestore-get-rules + source: my-firestore-instance + description: Retrieves the active Firestore security rules for the current project `, want: server.ToolConfigs{ "get_rules_tool": firestoregetrules.Config{ Name: "get_rules_tool", - Kind: "firestore-get-rules", + Type: "firestore-get-rules", Source: "my-firestore-instance", Description: "Retrieves the active Firestore security rules for the current project", AuthRequired: []string{}, @@ -56,19 +55,19 @@ func TestParseFromYamlFirestoreGetRules(t *testing.T) { { desc: "with auth requirements", in: ` - tools: - secure_get_rules: - kind: firestore-get-rules - source: prod-firestore - description: Get Firestore security rules with authentication - authRequired: - - google-auth-service - - admin-service + kind: tools + name: secure_get_rules + type: firestore-get-rules + source: prod-firestore + description: Get Firestore security rules with authentication + authRequired: + - google-auth-service + - admin-service `, want: server.ToolConfigs{ "secure_get_rules": firestoregetrules.Config{ Name: "secure_get_rules", - Kind: "firestore-get-rules", + Type: "firestore-get-rules", Source: "prod-firestore", Description: "Get Firestore security rules with authentication", AuthRequired: []string{"google-auth-service", "admin-service"}, @@ -78,15 +77,11 @@ func TestParseFromYamlFirestoreGetRules(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -99,58 +94,58 @@ func TestParseFromYamlMultipleTools(t *testing.T) { t.Fatalf("unexpected error: %s", err) } in := ` - tools: - get_dev_rules: - kind: firestore-get-rules - source: dev-firestore - description: Get development Firestore rules - authRequired: - - dev-auth - get_staging_rules: - kind: firestore-get-rules - source: staging-firestore - description: Get staging Firestore rules - get_prod_rules: - kind: firestore-get-rules - source: prod-firestore - description: Get production Firestore rules - authRequired: - - prod-auth - - admin-auth + kind: tools + name: get_dev_rules + type: firestore-get-rules + source: dev-firestore + description: Get development Firestore rules + authRequired: + - dev-auth +--- + kind: tools + name: get_staging_rules + type: firestore-get-rules + source: staging-firestore + description: Get staging Firestore rules +--- + kind: tools + name: get_prod_rules + type: firestore-get-rules + source: prod-firestore + description: Get production Firestore rules + authRequired: + - prod-auth + - admin-auth ` want := server.ToolConfigs{ "get_dev_rules": firestoregetrules.Config{ Name: "get_dev_rules", - Kind: "firestore-get-rules", + Type: "firestore-get-rules", Source: "dev-firestore", Description: "Get development Firestore rules", AuthRequired: []string{"dev-auth"}, }, "get_staging_rules": firestoregetrules.Config{ Name: "get_staging_rules", - Kind: "firestore-get-rules", + Type: "firestore-get-rules", Source: "staging-firestore", Description: "Get staging Firestore rules", AuthRequired: []string{}, }, "get_prod_rules": firestoregetrules.Config{ Name: "get_prod_rules", - Kind: "firestore-get-rules", + Type: "firestore-get-rules", Source: "prod-firestore", Description: "Get production Firestore rules", AuthRequired: []string{"prod-auth", "admin-auth"}, }, } - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err = yaml.UnmarshalContext(ctx, testutils.FormatYaml(in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(want, got.Tools); diff != "" { + if diff := cmp.Diff(want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } } diff --git a/internal/tools/firestore/firestorelistcollections/firestorelistcollections.go b/internal/tools/firestore/firestorelistcollections/firestorelistcollections.go index 4acb680a26..ff6927594a 100644 --- a/internal/tools/firestore/firestorelistcollections/firestorelistcollections.go +++ b/internal/tools/firestore/firestorelistcollections/firestorelistcollections.go @@ -27,12 +27,12 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "firestore-list-collections" +const resourceType string = "firestore-list-collections" const parentPathKey string = "parentPath" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -51,7 +51,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -60,8 +60,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -96,7 +96,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/firestore/firestorelistcollections/firestorelistcollections_test.go b/internal/tools/firestore/firestorelistcollections/firestorelistcollections_test.go index d3b08ae649..1b8b374a8e 100644 --- a/internal/tools/firestore/firestorelistcollections/firestorelistcollections_test.go +++ b/internal/tools/firestore/firestorelistcollections/firestorelistcollections_test.go @@ -17,7 +17,6 @@ package firestorelistcollections_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlFirestoreListCollections(t *testing.T) { { desc: "basic example", in: ` - tools: - list_collections_tool: - kind: firestore-list-collections - source: my-firestore-instance - description: List collections in Firestore + kind: tools + name: list_collections_tool + type: firestore-list-collections + source: my-firestore-instance + description: List collections in Firestore `, want: server.ToolConfigs{ "list_collections_tool": firestorelistcollections.Config{ Name: "list_collections_tool", - Kind: "firestore-list-collections", + Type: "firestore-list-collections", Source: "my-firestore-instance", Description: "List collections in Firestore", AuthRequired: []string{}, @@ -56,19 +55,19 @@ func TestParseFromYamlFirestoreListCollections(t *testing.T) { { desc: "with auth requirements", in: ` - tools: - secure_list_collections: - kind: firestore-list-collections - source: prod-firestore - description: List collections with authentication - authRequired: - - google-auth-service - - api-key-service + kind: tools + name: secure_list_collections + type: firestore-list-collections + source: prod-firestore + description: List collections with authentication + authRequired: + - google-auth-service + - api-key-service `, want: server.ToolConfigs{ "secure_list_collections": firestorelistcollections.Config{ Name: "secure_list_collections", - Kind: "firestore-list-collections", + Type: "firestore-list-collections", Source: "prod-firestore", Description: "List collections with authentication", AuthRequired: []string{"google-auth-service", "api-key-service"}, @@ -78,15 +77,11 @@ func TestParseFromYamlFirestoreListCollections(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -99,58 +94,58 @@ func TestParseFromYamlMultipleTools(t *testing.T) { t.Fatalf("unexpected error: %s", err) } in := ` - tools: - list_user_collections: - kind: firestore-list-collections - source: users-firestore - description: List user-related collections - authRequired: - - user-auth - list_product_collections: - kind: firestore-list-collections - source: products-firestore - description: List product-related collections - list_admin_collections: - kind: firestore-list-collections - source: admin-firestore - description: List administrative collections - authRequired: - - user-auth - - admin-auth + kind: tools + name: list_user_collections + type: firestore-list-collections + source: users-firestore + description: List user-related collections + authRequired: + - user-auth +--- + kind: tools + name: list_product_collections + type: firestore-list-collections + source: products-firestore + description: List product-related collections +--- + kind: tools + name: list_admin_collections + type: firestore-list-collections + source: admin-firestore + description: List administrative collections + authRequired: + - user-auth + - admin-auth ` want := server.ToolConfigs{ "list_user_collections": firestorelistcollections.Config{ Name: "list_user_collections", - Kind: "firestore-list-collections", + Type: "firestore-list-collections", Source: "users-firestore", Description: "List user-related collections", AuthRequired: []string{"user-auth"}, }, "list_product_collections": firestorelistcollections.Config{ Name: "list_product_collections", - Kind: "firestore-list-collections", + Type: "firestore-list-collections", Source: "products-firestore", Description: "List product-related collections", AuthRequired: []string{}, }, "list_admin_collections": firestorelistcollections.Config{ Name: "list_admin_collections", - Kind: "firestore-list-collections", + Type: "firestore-list-collections", Source: "admin-firestore", Description: "List administrative collections", AuthRequired: []string{"user-auth", "admin-auth"}, }, } - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err = yaml.UnmarshalContext(ctx, testutils.FormatYaml(in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(want, got.Tools); diff != "" { + if diff := cmp.Diff(want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } } diff --git a/internal/tools/firestore/firestorequery/firestorequery.go b/internal/tools/firestore/firestorequery/firestorequery.go index 3752f781ea..2868dd87f1 100644 --- a/internal/tools/firestore/firestorequery/firestorequery.go +++ b/internal/tools/firestore/firestorequery/firestorequery.go @@ -32,13 +32,13 @@ import ( // Constants for tool configuration const ( - kind = "firestore-query" + resourceType = "firestore-query" defaultLimit = 100 ) func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -60,7 +60,7 @@ type compatibleSource interface { // Config represents the configuration for the Firestore query tool type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -80,9 +80,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of tool configuration -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of tool configuration +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize creates a new Tool instance from the configuration @@ -159,7 +159,7 @@ var validOperators = map[string]bool{ // Invoke executes the Firestore query based on the provided parameters func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/firestore/firestorequery/firestorequery_test.go b/internal/tools/firestore/firestorequery/firestorequery_test.go index 178bbe8071..380b1b26d1 100644 --- a/internal/tools/firestore/firestorequery/firestorequery_test.go +++ b/internal/tools/firestore/firestorequery/firestorequery_test.go @@ -17,7 +17,6 @@ package firestorequery_test import ( "testing" - 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" @@ -38,22 +37,22 @@ func TestParseFromYamlFirestoreQuery(t *testing.T) { { desc: "basic example with parameterized collection path", in: ` - tools: - query_users_tool: - kind: firestore-query - source: my-firestore-instance - description: Query users collection with parameterized path - collectionPath: "users/{{.userId}}/documents" - parameters: - - name: userId - type: string - description: The user ID to query documents for - required: true + kind: tools + name: query_users_tool + type: firestore-query + source: my-firestore-instance + description: Query users collection with parameterized path + collectionPath: "users/{{.userId}}/documents" + parameters: + - name: userId + type: string + description: The user ID to query documents for + required: true `, want: server.ToolConfigs{ "query_users_tool": firestorequery.Config{ Name: "query_users_tool", - Kind: "firestore-query", + Type: "firestore-query", Source: "my-firestore-instance", Description: "Query users collection with parameterized path", CollectionPath: "users/{{.userId}}/documents", @@ -67,41 +66,41 @@ func TestParseFromYamlFirestoreQuery(t *testing.T) { { desc: "with parameterized filters", in: ` - tools: - query_products_tool: - kind: firestore-query - source: prod-firestore - description: Query products with dynamic filters - collectionPath: "products" - filters: | - { - "and": [ - {"field": "category", "op": "==", "value": {"stringValue": "{{.category}}"}}, - {"field": "price", "op": "<=", "value": {"doubleValue": {{.maxPrice}}}} - ] - } - parameters: - - name: category - type: string - description: Product category to filter by - required: true - - name: maxPrice - type: float - description: Maximum price for products - required: true + kind: tools + name: query_products_tool + type: firestore-query + source: prod-firestore + description: Query products with dynamic filters + collectionPath: "products" + filters: | + { + "and": [ + {"field": "category", "op": "==", "value": {"stringValue": "{{.category}}"}}, + {"field": "price", "op": "<=", "value": {"doubleValue": {{.maxPrice}}}} + ] + } + parameters: + - name: category + type: string + description: Product category to filter by + required: true + - name: maxPrice + type: float + description: Maximum price for products + required: true `, want: server.ToolConfigs{ "query_products_tool": firestorequery.Config{ Name: "query_products_tool", - Kind: "firestore-query", + Type: "firestore-query", Source: "prod-firestore", Description: "Query products with dynamic filters", CollectionPath: "products", Filters: `{ - "and": [ - {"field": "category", "op": "==", "value": {"stringValue": "{{.category}}"}}, - {"field": "price", "op": "<=", "value": {"doubleValue": {{.maxPrice}}}} - ] + "and": [ + {"field": "category", "op": "==", "value": {"stringValue": "{{.category}}"}}, + {"field": "price", "op": "<=", "value": {"doubleValue": {{.maxPrice}}}} + ] } `, AuthRequired: []string{}, @@ -115,30 +114,30 @@ func TestParseFromYamlFirestoreQuery(t *testing.T) { { desc: "with select fields and orderBy", in: ` - tools: - query_orders_tool: - kind: firestore-query - source: orders-firestore - description: Query orders with field selection - collectionPath: "orders" - select: - - orderId - - customerName - - totalAmount - orderBy: - field: "{{.sortField}}" - direction: "DESCENDING" - limit: 50 - parameters: - - name: sortField - type: string - description: Field to sort by - required: true + kind: tools + name: query_orders_tool + type: firestore-query + source: orders-firestore + description: Query orders with field selection + collectionPath: "orders" + select: + - orderId + - customerName + - totalAmount + orderBy: + field: "{{.sortField}}" + direction: "DESCENDING" + limit: 50 + parameters: + - name: sortField + type: string + description: Field to sort by + required: true `, want: server.ToolConfigs{ "query_orders_tool": firestorequery.Config{ Name: "query_orders_tool", - Kind: "firestore-query", + Type: "firestore-query", Source: "orders-firestore", Description: "Query orders with field selection", CollectionPath: "orders", @@ -158,59 +157,59 @@ func TestParseFromYamlFirestoreQuery(t *testing.T) { { desc: "with auth requirements and complex filters", in: ` - tools: - secure_query_tool: - kind: firestore-query - source: secure-firestore - description: Query with authentication and complex filters - collectionPath: "{{.collection}}" - filters: | - { - "or": [ - { - "and": [ - {"field": "status", "op": "==", "value": {"stringValue": "{{.status}}"}}, - {"field": "priority", "op": ">=", "value": {"integerValue": "{{.minPriority}}"}} - ] - }, - {"field": "urgent", "op": "==", "value": {"booleanValue": true}} - ] - } - analyzeQuery: true - authRequired: - - google-auth-service - - api-key-service - parameters: - - name: collection - type: string - description: Collection name to query - required: true - - name: status - type: string - description: Status to filter by - required: true - - name: minPriority - type: integer - description: Minimum priority level - default: 1 + kind: tools + name: secure_query_tool + type: firestore-query + source: secure-firestore + description: Query with authentication and complex filters + collectionPath: "{{.collection}}" + filters: | + { + "or": [ + { + "and": [ + {"field": "status", "op": "==", "value": {"stringValue": "{{.status}}"}}, + {"field": "priority", "op": ">=", "value": {"integerValue": "{{.minPriority}}"}} + ] + }, + {"field": "urgent", "op": "==", "value": {"booleanValue": true}} + ] + } + analyzeQuery: true + authRequired: + - google-auth-service + - api-key-service + parameters: + - name: collection + type: string + description: Collection name to query + required: true + - name: status + type: string + description: Status to filter by + required: true + - name: minPriority + type: integer + description: Minimum priority level + default: 1 `, want: server.ToolConfigs{ "secure_query_tool": firestorequery.Config{ Name: "secure_query_tool", - Kind: "firestore-query", + Type: "firestore-query", Source: "secure-firestore", Description: "Query with authentication and complex filters", CollectionPath: "{{.collection}}", Filters: `{ - "or": [ - { - "and": [ - {"field": "status", "op": "==", "value": {"stringValue": "{{.status}}"}}, - {"field": "priority", "op": ">=", "value": {"integerValue": "{{.minPriority}}"}} - ] - }, - {"field": "urgent", "op": "==", "value": {"booleanValue": true}} - ] + "or": [ + { + "and": [ + {"field": "status", "op": "==", "value": {"stringValue": "{{.status}}"}}, + {"field": "priority", "op": ">=", "value": {"integerValue": "{{.minPriority}}"}} + ] + }, + {"field": "urgent", "op": "==", "value": {"booleanValue": true}} + ] } `, AnalyzeQuery: true, @@ -226,71 +225,71 @@ func TestParseFromYamlFirestoreQuery(t *testing.T) { { desc: "with Firestore native JSON value types and template parameters", in: ` - tools: - query_with_typed_values: - kind: firestore-query - source: typed-firestore - description: Query with Firestore native JSON value types - collectionPath: "countries" - filters: | - { - "or": [ - {"field": "continent", "op": "==", "value": {"stringValue": "{{.continent}}"}}, - { - "and": [ - {"field": "area", "op": ">", "value": {"integerValue": "2000000"}}, - {"field": "area", "op": "<", "value": {"integerValue": "3000000"}}, - {"field": "population", "op": ">=", "value": {"integerValue": "{{.minPopulation}}"}}, - {"field": "gdp", "op": ">", "value": {"doubleValue": {{.minGdp}}}}, - {"field": "isActive", "op": "==", "value": {"booleanValue": {{.isActive}}}}, - {"field": "lastUpdated", "op": ">=", "value": {"timestampValue": "{{.startDate}}"}} - ] - } - ] - } - parameters: - - name: continent - type: string - description: Continent to filter by - required: true - - name: minPopulation - type: string - description: Minimum population as string - required: true - - name: minGdp - type: float - description: Minimum GDP value - required: true - - name: isActive - type: boolean - description: Filter by active status - required: true - - name: startDate - type: string - description: Start date in RFC3339 format - required: true + kind: tools + name: query_with_typed_values + type: firestore-query + source: typed-firestore + description: Query with Firestore native JSON value types + collectionPath: "countries" + filters: | + { + "or": [ + {"field": "continent", "op": "==", "value": {"stringValue": "{{.continent}}"}}, + { + "and": [ + {"field": "area", "op": ">", "value": {"integerValue": "2000000"}}, + {"field": "area", "op": "<", "value": {"integerValue": "3000000"}}, + {"field": "population", "op": ">=", "value": {"integerValue": "{{.minPopulation}}"}}, + {"field": "gdp", "op": ">", "value": {"doubleValue": {{.minGdp}}}}, + {"field": "isActive", "op": "==", "value": {"booleanValue": {{.isActive}}}}, + {"field": "lastUpdated", "op": ">=", "value": {"timestampValue": "{{.startDate}}"}} + ] + } + ] + } + parameters: + - name: continent + type: string + description: Continent to filter by + required: true + - name: minPopulation + type: string + description: Minimum population as string + required: true + - name: minGdp + type: float + description: Minimum GDP value + required: true + - name: isActive + type: boolean + description: Filter by active status + required: true + - name: startDate + type: string + description: Start date in RFC3339 format + required: true `, want: server.ToolConfigs{ "query_with_typed_values": firestorequery.Config{ Name: "query_with_typed_values", - Kind: "firestore-query", + Type: "firestore-query", Source: "typed-firestore", Description: "Query with Firestore native JSON value types", CollectionPath: "countries", Filters: `{ - "or": [ - {"field": "continent", "op": "==", "value": {"stringValue": "{{.continent}}"}}, - { - "and": [ - {"field": "area", "op": ">", "value": {"integerValue": "2000000"}}, - {"field": "area", "op": "<", "value": {"integerValue": "3000000"}}, - {"field": "population", "op": ">=", "value": {"integerValue": "{{.minPopulation}}"}}, - {"field": "gdp", "op": ">", "value": {"doubleValue": {{.minGdp}}}}, - {"field": "isActive", "op": "==", "value": {"booleanValue": {{.isActive}}}}, - {"field": "lastUpdated", "op": ">=", "value": {"timestampValue": "{{.startDate}}"}} - ] - } - ] + "or": [ + {"field": "continent", "op": "==", "value": {"stringValue": "{{.continent}}"}}, + { + "and": [ + {"field": "area", "op": ">", "value": {"integerValue": "2000000"}}, + {"field": "area", "op": "<", "value": {"integerValue": "3000000"}}, + {"field": "population", "op": ">=", "value": {"integerValue": "{{.minPopulation}}"}}, + {"field": "gdp", "op": ">", "value": {"doubleValue": {{.minGdp}}}}, + {"field": "isActive", "op": "==", "value": {"booleanValue": {{.isActive}}}}, + {"field": "lastUpdated", "op": ">=", "value": {"timestampValue": "{{.startDate}}"}} + ] + } + ] } `, AuthRequired: []string{}, @@ -307,15 +306,12 @@ func TestParseFromYamlFirestoreQuery(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -328,94 +324,98 @@ func TestParseFromYamlMultipleQueryTools(t *testing.T) { t.Fatalf("unexpected error: %s", err) } in := ` - tools: - query_user_posts: - kind: firestore-query - source: social-firestore - description: Query user posts with filtering - collectionPath: "users/{{.userId}}/posts" - filters: | - { - "and": [ - {"field": "visibility", "op": "==", "value": {"stringValue": "{{.visibility}}"}}, - {"field": "createdAt", "op": ">=", "value": {"timestampValue": "{{.startDate}}"}} - ] - } - select: - - title - - content - - likes - orderBy: - field: createdAt - direction: "{{.sortOrder}}" - limit: 20 - parameters: - - name: userId - type: string - description: User ID whose posts to query - required: true - - name: visibility - type: string - description: Post visibility (public, private, friends) - required: true - - name: startDate - type: string - description: Start date for posts - required: true - - name: sortOrder - type: string - description: Sort order (ASCENDING or DESCENDING) - default: "DESCENDING" - query_inventory: - kind: firestore-query - source: inventory-firestore - description: Query inventory items - collectionPath: "warehouses/{{.warehouseId}}/inventory" - filters: | - { - "field": "quantity", "op": "<", "value": {"integerValue": "{{.threshold}}"}} - parameters: - - name: warehouseId - type: string - description: Warehouse ID to check inventory - required: true - - name: threshold - type: integer - description: Quantity threshold for low stock - required: true - query_transactions: - kind: firestore-query - source: finance-firestore - description: Query financial transactions - collectionPath: "accounts/{{.accountId}}/transactions" - filters: | - { - "or": [ - {"field": "type", "op": "==", "value": {"stringValue": "{{.transactionType}}"}}, - {"field": "amount", "op": ">", "value": {"doubleValue": {{.minAmount}}}} - ] - } - analyzeQuery: true - authRequired: - - finance-auth - parameters: - - name: accountId - type: string - description: Account ID for transactions - required: true - - name: transactionType - type: string - description: Type of transaction - default: "all" - - name: minAmount - type: float - description: Minimum transaction amount - default: 0 + kind: tools + name: query_user_posts + type: firestore-query + source: social-firestore + description: Query user posts with filtering + collectionPath: "users/{{.userId}}/posts" + filters: | + { + "and": [ + {"field": "visibility", "op": "==", "value": {"stringValue": "{{.visibility}}"}}, + {"field": "createdAt", "op": ">=", "value": {"timestampValue": "{{.startDate}}"}} + ] + } + select: + - title + - content + - likes + orderBy: + field: createdAt + direction: "{{.sortOrder}}" + limit: 20 + parameters: + - name: userId + type: string + description: User ID whose posts to query + required: true + - name: visibility + type: string + description: Post visibility (public, private, friends) + required: true + - name: startDate + type: string + description: Start date for posts + required: true + - name: sortOrder + type: string + description: Sort order (ASCENDING or DESCENDING) + default: "DESCENDING" +--- + kind: tools + name: query_inventory + type: firestore-query + source: inventory-firestore + description: Query inventory items + collectionPath: "warehouses/{{.warehouseId}}/inventory" + filters: | + { + "field": "quantity", "op": "<", "value": {"integerValue": "{{.threshold}}"}} + parameters: + - name: warehouseId + type: string + description: Warehouse ID to check inventory + required: true + - name: threshold + type: integer + description: Quantity threshold for low stock + required: true +--- + kind: tools + name: query_transactions + type: firestore-query + source: finance-firestore + description: Query financial transactions + collectionPath: "accounts/{{.accountId}}/transactions" + filters: | + { + "or": [ + {"field": "type", "op": "==", "value": {"stringValue": "{{.transactionType}}"}}, + {"field": "amount", "op": ">", "value": {"doubleValue": {{.minAmount}}}} + ] + } + analyzeQuery: true + authRequired: + - finance-auth + parameters: + - name: accountId + type: string + description: Account ID for transactions + required: true + - name: transactionType + type: string + description: Type of transaction + default: "all" + - name: minAmount + type: float + description: Minimum transaction amount + default: 0 ` want := server.ToolConfigs{ "query_user_posts": firestorequery.Config{ Name: "query_user_posts", - Kind: "firestore-query", + Type: "firestore-query", Source: "social-firestore", Description: "Query user posts with filtering", CollectionPath: "users/{{.userId}}/posts", @@ -442,7 +442,7 @@ func TestParseFromYamlMultipleQueryTools(t *testing.T) { }, "query_inventory": firestorequery.Config{ Name: "query_inventory", - Kind: "firestore-query", + Type: "firestore-query", Source: "inventory-firestore", Description: "Query inventory items", CollectionPath: "warehouses/{{.warehouseId}}/inventory", @@ -457,7 +457,7 @@ func TestParseFromYamlMultipleQueryTools(t *testing.T) { }, "query_transactions": firestorequery.Config{ Name: "query_transactions", - Kind: "firestore-query", + Type: "firestore-query", Source: "finance-firestore", Description: "Query financial transactions", CollectionPath: "accounts/{{.accountId}}/transactions", @@ -478,15 +478,11 @@ func TestParseFromYamlMultipleQueryTools(t *testing.T) { }, } - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err = yaml.UnmarshalContext(ctx, testutils.FormatYaml(in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(want, got.Tools); diff != "" { + if diff := cmp.Diff(want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } } diff --git a/internal/tools/firestore/firestorequerycollection/firestorequerycollection.go b/internal/tools/firestore/firestorequerycollection/firestorequerycollection.go index b162854729..2a9867b1e7 100644 --- a/internal/tools/firestore/firestorequerycollection/firestorequerycollection.go +++ b/internal/tools/firestore/firestorequerycollection/firestorequerycollection.go @@ -31,7 +31,7 @@ import ( // Constants for tool configuration const ( - kind = "firestore-query-collection" + resourceType = "firestore-query-collection" defaultLimit = 100 defaultAnalyze = false maxFilterLength = 100 // Maximum filters to prevent abuse @@ -73,8 +73,8 @@ const ( ) func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -96,7 +96,7 @@ type compatibleSource interface { // Config represents the configuration for the Firestore query collection tool type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -105,9 +105,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of tool configuration -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of tool configuration +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize creates a new Tool instance from the configuration @@ -231,7 +231,7 @@ func (o *OrderByConfig) GetDirection() firestoreapi.Direction { // Invoke executes the Firestore query based on the provided parameters func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/firestore/firestorequerycollection/firestorequerycollection_test.go b/internal/tools/firestore/firestorequerycollection/firestorequerycollection_test.go index 355ce8e188..450ad18016 100644 --- a/internal/tools/firestore/firestorequerycollection/firestorequerycollection_test.go +++ b/internal/tools/firestore/firestorequerycollection/firestorequerycollection_test.go @@ -17,7 +17,6 @@ package firestorequerycollection_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlFirestoreQueryCollection(t *testing.T) { { desc: "basic example", in: ` - tools: - query_users_tool: - kind: firestore-query-collection - source: my-firestore-instance - description: Query users collection with filters and ordering + kind: tools + name: query_users_tool + type: firestore-query-collection + source: my-firestore-instance + description: Query users collection with filters and ordering `, want: server.ToolConfigs{ "query_users_tool": firestorequerycollection.Config{ Name: "query_users_tool", - Kind: "firestore-query-collection", + Type: "firestore-query-collection", Source: "my-firestore-instance", Description: "Query users collection with filters and ordering", AuthRequired: []string{}, @@ -56,19 +55,19 @@ func TestParseFromYamlFirestoreQueryCollection(t *testing.T) { { desc: "with auth requirements", in: ` - tools: - secure_query_tool: - kind: firestore-query-collection - source: prod-firestore - description: Query collections with authentication - authRequired: - - google-auth-service - - api-key-service + kind: tools + name: secure_query_tool + type: firestore-query-collection + source: prod-firestore + description: Query collections with authentication + authRequired: + - google-auth-service + - api-key-service `, want: server.ToolConfigs{ "secure_query_tool": firestorequerycollection.Config{ Name: "secure_query_tool", - Kind: "firestore-query-collection", + Type: "firestore-query-collection", Source: "prod-firestore", Description: "Query collections with authentication", AuthRequired: []string{"google-auth-service", "api-key-service"}, @@ -78,15 +77,12 @@ func TestParseFromYamlFirestoreQueryCollection(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -99,58 +95,58 @@ func TestParseFromYamlMultipleTools(t *testing.T) { t.Fatalf("unexpected error: %s", err) } in := ` - tools: - query_users: - kind: firestore-query-collection - source: users-firestore - description: Query user documents with filtering - authRequired: - - user-auth - query_products: - kind: firestore-query-collection - source: products-firestore - description: Query product catalog - query_orders: - kind: firestore-query-collection - source: orders-firestore - description: Query customer orders with complex filters - authRequired: - - user-auth - - admin-auth + kind: tools + name: query_users + type: firestore-query-collection + source: users-firestore + description: Query user documents with filtering + authRequired: + - user-auth +--- + kind: tools + name: query_products + type: firestore-query-collection + source: products-firestore + description: Query product catalog +--- + kind: tools + name: query_orders + type: firestore-query-collection + source: orders-firestore + description: Query customer orders with complex filters + authRequired: + - user-auth + - admin-auth ` want := server.ToolConfigs{ "query_users": firestorequerycollection.Config{ Name: "query_users", - Kind: "firestore-query-collection", + Type: "firestore-query-collection", Source: "users-firestore", Description: "Query user documents with filtering", AuthRequired: []string{"user-auth"}, }, "query_products": firestorequerycollection.Config{ Name: "query_products", - Kind: "firestore-query-collection", + Type: "firestore-query-collection", Source: "products-firestore", Description: "Query product catalog", AuthRequired: []string{}, }, "query_orders": firestorequerycollection.Config{ Name: "query_orders", - Kind: "firestore-query-collection", + Type: "firestore-query-collection", Source: "orders-firestore", Description: "Query customer orders with complex filters", AuthRequired: []string{"user-auth", "admin-auth"}, }, } - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err = yaml.UnmarshalContext(ctx, testutils.FormatYaml(in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(want, got.Tools); diff != "" { + if diff := cmp.Diff(want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } } diff --git a/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument.go b/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument.go index b93b117bba..76e1a7efcf 100644 --- a/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument.go +++ b/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument.go @@ -28,15 +28,15 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "firestore-update-document" +const resourceType string = "firestore-update-document" const documentPathKey string = "documentPath" const documentDataKey string = "documentData" const updateMaskKey string = "updateMask" const returnDocumentDataKey string = "returnData" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -55,7 +55,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -64,8 +64,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -139,7 +139,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument_test.go b/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument_test.go index 3311aeb86e..73d3b0e803 100644 --- a/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument_test.go +++ b/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument_test.go @@ -19,10 +19,11 @@ import ( "strings" "testing" - 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/sources" firestoreds "github.com/googleapis/genai-toolbox/internal/sources/firestore" + "github.com/googleapis/genai-toolbox/internal/testutils" "github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/util/parameters" ) @@ -31,59 +32,65 @@ func TestNewConfig(t *testing.T) { tests := []struct { name string yaml string - want Config + want server.ToolConfigs wantErr bool }{ { name: "valid config", yaml: ` -name: test-update-document -kind: firestore-update-document -source: test-firestore -description: Update a document in Firestore -authRequired: - - google-oauth -`, - want: Config{ - Name: "test-update-document", - Kind: "firestore-update-document", - Source: "test-firestore", - Description: "Update a document in Firestore", - AuthRequired: []string{"google-oauth"}, + kind: tools + name: test-update-document + type: firestore-update-document + source: test-firestore + description: Update a document in Firestore + authRequired: + - google-oauth + `, + want: server.ToolConfigs{ + "test-update-document": Config{ + Name: "test-update-document", + Type: "firestore-update-document", + Source: "test-firestore", + Description: "Update a document in Firestore", + AuthRequired: []string{"google-oauth"}, + }, }, wantErr: false, }, { name: "minimal config", yaml: ` -name: test-update-document -kind: firestore-update-document -source: test-firestore -description: Update a document -`, - want: Config{ - Name: "test-update-document", - Kind: "firestore-update-document", - Source: "test-firestore", - Description: "Update a document", + kind: tools + name: test-update-document + type: firestore-update-document + source: test-firestore + description: Update a document + `, + want: server.ToolConfigs{ + "test-update-document": Config{ + Name: "test-update-document", + Type: "firestore-update-document", + Source: "test-firestore", + Description: "Update a document", + AuthRequired: []string{}, + }, }, wantErr: false, }, { name: "invalid yaml", yaml: ` -name: test-update-document -kind: [invalid -`, + kind: tools + name: test-update-document + type: [invalid + `, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - decoder := yaml.NewDecoder(strings.NewReader(tt.yaml)) - got, err := newConfig(context.Background(), "test-update-document", decoder) - + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tt.yaml)) if tt.wantErr { if err == nil { t.Fatalf("expected error but got none") @@ -102,12 +109,12 @@ kind: [invalid } } -func TestConfig_ToolConfigKind(t *testing.T) { +func TestConfig_ToolConfigType(t *testing.T) { cfg := Config{} - got := cfg.ToolConfigKind() + got := cfg.ToolConfigType() want := "firestore-update-document" if got != want { - t.Fatalf("ToolConfigKind() = %v, want %v", got, want) + t.Fatalf("ToolConfigType() = %v, want %v", got, want) } } @@ -123,7 +130,7 @@ func TestConfig_Initialize(t *testing.T) { name: "valid initialization", config: Config{ Name: "test-update-document", - Kind: "firestore-update-document", + Type: "firestore-update-document", Source: "test-firestore", Description: "Update a document", }, @@ -161,8 +168,8 @@ func TestConfig_Initialize(t *testing.T) { if actualTool.Name != tt.config.Name { t.Fatalf("tool.Name = %v, want %v", actualTool.Name, tt.config.Name) } - if actualTool.Kind != "firestore-update-document" { - t.Fatalf("tool.Kind = %v, want %v", actualTool.Kind, "firestore-update-document") + if actualTool.Type != "firestore-update-document" { + t.Fatalf("tool.Type = %v, want %v", actualTool.Type, "firestore-update-document") } if diff := cmp.Diff(tt.config.AuthRequired, actualTool.AuthRequired); diff != "" { t.Fatalf("AuthRequired mismatch (-want +got):\n%s", diff) diff --git a/internal/tools/firestore/firestorevalidaterules/firestorevalidaterules.go b/internal/tools/firestore/firestorevalidaterules/firestorevalidaterules.go index 6677b76bb4..e41be2da88 100644 --- a/internal/tools/firestore/firestorevalidaterules/firestorevalidaterules.go +++ b/internal/tools/firestore/firestorevalidaterules/firestorevalidaterules.go @@ -26,7 +26,7 @@ import ( "google.golang.org/api/firebaserules/v1" ) -const kind string = "firestore-validate-rules" +const resourceType string = "firestore-validate-rules" // Parameter keys const ( @@ -34,8 +34,8 @@ const ( ) func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -54,7 +54,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -63,8 +63,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -107,7 +107,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/firestore/firestorevalidaterules/firestorevalidaterules_test.go b/internal/tools/firestore/firestorevalidaterules/firestorevalidaterules_test.go index f63945d078..f454bb5e35 100644 --- a/internal/tools/firestore/firestorevalidaterules/firestorevalidaterules_test.go +++ b/internal/tools/firestore/firestorevalidaterules/firestorevalidaterules_test.go @@ -17,7 +17,6 @@ package firestorevalidaterules_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlFirestoreValidateRules(t *testing.T) { { desc: "basic example", in: ` - tools: - validate_rules_tool: - kind: firestore-validate-rules - source: my-firestore-instance - description: Validate Firestore security rules + kind: tools + name: validate_rules_tool + type: firestore-validate-rules + source: my-firestore-instance + description: Validate Firestore security rules `, want: server.ToolConfigs{ "validate_rules_tool": firestorevalidaterules.Config{ Name: "validate_rules_tool", - Kind: "firestore-validate-rules", + Type: "firestore-validate-rules", Source: "my-firestore-instance", Description: "Validate Firestore security rules", AuthRequired: []string{}, @@ -56,19 +55,19 @@ func TestParseFromYamlFirestoreValidateRules(t *testing.T) { { desc: "with auth requirements", in: ` - tools: - secure_validate_rules: - kind: firestore-validate-rules - source: prod-firestore - description: Validate rules with authentication - authRequired: - - google-auth-service - - api-key-service + kind: tools + name: secure_validate_rules + type: firestore-validate-rules + source: prod-firestore + description: Validate rules with authentication + authRequired: + - google-auth-service + - api-key-service `, want: server.ToolConfigs{ "secure_validate_rules": firestorevalidaterules.Config{ Name: "secure_validate_rules", - Kind: "firestore-validate-rules", + Type: "firestore-validate-rules", Source: "prod-firestore", Description: "Validate rules with authentication", AuthRequired: []string{"google-auth-service", "api-key-service"}, @@ -78,15 +77,11 @@ func TestParseFromYamlFirestoreValidateRules(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -99,58 +94,58 @@ func TestParseFromYamlMultipleTools(t *testing.T) { t.Fatalf("unexpected error: %s", err) } in := ` - tools: - validate_dev_rules: - kind: firestore-validate-rules - source: dev-firestore - description: Validate development environment rules - authRequired: - - dev-auth - validate_staging_rules: - kind: firestore-validate-rules - source: staging-firestore - description: Validate staging environment rules - validate_prod_rules: - kind: firestore-validate-rules - source: prod-firestore - description: Validate production environment rules - authRequired: - - prod-auth - - admin-auth + kind: tools + name: validate_dev_rules + type: firestore-validate-rules + source: dev-firestore + description: Validate development environment rules + authRequired: + - dev-auth +--- + kind: tools + name: validate_staging_rules + type: firestore-validate-rules + source: staging-firestore + description: Validate staging environment rules +--- + kind: tools + name: validate_prod_rules + type: firestore-validate-rules + source: prod-firestore + description: Validate production environment rules + authRequired: + - prod-auth + - admin-auth ` want := server.ToolConfigs{ "validate_dev_rules": firestorevalidaterules.Config{ Name: "validate_dev_rules", - Kind: "firestore-validate-rules", + Type: "firestore-validate-rules", Source: "dev-firestore", Description: "Validate development environment rules", AuthRequired: []string{"dev-auth"}, }, "validate_staging_rules": firestorevalidaterules.Config{ Name: "validate_staging_rules", - Kind: "firestore-validate-rules", + Type: "firestore-validate-rules", Source: "staging-firestore", Description: "Validate staging environment rules", AuthRequired: []string{}, }, "validate_prod_rules": firestorevalidaterules.Config{ Name: "validate_prod_rules", - Kind: "firestore-validate-rules", + Type: "firestore-validate-rules", Source: "prod-firestore", Description: "Validate production environment rules", AuthRequired: []string{"prod-auth", "admin-auth"}, }, } - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err = yaml.UnmarshalContext(ctx, testutils.FormatYaml(in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(want, got.Tools); diff != "" { + if diff := cmp.Diff(want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } } diff --git a/internal/tools/http/http.go b/internal/tools/http/http.go index 4a97d9946c..82a3ef1c37 100644 --- a/internal/tools/http/http.go +++ b/internal/tools/http/http.go @@ -32,11 +32,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "http" +const resourceType string = "http" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -57,7 +57,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -74,8 +74,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -88,7 +88,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source kind must be `http`", kind) + return nil, fmt.Errorf("invalid source for %q tool: source type must be `http`", resourceType) } // Combine Source and Tool headers. @@ -227,7 +227,7 @@ func getHeaders(headerParams parameters.Parameters, defaultHeaders map[string]st } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/http/http_test.go b/internal/tools/http/http_test.go index 62bacbca4d..2cdb756ee7 100644 --- a/internal/tools/http/http_test.go +++ b/internal/tools/http/http_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -39,18 +38,18 @@ func TestParseFromYamlHTTP(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: http - source: my-instance - method: GET - description: some description - path: search - `, + kind: tools + name: example_tool + type: http + source: my-instance + method: GET + description: some description + path: search + `, want: server.ToolConfigs{ "example_tool": http.Config{ Name: "example_tool", - Kind: "http", + Type: "http", Source: "my-instance", Method: "GET", Path: "search", @@ -62,54 +61,54 @@ func TestParseFromYamlHTTP(t *testing.T) { { desc: "advanced example", in: ` - tools: - example_tool: - kind: http - source: my-instance - method: GET - path: "{{.pathParam}}?name=alice&pet=cat" - description: some description - authRequired: - - my-google-auth-service - - other-auth-service - queryParams: - - name: country - type: string - description: some description - authServices: - - name: my-google-auth-service - field: user_id - - name: other-auth-service - field: user_id - pathParams: - - name: pathParam - type: string - description: path param - requestBody: | - { - "age": {{.age}}, - "city": "{{.city}}", - "food": {{.food}} - } - bodyParams: - - name: age - type: integer - description: age num - - name: city - type: string - description: city string - headers: - Authorization: API_KEY - Content-Type: application/json - headerParams: - - name: Language - type: string - description: language string + kind: tools + name: example_tool + type: http + source: my-instance + method: GET + path: "{{.pathParam}}?name=alice&pet=cat" + description: some description + authRequired: + - my-google-auth-service + - other-auth-service + queryParams: + - name: country + type: string + description: some description + authServices: + - name: my-google-auth-service + field: user_id + - name: other-auth-service + field: user_id + pathParams: + - name: pathParam + type: string + description: path param + requestBody: | + { + "age": {{.age}}, + "city": "{{.city}}", + "food": {{.food}} + } + bodyParams: + - name: age + type: integer + description: age num + - name: city + type: string + description: city string + headers: + Authorization: API_KEY + Content-Type: application/json + headerParams: + - name: Language + type: string + description: language string `, want: server.ToolConfigs{ "example_tool": http.Config{ Name: "example_tool", - Kind: "http", + Type: "http", Source: "my-instance", Method: "GET", Path: "{{.pathParam}}?name=alice&pet=cat", @@ -140,15 +139,11 @@ func TestParseFromYamlHTTP(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -169,55 +164,51 @@ func TestFailParseFromYamlHTTP(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: http - source: my-instance - method: GOT - path: "search?name=alice&pet=cat" - description: some description - authRequired: - - my-google-auth-service - - other-auth-service - queryParams: - - name: country - type: string - description: some description - authServices: - - name: my-google-auth-service - field: user_id - - name: other-auth-service - field: user_id - requestBody: | - { - "age": {{.age}}, - "city": "{{.city}}" - } - bodyParams: - - name: age - type: integer - description: age num - - name: city - type: string - description: city string - headers: - Authorization: API_KEY - Content-Type: application/json - headerParams: - - name: Language - type: string - description: language string + kind: tools + name: example_tool + type: http + source: my-instance + method: GOT + path: "search?name=alice&pet=cat" + description: some description + authRequired: + - my-google-auth-service + - other-auth-service + queryParams: + - name: country + type: string + description: some description + authServices: + - name: my-google-auth-service + field: user_id + - name: other-auth-service + field: user_id + requestBody: | + { + "age": {{.age}}, + "city": "{{.city}}" + } + bodyParams: + - name: age + type: integer + description: age num + - name: city + type: string + description: city string + headers: + Authorization: API_KEY + Content-Type: application/json + headerParams: + - name: Language + type: string + description: language string `, err: `GOT is not a valid http method`, }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookeradddashboardelement/lookeradddashboardelement.go b/internal/tools/looker/lookeradddashboardelement/lookeradddashboardelement.go index ff3ff08d93..fb2d472846 100644 --- a/internal/tools/looker/lookeradddashboardelement/lookeradddashboardelement.go +++ b/internal/tools/looker/lookeradddashboardelement/lookeradddashboardelement.go @@ -29,11 +29,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-add-dashboard-element" +const resourceType string = "looker-add-dashboard-element" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -54,7 +54,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -64,8 +64,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -135,7 +135,7 @@ var ( ) func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -261,7 +261,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -273,7 +273,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookeradddashboardelement/lookeradddashboardelement_test.go b/internal/tools/looker/lookeradddashboardelement/lookeradddashboardelement_test.go index 93c007043f..0c55ee0f9d 100644 --- a/internal/tools/looker/lookeradddashboardelement/lookeradddashboardelement_test.go +++ b/internal/tools/looker/lookeradddashboardelement/lookeradddashboardelement_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerAddDashboardElement(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-add-dashboard-element - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-add-dashboard-element + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-add-dashboard-element", + Type: "looker-add-dashboard-element", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerAddDashboardElement(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerAddDashboardElement(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-add-dashboard-element - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-add-dashboard-element + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-add-dashboard-element\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-add-dashboard-element\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-add-dashboard-element\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-add-dashboard-element", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookeradddashboardfilter/lookeradddashboardfilter.go b/internal/tools/looker/lookeradddashboardfilter/lookeradddashboardfilter.go index 22e3d79f35..b3999ccdb4 100644 --- a/internal/tools/looker/lookeradddashboardfilter/lookeradddashboardfilter.go +++ b/internal/tools/looker/lookeradddashboardfilter/lookeradddashboardfilter.go @@ -28,11 +28,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-add-dashboard-filter" +const resourceType string = "looker-add-dashboard-filter" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -53,7 +53,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -63,8 +63,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -129,7 +129,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -230,7 +230,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -238,7 +238,7 @@ func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (boo } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookeradddashboardfilter/lookeradddashboardfilter_test.go b/internal/tools/looker/lookeradddashboardfilter/lookeradddashboardfilter_test.go index 43f43dc6c6..0f95161b67 100644 --- a/internal/tools/looker/lookeradddashboardfilter/lookeradddashboardfilter_test.go +++ b/internal/tools/looker/lookeradddashboardfilter/lookeradddashboardfilter_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerAddDashboardFilter(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-add-dashboard-filter - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-add-dashboard-filter + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-add-dashboard-filter", + Type: "looker-add-dashboard-filter", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerAddDashboardFilter(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerAddDashboardFilter(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-add-dashboard-filter - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-add-dashboard-filter + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-add-dashboard-filter\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-add-dashboard-filter\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-add-dashboard-filter\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-add-dashboard-filter", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookerconversationalanalytics/lookerconversationalanalytics.go b/internal/tools/looker/lookerconversationalanalytics/lookerconversationalanalytics.go index a32aa64084..e2055b7b48 100644 --- a/internal/tools/looker/lookerconversationalanalytics/lookerconversationalanalytics.go +++ b/internal/tools/looker/lookerconversationalanalytics/lookerconversationalanalytics.go @@ -34,7 +34,7 @@ import ( "golang.org/x/oauth2" ) -const kind string = "looker-conversational-analytics" +const resourceType string = "looker-conversational-analytics" const instructions = `**INSTRUCTIONS - FOLLOW THESE RULES:** 1. **CONTENT:** Your answer should present the supporting data and then provide a conclusion based on that data. @@ -42,8 +42,8 @@ const instructions = `**INSTRUCTIONS - FOLLOW THESE RULES:** 3. **NO CHARTS:** You are STRICTLY FORBIDDEN from generating any charts, graphs, images, or any other form of visualization.` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -126,7 +126,7 @@ type CAPayload struct { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -136,8 +136,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -150,11 +150,11 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } if s.GoogleCloudProject() == "" { - return nil, fmt.Errorf("project must be defined for source to use with %q tool", kind) + return nil, fmt.Errorf("project must be defined for source to use with %q tool", resourceType) } userQueryParameter := parameters.NewStringParameter("user_query_with_context", "The user's question, potentially including conversation history and system instructions for context.") @@ -216,7 +216,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -309,7 +309,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -561,7 +561,7 @@ func appendMessage(messages []map[string]any, newMessage map[string]any) []map[s } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookerconversationalanalytics/lookerconversationalanalytics_test.go b/internal/tools/looker/lookerconversationalanalytics/lookerconversationalanalytics_test.go index fbc17e47c4..9e0fdb26ed 100644 --- a/internal/tools/looker/lookerconversationalanalytics/lookerconversationalanalytics_test.go +++ b/internal/tools/looker/lookerconversationalanalytics/lookerconversationalanalytics_test.go @@ -17,7 +17,6 @@ package lookerconversationalanalytics_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlLookerConversationalAnalytics(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-conversational-analytics - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-conversational-analytics + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lookerconversationalanalytics.Config{ Name: "example_tool", - Kind: "looker-conversational-analytics", + Type: "looker-conversational-analytics", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,11 @@ func TestParseFromYamlLookerConversationalAnalytics(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/looker/lookercreateprojectfile/lookercreateprojectfile.go b/internal/tools/looker/lookercreateprojectfile/lookercreateprojectfile.go index c1a247aa07..79d2958ee6 100644 --- a/internal/tools/looker/lookercreateprojectfile/lookercreateprojectfile.go +++ b/internal/tools/looker/lookercreateprojectfile/lookercreateprojectfile.go @@ -28,11 +28,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-create-project-file" +const resourceType string = "looker-create-project-file" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -53,7 +53,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -63,8 +63,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -111,7 +111,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -169,7 +169,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -181,7 +181,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookercreateprojectfile/lookercreateprojectfile_test.go b/internal/tools/looker/lookercreateprojectfile/lookercreateprojectfile_test.go index bd9b910b4d..d8a90fa390 100644 --- a/internal/tools/looker/lookercreateprojectfile/lookercreateprojectfile_test.go +++ b/internal/tools/looker/lookercreateprojectfile/lookercreateprojectfile_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerCreateProjectFile(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-create-project-file - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-create-project-file + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-create-project-file", + Type: "looker-create-project-file", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerCreateProjectFile(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerCreateProjectFile(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-create-project-file - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-create-project-file + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-create-project-file\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-create-project-file\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-create-project-file\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-create-project-file", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookerdeleteprojectfile/lookerdeleteprojectfile.go b/internal/tools/looker/lookerdeleteprojectfile/lookerdeleteprojectfile.go index 0939316f3b..6748647fe6 100644 --- a/internal/tools/looker/lookerdeleteprojectfile/lookerdeleteprojectfile.go +++ b/internal/tools/looker/lookerdeleteprojectfile/lookerdeleteprojectfile.go @@ -28,11 +28,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-delete-project-file" +const resourceType string = "looker-delete-project-file" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -53,7 +53,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -63,8 +63,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -112,7 +112,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -161,7 +161,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -173,7 +173,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookerdeleteprojectfile/lookerdeleteprojectfile_test.go b/internal/tools/looker/lookerdeleteprojectfile/lookerdeleteprojectfile_test.go index ff0ab2bf7b..16f226a9f5 100644 --- a/internal/tools/looker/lookerdeleteprojectfile/lookerdeleteprojectfile_test.go +++ b/internal/tools/looker/lookerdeleteprojectfile/lookerdeleteprojectfile_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerDeleteProjectFile(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-delete-project-file - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-delete-project-file + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-delete-project-file", + Type: "looker-delete-project-file", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerDeleteProjectFile(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerDeleteProjectFile(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-delete-project-file - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-delete-project-file + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-delete-project-file\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-delete-project-file\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-delete-project-file\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-delete-project-file", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookerdevmode/lookerdevmode.go b/internal/tools/looker/lookerdevmode/lookerdevmode.go index 99646bbfd4..e46655dcb8 100644 --- a/internal/tools/looker/lookerdevmode/lookerdevmode.go +++ b/internal/tools/looker/lookerdevmode/lookerdevmode.go @@ -28,11 +28,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-dev-mode" +const resourceType string = "looker-dev-mode" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -53,7 +53,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -63,8 +63,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -109,7 +109,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -163,7 +163,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -175,7 +175,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookerdevmode/lookerdevmode_test.go b/internal/tools/looker/lookerdevmode/lookerdevmode_test.go index dd776f77e2..961bb5cb40 100644 --- a/internal/tools/looker/lookerdevmode/lookerdevmode_test.go +++ b/internal/tools/looker/lookerdevmode/lookerdevmode_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerDevMode(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-dev-mode - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-dev-mode + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-dev-mode", + Type: "looker-dev-mode", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerDevMode(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerDevMode(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-dev-mode - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-dev-mode + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-dev-mode\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-dev-mode\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-dev-mode\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-dev-mode", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookergenerateembedurl/lookergenerateembedurl.go b/internal/tools/looker/lookergenerateembedurl/lookergenerateembedurl.go index 8aa946e52f..99cf0bf609 100644 --- a/internal/tools/looker/lookergenerateembedurl/lookergenerateembedurl.go +++ b/internal/tools/looker/lookergenerateembedurl/lookergenerateembedurl.go @@ -29,11 +29,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-generate-embed-url" +const resourceType string = "looker-generate-embed-url" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -55,7 +55,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -65,8 +65,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -115,7 +115,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -175,7 +175,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -187,7 +187,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookergenerateembedurl/lookergenerateembedurl_test.go b/internal/tools/looker/lookergenerateembedurl/lookergenerateembedurl_test.go index 93dcd0eb88..08aeba23d5 100644 --- a/internal/tools/looker/lookergenerateembedurl/lookergenerateembedurl_test.go +++ b/internal/tools/looker/lookergenerateembedurl/lookergenerateembedurl_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerGenerateEmbedUrl(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-generate-embed-url - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-generate-embed-url + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-generate-embed-url", + Type: "looker-generate-embed-url", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,11 @@ func TestParseFromYamlLookerGenerateEmbedUrl(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -85,23 +80,19 @@ func TestFailParseFromYamlLookerGenerateEmbedUrl(t *testing.T) { { desc: "Invalid field", in: ` - tools: - example_tool: - kind: looker-generate-embed-url - source: my-instance - description: some description - invalid_field: "should not be here" + kind: tools + name: example_tool + type: looker-generate-embed-url + source: my-instance + description: some description + invalid_field: "should not be here" `, err: "unknown field", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookergetconnectiondatabases/lookergetconnectiondatabases.go b/internal/tools/looker/lookergetconnectiondatabases/lookergetconnectiondatabases.go index 232f47bd4f..d0c37ff589 100644 --- a/internal/tools/looker/lookergetconnectiondatabases/lookergetconnectiondatabases.go +++ b/internal/tools/looker/lookergetconnectiondatabases/lookergetconnectiondatabases.go @@ -27,11 +27,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-get-connection-databases" +const resourceType string = "looker-get-connection-databases" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -52,7 +52,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -62,8 +62,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -108,7 +108,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -149,7 +149,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -161,7 +161,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookergetconnectiondatabases/lookergetconnectiondatabases_test.go b/internal/tools/looker/lookergetconnectiondatabases/lookergetconnectiondatabases_test.go index 284d4102bb..6f137e85dc 100644 --- a/internal/tools/looker/lookergetconnectiondatabases/lookergetconnectiondatabases_test.go +++ b/internal/tools/looker/lookergetconnectiondatabases/lookergetconnectiondatabases_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerGetConnectionDatabases(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-get-connection-databases - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-get-connection-databases + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-get-connection-databases", + Type: "looker-get-connection-databases", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerGetConnectionDatabases(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerGetConnectionDatabases(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-get-connection-databases - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-get-connection-databases + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-get-connection-databases\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-get-connection-databases\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-get-connection-databases\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-get-connection-databases", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookergetconnections/lookergetconnections.go b/internal/tools/looker/lookergetconnections/lookergetconnections.go index 3b8b2681dc..ccd384c5f7 100644 --- a/internal/tools/looker/lookergetconnections/lookergetconnections.go +++ b/internal/tools/looker/lookergetconnections/lookergetconnections.go @@ -28,11 +28,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-get-connections" +const resourceType string = "looker-get-connections" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -53,7 +53,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -63,8 +63,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -108,7 +108,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -168,7 +168,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -180,7 +180,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookergetconnections/lookergetconnections_test.go b/internal/tools/looker/lookergetconnections/lookergetconnections_test.go index b921a57e94..0e7cc03777 100644 --- a/internal/tools/looker/lookergetconnections/lookergetconnections_test.go +++ b/internal/tools/looker/lookergetconnections/lookergetconnections_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerGetConnections(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-get-connections - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-get-connections + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-get-connections", + Type: "looker-get-connections", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerGetConnections(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerGetConnections(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-get-connections - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-get-connections + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-get-connections\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-get-connections\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-get-connections\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-get-connections", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookergetconnectionschemas/lookergetconnectionschemas.go b/internal/tools/looker/lookergetconnectionschemas/lookergetconnectionschemas.go index 8345a84a2c..5ce3007d97 100644 --- a/internal/tools/looker/lookergetconnectionschemas/lookergetconnectionschemas.go +++ b/internal/tools/looker/lookergetconnectionschemas/lookergetconnectionschemas.go @@ -27,11 +27,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-get-connection-schemas" +const resourceType string = "looker-get-connection-schemas" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -52,7 +52,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -62,8 +62,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -109,7 +109,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -155,7 +155,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -167,7 +167,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookergetconnectionschemas/lookergetconnectionschemas_test.go b/internal/tools/looker/lookergetconnectionschemas/lookergetconnectionschemas_test.go index 1c2951102f..c0e7207517 100644 --- a/internal/tools/looker/lookergetconnectionschemas/lookergetconnectionschemas_test.go +++ b/internal/tools/looker/lookergetconnectionschemas/lookergetconnectionschemas_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerGetConnectionSchemas(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-get-connection-schemas - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-get-connection-schemas + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-get-connection-schemas", + Type: "looker-get-connection-schemas", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerGetConnectionSchemas(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerGetConnectionSchemas(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-get-connection-schemas - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-get-connection-schemas + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-get-connection-schemas\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-get-connection-schemas\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-get-connection-schemas\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-get-connection-schemas", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookergetconnectiontablecolumns/lookergetconnectiontablecolumns.go b/internal/tools/looker/lookergetconnectiontablecolumns/lookergetconnectiontablecolumns.go index 2c7b7e878a..0b5f0e15c1 100644 --- a/internal/tools/looker/lookergetconnectiontablecolumns/lookergetconnectiontablecolumns.go +++ b/internal/tools/looker/lookergetconnectiontablecolumns/lookergetconnectiontablecolumns.go @@ -28,11 +28,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-get-connection-table-columns" +const resourceType string = "looker-get-connection-table-columns" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -53,7 +53,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -63,8 +63,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -112,7 +112,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -192,7 +192,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -204,7 +204,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookergetconnectiontablecolumns/lookergetconnectiontablecolumns_test.go b/internal/tools/looker/lookergetconnectiontablecolumns/lookergetconnectiontablecolumns_test.go index 3242a31ffb..c01a8ce8d1 100644 --- a/internal/tools/looker/lookergetconnectiontablecolumns/lookergetconnectiontablecolumns_test.go +++ b/internal/tools/looker/lookergetconnectiontablecolumns/lookergetconnectiontablecolumns_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerGetConnectionTableColumns(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-get-connection-table-columns - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-get-connection-table-columns + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-get-connection-table-columns", + Type: "looker-get-connection-table-columns", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerGetConnectionTableColumns(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerGetConnectionTableColumns(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-get-connection-table-columns - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-get-connection-table-columns + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-get-connection-table-columns\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-get-connection-table-columns\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-get-connection-table-columns\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-get-connection-table-columns", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookergetconnectiontables/lookergetconnectiontables.go b/internal/tools/looker/lookergetconnectiontables/lookergetconnectiontables.go index 0e416bd014..141f5e5478 100644 --- a/internal/tools/looker/lookergetconnectiontables/lookergetconnectiontables.go +++ b/internal/tools/looker/lookergetconnectiontables/lookergetconnectiontables.go @@ -28,11 +28,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-get-connection-tables" +const resourceType string = "looker-get-connection-tables" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -53,7 +53,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -63,8 +63,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -111,7 +111,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -183,7 +183,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -195,7 +195,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookergetconnectiontables/lookergetconnectiontables_test.go b/internal/tools/looker/lookergetconnectiontables/lookergetconnectiontables_test.go index 1b6ec50aa0..0267accaf5 100644 --- a/internal/tools/looker/lookergetconnectiontables/lookergetconnectiontables_test.go +++ b/internal/tools/looker/lookergetconnectiontables/lookergetconnectiontables_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerGetConnectionTables(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-get-connection-tables - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-get-connection-tables + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-get-connection-tables", + Type: "looker-get-connection-tables", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerGetConnectionTables(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerGetConnectionTables(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-get-connection-tables - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-get-connection-tables + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-get-connection-tables\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-get-connection-tables\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-get-connection-tables\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-get-connection-tables", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookergetdashboards/lookergetdashboards.go b/internal/tools/looker/lookergetdashboards/lookergetdashboards.go index c1f5a6788d..1fc574f104 100644 --- a/internal/tools/looker/lookergetdashboards/lookergetdashboards.go +++ b/internal/tools/looker/lookergetdashboards/lookergetdashboards.go @@ -28,11 +28,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-get-dashboards" +const resourceType string = "looker-get-dashboards" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -53,7 +53,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -63,8 +63,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -117,7 +117,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -194,7 +194,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -206,7 +206,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookergetdashboards/lookergetdashboards_test.go b/internal/tools/looker/lookergetdashboards/lookergetdashboards_test.go index b3eba2af62..83e2e8f9c5 100644 --- a/internal/tools/looker/lookergetdashboards/lookergetdashboards_test.go +++ b/internal/tools/looker/lookergetdashboards/lookergetdashboards_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerGetDashboards(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-get-dashboards - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-get-dashboards + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-get-dashboards", + Type: "looker-get-dashboards", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerGetDashboards(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerGetDashboards(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-get-dashboards - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-get-dashboards + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-get-dashboards\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-get-dashboards\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-get-dashboards\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-get-dashboards", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookergetdimensions/lookergetdimensions.go b/internal/tools/looker/lookergetdimensions/lookergetdimensions.go index 8b5269ba29..812dc41cb8 100644 --- a/internal/tools/looker/lookergetdimensions/lookergetdimensions.go +++ b/internal/tools/looker/lookergetdimensions/lookergetdimensions.go @@ -29,11 +29,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-get-dimensions" +const resourceType string = "looker-get-dimensions" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -55,7 +55,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -65,8 +65,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -110,7 +110,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -169,7 +169,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -181,7 +181,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookergetdimensions/lookergetdimensions_test.go b/internal/tools/looker/lookergetdimensions/lookergetdimensions_test.go index 53dba27533..5d63e5d074 100644 --- a/internal/tools/looker/lookergetdimensions/lookergetdimensions_test.go +++ b/internal/tools/looker/lookergetdimensions/lookergetdimensions_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerGetDimensions(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-get-dimensions - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-get-dimensions + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-get-dimensions", + Type: "looker-get-dimensions", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerGetDimensions(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerGetDimensions(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-get-dimensions - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-get-dimensions + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-get-dimensions\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-get-dimensions\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-get-dimensions\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-get-dimensions", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookergetexplores/lookergetexplores.go b/internal/tools/looker/lookergetexplores/lookergetexplores.go index d8818f5e3d..99c7ad5cac 100644 --- a/internal/tools/looker/lookergetexplores/lookergetexplores.go +++ b/internal/tools/looker/lookergetexplores/lookergetexplores.go @@ -28,11 +28,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-get-explores" +const resourceType string = "looker-get-explores" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -54,7 +54,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -64,8 +64,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -110,7 +110,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -178,7 +178,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -190,7 +190,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookergetexplores/lookergetexplores_test.go b/internal/tools/looker/lookergetexplores/lookergetexplores_test.go index 1c0b0d72b3..4e3aa50795 100644 --- a/internal/tools/looker/lookergetexplores/lookergetexplores_test.go +++ b/internal/tools/looker/lookergetexplores/lookergetexplores_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerGetExplores(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-get-explores - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-get-explores + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-get-explores", + Type: "looker-get-explores", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerGetExplores(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerGetFilters(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-get-explores - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-get-explores + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-get-explores\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-get-explores\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-get-explores\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-get-explores", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookergetfilters/lookergetfilters.go b/internal/tools/looker/lookergetfilters/lookergetfilters.go index 7f465dee6d..8171d7c421 100644 --- a/internal/tools/looker/lookergetfilters/lookergetfilters.go +++ b/internal/tools/looker/lookergetfilters/lookergetfilters.go @@ -29,11 +29,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-get-filters" +const resourceType string = "looker-get-filters" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -55,7 +55,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -65,8 +65,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -110,7 +110,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -169,7 +169,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -181,7 +181,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookergetfilters/lookergetfilters_test.go b/internal/tools/looker/lookergetfilters/lookergetfilters_test.go index 0cec5dd0bb..76b3ab19db 100644 --- a/internal/tools/looker/lookergetfilters/lookergetfilters_test.go +++ b/internal/tools/looker/lookergetfilters/lookergetfilters_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerGetFilters(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-get-filters - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-get-filters + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-get-filters", + Type: "looker-get-filters", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerGetFilters(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerGetFilters(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-get-filters - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-get-filters + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-get-filters\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-get-filters\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-get-filters\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-get-filters", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookergetlooks/lookergetlooks.go b/internal/tools/looker/lookergetlooks/lookergetlooks.go index f627de901e..bf934c4418 100644 --- a/internal/tools/looker/lookergetlooks/lookergetlooks.go +++ b/internal/tools/looker/lookergetlooks/lookergetlooks.go @@ -28,11 +28,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-get-looks" +const resourceType string = "looker-get-looks" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -53,7 +53,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -63,8 +63,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -117,7 +117,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -194,7 +194,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -206,7 +206,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookergetlooks/lookergetlooks_test.go b/internal/tools/looker/lookergetlooks/lookergetlooks_test.go index b6a4f23dd7..56320498eb 100644 --- a/internal/tools/looker/lookergetlooks/lookergetlooks_test.go +++ b/internal/tools/looker/lookergetlooks/lookergetlooks_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerGetLooks(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-get-looks - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-get-looks + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-get-looks", + Type: "looker-get-looks", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerGetLooks(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerGetLooks(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-get-looks - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-get-looks + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-get-looks\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-get-looks\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-get-looks\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-get-looks", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookergetmeasures/lookergetmeasures.go b/internal/tools/looker/lookergetmeasures/lookergetmeasures.go index 3255ab7a4d..bba3269451 100644 --- a/internal/tools/looker/lookergetmeasures/lookergetmeasures.go +++ b/internal/tools/looker/lookergetmeasures/lookergetmeasures.go @@ -29,11 +29,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-get-measures" +const resourceType string = "looker-get-measures" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -55,7 +55,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -65,8 +65,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -110,7 +110,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -169,7 +169,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -181,7 +181,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookergetmeasures/lookergetmeasures_test.go b/internal/tools/looker/lookergetmeasures/lookergetmeasures_test.go index 7587b4cd3c..cb29d86f85 100644 --- a/internal/tools/looker/lookergetmeasures/lookergetmeasures_test.go +++ b/internal/tools/looker/lookergetmeasures/lookergetmeasures_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerGetMeasures(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-get-measures - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-get-measures + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-get-measures", + Type: "looker-get-measures", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerGetMeasures(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerGetMeasures(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-get-measures - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-get-measures + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-get-measures\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-get-measures\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-get-measures\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-get-measures", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookergetmodels/lookergetmodels.go b/internal/tools/looker/lookergetmodels/lookergetmodels.go index 9c051ecb68..a90d986356 100644 --- a/internal/tools/looker/lookergetmodels/lookergetmodels.go +++ b/internal/tools/looker/lookergetmodels/lookergetmodels.go @@ -28,11 +28,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-get-models" +const resourceType string = "looker-get-models" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -54,7 +54,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -64,8 +64,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -109,7 +109,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -170,7 +170,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -182,7 +182,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookergetmodels/lookergetmodels_test.go b/internal/tools/looker/lookergetmodels/lookergetmodels_test.go index b28c02c317..742d004599 100644 --- a/internal/tools/looker/lookergetmodels/lookergetmodels_test.go +++ b/internal/tools/looker/lookergetmodels/lookergetmodels_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerGetModels(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-get-models - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-get-models + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-get-models", + Type: "looker-get-models", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerGetModels(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerGetModels(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-get-models - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-get-models + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-get-models\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-get-models\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-get-models\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-get-models", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookergetparameters/lookergetparameters.go b/internal/tools/looker/lookergetparameters/lookergetparameters.go index 49dd1db503..edacd0dc83 100644 --- a/internal/tools/looker/lookergetparameters/lookergetparameters.go +++ b/internal/tools/looker/lookergetparameters/lookergetparameters.go @@ -29,11 +29,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-get-parameters" +const resourceType string = "looker-get-parameters" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -55,7 +55,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -65,8 +65,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -110,7 +110,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -169,7 +169,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -181,7 +181,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookergetparameters/lookergetparameters_test.go b/internal/tools/looker/lookergetparameters/lookergetparameters_test.go index 3c4679e8ec..6c54db6e16 100644 --- a/internal/tools/looker/lookergetparameters/lookergetparameters_test.go +++ b/internal/tools/looker/lookergetparameters/lookergetparameters_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerGetParameters(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-get-parameters - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-get-parameters + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-get-parameters", + Type: "looker-get-parameters", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerGetParameters(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerGetParameters(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-get-parameters - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-get-parameters + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-get-parameters\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-get-parameters\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-get-parameters\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-get-parameters", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookergetprojectfile/lookergetprojectfile.go b/internal/tools/looker/lookergetprojectfile/lookergetprojectfile.go index cc8d1a792a..d7eafebf10 100644 --- a/internal/tools/looker/lookergetprojectfile/lookergetprojectfile.go +++ b/internal/tools/looker/lookergetprojectfile/lookergetprojectfile.go @@ -29,11 +29,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-get-project-file" +const resourceType string = "looker-get-project-file" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -54,7 +54,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -64,8 +64,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -111,7 +111,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -166,7 +166,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -178,7 +178,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookergetprojectfile/lookergetprojectfile_test.go b/internal/tools/looker/lookergetprojectfile/lookergetprojectfile_test.go index cfd182c1d6..d3d5c9382e 100644 --- a/internal/tools/looker/lookergetprojectfile/lookergetprojectfile_test.go +++ b/internal/tools/looker/lookergetprojectfile/lookergetprojectfile_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerGetProjectFile(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-get-project-file - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-get-project-file + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-get-project-file", + Type: "looker-get-project-file", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerGetProjectFile(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,19 @@ func TestFailParseFromYamlLookerGetProjectFile(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-get-project-file - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-get-project-file + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-get-project-file\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-get-project-file\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-get-project-file\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-get-project-file", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookergetprojectfiles/lookergetprojectfiles.go b/internal/tools/looker/lookergetprojectfiles/lookergetprojectfiles.go index 3a1d5ba216..832359dedf 100644 --- a/internal/tools/looker/lookergetprojectfiles/lookergetprojectfiles.go +++ b/internal/tools/looker/lookergetprojectfiles/lookergetprojectfiles.go @@ -28,11 +28,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-get-project-files" +const resourceType string = "looker-get-project-files" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -53,7 +53,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -63,8 +63,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -109,7 +109,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -182,7 +182,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -194,7 +194,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookergetprojectfiles/lookergetprojectfiles_test.go b/internal/tools/looker/lookergetprojectfiles/lookergetprojectfiles_test.go index 83a315b449..319b3f8461 100644 --- a/internal/tools/looker/lookergetprojectfiles/lookergetprojectfiles_test.go +++ b/internal/tools/looker/lookergetprojectfiles/lookergetprojectfiles_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerGetProjectFiles(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-get-project-files - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-get-project-files + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-get-project-files", + Type: "looker-get-project-files", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerGetProjectFiles(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerGetProjectFiles(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-get-project-files - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-get-project-files + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-get-project-files\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-get-project-files\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-get-project-files\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-get-project-files", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookergetprojects/lookergetprojects.go b/internal/tools/looker/lookergetprojects/lookergetprojects.go index de0e3a1efb..17f0c438d1 100644 --- a/internal/tools/looker/lookergetprojects/lookergetprojects.go +++ b/internal/tools/looker/lookergetprojects/lookergetprojects.go @@ -28,11 +28,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-get-projects" +const resourceType string = "looker-get-projects" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -53,7 +53,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -63,8 +63,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -108,7 +108,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -159,7 +159,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -171,7 +171,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookergetprojects/lookergetprojects_test.go b/internal/tools/looker/lookergetprojects/lookergetprojects_test.go index 3a25be54d5..b390257457 100644 --- a/internal/tools/looker/lookergetprojects/lookergetprojects_test.go +++ b/internal/tools/looker/lookergetprojects/lookergetprojects_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerGetProjects(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-get-projects - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-get-projects + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-get-projects", + Type: "looker-get-projects", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,11 @@ func TestParseFromYamlLookerGetProjects(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +81,19 @@ func TestFailParseFromYamlLookerGetProjecProjects(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-get-projects - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-get-projects + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-get-projects\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-get-projects\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-get-projects\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-get-projects", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookerhealthanalyze/lookerhealthanalyze.go b/internal/tools/looker/lookerhealthanalyze/lookerhealthanalyze.go index 3b7404b3dc..2a11cf0155 100644 --- a/internal/tools/looker/lookerhealthanalyze/lookerhealthanalyze.go +++ b/internal/tools/looker/lookerhealthanalyze/lookerhealthanalyze.go @@ -34,11 +34,11 @@ import ( // ================================================================================================================= // START MCP SERVER CORE LOGIC // ================================================================================================================= -const kind string = "looker-health-analyze" +const resourceType string = "looker-health-analyze" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -59,7 +59,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -69,8 +69,8 @@ type Config struct { var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -126,7 +126,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -210,7 +210,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -569,7 +569,7 @@ func (t *analyzeTool) explores(ctx context.Context, model, explore string) ([]ma // ================================================================================================================= func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookerhealthanalyze/lookerhealthanalyze_test.go b/internal/tools/looker/lookerhealthanalyze/lookerhealthanalyze_test.go index 7d41a972e8..52d0af8c89 100644 --- a/internal/tools/looker/lookerhealthanalyze/lookerhealthanalyze_test.go +++ b/internal/tools/looker/lookerhealthanalyze/lookerhealthanalyze_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerHealthAnalyze(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-health-analyze - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-health-analyze + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lha.Config{ Name: "example_tool", - Kind: "looker-health-analyze", + Type: "looker-health-analyze", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,11 @@ func TestParseFromYamlLookerHealthAnalyze(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -85,22 +80,18 @@ func TestFailParseFromYamlLookerHealthAnalyze(t *testing.T) { { desc: "Invalid field", in: ` - tools: - example_tool: - kind: looker-health-analyze - source: my-instance - invalid_field: true + kind: tools + name: example_tool + type: looker-health-analyze + source: my-instance + invalid_field: true `, - err: "unable to parse tool \"example_tool\" as kind \"looker-health-analyze\": [2:1] unknown field \"invalid_field\"", + err: "unable to parse tool \"example_tool\" as type \"looker-health-analyze\": [2:1] unknown field \"invalid_field\"", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookerhealthpulse/lookerhealthpulse.go b/internal/tools/looker/lookerhealthpulse/lookerhealthpulse.go index 393e8590cf..b0df8b1022 100644 --- a/internal/tools/looker/lookerhealthpulse/lookerhealthpulse.go +++ b/internal/tools/looker/lookerhealthpulse/lookerhealthpulse.go @@ -34,11 +34,11 @@ import ( // ================================================================================================================= // START MCP SERVER CORE LOGIC // ================================================================================================================= -const kind string = "looker-health-pulse" +const resourceType string = "looker-health-pulse" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -59,7 +59,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -69,8 +69,8 @@ type Config struct { var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -117,7 +117,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -174,7 +174,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -469,7 +469,7 @@ func (t *pulseTool) checkLegacyFeatures(ctx context.Context, source compatibleSo // ================================================================================================================= func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookerhealthpulse/lookerhealthpulse_test.go b/internal/tools/looker/lookerhealthpulse/lookerhealthpulse_test.go index 12a7b69a77..7ef3779bbd 100644 --- a/internal/tools/looker/lookerhealthpulse/lookerhealthpulse_test.go +++ b/internal/tools/looker/lookerhealthpulse/lookerhealthpulse_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerHealthPulse(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-health-pulse - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-health-pulse + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lhp.Config{ Name: "example_tool", - Kind: "looker-health-pulse", + Type: "looker-health-pulse", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,11 @@ func TestParseFromYamlLookerHealthPulse(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -85,22 +80,18 @@ func TestFailParseFromYamlLookerHealthPulse(t *testing.T) { { desc: "Invalid field", in: ` - tools: - example_tool: - kind: looker-health-pulse - source: my-instance - invalid_field: true + kind: tools + name: example_tool + type: looker-health-pulse + source: my-instance + invalid_field: true `, - err: "unable to parse tool \"example_tool\" as kind \"looker-health-pulse\": [2:1] unknown field \"invalid_field\"", + err: "unable to parse tool \"example_tool\" as type \"looker-health-pulse\": [2:1] unknown field \"invalid_field\"", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookerhealthvacuum/lookerhealthvacuum.go b/internal/tools/looker/lookerhealthvacuum/lookerhealthvacuum.go index ebf629a7a9..702808e86f 100644 --- a/internal/tools/looker/lookerhealthvacuum/lookerhealthvacuum.go +++ b/internal/tools/looker/lookerhealthvacuum/lookerhealthvacuum.go @@ -34,11 +34,11 @@ import ( // ================================================================================================================= // START MCP SERVER CORE LOGIC // ================================================================================================================= -const kind string = "looker-health-vacuum" +const resourceType string = "looker-health-vacuum" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -59,7 +59,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -69,8 +69,8 @@ type Config struct { var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -126,7 +126,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -188,7 +188,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -473,7 +473,7 @@ func (t *vacuumTool) getUsedExploreFields(ctx context.Context, model, explore st // ================================================================================================================= func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookerhealthvacuum/lookerhealthvacuum_test.go b/internal/tools/looker/lookerhealthvacuum/lookerhealthvacuum_test.go index 59fd2f2121..7da00fc980 100644 --- a/internal/tools/looker/lookerhealthvacuum/lookerhealthvacuum_test.go +++ b/internal/tools/looker/lookerhealthvacuum/lookerhealthvacuum_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerHealthVacuum(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-health-vacuum - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-health-vacuum + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lhv.Config{ Name: "example_tool", - Kind: "looker-health-vacuum", + Type: "looker-health-vacuum", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,11 @@ func TestParseFromYamlLookerHealthVacuum(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -85,22 +80,18 @@ func TestFailParseFromYamlLookerHealthVacuum(t *testing.T) { { desc: "Invalid field", in: ` - tools: - example_tool: - kind: looker-health-vacuum - source: my-instance - invalid_field: true + kind: tools + name: example_tool + type: looker-health-vacuum + source: my-instance + invalid_field: true `, - err: "unable to parse tool \"example_tool\" as kind \"looker-health-vacuum\": [2:1] unknown field \"invalid_field\"", + err: "unable to parse tool \"example_tool\" as type \"looker-health-vacuum\": [2:1] unknown field \"invalid_field\"", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookermakedashboard/lookermakedashboard.go b/internal/tools/looker/lookermakedashboard/lookermakedashboard.go index 911554ffb8..0ca266009d 100644 --- a/internal/tools/looker/lookermakedashboard/lookermakedashboard.go +++ b/internal/tools/looker/lookermakedashboard/lookermakedashboard.go @@ -30,11 +30,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-make-dashboard" +const resourceType string = "looker-make-dashboard" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -55,7 +55,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -65,8 +65,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -117,7 +117,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -214,7 +214,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -226,7 +226,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookermakedashboard/lookermakedashboard_test.go b/internal/tools/looker/lookermakedashboard/lookermakedashboard_test.go index 2da79199ed..ef332cb1f6 100644 --- a/internal/tools/looker/lookermakedashboard/lookermakedashboard_test.go +++ b/internal/tools/looker/lookermakedashboard/lookermakedashboard_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerMakeDashboard(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-make-dashboard - source: my-instance - description: some description - `, + kind: tools + name: example_tool + type: looker-make-dashboard + source: my-instance + description: some description + `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-make-dashboard", + Type: "looker-make-dashboard", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,11 @@ func TestParseFromYamlLookerMakeDashboard(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +81,19 @@ func TestFailParseFromYamlMakeDashboard(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-make-dashboard - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-make-dashboard + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-make-dashboard\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-make-dashboard\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-make-dashboard\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-make-dashboard", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookermakelook/lookermakelook.go b/internal/tools/looker/lookermakelook/lookermakelook.go index 20aa9e1867..9784d1b953 100644 --- a/internal/tools/looker/lookermakelook/lookermakelook.go +++ b/internal/tools/looker/lookermakelook/lookermakelook.go @@ -31,11 +31,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-make-look" +const resourceType string = "looker-make-look" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -56,7 +56,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -66,8 +66,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -124,7 +124,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -235,7 +235,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -247,7 +247,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookermakelook/lookermakelook_test.go b/internal/tools/looker/lookermakelook/lookermakelook_test.go index f6a3bd71f5..38e06a9aee 100644 --- a/internal/tools/looker/lookermakelook/lookermakelook_test.go +++ b/internal/tools/looker/lookermakelook/lookermakelook_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerMakeLook(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-make-look - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-make-look + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-make-look", + Type: "looker-make-look", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,11 @@ func TestParseFromYamlLookerMakeLook(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +81,19 @@ func TestFailParseFromYamlLookerMakeLook(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-make-look - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-make-look + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-make-look\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-make-look\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-make-look\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-make-look", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookerquery/lookerquery.go b/internal/tools/looker/lookerquery/lookerquery.go index 2486d3e54a..13dee7a81d 100644 --- a/internal/tools/looker/lookerquery/lookerquery.go +++ b/internal/tools/looker/lookerquery/lookerquery.go @@ -30,11 +30,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-query" +const resourceType string = "looker-query" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -55,7 +55,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -65,8 +65,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -110,7 +110,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -162,7 +162,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -174,7 +174,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookerquery/lookerquery_test.go b/internal/tools/looker/lookerquery/lookerquery_test.go index e204096e50..1e30a96da4 100644 --- a/internal/tools/looker/lookerquery/lookerquery_test.go +++ b/internal/tools/looker/lookerquery/lookerquery_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerQuery(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-query - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-query + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-query", + Type: "looker-query", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,11 @@ func TestParseFromYamlLookerQuery(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +81,19 @@ func TestFailParseFromYamlLookerQuery(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-query - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-query + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-query\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-query\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-query\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-query", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookerquerysql/lookerquerysql.go b/internal/tools/looker/lookerquerysql/lookerquerysql.go index c1a36132af..71eb14e27a 100644 --- a/internal/tools/looker/lookerquerysql/lookerquerysql.go +++ b/internal/tools/looker/lookerquerysql/lookerquerysql.go @@ -29,11 +29,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-query-sql" +const resourceType string = "looker-query-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -54,7 +54,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -64,8 +64,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -109,7 +109,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -152,7 +152,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -164,7 +164,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookerquerysql/lookerquerysql_test.go b/internal/tools/looker/lookerquerysql/lookerquerysql_test.go index bb8e25d7a4..6a49f36bbe 100644 --- a/internal/tools/looker/lookerquerysql/lookerquerysql_test.go +++ b/internal/tools/looker/lookerquerysql/lookerquerysql_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerQuerySql(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-query-sql - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-query-sql + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-query-sql", + Type: "looker-query-sql", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerQuerySql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerQuerySql(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-query-sql - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-query-sql + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-query-sql\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-query-sql\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-query-sql\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-query-sql", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookerqueryurl/lookerqueryurl.go b/internal/tools/looker/lookerqueryurl/lookerqueryurl.go index 5648f1327e..e47764eccf 100644 --- a/internal/tools/looker/lookerqueryurl/lookerqueryurl.go +++ b/internal/tools/looker/lookerqueryurl/lookerqueryurl.go @@ -29,11 +29,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-query-url" +const resourceType string = "looker-query-url" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -54,7 +54,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -64,8 +64,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -116,7 +116,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -181,7 +181,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -193,7 +193,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookerqueryurl/lookerqueryurl_test.go b/internal/tools/looker/lookerqueryurl/lookerqueryurl_test.go index 740e3aaa3e..e98838f913 100644 --- a/internal/tools/looker/lookerqueryurl/lookerqueryurl_test.go +++ b/internal/tools/looker/lookerqueryurl/lookerqueryurl_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerQueryUrl(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-query-url - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-query-url + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-query-url", + Type: "looker-query-url", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerQueryUrl(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerQueryUrl(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-query-url - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-query-url + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-query-url\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-query-url\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-query-url\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-query-url", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookerrundashboard/lookerrundashboard.go b/internal/tools/looker/lookerrundashboard/lookerrundashboard.go index 4dde17cf45..8970c25671 100644 --- a/internal/tools/looker/lookerrundashboard/lookerrundashboard.go +++ b/internal/tools/looker/lookerrundashboard/lookerrundashboard.go @@ -31,11 +31,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-run-dashboard" +const resourceType string = "looker-run-dashboard" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -56,7 +56,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -66,8 +66,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -115,7 +115,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -178,7 +178,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -279,7 +279,7 @@ func merge(channels ...<-chan map[string]any) <-chan map[string]any { } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookerrundashboard/lookerrundashboard_test.go b/internal/tools/looker/lookerrundashboard/lookerrundashboard_test.go index 6726e04545..20b55ce433 100644 --- a/internal/tools/looker/lookerrundashboard/lookerrundashboard_test.go +++ b/internal/tools/looker/lookerrundashboard/lookerrundashboard_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerRunDashboard(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-run-dashboard - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-run-dashboard + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-run-dashboard", + Type: "looker-run-dashboard", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerRunDashboard(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerRunDashboard(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-run-dashboard - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-run-dashboard + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-run-dashboard\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-run-dashboard\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-run-dashboard\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-run-dashboard", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookerrunlook/lookerrunlook.go b/internal/tools/looker/lookerrunlook/lookerrunlook.go index dc8ee5b20a..14513dfa6f 100644 --- a/internal/tools/looker/lookerrunlook/lookerrunlook.go +++ b/internal/tools/looker/lookerrunlook/lookerrunlook.go @@ -30,11 +30,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-run-look" +const resourceType string = "looker-run-look" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -55,7 +55,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -65,8 +65,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -116,7 +116,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -191,7 +191,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -199,7 +199,7 @@ func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (boo } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookerrunlook/lookerrunlook_test.go b/internal/tools/looker/lookerrunlook/lookerrunlook_test.go index ac2dfbe99c..ea4076b843 100644 --- a/internal/tools/looker/lookerrunlook/lookerrunlook_test.go +++ b/internal/tools/looker/lookerrunlook/lookerrunlook_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerRunLook(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-run-look - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-run-look + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-run-look", + Type: "looker-run-look", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerRunLook(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerRunLook(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-run-look - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-run-look + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-run-look\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-run-look\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-run-look\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-run-look", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/looker/lookerupdateprojectfile/lookerupdateprojectfile.go b/internal/tools/looker/lookerupdateprojectfile/lookerupdateprojectfile.go index 4c0b63daee..40971944c7 100644 --- a/internal/tools/looker/lookerupdateprojectfile/lookerupdateprojectfile.go +++ b/internal/tools/looker/lookerupdateprojectfile/lookerupdateprojectfile.go @@ -28,11 +28,11 @@ import ( v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4" ) -const kind string = "looker-update-project-file" +const resourceType string = "looker-update-project-file" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -52,7 +52,7 @@ type compatibleSource interface { } type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -62,8 +62,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -112,7 +112,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -174,7 +174,7 @@ func (t Tool) Authorized(verifiedAuthServices []string) bool { } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return false, err } @@ -182,7 +182,7 @@ func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (boo } func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return "", err } diff --git a/internal/tools/looker/lookerupdateprojectfile/lookerupdateprojectfile_test.go b/internal/tools/looker/lookerupdateprojectfile/lookerupdateprojectfile_test.go index fef23faab7..2d7064bbb2 100644 --- a/internal/tools/looker/lookerupdateprojectfile/lookerupdateprojectfile_test.go +++ b/internal/tools/looker/lookerupdateprojectfile/lookerupdateprojectfile_test.go @@ -18,7 +18,6 @@ import ( "strings" "testing" - 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" @@ -38,16 +37,16 @@ func TestParseFromYamlLookerUpdateProjectFile(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: looker-update-project-file - source: my-instance - description: some description + kind: tools + name: example_tool + type: looker-update-project-file + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": lkr.Config{ Name: "example_tool", - Kind: "looker-update-project-file", + Type: "looker-update-project-file", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -57,15 +56,12 @@ func TestParseFromYamlLookerUpdateProjectFile(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -86,23 +82,20 @@ func TestFailParseFromYamlLookerUpdateProjectFile(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: looker-update-project-file - source: my-instance - method: GOT - description: some description + kind: tools + name: example_tool + type: looker-update-project-file + source: my-instance + method: GOT + description: some description `, - err: "unable to parse tool \"example_tool\" as kind \"looker-update-project-file\": [4:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n 3 | kind: looker-update-project-file\n> 4 | method: GOT\n ^\n 5 | source: my-instance", + err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-update-project-file\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-update-project-file", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/mindsdb/mindsdbexecutesql/mindsdbexecutesql.go b/internal/tools/mindsdb/mindsdbexecutesql/mindsdbexecutesql.go index 6545f6bafb..da8c023987 100644 --- a/internal/tools/mindsdb/mindsdbexecutesql/mindsdbexecutesql.go +++ b/internal/tools/mindsdb/mindsdbexecutesql/mindsdbexecutesql.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "mindsdb-execute-sql" +const resourceType string = "mindsdb-execute-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -58,8 +58,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -98,7 +98,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/mindsdb/mindsdbexecutesql/mindsdbexecutesql_test.go b/internal/tools/mindsdb/mindsdbexecutesql/mindsdbexecutesql_test.go index 4c5f2b84cb..db59ec7c54 100644 --- a/internal/tools/mindsdb/mindsdbexecutesql/mindsdbexecutesql_test.go +++ b/internal/tools/mindsdb/mindsdbexecutesql/mindsdbexecutesql_test.go @@ -17,7 +17,6 @@ package mindsdbexecutesql_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlExecuteSql(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mindsdb-execute-sql - source: my-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: mindsdb-execute-sql + source: my-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": mindsdbexecutesql.Config{ Name: "example_tool", - Kind: "mindsdb-execute-sql", + Type: "mindsdb-execute-sql", Source: "my-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,15 +58,12 @@ func TestParseFromYamlExecuteSql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/mindsdb/mindsdbsql/mindsdbsql.go b/internal/tools/mindsdb/mindsdbsql/mindsdbsql.go index 834dcdf007..3fc78c6fcd 100644 --- a/internal/tools/mindsdb/mindsdbsql/mindsdbsql.go +++ b/internal/tools/mindsdb/mindsdbsql/mindsdbsql.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "mindsdb-sql" +const resourceType string = "mindsdb-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Statement string `yaml:"statement" validate:"required"` @@ -61,8 +61,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -100,7 +100,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/mindsdb/mindsdbsql/mindsdbsql_test.go b/internal/tools/mindsdb/mindsdbsql/mindsdbsql_test.go index 3493717391..d203797196 100644 --- a/internal/tools/mindsdb/mindsdbsql/mindsdbsql_test.go +++ b/internal/tools/mindsdb/mindsdbsql/mindsdbsql_test.go @@ -17,7 +17,6 @@ package mindsdbsql_test import ( "testing" - 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" @@ -38,30 +37,30 @@ func TestParseFromYamlmindsdbsql(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mindsdb-sql - source: my-mindsdbsql-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - authRequired: - - my-google-auth-service - - other-auth-service - parameters: - - name: country - type: string - description: some description - authServices: - - name: my-google-auth-service - field: user_id - - name: other-auth-service - field: user_id + kind: tools + name: example_tool + type: mindsdb-sql + source: my-mindsdbsql-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + authRequired: + - my-google-auth-service + - other-auth-service + parameters: + - name: country + type: string + description: some description + authServices: + - name: my-google-auth-service + field: user_id + - name: other-auth-service + field: user_id `, want: server.ToolConfigs{ "example_tool": mindsdbsql.Config{ Name: "example_tool", - Kind: "mindsdb-sql", + Type: "mindsdb-sql", Source: "my-mindsdbsql-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -77,15 +76,12 @@ func TestParseFromYamlmindsdbsql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -105,41 +101,41 @@ func TestParseFromYamlWithTemplateParamsmindsdbsql(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mindsdb-sql - source: my-mindsdbsql-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - authRequired: - - my-google-auth-service - - other-auth-service - parameters: - - name: country - type: string - description: some description - authServices: - - name: my-google-auth-service - field: user_id - - name: other-auth-service - field: user_id - templateParameters: - - name: tableName - type: string - description: The table to select hotels from. - - name: fieldArray - type: array - description: The columns to return for the query. - items: - name: column - type: string - description: A column name that will be returned from the query. + kind: tools + name: example_tool + type: mindsdb-sql + source: my-mindsdbsql-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + authRequired: + - my-google-auth-service + - other-auth-service + parameters: + - name: country + type: string + description: some description + authServices: + - name: my-google-auth-service + field: user_id + - name: other-auth-service + field: user_id + templateParameters: + - name: tableName + type: string + description: The table to select hotels from. + - name: fieldArray + type: array + description: The columns to return for the query. + items: + name: column + type: string + description: A column name that will be returned from the query. `, want: server.ToolConfigs{ "example_tool": mindsdbsql.Config{ Name: "example_tool", - Kind: "mindsdb-sql", + Type: "mindsdb-sql", Source: "my-mindsdbsql-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -159,15 +155,12 @@ func TestParseFromYamlWithTemplateParamsmindsdbsql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/mongodb/mongodbaggregate/mongodbaggregate.go b/internal/tools/mongodb/mongodbaggregate/mongodbaggregate.go index 0b7ee56227..76210afa2a 100644 --- a/internal/tools/mongodb/mongodbaggregate/mongodbaggregate.go +++ b/internal/tools/mongodb/mongodbaggregate/mongodbaggregate.go @@ -27,11 +27,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" ) -const kind string = "mongodb-aggregate" +const resourceType string = "mongodb-aggregate" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` AuthRequired []string `yaml:"authRequired" validate:"required"` Description string `yaml:"description" validate:"required"` @@ -65,8 +65,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -103,7 +103,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/mongodb/mongodbaggregate/mongodbaggregate_test.go b/internal/tools/mongodb/mongodbaggregate/mongodbaggregate_test.go index 266ac5e982..a9adf7f272 100644 --- a/internal/tools/mongodb/mongodbaggregate/mongodbaggregate_test.go +++ b/internal/tools/mongodb/mongodbaggregate/mongodbaggregate_test.go @@ -21,7 +21,6 @@ import ( "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" @@ -40,25 +39,25 @@ func TestParseFromYamlMongoQuery(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mongodb-aggregate - source: my-instance - description: some description - database: test_db - collection: test_coll - readOnly: true - pipelinePayload: | - [{ $match: { name: {{json .name}} }}] - pipelineParams: - - name: name - type: string - description: small description + kind: tools + name: example_tool + type: mongodb-aggregate + source: my-instance + description: some description + database: test_db + collection: test_coll + readOnly: true + pipelinePayload: | + [{ $match: { name: {{json .name}} }}] + pipelineParams: + - name: name + type: string + description: small description `, want: server.ToolConfigs{ "example_tool": mongodbaggregate.Config{ Name: "example_tool", - Kind: "mongodb-aggregate", + Type: "mongodb-aggregate", Source: "my-instance", AuthRequired: []string{}, Database: "test_db", @@ -81,15 +80,12 @@ func TestParseFromYamlMongoQuery(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -110,25 +106,21 @@ func TestFailParseFromYamlMongoQuery(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: mongodb-aggregate - source: my-instance - description: some description - collection: test_coll - pipelinePayload: | - [{ $match: { name : {{json .name}} }}] + kind: tools + name: example_tool + type: mongodb-aggregate + source: my-instance + description: some description + collection: test_coll + pipelinePayload: | + [{ $match: { name : {{json .name}} }}] `, - err: `unable to parse tool "example_tool" as kind "mongodb-aggregate"`, + err: `unable to parse tool "example_tool" as type "mongodb-aggregate"`, }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/mongodb/mongodbdeletemany/mongodbdeletemany.go b/internal/tools/mongodb/mongodbdeletemany/mongodbdeletemany.go index ca746de1cd..6b4bd9de27 100644 --- a/internal/tools/mongodb/mongodbdeletemany/mongodbdeletemany.go +++ b/internal/tools/mongodb/mongodbdeletemany/mongodbdeletemany.go @@ -27,11 +27,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" ) -const kind string = "mongodb-delete-many" +const resourceType string = "mongodb-delete-many" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` AuthRequired []string `yaml:"authRequired" validate:"required"` Description string `yaml:"description" validate:"required"` @@ -63,8 +63,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -107,7 +107,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/mongodb/mongodbdeletemany/mongodbdeletemany_test.go b/internal/tools/mongodb/mongodbdeletemany/mongodbdeletemany_test.go index e5861949cf..af9ee4933e 100644 --- a/internal/tools/mongodb/mongodbdeletemany/mongodbdeletemany_test.go +++ b/internal/tools/mongodb/mongodbdeletemany/mongodbdeletemany_test.go @@ -21,7 +21,6 @@ import ( "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" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" @@ -40,24 +39,24 @@ func TestParseFromYamlMongoQuery(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mongodb-delete-many - source: my-instance - description: some description - database: test_db - collection: test_coll - filterPayload: | - { name: {{json .name}} } - filterParams: - - name: name - type: string - description: small description + kind: tools + name: example_tool + type: mongodb-delete-many + source: my-instance + description: some description + database: test_db + collection: test_coll + filterPayload: | + { name: {{json .name}} } + filterParams: + - name: name + type: string + description: small description `, want: server.ToolConfigs{ "example_tool": mongodbdeletemany.Config{ Name: "example_tool", - Kind: "mongodb-delete-many", + Type: "mongodb-delete-many", Source: "my-instance", AuthRequired: []string{}, Database: "test_db", @@ -79,15 +78,11 @@ func TestParseFromYamlMongoQuery(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -108,25 +103,21 @@ func TestFailParseFromYamlMongoQuery(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: mongodb-delete-many - source: my-instance - description: some description - collection: test_coll - filterPayload: | - { name : {{json .name}} } + kind: tools + name: example_tool + type: mongodb-delete-many + source: my-instance + description: some description + collection: test_coll + filterPayload: | + { name : {{json .name}} } `, - err: `unable to parse tool "example_tool" as kind "mongodb-delete-many"`, + err: `unable to parse tool "example_tool" as type "mongodb-delete-many"`, }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/mongodb/mongodbdeleteone/mongodbdeleteone.go b/internal/tools/mongodb/mongodbdeleteone/mongodbdeleteone.go index 477a3424db..a2506f8a40 100644 --- a/internal/tools/mongodb/mongodbdeleteone/mongodbdeleteone.go +++ b/internal/tools/mongodb/mongodbdeleteone/mongodbdeleteone.go @@ -27,11 +27,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" ) -const kind string = "mongodb-delete-one" +const resourceType string = "mongodb-delete-one" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` AuthRequired []string `yaml:"authRequired" validate:"required"` Description string `yaml:"description" validate:"required"` @@ -63,8 +63,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -107,7 +107,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/mongodb/mongodbdeleteone/mongodbdeleteone_test.go b/internal/tools/mongodb/mongodbdeleteone/mongodbdeleteone_test.go index 4aa99da297..3f395c6315 100644 --- a/internal/tools/mongodb/mongodbdeleteone/mongodbdeleteone_test.go +++ b/internal/tools/mongodb/mongodbdeleteone/mongodbdeleteone_test.go @@ -21,7 +21,6 @@ import ( "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" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" @@ -40,24 +39,24 @@ func TestParseFromYamlMongoQuery(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mongodb-delete-one - source: my-instance - description: some description - database: test_db - collection: test_coll - filterPayload: | - { name: {{json .name}} } - filterParams: - - name: name - type: string - description: small description + kind: tools + name: example_tool + type: mongodb-delete-one + source: my-instance + description: some description + database: test_db + collection: test_coll + filterPayload: | + { name: {{json .name}} } + filterParams: + - name: name + type: string + description: small description `, want: server.ToolConfigs{ "example_tool": mongodbdeleteone.Config{ Name: "example_tool", - Kind: "mongodb-delete-one", + Type: "mongodb-delete-one", Source: "my-instance", AuthRequired: []string{}, Database: "test_db", @@ -79,15 +78,11 @@ func TestParseFromYamlMongoQuery(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -108,25 +103,21 @@ func TestFailParseFromYamlMongoQuery(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: mongodb-delete-one - source: my-instance - description: some description - collection: test_coll - filterPayload: | - { name : {{json .name}} } + kind: tools + name: example_tool + type: mongodb-delete-one + source: my-instance + description: some description + collection: test_coll + filterPayload: | + { name : {{json .name}} } `, - err: `unable to parse tool "example_tool" as kind "mongodb-delete-one"`, + err: `unable to parse tool "example_tool" as type "mongodb-delete-one"`, }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/mongodb/mongodbfind/mongodbfind.go b/internal/tools/mongodb/mongodbfind/mongodbfind.go index 37374f0764..47083dba2c 100644 --- a/internal/tools/mongodb/mongodbfind/mongodbfind.go +++ b/internal/tools/mongodb/mongodbfind/mongodbfind.go @@ -30,11 +30,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" ) -const kind string = "mongodb-find" +const resourceType string = "mongodb-find" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -53,7 +53,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` AuthRequired []string `yaml:"authRequired" validate:"required"` Description string `yaml:"description" validate:"required"` @@ -71,8 +71,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -158,7 +158,7 @@ func getOptions(ctx context.Context, sortParameters parameters.Parameters, proje } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/mongodb/mongodbfind/mongodbfind_test.go b/internal/tools/mongodb/mongodbfind/mongodbfind_test.go index 6b56d9c7c4..dcc2591414 100644 --- a/internal/tools/mongodb/mongodbfind/mongodbfind_test.go +++ b/internal/tools/mongodb/mongodbfind/mongodbfind_test.go @@ -21,7 +21,6 @@ import ( "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" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" @@ -40,30 +39,30 @@ func TestParseFromYamlMongoQuery(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mongodb-find - source: my-instance - description: some description - database: test_db - collection: test_coll - filterPayload: | - { name: {{json .name}} } - filterParams: - - name: name - type: string - description: small description - projectPayload: | - { name: 1, age: 1 } - projectParams: [] - sortPayload: | - { timestamp: -1 } - sortParams: [] + kind: tools + name: example_tool + type: mongodb-find + source: my-instance + description: some description + database: test_db + collection: test_coll + filterPayload: | + { name: {{json .name}} } + filterParams: + - name: name + type: string + description: small description + projectPayload: | + { name: 1, age: 1 } + projectParams: [] + sortPayload: | + { timestamp: -1 } + sortParams: [] `, want: server.ToolConfigs{ "example_tool": mongodbfind.Config{ Name: "example_tool", - Kind: "mongodb-find", + Type: "mongodb-find", Source: "my-instance", AuthRequired: []string{}, Database: "test_db", @@ -89,15 +88,11 @@ func TestParseFromYamlMongoQuery(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -118,25 +113,21 @@ func TestFailParseFromYamlMongoQuery(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: mongodb-find - source: my-instance - description: some description - collection: test_coll - filterPayload: | - { name : {{json .name}} } + kind: tools + name: example_tool + type: mongodb-find + source: my-instance + description: some description + collection: test_coll + filterPayload: | + { name : {{json .name}} } `, - err: `unable to parse tool "example_tool" as kind "mongodb-find"`, + err: `unable to parse tool "example_tool" as type "mongodb-find"`, }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/mongodb/mongodbfindone/mongodbfindone.go b/internal/tools/mongodb/mongodbfindone/mongodbfindone.go index 8aa9e59b5b..2e185f088e 100644 --- a/internal/tools/mongodb/mongodbfindone/mongodbfindone.go +++ b/internal/tools/mongodb/mongodbfindone/mongodbfindone.go @@ -29,11 +29,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools" ) -const kind string = "mongodb-find-one" +const resourceType string = "mongodb-find-one" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -52,7 +52,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` AuthRequired []string `yaml:"authRequired" validate:"required"` Description string `yaml:"description" validate:"required"` @@ -67,8 +67,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -111,7 +111,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/mongodb/mongodbfindone/mongodbfindone_test.go b/internal/tools/mongodb/mongodbfindone/mongodbfindone_test.go index a8d5b9bfc0..ce23e01e11 100644 --- a/internal/tools/mongodb/mongodbfindone/mongodbfindone_test.go +++ b/internal/tools/mongodb/mongodbfindone/mongodbfindone_test.go @@ -21,7 +21,6 @@ import ( "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" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" @@ -40,27 +39,27 @@ func TestParseFromYamlMongoQuery(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mongodb-find-one - source: my-instance - description: some description - database: test_db - collection: test_coll - filterPayload: | - { name: {{json .name}} } - filterParams: - - name: name - type: string - description: small description - projectPayload: | - { name: 1, age: 1 } - projectParams: [] + kind: tools + name: example_tool + type: mongodb-find-one + source: my-instance + description: some description + database: test_db + collection: test_coll + filterPayload: | + { name: {{json .name}} } + filterParams: + - name: name + type: string + description: small description + projectPayload: | + { name: 1, age: 1 } + projectParams: [] `, want: server.ToolConfigs{ "example_tool": mongodbfindone.Config{ Name: "example_tool", - Kind: "mongodb-find-one", + Type: "mongodb-find-one", Source: "my-instance", AuthRequired: []string{}, Database: "test_db", @@ -84,15 +83,11 @@ func TestParseFromYamlMongoQuery(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -113,25 +108,21 @@ func TestFailParseFromYamlMongoQuery(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: mongodb-find-one - source: my-instance - description: some description - collection: test_coll - filterPayload: | - { name : {{json .name}} } + kind: tools + name: example_tool + type: mongodb-find-one + source: my-instance + description: some description + collection: test_coll + filterPayload: | + { name : {{json .name}} } `, - err: `unable to parse tool "example_tool" as kind "mongodb-find-one"`, + err: `unable to parse tool "example_tool" as type "mongodb-find-one"`, }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/mongodb/mongodbinsertmany/mongodbinsertmany.go b/internal/tools/mongodb/mongodbinsertmany/mongodbinsertmany.go index 9a0b07730b..d7e43de7f1 100644 --- a/internal/tools/mongodb/mongodbinsertmany/mongodbinsertmany.go +++ b/internal/tools/mongodb/mongodbinsertmany/mongodbinsertmany.go @@ -26,13 +26,13 @@ import ( "go.mongodb.org/mongo-driver/mongo" ) -const kind string = "mongodb-insert-many" +const resourceType string = "mongodb-insert-many" const paramDataKey = "data" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -51,7 +51,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` AuthRequired []string `yaml:"authRequired" validate:"required"` Description string `yaml:"description" validate:"required"` @@ -63,8 +63,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -101,7 +101,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/mongodb/mongodbinsertmany/mongodbinsertmany_test.go b/internal/tools/mongodb/mongodbinsertmany/mongodbinsertmany_test.go index 19ac3ce0c1..e965e056d9 100644 --- a/internal/tools/mongodb/mongodbinsertmany/mongodbinsertmany_test.go +++ b/internal/tools/mongodb/mongodbinsertmany/mongodbinsertmany_test.go @@ -20,7 +20,6 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbinsertmany" - 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" @@ -39,18 +38,18 @@ func TestParseFromYamlMongoQuery(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mongodb-insert-many - source: my-instance - description: some description - database: test_db - collection: test_coll + kind: tools + name: example_tool + type: mongodb-insert-many + source: my-instance + description: some description + database: test_db + collection: test_coll `, want: server.ToolConfigs{ "example_tool": mongodbinsertmany.Config{ Name: "example_tool", - Kind: "mongodb-insert-many", + Type: "mongodb-insert-many", Source: "my-instance", AuthRequired: []string{}, Database: "test_db", @@ -63,19 +62,19 @@ func TestParseFromYamlMongoQuery(t *testing.T) { { desc: "true canonical", in: ` - tools: - example_tool: - kind: mongodb-insert-many - source: my-instance - description: some description - database: test_db - collection: test_coll - canonical: true + kind: tools + name: example_tool + type: mongodb-insert-many + source: my-instance + description: some description + database: test_db + collection: test_coll + canonical: true `, want: server.ToolConfigs{ "example_tool": mongodbinsertmany.Config{ Name: "example_tool", - Kind: "mongodb-insert-many", + Type: "mongodb-insert-many", Source: "my-instance", AuthRequired: []string{}, Database: "test_db", @@ -88,19 +87,19 @@ func TestParseFromYamlMongoQuery(t *testing.T) { { desc: "false canonical", in: ` - tools: - example_tool: - kind: mongodb-insert-many - source: my-instance - description: some description - database: test_db - collection: test_coll - canonical: false + kind: tools + name: example_tool + type: mongodb-insert-many + source: my-instance + description: some description + database: test_db + collection: test_coll + canonical: false `, want: server.ToolConfigs{ "example_tool": mongodbinsertmany.Config{ Name: "example_tool", - Kind: "mongodb-insert-many", + Type: "mongodb-insert-many", Source: "my-instance", AuthRequired: []string{}, Database: "test_db", @@ -113,15 +112,11 @@ func TestParseFromYamlMongoQuery(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -142,23 +137,19 @@ func TestFailParseFromYamlMongoQuery(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: mongodb-insert-many - source: my-instance - description: some description - collection: test_coll + kind: tools + name: example_tool + type: mongodb-insert-many + source: my-instance + description: some description + collection: test_coll `, - err: `unable to parse tool "example_tool" as kind "mongodb-insert-many"`, + err: `unable to parse tool "example_tool" as type "mongodb-insert-many"`, }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/mongodb/mongodbinsertone/mongodbinsertone.go b/internal/tools/mongodb/mongodbinsertone/mongodbinsertone.go index cd76f7688c..bebe175d23 100644 --- a/internal/tools/mongodb/mongodbinsertone/mongodbinsertone.go +++ b/internal/tools/mongodb/mongodbinsertone/mongodbinsertone.go @@ -26,13 +26,13 @@ import ( "go.mongodb.org/mongo-driver/mongo" ) -const kind string = "mongodb-insert-one" +const resourceType string = "mongodb-insert-one" const dataParamsKey = "data" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -51,7 +51,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` AuthRequired []string `yaml:"authRequired" validate:"required"` Description string `yaml:"description" validate:"required"` @@ -63,8 +63,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -102,7 +102,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/mongodb/mongodbinsertone/mongodbinsertone_test.go b/internal/tools/mongodb/mongodbinsertone/mongodbinsertone_test.go index a61dde20b0..ace38f2d78 100644 --- a/internal/tools/mongodb/mongodbinsertone/mongodbinsertone_test.go +++ b/internal/tools/mongodb/mongodbinsertone/mongodbinsertone_test.go @@ -20,7 +20,6 @@ import ( "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbinsertone" - 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" @@ -39,18 +38,18 @@ func TestParseFromYamlMongoQuery(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mongodb-insert-one - source: my-instance - description: some description - database: test_db - collection: test_coll + kind: tools + name: example_tool + type: mongodb-insert-one + source: my-instance + description: some description + database: test_db + collection: test_coll `, want: server.ToolConfigs{ "example_tool": mongodbinsertone.Config{ Name: "example_tool", - Kind: "mongodb-insert-one", + Type: "mongodb-insert-one", Source: "my-instance", AuthRequired: []string{}, Database: "test_db", @@ -63,19 +62,19 @@ func TestParseFromYamlMongoQuery(t *testing.T) { { desc: "true canonical", in: ` - tools: - example_tool: - kind: mongodb-insert-one - source: my-instance - description: some description - database: test_db - collection: test_coll - canonical: true + kind: tools + name: example_tool + type: mongodb-insert-one + source: my-instance + description: some description + database: test_db + collection: test_coll + canonical: true `, want: server.ToolConfigs{ "example_tool": mongodbinsertone.Config{ Name: "example_tool", - Kind: "mongodb-insert-one", + Type: "mongodb-insert-one", Source: "my-instance", AuthRequired: []string{}, Database: "test_db", @@ -88,19 +87,19 @@ func TestParseFromYamlMongoQuery(t *testing.T) { { desc: "false canonical", in: ` - tools: - example_tool: - kind: mongodb-insert-one - source: my-instance - description: some description - database: test_db - collection: test_coll - canonical: false + kind: tools + name: example_tool + type: mongodb-insert-one + source: my-instance + description: some description + database: test_db + collection: test_coll + canonical: false `, want: server.ToolConfigs{ "example_tool": mongodbinsertone.Config{ Name: "example_tool", - Kind: "mongodb-insert-one", + Type: "mongodb-insert-one", Source: "my-instance", AuthRequired: []string{}, Database: "test_db", @@ -113,15 +112,11 @@ func TestParseFromYamlMongoQuery(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -142,24 +137,20 @@ func TestFailParseFromYamlMongoQuery(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: mongodb-insert-one - source: my-instance - description: some description - collection: test_coll - canonical: true + kind: tools + name: example_tool + type: mongodb-insert-one + source: my-instance + description: some description + collection: test_coll + canonical: true `, - err: `unable to parse tool "example_tool" as kind "mongodb-insert-one"`, + err: `unable to parse tool "example_tool" as type "mongodb-insert-one"`, }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany.go b/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany.go index dcf4467f74..2d4def3fdc 100644 --- a/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany.go +++ b/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany.go @@ -26,11 +26,11 @@ import ( "go.mongodb.org/mongo-driver/mongo" ) -const kind string = "mongodb-update-many" +const resourceType string = "mongodb-update-many" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` AuthRequired []string `yaml:"authRequired" validate:"required"` Description string `yaml:"description" validate:"required"` @@ -66,8 +66,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -110,7 +110,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany_test.go b/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany_test.go index b7353afe08..f3fcf468d5 100644 --- a/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany_test.go +++ b/internal/tools/mongodb/mongodbupdatemany/mongodbupdatemany_test.go @@ -21,7 +21,6 @@ import ( "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" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" @@ -40,30 +39,30 @@ func TestParseFromYamlMongoQuery(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mongodb-update-many - source: my-instance - description: some description - database: test_db - collection: test_coll - filterPayload: | - { name: {{json .name}} } - filterParams: - - name: name - type: string - description: small description - updatePayload: | - { $set: { name: {{json .name}} } } - updateParams: - - name: name - type: string - description: small description + kind: tools + name: example_tool + type: mongodb-update-many + source: my-instance + description: some description + database: test_db + collection: test_coll + filterPayload: | + { name: {{json .name}} } + filterParams: + - name: name + type: string + description: small description + updatePayload: | + { $set: { name: {{json .name}} } } + updateParams: + - name: name + type: string + description: small description `, want: server.ToolConfigs{ "example_tool": mongodbupdatemany.Config{ Name: "example_tool", - Kind: "mongodb-update-many", + Type: "mongodb-update-many", Source: "my-instance", AuthRequired: []string{}, Database: "test_db", @@ -96,31 +95,31 @@ func TestParseFromYamlMongoQuery(t *testing.T) { { desc: "true canonical", in: ` - tools: - example_tool: - kind: mongodb-update-many - source: my-instance - description: some description - database: test_db - collection: test_coll - filterPayload: | - { name: {{json .name}} } - filterParams: - - name: name - type: string - description: small description - canonical: true - updatePayload: | - { $set: { name: {{json .name}} } } - updateParams: - - name: name - type: string - description: small description + kind: tools + name: example_tool + type: mongodb-update-many + source: my-instance + description: some description + database: test_db + collection: test_coll + filterPayload: | + { name: {{json .name}} } + filterParams: + - name: name + type: string + description: small description + canonical: true + updatePayload: | + { $set: { name: {{json .name}} } } + updateParams: + - name: name + type: string + description: small description `, want: server.ToolConfigs{ "example_tool": mongodbupdatemany.Config{ Name: "example_tool", - Kind: "mongodb-update-many", + Type: "mongodb-update-many", Source: "my-instance", AuthRequired: []string{}, Database: "test_db", @@ -153,31 +152,31 @@ func TestParseFromYamlMongoQuery(t *testing.T) { { desc: "false canonical", in: ` - tools: - example_tool: - kind: mongodb-update-many - source: my-instance - description: some description - database: test_db - collection: test_coll - filterPayload: | - { name: {{json .name}} } - filterParams: - - name: name - type: string - description: small description - canonical: false - updatePayload: | - { $set: { name: {{json .name}} } } - updateParams: - - name: name - type: string - description: small description + kind: tools + name: example_tool + type: mongodb-update-many + source: my-instance + description: some description + database: test_db + collection: test_coll + filterPayload: | + { name: {{json .name}} } + filterParams: + - name: name + type: string + description: small description + canonical: false + updatePayload: | + { $set: { name: {{json .name}} } } + updateParams: + - name: name + type: string + description: small description `, want: server.ToolConfigs{ "example_tool": mongodbupdatemany.Config{ Name: "example_tool", - Kind: "mongodb-update-many", + Type: "mongodb-update-many", Source: "my-instance", AuthRequired: []string{}, Database: "test_db", @@ -210,15 +209,11 @@ func TestParseFromYamlMongoQuery(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -239,36 +234,32 @@ func TestFailParseFromYamlMongoQuery(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: mongodb-update-many - source: my-instance - description: some description - collection: test_coll - filterPayload: | - { name : {{json .name}} } - filterParams: - - name: name - type: string - description: small description - canonical: true - updatePayload: | - { $set: { name: {{json .name}} } } - updateParams: - - name: data - type: string - description: the content in json + kind: tools + name: example_tool + type: mongodb-update-many + source: my-instance + description: some description + collection: test_coll + filterPayload: | + { name : {{json .name}} } + filterParams: + - name: name + type: string + description: small description + canonical: true + updatePayload: | + { $set: { name: {{json .name}} } } + updateParams: + - name: data + type: string + description: the content in json `, - err: `unable to parse tool "example_tool" as kind "mongodb-update-many"`, + err: `unable to parse tool "example_tool" as type "mongodb-update-many"`, }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/mongodb/mongodbupdateone/mongodbupdateone.go b/internal/tools/mongodb/mongodbupdateone/mongodbupdateone.go index 938bbb6dce..1addaf8d29 100644 --- a/internal/tools/mongodb/mongodbupdateone/mongodbupdateone.go +++ b/internal/tools/mongodb/mongodbupdateone/mongodbupdateone.go @@ -26,11 +26,11 @@ import ( "go.mongodb.org/mongo-driver/mongo" ) -const kind string = "mongodb-update-one" +const resourceType string = "mongodb-update-one" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` AuthRequired []string `yaml:"authRequired" validate:"required"` Description string `yaml:"description" validate:"required"` @@ -67,8 +67,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -111,7 +111,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/mongodb/mongodbupdateone/mongodbupdateone_test.go b/internal/tools/mongodb/mongodbupdateone/mongodbupdateone_test.go index b450892fb2..87202485f7 100644 --- a/internal/tools/mongodb/mongodbupdateone/mongodbupdateone_test.go +++ b/internal/tools/mongodb/mongodbupdateone/mongodbupdateone_test.go @@ -21,7 +21,6 @@ import ( "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" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/testutils" @@ -40,31 +39,31 @@ func TestParseFromYamlMongoQuery(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mongodb-update-one - source: my-instance - description: some description - database: test_db - collection: test_coll - filterPayload: | - { name: {{json .name}} } - filterParams: - - name: name - type: string - description: small description - updatePayload: | - { $set : { item: {{json .item}} } } - updateParams: - - name: item - type: string - description: small description - upsert: true + kind: tools + name: example_tool + type: mongodb-update-one + source: my-instance + description: some description + database: test_db + collection: test_coll + filterPayload: | + { name: {{json .name}} } + filterParams: + - name: name + type: string + description: small description + updatePayload: | + { $set : { item: {{json .item}} } } + updateParams: + - name: item + type: string + description: small description + upsert: true `, want: server.ToolConfigs{ "example_tool": mongodbupdateone.Config{ Name: "example_tool", - Kind: "mongodb-update-one", + Type: "mongodb-update-one", Source: "my-instance", AuthRequired: []string{}, Database: "test_db", @@ -98,32 +97,32 @@ func TestParseFromYamlMongoQuery(t *testing.T) { { desc: "false canonical", in: ` - tools: - example_tool: - kind: mongodb-update-one - source: my-instance - description: some description - database: test_db - collection: test_coll - filterPayload: | - { name: {{json .name}} } - filterParams: - - name: name - type: string - description: small description - updatePayload: | - { $set : { item: {{json .item}} } } - updateParams: - - name: item - type: string - description: small description - canonical: false - upsert: true + kind: tools + name: example_tool + type: mongodb-update-one + source: my-instance + description: some description + database: test_db + collection: test_coll + filterPayload: | + { name: {{json .name}} } + filterParams: + - name: name + type: string + description: small description + updatePayload: | + { $set : { item: {{json .item}} } } + updateParams: + - name: item + type: string + description: small description + canonical: false + upsert: true `, want: server.ToolConfigs{ "example_tool": mongodbupdateone.Config{ Name: "example_tool", - Kind: "mongodb-update-one", + Type: "mongodb-update-one", Source: "my-instance", AuthRequired: []string{}, Database: "test_db", @@ -157,32 +156,32 @@ func TestParseFromYamlMongoQuery(t *testing.T) { { desc: "true canonical", in: ` - tools: - example_tool: - kind: mongodb-update-one - source: my-instance - description: some description - database: test_db - collection: test_coll - filterPayload: | - { name: {{json .name}} } - filterParams: - - name: name - type: string - description: small description - updatePayload: | - { $set : { item: {{json .item}} } } - updateParams: - - name: item - type: string - description: small description - canonical: true - upsert: true + kind: tools + name: example_tool + type: mongodb-update-one + source: my-instance + description: some description + database: test_db + collection: test_coll + filterPayload: | + { name: {{json .name}} } + filterParams: + - name: name + type: string + description: small description + updatePayload: | + { $set : { item: {{json .item}} } } + updateParams: + - name: item + type: string + description: small description + canonical: true + upsert: true `, want: server.ToolConfigs{ "example_tool": mongodbupdateone.Config{ Name: "example_tool", - Kind: "mongodb-update-one", + Type: "mongodb-update-one", Source: "my-instance", AuthRequired: []string{}, Database: "test_db", @@ -216,15 +215,11 @@ func TestParseFromYamlMongoQuery(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -245,24 +240,20 @@ func TestFailParseFromYamlMongoQuery(t *testing.T) { { desc: "Invalid method", in: ` - tools: - example_tool: - kind: mongodb-update-one - source: my-instance - description: some description - collection: test_coll - filterPayload: | - { name : {{json .name}} }`, - err: `unable to parse tool "example_tool" as kind "mongodb-update-one"`, + kind: tools + name: example_tool + type: mongodb-update-one + source: my-instance + description: some description + collection: test_coll + filterPayload: | + { name : {{json .name}} }`, + err: `unable to parse tool "example_tool" as type "mongodb-update-one"`, }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/mssql/mssqlexecutesql/mssqlexecutesql.go b/internal/tools/mssql/mssqlexecutesql/mssqlexecutesql.go index 00d3bc30e4..cdaa8df1e9 100644 --- a/internal/tools/mssql/mssqlexecutesql/mssqlexecutesql.go +++ b/internal/tools/mssql/mssqlexecutesql/mssqlexecutesql.go @@ -27,11 +27,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "mssql-execute-sql" +const resourceType string = "mssql-execute-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -59,8 +59,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -90,7 +90,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -106,7 +106,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para if err != nil { return nil, fmt.Errorf("error getting logger: %s", err) } - logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", kind, sql)) + logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", resourceType, sql)) return source.RunSQL(ctx, sql, nil) } diff --git a/internal/tools/mssql/mssqlexecutesql/mssqlexecutesql_test.go b/internal/tools/mssql/mssqlexecutesql/mssqlexecutesql_test.go index 5042b54215..560be13cad 100644 --- a/internal/tools/mssql/mssqlexecutesql/mssqlexecutesql_test.go +++ b/internal/tools/mssql/mssqlexecutesql/mssqlexecutesql_test.go @@ -17,7 +17,6 @@ package mssqlexecutesql_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlExecuteSql(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mssql-execute-sql - source: my-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: mssql-execute-sql + source: my-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": mssqlexecutesql.Config{ Name: "example_tool", - Kind: "mssql-execute-sql", + Type: "mssql-execute-sql", Source: "my-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,15 +58,12 @@ func TestParseFromYamlExecuteSql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/mssql/mssqllisttables/mssqllisttables.go b/internal/tools/mssql/mssqllisttables/mssqllisttables.go index a93ab96db6..99a5e2d36e 100644 --- a/internal/tools/mssql/mssqllisttables/mssqllisttables.go +++ b/internal/tools/mssql/mssqllisttables/mssqllisttables.go @@ -26,7 +26,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "mssql-list-tables" +const resourceType string = "mssql-list-tables" const listTablesStatement = ` WITH table_info AS ( @@ -278,8 +278,8 @@ const listTablesStatement = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -298,7 +298,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -307,8 +307,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -340,7 +340,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/mssql/mssqllisttables/mssqllisttables_test.go b/internal/tools/mssql/mssqllisttables/mssqllisttables_test.go index 029a89a1ca..1da6d18eae 100644 --- a/internal/tools/mssql/mssqllisttables/mssqllisttables_test.go +++ b/internal/tools/mssql/mssqllisttables/mssqllisttables_test.go @@ -17,7 +17,6 @@ package mssqllisttables_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlmssqlListTables(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mssql-list-tables - source: my-mssql-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: mssql-list-tables + source: my-mssql-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": mssqllisttables.Config{ Name: "example_tool", - Kind: "mssql-list-tables", + Type: "mssql-list-tables", Source: "my-mssql-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,15 +58,12 @@ func TestParseFromYamlmssqlListTables(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/mssql/mssqlsql/mssqlsql.go b/internal/tools/mssql/mssqlsql/mssqlsql.go index f8a76a7e2f..60c60550ee 100644 --- a/internal/tools/mssql/mssqlsql/mssqlsql.go +++ b/internal/tools/mssql/mssqlsql/mssqlsql.go @@ -27,11 +27,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "mssql-sql" +const resourceType string = "mssql-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Statement string `yaml:"statement" validate:"required"` @@ -62,8 +62,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -95,7 +95,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/mssql/mssqlsql/mssqlsql_test.go b/internal/tools/mssql/mssqlsql/mssqlsql_test.go index 3fb9b44d8c..043b97f0ce 100644 --- a/internal/tools/mssql/mssqlsql/mssqlsql_test.go +++ b/internal/tools/mssql/mssqlsql/mssqlsql_test.go @@ -17,7 +17,6 @@ package mssqlsql_test import ( "testing" - 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" @@ -38,30 +37,30 @@ func TestParseFromYamlMssql(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mssql-sql - source: my-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - authRequired: - - my-google-auth-service - - other-auth-service - parameters: - - name: country - type: string - description: some description - authServices: - - name: my-google-auth-service - field: user_id - - name: other-auth-service - field: user_id + kind: tools + name: example_tool + type: mssql-sql + source: my-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + authRequired: + - my-google-auth-service + - other-auth-service + parameters: + - name: country + type: string + description: some description + authServices: + - name: my-google-auth-service + field: user_id + - name: other-auth-service + field: user_id `, want: server.ToolConfigs{ "example_tool": mssqlsql.Config{ Name: "example_tool", - Kind: "mssql-sql", + Type: "mssql-sql", Source: "my-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -77,15 +76,12 @@ func TestParseFromYamlMssql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -105,41 +101,41 @@ func TestParseFromYamlWithTemplateMssql(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mssql-sql - source: my-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - authRequired: - - my-google-auth-service - - other-auth-service - parameters: - - name: country - type: string - description: some description - authServices: - - name: my-google-auth-service - field: user_id - - name: other-auth-service - field: user_id - templateParameters: - - name: tableName - type: string - description: The table to select hotels from. - - name: fieldArray - type: array - description: The columns to return for the query. - items: - name: column - type: string - description: A column name that will be returned from the query. + kind: tools + name: example_tool + type: mssql-sql + source: my-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + authRequired: + - my-google-auth-service + - other-auth-service + parameters: + - name: country + type: string + description: some description + authServices: + - name: my-google-auth-service + field: user_id + - name: other-auth-service + field: user_id + templateParameters: + - name: tableName + type: string + description: The table to select hotels from. + - name: fieldArray + type: array + description: The columns to return for the query. + items: + name: column + type: string + description: A column name that will be returned from the query. `, want: server.ToolConfigs{ "example_tool": mssqlsql.Config{ Name: "example_tool", - Kind: "mssql-sql", + Type: "mssql-sql", Source: "my-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -159,15 +155,12 @@ func TestParseFromYamlWithTemplateMssql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/mysql/mysqlexecutesql/mysqlexecutesql.go b/internal/tools/mysql/mysqlexecutesql/mysqlexecutesql.go index 5031553074..289c895ae6 100644 --- a/internal/tools/mysql/mysqlexecutesql/mysqlexecutesql.go +++ b/internal/tools/mysql/mysqlexecutesql/mysqlexecutesql.go @@ -27,11 +27,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "mysql-execute-sql" +const resourceType string = "mysql-execute-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -59,8 +59,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -90,7 +90,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -106,7 +106,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para if err != nil { return nil, fmt.Errorf("error getting logger: %s", err) } - logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", kind, sql)) + logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", resourceType, sql)) return source.RunSQL(ctx, sql, nil) } diff --git a/internal/tools/mysql/mysqlexecutesql/mysqlexecutesql_test.go b/internal/tools/mysql/mysqlexecutesql/mysqlexecutesql_test.go index 9044c2575d..43b4324728 100644 --- a/internal/tools/mysql/mysqlexecutesql/mysqlexecutesql_test.go +++ b/internal/tools/mysql/mysqlexecutesql/mysqlexecutesql_test.go @@ -17,7 +17,6 @@ package mysqlexecutesql_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlExecuteSql(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mysql-execute-sql - source: my-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: mysql-execute-sql + source: my-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": mysqlexecutesql.Config{ Name: "example_tool", - Kind: "mysql-execute-sql", + Type: "mysql-execute-sql", Source: "my-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,15 +58,12 @@ func TestParseFromYamlExecuteSql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/mysql/mysqlgetqueryplan/mysqlgetqueryplan.go b/internal/tools/mysql/mysqlgetqueryplan/mysqlgetqueryplan.go index 8707935e0f..9cf6c88d3b 100644 --- a/internal/tools/mysql/mysqlgetqueryplan/mysqlgetqueryplan.go +++ b/internal/tools/mysql/mysqlgetqueryplan/mysqlgetqueryplan.go @@ -29,11 +29,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "mysql-get-query-plan" +const resourceType string = "mysql-get-query-plan" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -52,7 +52,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -61,8 +61,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -92,7 +92,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -108,7 +108,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para if err != nil { return nil, fmt.Errorf("error getting logger: %s", err) } - logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", kind, sql)) + logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", resourceType, sql)) query := fmt.Sprintf("EXPLAIN FORMAT=JSON %s", sql) result, err := source.RunSQL(ctx, query, nil) diff --git a/internal/tools/mysql/mysqlgetqueryplan/mysqlgetqueryplan_test.go b/internal/tools/mysql/mysqlgetqueryplan/mysqlgetqueryplan_test.go index b06248dbaf..43ed82aa35 100644 --- a/internal/tools/mysql/mysqlgetqueryplan/mysqlgetqueryplan_test.go +++ b/internal/tools/mysql/mysqlgetqueryplan/mysqlgetqueryplan_test.go @@ -17,7 +17,6 @@ package mysqlgetqueryplan_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlGetQueryPlan(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mysql-get-query-plan - source: my-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: mysql-get-query-plan + source: my-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": mysqlgetqueryplan.Config{ Name: "example_tool", - Kind: "mysql-get-query-plan", + Type: "mysql-get-query-plan", Source: "my-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,15 +58,12 @@ func TestParseFromYamlGetQueryPlan(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/mysql/mysqllistactivequeries/mysqllistactivequeries.go b/internal/tools/mysql/mysqllistactivequeries/mysqllistactivequeries.go index be1df8d6cc..32dfc8d735 100644 --- a/internal/tools/mysql/mysqllistactivequeries/mysqllistactivequeries.go +++ b/internal/tools/mysql/mysqllistactivequeries/mysqllistactivequeries.go @@ -29,7 +29,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "mysql-list-active-queries" +const resourceType string = "mysql-list-active-queries" const listActiveQueriesStatementMySQL = ` SELECT @@ -94,8 +94,8 @@ const listActiveQueriesStatementCloudSQLMySQL = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -114,7 +114,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -123,8 +123,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -136,7 +136,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible _, ok = rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source) + return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source) } allParameters := parameters.Parameters{ @@ -146,14 +146,14 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, allParameters, nil) var statement string - sourceKind := rawS.SourceKind() - switch sourceKind { - case mysql.SourceKind: + sourceType := rawS.SourceType() + switch sourceType { + case mysql.SourceType: statement = listActiveQueriesStatementMySQL - case cloudsqlmysql.SourceKind: + case cloudsqlmysql.SourceType: statement = listActiveQueriesStatementCloudSQLMySQL default: - return nil, fmt.Errorf("unsupported source kind: %s", cfg.Source) + return nil, fmt.Errorf("unsupported source type: %s", cfg.Source) } // finish tool setup t := Tool{ @@ -178,7 +178,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -199,7 +199,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para if err != nil { return nil, fmt.Errorf("error getting logger: %s", err) } - logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", kind, t.statement)) + logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", resourceType, t.statement)) return source.RunSQL(ctx, t.statement, []any{duration, duration, limit}) } diff --git a/internal/tools/mysql/mysqllistactivequeries/mysqllistactivequeries_test.go b/internal/tools/mysql/mysqllistactivequeries/mysqllistactivequeries_test.go index cacc41c1ed..5351981f38 100644 --- a/internal/tools/mysql/mysqllistactivequeries/mysqllistactivequeries_test.go +++ b/internal/tools/mysql/mysqllistactivequeries/mysqllistactivequeries_test.go @@ -17,7 +17,6 @@ package mysqllistactivequeries_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlExecuteSql(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mysql-list-active-queries - source: my-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: mysql-list-active-queries + source: my-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": mysqllistactivequeries.Config{ Name: "example_tool", - Kind: "mysql-list-active-queries", + Type: "mysql-list-active-queries", Source: "my-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,15 +58,12 @@ func TestParseFromYamlExecuteSql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/mysql/mysqllisttablefragmentation/mysqllisttablefragmentation.go b/internal/tools/mysql/mysqllisttablefragmentation/mysqllisttablefragmentation.go index 7297fc805f..2ad5a232eb 100644 --- a/internal/tools/mysql/mysqllisttablefragmentation/mysqllisttablefragmentation.go +++ b/internal/tools/mysql/mysqllisttablefragmentation/mysqllisttablefragmentation.go @@ -27,7 +27,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "mysql-list-table-fragmentation" +const resourceType string = "mysql-list-table-fragmentation" const listTableFragmentationStatement = ` SELECT @@ -52,8 +52,8 @@ const listTableFragmentationStatement = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -72,7 +72,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -81,8 +81,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -115,7 +115,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -144,7 +144,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para if err != nil { return nil, fmt.Errorf("error getting logger: %s", err) } - logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", kind, listTableFragmentationStatement)) + logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", resourceType, listTableFragmentationStatement)) sliceParams := []any{table_schema, table_schema, table_name, table_name, data_free_threshold_bytes, limit} return source.RunSQL(ctx, listTableFragmentationStatement, sliceParams) } diff --git a/internal/tools/mysql/mysqllisttablefragmentation/mysqllisttablefragmentation_test.go b/internal/tools/mysql/mysqllisttablefragmentation/mysqllisttablefragmentation_test.go index 401f672e72..07867ae8b1 100644 --- a/internal/tools/mysql/mysqllisttablefragmentation/mysqllisttablefragmentation_test.go +++ b/internal/tools/mysql/mysqllisttablefragmentation/mysqllisttablefragmentation_test.go @@ -17,7 +17,6 @@ package mysqllisttablefragmentation_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlExecuteSql(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mysql-list-table-fragmentation - source: my-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: mysql-list-table-fragmentation + source: my-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": mysqllisttablefragmentation.Config{ Name: "example_tool", - Kind: "mysql-list-table-fragmentation", + Type: "mysql-list-table-fragmentation", Source: "my-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,15 +58,12 @@ func TestParseFromYamlExecuteSql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/mysql/mysqllisttables/mysqllisttables.go b/internal/tools/mysql/mysqllisttables/mysqllisttables.go index dc2c265071..1bc1753564 100644 --- a/internal/tools/mysql/mysqllisttables/mysqllisttables.go +++ b/internal/tools/mysql/mysqllisttables/mysqllisttables.go @@ -26,7 +26,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "mysql-list-tables" +const resourceType string = "mysql-list-tables" const listTablesStatement = ` SELECT @@ -182,8 +182,8 @@ const listTablesStatement = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -202,7 +202,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -211,8 +211,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -245,7 +245,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/mysql/mysqllisttables/mysqllisttables_test.go b/internal/tools/mysql/mysqllisttables/mysqllisttables_test.go index c195e4f4e7..5112d88ed9 100644 --- a/internal/tools/mysql/mysqllisttables/mysqllisttables_test.go +++ b/internal/tools/mysql/mysqllisttables/mysqllisttables_test.go @@ -17,7 +17,6 @@ package mysqllisttables_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlMySQLListTables(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mysql-list-tables - source: my-mysql-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: mysql-list-tables + source: my-mysql-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": mysqllisttables.Config{ Name: "example_tool", - Kind: "mysql-list-tables", + Type: "mysql-list-tables", Source: "my-mysql-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,15 +58,12 @@ func TestParseFromYamlMySQLListTables(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/mysql/mysqllisttablesmissinguniqueindexes/mysqllisttablesmissinguniqueindexes.go b/internal/tools/mysql/mysqllisttablesmissinguniqueindexes/mysqllisttablesmissinguniqueindexes.go index d55ad4fa02..8b5464df0d 100644 --- a/internal/tools/mysql/mysqllisttablesmissinguniqueindexes/mysqllisttablesmissinguniqueindexes.go +++ b/internal/tools/mysql/mysqllisttablesmissinguniqueindexes/mysqllisttablesmissinguniqueindexes.go @@ -27,7 +27,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "mysql-list-tables-missing-unique-indexes" +const resourceType string = "mysql-list-tables-missing-unique-indexes" const listTablesMissingUniqueIndexesStatement = ` SELECT @@ -53,8 +53,8 @@ const listTablesMissingUniqueIndexesStatement = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -73,7 +73,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -82,8 +82,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -114,7 +114,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -135,7 +135,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para if err != nil { return nil, fmt.Errorf("error getting logger: %s", err) } - logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", kind, listTablesMissingUniqueIndexesStatement)) + logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", resourceType, listTablesMissingUniqueIndexesStatement)) return source.RunSQL(ctx, listTablesMissingUniqueIndexesStatement, []any{table_schema, table_schema, limit}) } diff --git a/internal/tools/mysql/mysqllisttablesmissinguniqueindexes/mysqllisttablesmissinguniqueindexes_test.go b/internal/tools/mysql/mysqllisttablesmissinguniqueindexes/mysqllisttablesmissinguniqueindexes_test.go index 6ee9c87347..3c1f0715cb 100644 --- a/internal/tools/mysql/mysqllisttablesmissinguniqueindexes/mysqllisttablesmissinguniqueindexes_test.go +++ b/internal/tools/mysql/mysqllisttablesmissinguniqueindexes/mysqllisttablesmissinguniqueindexes_test.go @@ -17,7 +17,6 @@ package mysqllisttablesmissinguniqueindexes_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlExecuteSql(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mysql-list-tables-missing-unique-indexes - source: my-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: mysql-list-tables-missing-unique-indexes + source: my-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": mysqllisttablesmissinguniqueindexes.Config{ Name: "example_tool", - Kind: "mysql-list-tables-missing-unique-indexes", + Type: "mysql-list-tables-missing-unique-indexes", Source: "my-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,15 +58,12 @@ func TestParseFromYamlExecuteSql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/mysql/mysqlsql/mysqlsql.go b/internal/tools/mysql/mysqlsql/mysqlsql.go index 5c1b83a135..3e84b49158 100644 --- a/internal/tools/mysql/mysqlsql/mysqlsql.go +++ b/internal/tools/mysql/mysqlsql/mysqlsql.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "mysql-sql" +const resourceType string = "mysql-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Statement string `yaml:"statement" validate:"required"` @@ -61,8 +61,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -94,7 +94,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/mysql/mysqlsql/mysqlsql_test.go b/internal/tools/mysql/mysqlsql/mysqlsql_test.go index 5863477f0b..d825720de0 100644 --- a/internal/tools/mysql/mysqlsql/mysqlsql_test.go +++ b/internal/tools/mysql/mysqlsql/mysqlsql_test.go @@ -17,7 +17,6 @@ package mysqlsql_test import ( "testing" - 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" @@ -38,30 +37,30 @@ func TestParseFromYamlMySQL(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mysql-sql - source: my-mysql-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - authRequired: - - my-google-auth-service - - other-auth-service - parameters: - - name: country - type: string - description: some description - authServices: - - name: my-google-auth-service - field: user_id - - name: other-auth-service - field: user_id + kind: tools + name: example_tool + type: mysql-sql + source: my-mysql-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + authRequired: + - my-google-auth-service + - other-auth-service + parameters: + - name: country + type: string + description: some description + authServices: + - name: my-google-auth-service + field: user_id + - name: other-auth-service + field: user_id `, want: server.ToolConfigs{ "example_tool": mysqlsql.Config{ Name: "example_tool", - Kind: "mysql-sql", + Type: "mysql-sql", Source: "my-mysql-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -77,15 +76,12 @@ func TestParseFromYamlMySQL(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -105,41 +101,41 @@ func TestParseFromYamlWithTemplateParamsMySQL(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: mysql-sql - source: my-mysql-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - authRequired: - - my-google-auth-service - - other-auth-service - parameters: - - name: country - type: string - description: some description - authServices: - - name: my-google-auth-service - field: user_id - - name: other-auth-service - field: user_id - templateParameters: - - name: tableName - type: string - description: The table to select hotels from. - - name: fieldArray - type: array - description: The columns to return for the query. - items: - name: column - type: string - description: A column name that will be returned from the query. + kind: tools + name: example_tool + type: mysql-sql + source: my-mysql-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + authRequired: + - my-google-auth-service + - other-auth-service + parameters: + - name: country + type: string + description: some description + authServices: + - name: my-google-auth-service + field: user_id + - name: other-auth-service + field: user_id + templateParameters: + - name: tableName + type: string + description: The table to select hotels from. + - name: fieldArray + type: array + description: The columns to return for the query. + items: + name: column + type: string + description: A column name that will be returned from the query. `, want: server.ToolConfigs{ "example_tool": mysqlsql.Config{ Name: "example_tool", - Kind: "mysql-sql", + Type: "mysql-sql", Source: "my-mysql-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -159,15 +155,12 @@ func TestParseFromYamlWithTemplateParamsMySQL(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/neo4j/neo4jcypher/neo4jcypher.go b/internal/tools/neo4j/neo4jcypher/neo4jcypher.go index a193e4b5ab..d431af349c 100644 --- a/internal/tools/neo4j/neo4jcypher/neo4jcypher.go +++ b/internal/tools/neo4j/neo4jcypher/neo4jcypher.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "neo4j-cypher" +const resourceType string = "neo4j-cypher" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Statement string `yaml:"statement" validate:"required"` @@ -60,8 +60,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -86,7 +86,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/neo4j/neo4jcypher/neo4jcypher_test.go b/internal/tools/neo4j/neo4jcypher/neo4jcypher_test.go index 898583f961..d20cb1822c 100644 --- a/internal/tools/neo4j/neo4jcypher/neo4jcypher_test.go +++ b/internal/tools/neo4j/neo4jcypher/neo4jcypher_test.go @@ -17,7 +17,6 @@ package neo4jcypher import ( "testing" - "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" @@ -37,25 +36,25 @@ func TestParseFromYamlNeo4j(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: neo4j-cypher - source: my-neo4j-instance - description: some tool description - authRequired: - - my-google-auth-service - - other-auth-service - statement: | - MATCH (c:Country) WHERE c.name = $country RETURN c.id as id; - parameters: - - name: country - type: string - description: country parameter description + kind: tools + name: example_tool + type: neo4j-cypher + source: my-neo4j-instance + description: some tool description + authRequired: + - my-google-auth-service + - other-auth-service + statement: | + MATCH (c:Country) WHERE c.name = $country RETURN c.id as id; + parameters: + - name: country + type: string + description: country parameter description `, want: server.ToolConfigs{ "example_tool": Config{ Name: "example_tool", - Kind: "neo4j-cypher", + Type: "neo4j-cypher", Source: "my-neo4j-instance", Description: "some tool description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -69,15 +68,12 @@ func TestParseFromYamlNeo4j(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err = yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/neo4j/neo4jexecutecypher/neo4jexecutecypher.go b/internal/tools/neo4j/neo4jexecutecypher/neo4jexecutecypher.go index 704ae34be6..5a0ce23a82 100644 --- a/internal/tools/neo4j/neo4jexecutecypher/neo4jexecutecypher.go +++ b/internal/tools/neo4j/neo4jexecutecypher/neo4jexecutecypher.go @@ -25,11 +25,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "neo4j-execute-cypher" +const resourceType string = "neo4j-execute-cypher" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -48,7 +48,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` ReadOnly bool `yaml:"readOnly"` @@ -58,8 +58,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -95,7 +95,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/neo4j/neo4jexecutecypher/neo4jexecutecypher_test.go b/internal/tools/neo4j/neo4jexecutecypher/neo4jexecutecypher_test.go index a287292647..d45a7ba3d4 100644 --- a/internal/tools/neo4j/neo4jexecutecypher/neo4jexecutecypher_test.go +++ b/internal/tools/neo4j/neo4jexecutecypher/neo4jexecutecypher_test.go @@ -17,7 +17,6 @@ package neo4jexecutecypher import ( "testing" - "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" @@ -36,19 +35,19 @@ func TestParseFromYamlNeo4j(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: neo4j-execute-cypher - source: my-neo4j-instance - description: some tool description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: neo4j-execute-cypher + source: my-neo4j-instance + description: some tool description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": Config{ Name: "example_tool", - Kind: "neo4j-execute-cypher", + Type: "neo4j-execute-cypher", Source: "my-neo4j-instance", Description: "some tool description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -58,20 +57,20 @@ func TestParseFromYamlNeo4j(t *testing.T) { { desc: "readonly example", in: ` - tools: - example_tool: - kind: neo4j-execute-cypher - source: my-neo4j-instance - description: some tool description - readOnly: true - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: neo4j-execute-cypher + source: my-neo4j-instance + description: some tool description + readOnly: true + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": Config{ Name: "example_tool", - Kind: "neo4j-execute-cypher", + Type: "neo4j-execute-cypher", Source: "my-neo4j-instance", ReadOnly: true, Description: "some tool description", @@ -82,15 +81,12 @@ func TestParseFromYamlNeo4j(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err = yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/neo4j/neo4jschema/neo4jschema.go b/internal/tools/neo4j/neo4jschema/neo4jschema.go index 35e692a3f3..755b1a448a 100644 --- a/internal/tools/neo4j/neo4jschema/neo4jschema.go +++ b/internal/tools/neo4j/neo4jschema/neo4jschema.go @@ -31,13 +31,13 @@ import ( "github.com/neo4j/neo4j-go-driver/v5/neo4j" ) -// kind defines the unique identifier for this tool. -const kind string = "neo4j-schema" +// type defines the unique identifier for this tool. +const resourceType string = "neo4j-schema" // init registers the tool with the application's tool registry when the package is initialized. func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -62,7 +62,7 @@ type compatibleSource interface { // These settings are typically read from a YAML file. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -72,9 +72,9 @@ type Config struct { // Statically verify that Config implements the tools.ToolConfig interface. var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of this tool configuration. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of this tool configuration. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize sets up the tool with its dependencies and returns a ready-to-use Tool instance. @@ -114,7 +114,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, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/neo4j/neo4jschema/neo4jschema_test.go b/internal/tools/neo4j/neo4jschema/neo4jschema_test.go index 6960dd7c58..850e237245 100644 --- a/internal/tools/neo4j/neo4jschema/neo4jschema_test.go +++ b/internal/tools/neo4j/neo4jschema/neo4jschema_test.go @@ -18,7 +18,6 @@ package neo4jschema import ( "testing" - "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" @@ -39,19 +38,19 @@ func TestParseFromYamlNeo4j(t *testing.T) { { desc: "basic example with default cache expiration", in: ` - tools: - example_tool: - kind: neo4j-schema - source: my-neo4j-instance - description: some tool description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: neo4j-schema + source: my-neo4j-instance + description: some tool description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": Config{ Name: "example_tool", - Kind: "neo4j-schema", + Type: "neo4j-schema", Source: "my-neo4j-instance", Description: "some tool description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -62,17 +61,17 @@ func TestParseFromYamlNeo4j(t *testing.T) { { desc: "cache expire minutes set explicitly", in: ` - tools: - example_tool: - kind: neo4j-schema - source: my-neo4j-instance - description: some tool description - cacheExpireMinutes: 30 + kind: tools + name: example_tool + type: neo4j-schema + source: my-neo4j-instance + description: some tool description + cacheExpireMinutes: 30 `, want: server.ToolConfigs{ "example_tool": Config{ Name: "example_tool", - Kind: "neo4j-schema", + Type: "neo4j-schema", Source: "my-neo4j-instance", Description: "some tool description", AuthRequired: []string{}, // Expect an empty slice, not nil. @@ -83,15 +82,12 @@ func TestParseFromYamlNeo4j(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err = yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/oceanbase/oceanbaseexecutesql/oceanbaseexecutesql.go b/internal/tools/oceanbase/oceanbaseexecutesql/oceanbaseexecutesql.go index ab9d1ac86c..75045dc0c8 100644 --- a/internal/tools/oceanbase/oceanbaseexecutesql/oceanbaseexecutesql.go +++ b/internal/tools/oceanbase/oceanbaseexecutesql/oceanbaseexecutesql.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "oceanbase-execute-sql" +const resourceType string = "oceanbase-execute-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -41,7 +41,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -58,8 +58,8 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.T return actual, nil } -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -90,7 +90,7 @@ type Tool struct { // Invoke executes the SQL statement provided in the parameters. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/oceanbase/oceanbaseexecutesql/oceanbaseexecutesql_test.go b/internal/tools/oceanbase/oceanbaseexecutesql/oceanbaseexecutesql_test.go index 0653765d2a..7b7f36e7a3 100644 --- a/internal/tools/oceanbase/oceanbaseexecutesql/oceanbaseexecutesql_test.go +++ b/internal/tools/oceanbase/oceanbaseexecutesql/oceanbaseexecutesql_test.go @@ -17,7 +17,6 @@ package oceanbaseexecutesql_test import ( "testing" - 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" @@ -38,19 +37,19 @@ func TestParseFromYamlExecuteSql(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: oceanbase-execute-sql - source: my-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: oceanbase-execute-sql + source: my-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": oceanbaseexecutesql.Config{ Name: "example_tool", - Kind: "oceanbase-execute-sql", + Type: "oceanbase-execute-sql", Source: "my-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -60,15 +59,12 @@ func TestParseFromYamlExecuteSql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/oceanbase/oceanbasesql/oceanbasesql.go b/internal/tools/oceanbase/oceanbasesql/oceanbasesql.go index 3e311af599..f9178fd9d1 100644 --- a/internal/tools/oceanbase/oceanbasesql/oceanbasesql.go +++ b/internal/tools/oceanbase/oceanbasesql/oceanbasesql.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "oceanbase-sql" +const resourceType string = "oceanbase-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -41,7 +41,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Statement string `yaml:"statement" validate:"required"` @@ -61,8 +61,8 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.T return actual, nil } -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -95,7 +95,7 @@ type Tool struct { // Invoke executes the SQL statement with the provided parameters. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/oceanbase/oceanbasesql/oceanbasesql_test.go b/internal/tools/oceanbase/oceanbasesql/oceanbasesql_test.go index 0b1806dd84..2df6c04ba1 100644 --- a/internal/tools/oceanbase/oceanbasesql/oceanbasesql_test.go +++ b/internal/tools/oceanbase/oceanbasesql/oceanbasesql_test.go @@ -17,7 +17,6 @@ package oceanbasesql_test import ( "testing" - 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" @@ -39,21 +38,21 @@ func TestParseFromYamlOceanBaseSql(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: oceanbase-sql - source: my-instance - description: some description - statement: select * from t where id = ? - parameters: - - name: id - type: string - description: id param + kind: tools + name: example_tool + type: oceanbase-sql + source: my-instance + description: some description + statement: select * from t where id = ? + parameters: + - name: id + type: string + description: id param `, want: server.ToolConfigs{ "example_tool": oceanbasesql.Config{ Name: "example_tool", - Kind: "oceanbase-sql", + Type: "oceanbase-sql", Source: "my-instance", Description: "some description", Statement: "select * from t where id = ?", @@ -67,15 +66,12 @@ func TestParseFromYamlOceanBaseSql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/oracle/oracleexecutesql/oracleexecutesql.go b/internal/tools/oracle/oracleexecutesql/oracleexecutesql.go index 3cd32a8954..c67c60bd58 100644 --- a/internal/tools/oracle/oracleexecutesql/oracleexecutesql.go +++ b/internal/tools/oracle/oracleexecutesql/oracleexecutesql.go @@ -15,11 +15,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "oracle-execute-sql" +const resourceType string = "oracle-execute-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -38,7 +38,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -47,8 +47,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -78,7 +78,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -94,7 +94,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para if err != nil { return nil, fmt.Errorf("error getting logger: %s", err) } - logger.DebugContext(ctx, "executing `%s` tool query: %s", kind, sqlParam) + logger.DebugContext(ctx, "executing `%s` tool query: %s", resourceType, sqlParam) return source.RunSQL(ctx, sqlParam, nil) } diff --git a/internal/tools/oracle/oracleexecutesql/oracleexecutesql_test.go b/internal/tools/oracle/oracleexecutesql/oracleexecutesql_test.go index 834d3d6981..1d416ca087 100644 --- a/internal/tools/oracle/oracleexecutesql/oracleexecutesql_test.go +++ b/internal/tools/oracle/oracleexecutesql/oracleexecutesql_test.go @@ -5,7 +5,6 @@ package oracleexecutesql_test import ( "testing" - 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" @@ -25,18 +24,18 @@ func TestParseFromYamlOracleExecuteSql(t *testing.T) { { desc: "basic example with auth", in: ` - tools: - run_adhoc_query: - kind: oracle-execute-sql - source: my-oracle-instance - description: Executes arbitrary SQL statements like INSERT or UPDATE. - authRequired: - - my-google-auth-service + kind: tools + name: run_adhoc_query + type: oracle-execute-sql + source: my-oracle-instance + description: Executes arbitrary SQL statements like INSERT or UPDATE. + authRequired: + - my-google-auth-service `, want: server.ToolConfigs{ "run_adhoc_query": oracleexecutesql.Config{ Name: "run_adhoc_query", - Kind: "oracle-execute-sql", + Type: "oracle-execute-sql", Source: "my-oracle-instance", Description: "Executes arbitrary SQL statements like INSERT or UPDATE.", AuthRequired: []string{"my-google-auth-service"}, @@ -46,16 +45,16 @@ func TestParseFromYamlOracleExecuteSql(t *testing.T) { { desc: "example without authRequired", in: ` - tools: - run_simple_update: - kind: oracle-execute-sql - source: db-dev - description: Runs a simple update operation. + kind: tools + name: run_simple_update + type: oracle-execute-sql + source: db-dev + description: Runs a simple update operation. `, want: server.ToolConfigs{ "run_simple_update": oracleexecutesql.Config{ Name: "run_simple_update", - Kind: "oracle-execute-sql", + Type: "oracle-execute-sql", Source: "db-dev", Description: "Runs a simple update operation.", AuthRequired: []string{}, @@ -65,15 +64,12 @@ func TestParseFromYamlOracleExecuteSql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + // Parse contents + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/oracle/oraclesql/oraclesql.go b/internal/tools/oracle/oraclesql/oraclesql.go index c9f099d15a..1a8390bce6 100644 --- a/internal/tools/oracle/oraclesql/oraclesql.go +++ b/internal/tools/oracle/oraclesql/oraclesql.go @@ -14,11 +14,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "oracle-sql" +const resourceType string = "oracle-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -37,7 +37,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Statement string `yaml:"statement" validate:"required"` @@ -49,8 +49,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -82,7 +82,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/oracle/oraclesql/oraclesql_test.go b/internal/tools/oracle/oraclesql/oraclesql_test.go index 2ba0a7321c..190afc2594 100644 --- a/internal/tools/oracle/oraclesql/oraclesql_test.go +++ b/internal/tools/oracle/oraclesql/oraclesql_test.go @@ -4,7 +4,6 @@ package oraclesql_test import ( "testing" - 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" @@ -24,19 +23,19 @@ func TestParseFromYamlOracleSql(t *testing.T) { { desc: "basic example with statement and auth", in: ` - tools: - get_user_by_id: - kind: oracle-sql - source: my-oracle-instance - description: Retrieves user details by ID. - statement: "SELECT id, name, email FROM users WHERE id = :1" - authRequired: - - my-google-auth-service + kind: tools + name: get_user_by_id + type: oracle-sql + source: my-oracle-instance + description: Retrieves user details by ID. + statement: "SELECT id, name, email FROM users WHERE id = :1" + authRequired: + - my-google-auth-service `, want: server.ToolConfigs{ "get_user_by_id": oraclesql.Config{ Name: "get_user_by_id", - Kind: "oracle-sql", + Type: "oracle-sql", Source: "my-oracle-instance", Description: "Retrieves user details by ID.", Statement: "SELECT id, name, email FROM users WHERE id = :1", @@ -47,17 +46,17 @@ func TestParseFromYamlOracleSql(t *testing.T) { { desc: "example with parameters and template parameters", in: ` - tools: - get_orders: - kind: oracle-sql - source: db-prod - description: Gets orders for a customer with optional filtering. - statement: "SELECT * FROM ${SCHEMA}.ORDERS WHERE customer_id = :customer_id AND status = :status" + kind: tools + name: get_orders + type: oracle-sql + source: db-prod + description: Gets orders for a customer with optional filtering. + statement: "SELECT * FROM ${SCHEMA}.ORDERS WHERE customer_id = :customer_id AND status = :status" `, want: server.ToolConfigs{ "get_orders": oraclesql.Config{ Name: "get_orders", - Kind: "oracle-sql", + Type: "oracle-sql", Source: "db-prod", Description: "Gets orders for a customer with optional filtering.", Statement: "SELECT * FROM ${SCHEMA}.ORDERS WHERE customer_id = :customer_id AND status = :status", @@ -68,15 +67,12 @@ func TestParseFromYamlOracleSql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + // Parse contents + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgresdatabaseoverview/postgresdatabaseoverview.go b/internal/tools/postgres/postgresdatabaseoverview/postgresdatabaseoverview.go index 22db6d53ea..541aee41e0 100644 --- a/internal/tools/postgres/postgresdatabaseoverview/postgresdatabaseoverview.go +++ b/internal/tools/postgres/postgresdatabaseoverview/postgresdatabaseoverview.go @@ -26,7 +26,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-database-overview" +const resourceType string = "postgres-database-overview" const databaseOverviewStatement = ` SELECT @@ -43,8 +43,8 @@ const databaseOverviewStatement = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -63,7 +63,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -72,8 +72,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -111,7 +111,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgresdatabaseoverview/postgresdatabaseoverview_test.go b/internal/tools/postgres/postgresdatabaseoverview/postgresdatabaseoverview_test.go index 63ea550d2a..77c455733a 100644 --- a/internal/tools/postgres/postgresdatabaseoverview/postgresdatabaseoverview_test.go +++ b/internal/tools/postgres/postgresdatabaseoverview/postgresdatabaseoverview_test.go @@ -17,7 +17,6 @@ package postgresdatabaseoverview_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgresDatabaseOverview(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-database-overview - source: my-postgres-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-database-overview + source: my-postgres-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgresdatabaseoverview.Config{ Name: "example_tool", - Kind: "postgres-database-overview", + Type: "postgres-database-overview", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,16 +58,16 @@ func TestParseFromYamlPostgresDatabaseOverview(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-database-overview - source: my-postgres-instance - description: some description + kind: tools + name: example_tool + type: postgres-database-overview + source: my-postgres-instance + description: some description `, want: server.ToolConfigs{ "example_tool": postgresdatabaseoverview.Config{ Name: "example_tool", - Kind: "postgres-database-overview", + Type: "postgres-database-overview", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,12 @@ func TestParseFromYamlPostgresDatabaseOverview(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgresexecutesql/postgresexecutesql.go b/internal/tools/postgres/postgresexecutesql/postgresexecutesql.go index 287d2ee517..2b9bec3ad6 100644 --- a/internal/tools/postgres/postgresexecutesql/postgresexecutesql.go +++ b/internal/tools/postgres/postgresexecutesql/postgresexecutesql.go @@ -27,11 +27,11 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-execute-sql" +const resourceType string = "postgres-execute-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -59,8 +59,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -90,7 +90,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -105,7 +105,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para if err != nil { return nil, fmt.Errorf("error getting logger: %s", err) } - logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", kind, sql)) + logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", resourceType, sql)) return source.RunSQL(ctx, sql, nil) } diff --git a/internal/tools/postgres/postgresexecutesql/postgresexecutesql_test.go b/internal/tools/postgres/postgresexecutesql/postgresexecutesql_test.go index 6351b54c64..9d4c61e929 100644 --- a/internal/tools/postgres/postgresexecutesql/postgresexecutesql_test.go +++ b/internal/tools/postgres/postgresexecutesql/postgresexecutesql_test.go @@ -17,7 +17,6 @@ package postgresexecutesql_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlExecuteSql(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-execute-sql - source: my-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-execute-sql + source: my-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgresexecutesql.Config{ Name: "example_tool", - Kind: "postgres-execute-sql", + Type: "postgres-execute-sql", Source: "my-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,15 +58,12 @@ func TestParseFromYamlExecuteSql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgresgetcolumncardinality/postgresgetcolumncardinality.go b/internal/tools/postgres/postgresgetcolumncardinality/postgresgetcolumncardinality.go index 0d1f293acc..754ba15775 100644 --- a/internal/tools/postgres/postgresgetcolumncardinality/postgresgetcolumncardinality.go +++ b/internal/tools/postgres/postgresgetcolumncardinality/postgresgetcolumncardinality.go @@ -26,7 +26,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-get-column-cardinality" +const resourceType string = "postgres-get-column-cardinality" const getColumnCardinality = ` SELECT @@ -48,8 +48,8 @@ const getColumnCardinality = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -68,7 +68,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -77,8 +77,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -123,7 +123,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgresgetcolumncardinality/postgresgetcolumncardinality_test.go b/internal/tools/postgres/postgresgetcolumncardinality/postgresgetcolumncardinality_test.go index e1ea31fe59..c9eef23c26 100644 --- a/internal/tools/postgres/postgresgetcolumncardinality/postgresgetcolumncardinality_test.go +++ b/internal/tools/postgres/postgresgetcolumncardinality/postgresgetcolumncardinality_test.go @@ -17,7 +17,6 @@ package postgresgetcolumncardinality_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgresGetColumnCardinality(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-get-column-cardinality - source: my-postgres-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-get-column-cardinality + source: my-postgres-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgresgetcolumncardinality.Config{ Name: "example_tool", - Kind: "postgres-get-column-cardinality", + Type: "postgres-get-column-cardinality", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,16 +58,16 @@ func TestParseFromYamlPostgresGetColumnCardinality(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-get-column-cardinality - source: my-postgres-instance - description: some description + kind: tools + name: example_tool + type: postgres-get-column-cardinality + source: my-postgres-instance + description: some description `, want: server.ToolConfigs{ "example_tool": postgresgetcolumncardinality.Config{ Name: "example_tool", - Kind: "postgres-get-column-cardinality", + Type: "postgres-get-column-cardinality", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,12 @@ func TestParseFromYamlPostgresGetColumnCardinality(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgreslistactivequeries/postgreslistactivequeries.go b/internal/tools/postgres/postgreslistactivequeries/postgreslistactivequeries.go index 7dbf1dea82..f53b158e8d 100644 --- a/internal/tools/postgres/postgreslistactivequeries/postgreslistactivequeries.go +++ b/internal/tools/postgres/postgreslistactivequeries/postgreslistactivequeries.go @@ -26,7 +26,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-list-active-queries" +const resourceType string = "postgres-list-active-queries" const listActiveQueriesStatement = ` SELECT @@ -52,8 +52,8 @@ const listActiveQueriesStatement = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -72,7 +72,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -81,8 +81,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -119,7 +119,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgreslistactivequeries/postgreslistactivequeries_test.go b/internal/tools/postgres/postgreslistactivequeries/postgreslistactivequeries_test.go index 96a5caeb0e..1cf079d0d8 100644 --- a/internal/tools/postgres/postgreslistactivequeries/postgreslistactivequeries_test.go +++ b/internal/tools/postgres/postgreslistactivequeries/postgreslistactivequeries_test.go @@ -17,7 +17,6 @@ package postgreslistactivequeries_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgresListTables(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-active-queries - source: my-postgres-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-list-active-queries + source: my-postgres-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgreslistactivequeries.Config{ Name: "example_tool", - Kind: "postgres-list-active-queries", + Type: "postgres-list-active-queries", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,16 +58,16 @@ func TestParseFromYamlPostgresListTables(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-active-queries - source: my-postgres-instance - description: some description + kind: tools + name: example_tool + type: postgres-list-active-queries + source: my-postgres-instance + description: some description `, want: server.ToolConfigs{ "example_tool": postgreslistactivequeries.Config{ Name: "example_tool", - Kind: "postgres-list-active-queries", + Type: "postgres-list-active-queries", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,11 @@ func TestParseFromYamlPostgresListTables(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgreslistavailableextensions/postgreslistavailableextensions.go b/internal/tools/postgres/postgreslistavailableextensions/postgreslistavailableextensions.go index 0292d9cb29..900c22a6e3 100644 --- a/internal/tools/postgres/postgreslistavailableextensions/postgreslistavailableextensions.go +++ b/internal/tools/postgres/postgreslistavailableextensions/postgreslistavailableextensions.go @@ -26,7 +26,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-list-available-extensions" +const resourceType string = "postgres-list-available-extensions" const listAvailableExtensionsQuery = ` SELECT @@ -39,8 +39,8 @@ const listAvailableExtensionsQuery = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -59,7 +59,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -68,8 +68,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -101,7 +101,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgreslistavailableextensions/postgreslistavailableextensions_test.go b/internal/tools/postgres/postgreslistavailableextensions/postgreslistavailableextensions_test.go index 8c26d59cdd..2a45d2b502 100644 --- a/internal/tools/postgres/postgreslistavailableextensions/postgreslistavailableextensions_test.go +++ b/internal/tools/postgres/postgreslistavailableextensions/postgreslistavailableextensions_test.go @@ -17,7 +17,6 @@ package postgreslistavailableextensions_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgres(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-available-extensions - source: my-pg-instance - description: "some description" - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-list-available-extensions + source: my-pg-instance + description: "some description" + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgreslistavailableextensions.Config{ Name: "example_tool", - Kind: "postgres-list-available-extensions", + Type: "postgres-list-available-extensions", Source: "my-pg-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,16 +58,16 @@ func TestParseFromYamlPostgres(t *testing.T) { { desc: "basic example without authRequired", in: ` - tools: - example_tool: - kind: postgres-list-available-extensions - source: my-pg-instance - description: "some description" + kind: tools + name: example_tool + type: postgres-list-available-extensions + source: my-pg-instance + description: "some description" `, want: server.ToolConfigs{ "example_tool": postgreslistavailableextensions.Config{ Name: "example_tool", - Kind: "postgres-list-available-extensions", + Type: "postgres-list-available-extensions", Source: "my-pg-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,11 @@ func TestParseFromYamlPostgres(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgreslistdatabasestats/postgreslistdatabasestats.go b/internal/tools/postgres/postgreslistdatabasestats/postgreslistdatabasestats.go index 0a0ed209c9..8bb221d737 100644 --- a/internal/tools/postgres/postgreslistdatabasestats/postgreslistdatabasestats.go +++ b/internal/tools/postgres/postgreslistdatabasestats/postgreslistdatabasestats.go @@ -26,7 +26,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-list-database-stats" +const resourceType string = "postgres-list-database-stats" // SQL query to list database statistics const listDatabaseStats = ` @@ -96,8 +96,8 @@ const listDatabaseStats = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -116,7 +116,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -125,8 +125,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -188,7 +188,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgreslistdatabasestats/postgreslistdatabasestats_test.go b/internal/tools/postgres/postgreslistdatabasestats/postgreslistdatabasestats_test.go index 760370f630..d90211e9e4 100644 --- a/internal/tools/postgres/postgreslistdatabasestats/postgreslistdatabasestats_test.go +++ b/internal/tools/postgres/postgreslistdatabasestats/postgreslistdatabasestats_test.go @@ -17,7 +17,6 @@ package postgreslistdatabasestats_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgresListDatabaseStats(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-database-stats - source: my-postgres-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-list-database-stats + source: my-postgres-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgreslistdatabasestats.Config{ Name: "example_tool", - Kind: "postgres-list-database-stats", + Type: "postgres-list-database-stats", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,16 +58,16 @@ func TestParseFromYamlPostgresListDatabaseStats(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-database-stats - source: my-postgres-instance - description: some description + kind: tools + name: example_tool + type: postgres-list-database-stats + source: my-postgres-instance + description: some description `, want: server.ToolConfigs{ "example_tool": postgreslistdatabasestats.Config{ Name: "example_tool", - Kind: "postgres-list-database-stats", + Type: "postgres-list-database-stats", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,11 @@ func TestParseFromYamlPostgresListDatabaseStats(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgreslistindexes/postgreslistindexes.go b/internal/tools/postgres/postgreslistindexes/postgreslistindexes.go index d0c6e1524d..4f4bf16b1e 100644 --- a/internal/tools/postgres/postgreslistindexes/postgreslistindexes.go +++ b/internal/tools/postgres/postgreslistindexes/postgreslistindexes.go @@ -26,7 +26,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-list-indexes" +const resourceType string = "postgres-list-indexes" const listIndexesStatement = ` WITH IndexDetails AS ( @@ -75,8 +75,8 @@ const listIndexesStatement = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -95,7 +95,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -104,8 +104,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -150,7 +150,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgreslistindexes/postgreslistindexes_test.go b/internal/tools/postgres/postgreslistindexes/postgreslistindexes_test.go index c5aaacfab7..7c0da6e6a1 100644 --- a/internal/tools/postgres/postgreslistindexes/postgreslistindexes_test.go +++ b/internal/tools/postgres/postgreslistindexes/postgreslistindexes_test.go @@ -17,7 +17,6 @@ package postgreslistindexes_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgresListIndexes(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-indexes - source: my-postgres-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-list-indexes + source: my-postgres-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgreslistindexes.Config{ Name: "example_tool", - Kind: "postgres-list-indexes", + Type: "postgres-list-indexes", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,16 +58,16 @@ func TestParseFromYamlPostgresListIndexes(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-indexes - source: my-postgres-instance - description: some description + kind: tools + name: example_tool + type: postgres-list-indexes + source: my-postgres-instance + description: some description `, want: server.ToolConfigs{ "example_tool": postgreslistindexes.Config{ Name: "example_tool", - Kind: "postgres-list-indexes", + Type: "postgres-list-indexes", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,12 @@ func TestParseFromYamlPostgresListIndexes(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgreslistinstalledextensions/postgreslistinstalledextensions.go b/internal/tools/postgres/postgreslistinstalledextensions/postgreslistinstalledextensions.go index 2877958688..57c8914095 100644 --- a/internal/tools/postgres/postgreslistinstalledextensions/postgreslistinstalledextensions.go +++ b/internal/tools/postgres/postgreslistinstalledextensions/postgreslistinstalledextensions.go @@ -26,7 +26,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-list-installed-extensions" +const resourceType string = "postgres-list-installed-extensions" const listAvailableExtensionsQuery = ` SELECT @@ -50,8 +50,8 @@ const listAvailableExtensionsQuery = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -70,7 +70,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -79,8 +79,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -110,7 +110,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgreslistinstalledextensions/postgreslistinstalledextensions_test.go b/internal/tools/postgres/postgreslistinstalledextensions/postgreslistinstalledextensions_test.go index 8fb6b1e2a3..5ca5dbe3c0 100644 --- a/internal/tools/postgres/postgreslistinstalledextensions/postgreslistinstalledextensions_test.go +++ b/internal/tools/postgres/postgreslistinstalledextensions/postgreslistinstalledextensions_test.go @@ -17,7 +17,6 @@ package postgreslistinstalledextensions_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgres(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-installed-extensions - source: my-pg-instance - description: "some description" - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-list-installed-extensions + source: my-pg-instance + description: "some description" + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgreslistinstalledextensions.Config{ Name: "example_tool", - Kind: "postgres-list-installed-extensions", + Type: "postgres-list-installed-extensions", Source: "my-pg-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,16 +58,16 @@ func TestParseFromYamlPostgres(t *testing.T) { { desc: "basic example without authRequired", in: ` - tools: - example_tool: - kind: postgres-list-installed-extensions - source: my-pg-instance - description: "some description" + kind: tools + name: example_tool + type: postgres-list-installed-extensions + source: my-pg-instance + description: "some description" `, want: server.ToolConfigs{ "example_tool": postgreslistinstalledextensions.Config{ Name: "example_tool", - Kind: "postgres-list-installed-extensions", + Type: "postgres-list-installed-extensions", Source: "my-pg-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,12 @@ func TestParseFromYamlPostgres(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgreslistlocks/postgreslistlocks.go b/internal/tools/postgres/postgreslistlocks/postgreslistlocks.go index d053ea7f5a..12e2cde588 100644 --- a/internal/tools/postgres/postgreslistlocks/postgreslistlocks.go +++ b/internal/tools/postgres/postgreslistlocks/postgreslistlocks.go @@ -26,7 +26,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-list-locks" +const resourceType string = "postgres-list-locks" const listLocks = ` SELECT @@ -50,8 +50,8 @@ const listLocks = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -70,7 +70,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -79,8 +79,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -121,7 +121,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgreslistlocks/postgreslistlocks_test.go b/internal/tools/postgres/postgreslistlocks/postgreslistlocks_test.go index 1615e4870b..d34352e484 100644 --- a/internal/tools/postgres/postgreslistlocks/postgreslistlocks_test.go +++ b/internal/tools/postgres/postgreslistlocks/postgreslistlocks_test.go @@ -17,7 +17,6 @@ package postgreslistlocks_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgresListLocks(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-locks - source: my-postgres-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-list-locks + source: my-postgres-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgreslistlocks.Config{ Name: "example_tool", - Kind: "postgres-list-locks", + Type: "postgres-list-locks", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,16 +58,16 @@ func TestParseFromYamlPostgresListLocks(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-locks - source: my-postgres-instance - description: some description + kind: tools + name: example_tool + type: postgres-list-locks + source: my-postgres-instance + description: some description `, want: server.ToolConfigs{ "example_tool": postgreslistlocks.Config{ Name: "example_tool", - Kind: "postgres-list-locks", + Type: "postgres-list-locks", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,12 @@ func TestParseFromYamlPostgresListLocks(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgreslistpgsettings/postgreslistpgsettings.go b/internal/tools/postgres/postgreslistpgsettings/postgreslistpgsettings.go index 09bb97828b..83bdf89029 100644 --- a/internal/tools/postgres/postgreslistpgsettings/postgreslistpgsettings.go +++ b/internal/tools/postgres/postgreslistpgsettings/postgreslistpgsettings.go @@ -26,7 +26,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-list-pg-settings" +const resourceType string = "postgres-list-pg-settings" const listPgSettingsStatement = ` SELECT @@ -48,8 +48,8 @@ const listPgSettingsStatement = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -68,7 +68,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -77,8 +77,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -116,7 +116,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgreslistpgsettings/postgreslistpgsettings_test.go b/internal/tools/postgres/postgreslistpgsettings/postgreslistpgsettings_test.go index a2aa9fe78b..eb98a8e370 100644 --- a/internal/tools/postgres/postgreslistpgsettings/postgreslistpgsettings_test.go +++ b/internal/tools/postgres/postgreslistpgsettings/postgreslistpgsettings_test.go @@ -17,7 +17,6 @@ package postgreslistpgsettings_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgreslistPgSettings(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-pg-settings - source: my-postgres-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-list-pg-settings + source: my-postgres-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgreslistpgsettings.Config{ Name: "example_tool", - Kind: "postgres-list-pg-settings", + Type: "postgres-list-pg-settings", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,16 +58,16 @@ func TestParseFromYamlPostgreslistPgSettings(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-pg-settings - source: my-postgres-instance - description: some description + kind: tools + name: example_tool + type: postgres-list-pg-settings + source: my-postgres-instance + description: some description `, want: server.ToolConfigs{ "example_tool": postgreslistpgsettings.Config{ Name: "example_tool", - Kind: "postgres-list-pg-settings", + Type: "postgres-list-pg-settings", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,11 @@ func TestParseFromYamlPostgreslistPgSettings(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgreslistpublicationtables/postgreslistpublicationtables.go b/internal/tools/postgres/postgreslistpublicationtables/postgreslistpublicationtables.go index a6f1c8fffd..f2362dfd6e 100644 --- a/internal/tools/postgres/postgreslistpublicationtables/postgreslistpublicationtables.go +++ b/internal/tools/postgres/postgreslistpublicationtables/postgreslistpublicationtables.go @@ -26,7 +26,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-list-publication-tables" +const resourceType string = "postgres-list-publication-tables" const listPublicationTablesStatement = ` WITH @@ -59,8 +59,8 @@ const listPublicationTablesStatement = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -79,7 +79,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -88,8 +88,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -129,7 +129,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgreslistpublicationtables/postgreslistpublicationtables_test.go b/internal/tools/postgres/postgreslistpublicationtables/postgreslistpublicationtables_test.go index 211567c4a8..96e4db1b95 100644 --- a/internal/tools/postgres/postgreslistpublicationtables/postgreslistpublicationtables_test.go +++ b/internal/tools/postgres/postgreslistpublicationtables/postgreslistpublicationtables_test.go @@ -17,7 +17,6 @@ package postgreslistpublicationtables_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgresListPublicationTables(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-publication-tables - source: my-postgres-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-list-publication-tables + source: my-postgres-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgreslistpublicationtables.Config{ Name: "example_tool", - Kind: "postgres-list-publication-tables", + Type: "postgres-list-publication-tables", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,16 +58,16 @@ func TestParseFromYamlPostgresListPublicationTables(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-publication-tables - source: my-postgres-instance - description: some description + kind: tools + name: example_tool + type: postgres-list-publication-tables + source: my-postgres-instance + description: some description `, want: server.ToolConfigs{ "example_tool": postgreslistpublicationtables.Config{ Name: "example_tool", - Kind: "postgres-list-publication-tables", + Type: "postgres-list-publication-tables", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,11 @@ func TestParseFromYamlPostgresListPublicationTables(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgreslistquerystats/postgreslistquerystats.go b/internal/tools/postgres/postgreslistquerystats/postgreslistquerystats.go index bd62c85c9b..1aa68becb8 100644 --- a/internal/tools/postgres/postgreslistquerystats/postgreslistquerystats.go +++ b/internal/tools/postgres/postgreslistquerystats/postgreslistquerystats.go @@ -26,7 +26,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-list-query-stats" +const resourceType string = "postgres-list-query-stats" const listQueryStats = ` SELECT @@ -49,8 +49,8 @@ const listQueryStats = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -69,7 +69,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -78,8 +78,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -123,7 +123,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgreslistquerystats/postgreslistquerystats_test.go b/internal/tools/postgres/postgreslistquerystats/postgreslistquerystats_test.go index c8408aa952..694a780d80 100644 --- a/internal/tools/postgres/postgreslistquerystats/postgreslistquerystats_test.go +++ b/internal/tools/postgres/postgreslistquerystats/postgreslistquerystats_test.go @@ -17,7 +17,6 @@ package postgreslistquerystats_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgresListQueryStats(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-query-stats - source: my-postgres-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-list-query-stats + source: my-postgres-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgreslistquerystats.Config{ Name: "example_tool", - Kind: "postgres-list-query-stats", + Type: "postgres-list-query-stats", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,16 +58,16 @@ func TestParseFromYamlPostgresListQueryStats(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-query-stats - source: my-postgres-instance - description: some description + kind: tools + name: example_tool + type: postgres-list-query-stats + source: my-postgres-instance + description: some description `, want: server.ToolConfigs{ "example_tool": postgreslistquerystats.Config{ Name: "example_tool", - Kind: "postgres-list-query-stats", + Type: "postgres-list-query-stats", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,11 @@ func TestParseFromYamlPostgresListQueryStats(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgreslistroles/postgreslistroles.go b/internal/tools/postgres/postgreslistroles/postgreslistroles.go index d7744b6d36..b1b814b352 100644 --- a/internal/tools/postgres/postgreslistroles/postgreslistroles.go +++ b/internal/tools/postgres/postgreslistroles/postgreslistroles.go @@ -26,7 +26,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-list-roles" +const resourceType string = "postgres-list-roles" const listRolesStatement = ` WITH RoleDetails AS ( @@ -71,8 +71,8 @@ const listRolesStatement = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -91,7 +91,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -100,8 +100,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -144,7 +144,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgreslistroles/postgreslistroles_test.go b/internal/tools/postgres/postgreslistroles/postgreslistroles_test.go index cf4249f6ff..1d3c89f056 100644 --- a/internal/tools/postgres/postgreslistroles/postgreslistroles_test.go +++ b/internal/tools/postgres/postgreslistroles/postgreslistroles_test.go @@ -17,7 +17,6 @@ package postgreslistroles_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgresListRoles(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-roles - source: my-postgres-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-list-roles + source: my-postgres-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgreslistroles.Config{ Name: "example_tool", - Kind: "postgres-list-roles", + Type: "postgres-list-roles", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,16 +58,16 @@ func TestParseFromYamlPostgresListRoles(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-roles - source: my-postgres-instance - description: some description + kind: tools + name: example_tool + type: postgres-list-roles + source: my-postgres-instance + description: some description `, want: server.ToolConfigs{ "example_tool": postgreslistroles.Config{ Name: "example_tool", - Kind: "postgres-list-roles", + Type: "postgres-list-roles", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,11 @@ func TestParseFromYamlPostgresListRoles(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgreslistschemas/postgreslistschemas.go b/internal/tools/postgres/postgreslistschemas/postgreslistschemas.go index 281f19b29f..8fae3cc844 100644 --- a/internal/tools/postgres/postgreslistschemas/postgreslistschemas.go +++ b/internal/tools/postgres/postgreslistschemas/postgreslistschemas.go @@ -26,7 +26,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-list-schemas" +const resourceType string = "postgres-list-schemas" const listSchemasStatement = ` WITH @@ -83,8 +83,8 @@ const listSchemasStatement = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -103,7 +103,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -112,8 +112,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -152,7 +152,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgreslistschemas/postgreslistschemas_test.go b/internal/tools/postgres/postgreslistschemas/postgreslistschemas_test.go index a416d584bd..62332b7e7d 100644 --- a/internal/tools/postgres/postgreslistschemas/postgreslistschemas_test.go +++ b/internal/tools/postgres/postgreslistschemas/postgreslistschemas_test.go @@ -17,7 +17,6 @@ package postgreslistschemas_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgreslistSchemas(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-schemas - source: my-postgres-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-list-schemas + source: my-postgres-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgreslistschemas.Config{ Name: "example_tool", - Kind: "postgres-list-schemas", + Type: "postgres-list-schemas", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,16 +58,16 @@ func TestParseFromYamlPostgreslistSchemas(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-schemas - source: my-postgres-instance - description: some description + kind: tools + name: example_tool + type: postgres-list-schemas + source: my-postgres-instance + description: some description `, want: server.ToolConfigs{ "example_tool": postgreslistschemas.Config{ Name: "example_tool", - Kind: "postgres-list-schemas", + Type: "postgres-list-schemas", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,11 @@ func TestParseFromYamlPostgreslistSchemas(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgreslistsequences/postgreslistsequences.go b/internal/tools/postgres/postgreslistsequences/postgreslistsequences.go index 6245da4e58..616d341e51 100644 --- a/internal/tools/postgres/postgreslistsequences/postgreslistsequences.go +++ b/internal/tools/postgres/postgreslistsequences/postgreslistsequences.go @@ -26,7 +26,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-list-sequences" +const resourceType string = "postgres-list-sequences" const listSequencesStatement = ` SELECT @@ -49,8 +49,8 @@ const listSequencesStatement = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -69,7 +69,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -78,8 +78,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -122,7 +122,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgreslistsequences/postgreslistsequences_test.go b/internal/tools/postgres/postgreslistsequences/postgreslistsequences_test.go index 566da0ef7b..5491eec275 100644 --- a/internal/tools/postgres/postgreslistsequences/postgreslistsequences_test.go +++ b/internal/tools/postgres/postgreslistsequences/postgreslistsequences_test.go @@ -17,7 +17,6 @@ package postgreslistsequences_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgresListSequences(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-sequences - source: my-postgres-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-list-sequences + source: my-postgres-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgreslistsequences.Config{ Name: "example_tool", - Kind: "postgres-list-sequences", + Type: "postgres-list-sequences", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,16 +58,16 @@ func TestParseFromYamlPostgresListSequences(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-sequences - source: my-postgres-instance - description: some description + kind: tools + name: example_tool + type: postgres-list-sequences + source: my-postgres-instance + description: some description `, want: server.ToolConfigs{ "example_tool": postgreslistsequences.Config{ Name: "example_tool", - Kind: "postgres-list-sequences", + Type: "postgres-list-sequences", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,11 @@ func TestParseFromYamlPostgresListSequences(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgresliststoredprocedure/postgresliststoredprocedure.go b/internal/tools/postgres/postgresliststoredprocedure/postgresliststoredprocedure.go index bef15ca468..713826ab3a 100644 --- a/internal/tools/postgres/postgresliststoredprocedure/postgresliststoredprocedure.go +++ b/internal/tools/postgres/postgresliststoredprocedure/postgresliststoredprocedure.go @@ -29,7 +29,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-list-stored-procedure" +const resourceType string = "postgres-list-stored-procedure" const listStoredProcedure = ` SELECT @@ -53,8 +53,8 @@ const listStoredProcedure = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -75,11 +75,11 @@ var _ compatibleSource = &alloydbpg.Source{} var _ compatibleSource = &cloudsqlpg.Source{} var _ compatibleSource = &postgres.Source{} -var compatibleSources = [...]string{alloydbpg.SourceKind, cloudsqlpg.SourceKind, postgres.SourceKind} +var compatibleSources = [...]string{alloydbpg.SourceType, cloudsqlpg.SourceType, postgres.SourceType} type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -88,8 +88,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -102,7 +102,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // verify the source is compatible s, ok := rawS.(compatibleSource) if !ok { - return nil, fmt.Errorf("invalid source for %q tool: source kind must be one of %q", kind, compatibleSources) + return nil, fmt.Errorf("invalid source for %q tool: source type must be one of %q", resourceType, compatibleSources) } allParameters := parameters.Parameters{ @@ -120,11 +120,9 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) // finish tool setup return Tool{ - name: cfg.Name, - kind: cfg.Kind, - authRequired: cfg.AuthRequired, - allParams: allParameters, - pool: s.PostgresPool(), + Config: cfg, + allParams: allParameters, + pool: s.PostgresPool(), manifest: tools.Manifest{ Description: cfg.Description, Parameters: paramManifest, @@ -139,13 +137,10 @@ var _ tools.Tool = Tool{} type Tool struct { Config - 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 + allParams parameters.Parameters `yaml:"allParams"` + pool *pgxpool.Pool + manifest tools.Manifest + mcpManifest tools.McpManifest } func (t Tool) ToConfig() tools.ToolConfig { @@ -202,7 +197,7 @@ func (t Tool) McpManifest() tools.McpManifest { } func (t Tool) Authorized(verifiedAuthServices []string) bool { - return tools.IsAuthorized(t.authRequired, verifiedAuthServices) + return tools.IsAuthorized(t.AuthRequired, verifiedAuthServices) } func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) { diff --git a/internal/tools/postgres/postgresliststoredprocedure/postgresliststoredprocedure_test.go b/internal/tools/postgres/postgresliststoredprocedure/postgresliststoredprocedure_test.go index 0ded95f2d5..63593bd0ec 100644 --- a/internal/tools/postgres/postgresliststoredprocedure/postgresliststoredprocedure_test.go +++ b/internal/tools/postgres/postgresliststoredprocedure/postgresliststoredprocedure_test.go @@ -17,7 +17,6 @@ package postgresliststoredprocedure_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgresListStoredProcedure(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-stored-procedure - source: my-postgres-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-list-stored-procedure + source: my-postgres-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgresliststoredprocedure.Config{ Name: "example_tool", - Kind: "postgres-list-stored-procedure", + Type: "postgres-list-stored-procedure", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,16 +58,16 @@ func TestParseFromYamlPostgresListStoredProcedure(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-stored-procedure - source: my-postgres-instance - description: some description + kind: tools + name: example_tool + type: postgres-list-stored-procedure + source: my-postgres-instance + description: some description `, want: server.ToolConfigs{ "example_tool": postgresliststoredprocedure.Config{ Name: "example_tool", - Kind: "postgres-list-stored-procedure", + Type: "postgres-list-stored-procedure", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,11 @@ func TestParseFromYamlPostgresListStoredProcedure(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgreslisttables/postgreslisttables.go b/internal/tools/postgres/postgreslisttables/postgreslisttables.go index 2dac1a957c..64a62d2fb2 100644 --- a/internal/tools/postgres/postgreslisttables/postgreslisttables.go +++ b/internal/tools/postgres/postgreslisttables/postgreslisttables.go @@ -26,7 +26,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-list-tables" +const resourceType string = "postgres-list-tables" const listTablesStatement = ` WITH desired_relkinds AS ( @@ -107,8 +107,8 @@ const listTablesStatement = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -127,7 +127,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -136,8 +136,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -169,7 +169,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgreslisttables/postgreslisttables_test.go b/internal/tools/postgres/postgreslisttables/postgreslisttables_test.go index ded7f9e4cb..fdb66825c9 100644 --- a/internal/tools/postgres/postgreslisttables/postgreslisttables_test.go +++ b/internal/tools/postgres/postgreslisttables/postgreslisttables_test.go @@ -17,7 +17,6 @@ package postgreslisttables_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgresListTables(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-tables - source: my-postgres-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-list-tables + source: my-postgres-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgreslisttables.Config{ Name: "example_tool", - Kind: "postgres-list-tables", + Type: "postgres-list-tables", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,15 +58,12 @@ func TestParseFromYamlPostgresListTables(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgreslisttablespaces/postgreslisttablespaces.go b/internal/tools/postgres/postgreslisttablespaces/postgreslisttablespaces.go index e4008706ce..e1e3b2e7ea 100644 --- a/internal/tools/postgres/postgreslisttablespaces/postgreslisttablespaces.go +++ b/internal/tools/postgres/postgreslisttablespaces/postgreslisttablespaces.go @@ -26,7 +26,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-list-tablespaces" +const resourceType string = "postgres-list-tablespaces" const listTableSpacesStatement = ` WITH @@ -55,8 +55,8 @@ const listTableSpacesStatement = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -75,7 +75,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -84,8 +84,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -127,7 +127,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgreslisttablespaces/postgreslisttablespaces_test.go b/internal/tools/postgres/postgreslisttablespaces/postgreslisttablespaces_test.go index 0d28d5abf3..88e134221a 100644 --- a/internal/tools/postgres/postgreslisttablespaces/postgreslisttablespaces_test.go +++ b/internal/tools/postgres/postgreslisttablespaces/postgreslisttablespaces_test.go @@ -17,7 +17,6 @@ package postgreslisttablespaces_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgresListTablespaces(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-tablespaces - source: my-postgres-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-list-tablespaces + source: my-postgres-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgreslisttablespaces.Config{ Name: "example_tool", - Kind: "postgres-list-tablespaces", + Type: "postgres-list-tablespaces", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,16 +58,16 @@ func TestParseFromYamlPostgresListTablespaces(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-tablespaces - source: my-postgres-instance - description: some description + kind: tools + name: example_tool + type: postgres-list-tablespaces + source: my-postgres-instance + description: some description `, want: server.ToolConfigs{ "example_tool": postgreslisttablespaces.Config{ Name: "example_tool", - Kind: "postgres-list-tablespaces", + Type: "postgres-list-tablespaces", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,12 @@ func TestParseFromYamlPostgresListTablespaces(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgreslisttablestats/postgreslisttablestats.go b/internal/tools/postgres/postgreslisttablestats/postgreslisttablestats.go index 8e1ea7ddb5..eca7e495b0 100644 --- a/internal/tools/postgres/postgreslisttablestats/postgreslisttablestats.go +++ b/internal/tools/postgres/postgreslisttablestats/postgreslisttablestats.go @@ -26,7 +26,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-list-table-stats" +const resourceType string = "postgres-list-table-stats" const listTableStats = ` WITH table_stats AS ( @@ -76,8 +76,8 @@ const listTableStats = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -96,7 +96,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -105,8 +105,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -161,7 +161,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgreslisttablestats/postgreslisttablestats_test.go b/internal/tools/postgres/postgreslisttablestats/postgreslisttablestats_test.go index cfaac3eda5..c0c71c4924 100644 --- a/internal/tools/postgres/postgreslisttablestats/postgreslisttablestats_test.go +++ b/internal/tools/postgres/postgreslisttablestats/postgreslisttablestats_test.go @@ -17,7 +17,6 @@ package postgreslisttablestats_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgresListTableStats(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-table-stats - source: my-postgres-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-list-table-stats + source: my-postgres-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgreslisttablestats.Config{ Name: "example_tool", - Kind: "postgres-list-table-stats", + Type: "postgres-list-table-stats", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,16 +58,16 @@ func TestParseFromYamlPostgresListTableStats(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-table-stats - source: my-postgres-instance - description: some description + kind: tools + name: example_tool + type: postgres-list-table-stats + source: my-postgres-instance + description: some description `, want: server.ToolConfigs{ "example_tool": postgreslisttablestats.Config{ Name: "example_tool", - Kind: "postgres-list-table-stats", + Type: "postgres-list-table-stats", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,11 @@ func TestParseFromYamlPostgresListTableStats(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgreslisttriggers/postgreslisttriggers.go b/internal/tools/postgres/postgreslisttriggers/postgreslisttriggers.go index 85ae403505..5071bb7035 100644 --- a/internal/tools/postgres/postgreslisttriggers/postgreslisttriggers.go +++ b/internal/tools/postgres/postgreslisttriggers/postgreslisttriggers.go @@ -26,7 +26,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-list-triggers" +const resourceType string = "postgres-list-triggers" const listTriggersStatement = ` WITH @@ -75,8 +75,8 @@ const listTriggersStatement = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -95,7 +95,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -104,8 +104,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -149,7 +149,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgreslisttriggers/postgreslisttriggers_test.go b/internal/tools/postgres/postgreslisttriggers/postgreslisttriggers_test.go index ac3efb4337..ecec935040 100644 --- a/internal/tools/postgres/postgreslisttriggers/postgreslisttriggers_test.go +++ b/internal/tools/postgres/postgreslisttriggers/postgreslisttriggers_test.go @@ -17,7 +17,6 @@ package postgreslisttriggers_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgreslistTriggers(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-triggers - source: my-postgres-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-list-triggers + source: my-postgres-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgreslisttriggers.Config{ Name: "example_tool", - Kind: "postgres-list-triggers", + Type: "postgres-list-triggers", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,16 +58,16 @@ func TestParseFromYamlPostgreslistTriggers(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-triggers - source: my-postgres-instance - description: some description + kind: tools + name: example_tool + type: postgres-list-triggers + source: my-postgres-instance + description: some description `, want: server.ToolConfigs{ "example_tool": postgreslisttriggers.Config{ Name: "example_tool", - Kind: "postgres-list-triggers", + Type: "postgres-list-triggers", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,12 @@ func TestParseFromYamlPostgreslistTriggers(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgreslistviews/postgreslistviews.go b/internal/tools/postgres/postgreslistviews/postgreslistviews.go index a6dd7faf10..fa2f8c49e8 100644 --- a/internal/tools/postgres/postgreslistviews/postgreslistviews.go +++ b/internal/tools/postgres/postgreslistviews/postgreslistviews.go @@ -26,7 +26,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-list-views" +const resourceType string = "postgres-list-views" const listViewsStatement = ` WITH list_views AS ( @@ -50,8 +50,8 @@ const listViewsStatement = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -70,7 +70,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -79,8 +79,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -119,7 +119,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgreslistviews/postgreslistviews_test.go b/internal/tools/postgres/postgreslistviews/postgreslistviews_test.go index ffa234569f..660a77a431 100644 --- a/internal/tools/postgres/postgreslistviews/postgreslistviews_test.go +++ b/internal/tools/postgres/postgreslistviews/postgreslistviews_test.go @@ -17,7 +17,6 @@ package postgreslistviews_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgresListViews(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-views - source: my-postgres-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-list-views + source: my-postgres-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgreslistviews.Config{ Name: "example_tool", - Kind: "postgres-list-views", + Type: "postgres-list-views", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,16 +58,16 @@ func TestParseFromYamlPostgresListViews(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-list-views - source: my-postgres-instance - description: some description + kind: tools + name: example_tool + type: postgres-list-views + source: my-postgres-instance + description: some description `, want: server.ToolConfigs{ "example_tool": postgreslistviews.Config{ Name: "example_tool", - Kind: "postgres-list-views", + Type: "postgres-list-views", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,12 @@ func TestParseFromYamlPostgresListViews(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgreslongrunningtransactions/postgreslongrunningtransactions.go b/internal/tools/postgres/postgreslongrunningtransactions/postgreslongrunningtransactions.go index aebce2cd6c..6491c676ff 100644 --- a/internal/tools/postgres/postgreslongrunningtransactions/postgreslongrunningtransactions.go +++ b/internal/tools/postgres/postgreslongrunningtransactions/postgreslongrunningtransactions.go @@ -26,7 +26,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-long-running-transactions" +const resourceType string = "postgres-long-running-transactions" const longRunningTransactions = ` SELECT @@ -57,8 +57,8 @@ const longRunningTransactions = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -77,7 +77,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -86,8 +86,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -131,7 +131,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgreslongrunningtransactions/postgreslongrunningtransactions_test.go b/internal/tools/postgres/postgreslongrunningtransactions/postgreslongrunningtransactions_test.go index d1809933da..58fc3c8454 100644 --- a/internal/tools/postgres/postgreslongrunningtransactions/postgreslongrunningtransactions_test.go +++ b/internal/tools/postgres/postgreslongrunningtransactions/postgreslongrunningtransactions_test.go @@ -17,7 +17,6 @@ package postgreslongrunningtransactions_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgresLongRunningTransactions(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-long-running-transactions - source: my-postgres-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-long-running-transactions + source: my-postgres-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgreslongrunningtransactions.Config{ Name: "example_tool", - Kind: "postgres-long-running-transactions", + Type: "postgres-long-running-transactions", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,16 +58,16 @@ func TestParseFromYamlPostgresLongRunningTransactions(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-long-running-transactions - source: my-postgres-instance - description: some description + kind: tools + name: example_tool + type: postgres-long-running-transactions + source: my-postgres-instance + description: some description `, want: server.ToolConfigs{ "example_tool": postgreslongrunningtransactions.Config{ Name: "example_tool", - Kind: "postgres-long-running-transactions", + Type: "postgres-long-running-transactions", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,11 @@ func TestParseFromYamlPostgresLongRunningTransactions(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgresreplicationstats/postgresreplicationstats.go b/internal/tools/postgres/postgresreplicationstats/postgresreplicationstats.go index d737495d0f..393b6a9016 100644 --- a/internal/tools/postgres/postgresreplicationstats/postgresreplicationstats.go +++ b/internal/tools/postgres/postgresreplicationstats/postgresreplicationstats.go @@ -26,7 +26,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-replication-stats" +const resourceType string = "postgres-replication-stats" const replicationStats = ` SELECT @@ -47,8 +47,8 @@ const replicationStats = ` ` func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -67,7 +67,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -76,8 +76,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -118,7 +118,7 @@ func (t Tool) ToConfig() tools.ToolConfig { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgresreplicationstats/postgresreplicationstats_test.go b/internal/tools/postgres/postgresreplicationstats/postgresreplicationstats_test.go index 1958d42895..87952ecee6 100644 --- a/internal/tools/postgres/postgresreplicationstats/postgresreplicationstats_test.go +++ b/internal/tools/postgres/postgresreplicationstats/postgresreplicationstats_test.go @@ -17,7 +17,6 @@ package postgresreplicationstats_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlPostgresReplicationStats(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-replication-stats - source: my-postgres-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: postgres-replication-stats + source: my-postgres-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": postgresreplicationstats.Config{ Name: "example_tool", - Kind: "postgres-replication-stats", + Type: "postgres-replication-stats", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,16 +58,16 @@ func TestParseFromYamlPostgresReplicationStats(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-replication-stats - source: my-postgres-instance - description: some description + kind: tools + name: example_tool + type: postgres-replication-stats + source: my-postgres-instance + description: some description `, want: server.ToolConfigs{ "example_tool": postgresreplicationstats.Config{ Name: "example_tool", - Kind: "postgres-replication-stats", + Type: "postgres-replication-stats", Source: "my-postgres-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,12 @@ func TestParseFromYamlPostgresReplicationStats(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/postgres/postgressql/postgressql.go b/internal/tools/postgres/postgressql/postgressql.go index b7b0c0ea7d..8614af3092 100644 --- a/internal/tools/postgres/postgressql/postgressql.go +++ b/internal/tools/postgres/postgressql/postgressql.go @@ -26,11 +26,11 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -const kind string = "postgres-sql" +const resourceType string = "postgres-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Statement string `yaml:"statement" validate:"required"` @@ -61,8 +61,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -94,7 +94,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/postgres/postgressql/postgressql_test.go b/internal/tools/postgres/postgressql/postgressql_test.go index c29152ad9b..76d8b88f76 100644 --- a/internal/tools/postgres/postgressql/postgressql_test.go +++ b/internal/tools/postgres/postgressql/postgressql_test.go @@ -17,7 +17,6 @@ package postgressql_test import ( "testing" - 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" @@ -38,30 +37,30 @@ func TestParseFromYamlPostgres(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-sql - source: my-pg-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - authRequired: - - my-google-auth-service - - other-auth-service - parameters: - - name: country - type: string - description: some description - authServices: - - name: my-google-auth-service - field: user_id - - name: other-auth-service - field: user_id + kind: tools + name: example_tool + type: postgres-sql + source: my-pg-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + authRequired: + - my-google-auth-service + - other-auth-service + parameters: + - name: country + type: string + description: some description + authServices: + - name: my-google-auth-service + field: user_id + - name: other-auth-service + field: user_id `, want: server.ToolConfigs{ "example_tool": postgressql.Config{ Name: "example_tool", - Kind: "postgres-sql", + Type: "postgres-sql", Source: "my-pg-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -77,15 +76,12 @@ func TestParseFromYamlPostgres(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -106,33 +102,33 @@ func TestParseFromYamlWithTemplateParamsPostgres(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: postgres-sql - source: my-pg-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - parameters: - - name: name - type: string - description: some description - templateParameters: - - name: tableName - type: string - description: The table to select hotels from. - - name: fieldArray - type: array - description: The columns to return for the query. - items: - name: column - type: string - description: A column name that will be returned from the query. + kind: tools + name: example_tool + type: postgres-sql + source: my-pg-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + parameters: + - name: name + type: string + description: some description + templateParameters: + - name: tableName + type: string + description: The table to select hotels from. + - name: fieldArray + type: array + description: The columns to return for the query. + items: + name: column + type: string + description: A column name that will be returned from the query. `, want: server.ToolConfigs{ "example_tool": postgressql.Config{ Name: "example_tool", - Kind: "postgres-sql", + Type: "postgres-sql", Source: "my-pg-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -150,15 +146,12 @@ func TestParseFromYamlWithTemplateParamsPostgres(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/redis/redis.go b/internal/tools/redis/redis.go index 9103afd5af..2550411e4e 100644 --- a/internal/tools/redis/redis.go +++ b/internal/tools/redis/redis.go @@ -25,11 +25,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "redis" +const resourceType string = "redis" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -48,7 +48,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Commands [][]string `yaml:"commands" validate:"required"` @@ -59,8 +59,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -85,7 +85,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/redis/redis_test.go b/internal/tools/redis/redis_test.go index 5ee4ce3841..88b50d8274 100644 --- a/internal/tools/redis/redis_test.go +++ b/internal/tools/redis/redis_test.go @@ -17,7 +17,6 @@ package redis_test import ( "testing" - 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" @@ -38,23 +37,23 @@ func TestParseFromYamlRedis(t *testing.T) { { desc: "basic example", in: ` - tools: - redis_tool: - kind: redis - source: my-redis-instance - description: some description - commands: - - [SET, greeting, "hello, {{.name}}"] - - [GET, id] - parameters: - - name: name - type: string - description: user name + kind: tools + name: redis_tool + type: redis + source: my-redis-instance + description: some description + commands: + - [SET, greeting, "hello, {{.name}}"] + - [GET, id] + parameters: + - name: name + type: string + description: user name `, want: server.ToolConfigs{ "redis_tool": redis.Config{ Name: "redis_tool", - Kind: "redis", + Type: "redis", Source: "my-redis-instance", Description: "some description", AuthRequired: []string{}, @@ -68,15 +67,11 @@ func TestParseFromYamlRedis(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/serverlessspark/createbatch/config.go b/internal/tools/serverlessspark/createbatch/config.go index bcbf611584..229ddef936 100644 --- a/internal/tools/serverlessspark/createbatch/config.go +++ b/internal/tools/serverlessspark/createbatch/config.go @@ -43,7 +43,7 @@ type compatibleSource interface { // Initialize implementation. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` RuntimeConfig *dataprocpb.RuntimeConfig `yaml:"runtimeConfig"` @@ -56,7 +56,7 @@ func NewConfig(ctx context.Context, name string, decoder *yaml.Decoder) (Config, // conversion for RuntimeConfig and EnvironmentConfig. var ymlCfg struct { Name string `yaml:"name"` - Kind string `yaml:"kind"` + Type string `yaml:"type"` Source string `yaml:"source"` Description string `yaml:"description"` RuntimeConfig any `yaml:"runtimeConfig"` @@ -70,7 +70,7 @@ func NewConfig(ctx context.Context, name string, decoder *yaml.Decoder) (Config, cfg := Config{ Name: name, - Kind: ymlCfg.Kind, + Type: ymlCfg.Type, Source: ymlCfg.Source, Description: ymlCfg.Description, AuthRequired: ymlCfg.AuthRequired, diff --git a/internal/tools/serverlessspark/createbatch/tool.go b/internal/tools/serverlessspark/createbatch/tool.go index 98dd9d6640..ad43b86d88 100644 --- a/internal/tools/serverlessspark/createbatch/tool.go +++ b/internal/tools/serverlessspark/createbatch/tool.go @@ -34,7 +34,7 @@ type BatchBuilder interface { func NewTool(cfg Config, originalCfg tools.ToolConfig, srcs map[string]sources.Source, builder BatchBuilder) (*Tool, error) { desc := cfg.Description if desc == "" { - desc = fmt.Sprintf("Creates a Serverless Spark (aka Dataproc Serverless) %s operation.", cfg.Kind) + desc = fmt.Sprintf("Creates a Serverless Spark (aka Dataproc Serverless) %s operation.", cfg.Type) } allParameters := builder.Parameters() @@ -66,7 +66,7 @@ type Tool struct { } func (t *Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/serverlessspark/serverlesssparkcancelbatch/serverlesssparkcancelbatch.go b/internal/tools/serverlessspark/serverlesssparkcancelbatch/serverlesssparkcancelbatch.go index cfd5f37cab..9a8af0a13e 100644 --- a/internal/tools/serverlessspark/serverlesssparkcancelbatch/serverlesssparkcancelbatch.go +++ b/internal/tools/serverlessspark/serverlesssparkcancelbatch/serverlesssparkcancelbatch.go @@ -27,11 +27,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind = "serverless-spark-cancel-batch" +const resourceType = "serverless-spark-cancel-batch" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -59,9 +59,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the unique name for this tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the unique name for this tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize creates a new Tool instance. @@ -100,7 +100,7 @@ type Tool struct { // Invoke executes the tool's operation. func (t *Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/serverlessspark/serverlesssparkcancelbatch/serverlesssparkcancelbatch_test.go b/internal/tools/serverlessspark/serverlesssparkcancelbatch/serverlesssparkcancelbatch_test.go index 5348399a32..463fbf33e1 100644 --- a/internal/tools/serverlessspark/serverlesssparkcancelbatch/serverlesssparkcancelbatch_test.go +++ b/internal/tools/serverlessspark/serverlesssparkcancelbatch/serverlesssparkcancelbatch_test.go @@ -17,7 +17,6 @@ package serverlesssparkcancelbatch_test import ( "testing" - "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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: serverless-spark-cancel-batch - source: my-instance - description: some description + kind: tools + name: example_tool + type: serverless-spark-cancel-batch + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": serverlesssparkcancelbatch.Config{ Name: "example_tool", - Kind: "serverless-spark-cancel-batch", + Type: "serverless-spark-cancel-batch", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got, yaml.Strict()) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/serverlessspark/serverlesssparkcreatepysparkbatch/serverlesssparkcreatepysparkbatch.go b/internal/tools/serverlessspark/serverlesssparkcreatepysparkbatch/serverlesssparkcreatepysparkbatch.go index d07fa01b92..c0801059f8 100644 --- a/internal/tools/serverlessspark/serverlesssparkcreatepysparkbatch/serverlesssparkcreatepysparkbatch.go +++ b/internal/tools/serverlessspark/serverlesssparkcreatepysparkbatch/serverlesssparkcreatepysparkbatch.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind = "serverless-spark-create-pyspark-batch" +const resourceType = "serverless-spark-create-pyspark-batch" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,9 +49,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the unique name for this tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the unique name for this tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize creates a new Tool instance. diff --git a/internal/tools/serverlessspark/serverlesssparkcreatesparkbatch/serverlesssparkcreatesparkbatch.go b/internal/tools/serverlessspark/serverlesssparkcreatesparkbatch/serverlesssparkcreatesparkbatch.go index e16b1904e2..403ea1573a 100644 --- a/internal/tools/serverlessspark/serverlesssparkcreatesparkbatch/serverlesssparkcreatesparkbatch.go +++ b/internal/tools/serverlessspark/serverlesssparkcreatesparkbatch/serverlesssparkcreatesparkbatch.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind = "serverless-spark-create-spark-batch" +const resourceType = "serverless-spark-create-spark-batch" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,9 +49,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the unique name for this tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the unique name for this tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize creates a new Tool instance. diff --git a/internal/tools/serverlessspark/serverlesssparkgetbatch/serverlesssparkgetbatch.go b/internal/tools/serverlessspark/serverlesssparkgetbatch/serverlesssparkgetbatch.go index 14ef9d1798..a892c4746f 100644 --- a/internal/tools/serverlessspark/serverlesssparkgetbatch/serverlesssparkgetbatch.go +++ b/internal/tools/serverlessspark/serverlesssparkgetbatch/serverlesssparkgetbatch.go @@ -27,11 +27,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind = "serverless-spark-get-batch" +const resourceType = "serverless-spark-get-batch" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -59,9 +59,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the unique name for this tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the unique name for this tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize creates a new Tool instance. @@ -100,7 +100,7 @@ type Tool struct { // Invoke executes the tool's operation. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/serverlessspark/serverlesssparkgetbatch/serverlesssparkgetbatch_test.go b/internal/tools/serverlessspark/serverlesssparkgetbatch/serverlesssparkgetbatch_test.go index f7589f7b07..e47ec519fb 100644 --- a/internal/tools/serverlessspark/serverlesssparkgetbatch/serverlesssparkgetbatch_test.go +++ b/internal/tools/serverlessspark/serverlesssparkgetbatch/serverlesssparkgetbatch_test.go @@ -17,7 +17,6 @@ package serverlesssparkgetbatch_test import ( "testing" - "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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: serverless-spark-get-batch - source: my-instance - description: some description + kind: tools + name: example_tool + type: serverless-spark-get-batch + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": serverlesssparkgetbatch.Config{ Name: "example_tool", - Kind: "serverless-spark-get-batch", + Type: "serverless-spark-get-batch", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got, yaml.Strict()) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/serverlessspark/serverlesssparklistbatches/serverlesssparklistbatches.go b/internal/tools/serverlessspark/serverlesssparklistbatches/serverlesssparklistbatches.go index 4f8855c831..e064d83f07 100644 --- a/internal/tools/serverlessspark/serverlesssparklistbatches/serverlesssparklistbatches.go +++ b/internal/tools/serverlessspark/serverlesssparklistbatches/serverlesssparklistbatches.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind = "serverless-spark-list-batches" +const resourceType = "serverless-spark-list-batches" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -58,9 +58,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the unique name for this tool. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the unique name for this tool. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize creates a new Tool instance. @@ -101,7 +101,7 @@ type Tool struct { // Invoke executes the tool's operation. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/serverlessspark/serverlesssparklistbatches/serverlesssparklistbatches_test.go b/internal/tools/serverlessspark/serverlesssparklistbatches/serverlesssparklistbatches_test.go index 95a1123740..5b465baaa4 100644 --- a/internal/tools/serverlessspark/serverlesssparklistbatches/serverlesssparklistbatches_test.go +++ b/internal/tools/serverlessspark/serverlesssparklistbatches/serverlesssparklistbatches_test.go @@ -17,7 +17,6 @@ package serverlesssparklistbatches_test import ( "testing" - "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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: serverless-spark-list-batches - source: my-instance - description: some description + kind: tools + name: example_tool + type: serverless-spark-list-batches + source: my-instance + description: some description `, want: server.ToolConfigs{ "example_tool": serverlesssparklistbatches.Config{ Name: "example_tool", - Kind: "serverless-spark-list-batches", + Type: "serverless-spark-list-batches", Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got, yaml.Strict()) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/serverlessspark/testutils/testutils.go b/internal/tools/serverlessspark/testutils/testutils.go index a8a2cfc5a3..d9ff086445 100644 --- a/internal/tools/serverlessspark/testutils/testutils.go +++ b/internal/tools/serverlessspark/testutils/testutils.go @@ -20,7 +20,6 @@ import ( "testing" dataproc "cloud.google.com/go/dataproc/v2/apiv1/dataprocpb" - "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" @@ -30,7 +29,7 @@ import ( ) // RunParseFromYAMLTests runs a suite of tests for parsing tool configurations from YAML. -func RunParseFromYAMLTests(t *testing.T, kind string, newConfig func(c createbatch.Config) tools.ToolConfig) { +func RunParseFromYAMLTests(t *testing.T, resourceType string, newConfig func(c createbatch.Config) tools.ToolConfig) { t.Helper() ctx, err := testutils.ContextWithNewLogger() if err != nil { @@ -46,16 +45,16 @@ func RunParseFromYAMLTests(t *testing.T, kind string, newConfig func(c createbat { desc: "basic example", in: fmt.Sprintf(` - tools: - example_tool: - kind: %s - source: my-instance - description: some description - `, kind), + kind: tools + name: example_tool + type: %s + source: my-instance + description: some description + `, resourceType), want: server.ToolConfigs{ "example_tool": newConfig(createbatch.Config{ Name: "example_tool", - Kind: kind, + Type: resourceType, Source: "my-instance", Description: "some description", AuthRequired: []string{}, @@ -65,22 +64,22 @@ func RunParseFromYAMLTests(t *testing.T, kind string, newConfig func(c createbat { desc: "detailed config", in: fmt.Sprintf(` - tools: - example_tool: - kind: %s - source: my-instance - description: some description - runtimeConfig: - properties: - "spark.driver.memory": "1g" - environmentConfig: - executionConfig: - networkUri: "my-network" - `, kind), + kind: tools + name: example_tool + type: %s + source: my-instance + description: some description + runtimeConfig: + properties: + "spark.driver.memory": "1g" + environmentConfig: + executionConfig: + networkUri: "my-network" + `, resourceType), want: server.ToolConfigs{ "example_tool": newConfig(createbatch.Config{ Name: "example_tool", - Kind: kind, + Type: resourceType, Source: "my-instance", Description: "some description", RuntimeConfig: &dataproc.RuntimeConfig{ @@ -98,36 +97,33 @@ func RunParseFromYAMLTests(t *testing.T, kind string, newConfig func(c createbat { desc: "invalid runtime config", in: fmt.Sprintf(` - tools: - example_tool: - kind: %s - source: my-instance - description: some description - runtimeConfig: - invalidField: true - `, kind), + kind: tools + name: example_tool + type: %s + source: my-instance + description: some description + runtimeConfig: + invalidField: true + `, resourceType), wantErr: "unmarshal runtimeConfig", }, { desc: "invalid environment config", in: fmt.Sprintf(` - tools: - example_tool: - kind: %s - source: my-instance - description: some description - environmentConfig: - invalidField: true - `, kind), + kind: tools + name: example_tool + type: %s + source: my-instance + description: some description + environmentConfig: + invalidField: true + `, resourceType), wantErr: "unmarshal environmentConfig", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got, yaml.Strict()) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if tc.wantErr != "" { if err == nil { t.Fatal("expected error, got nil") @@ -141,7 +137,7 @@ func RunParseFromYAMLTests(t *testing.T, kind string, newConfig func(c createbat t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools, protocmp.Transform()); diff != "" { + if diff := cmp.Diff(tc.want, got, protocmp.Transform()); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/singlestore/singlestoreexecutesql/singlestoreexecutesql.go b/internal/tools/singlestore/singlestoreexecutesql/singlestoreexecutesql.go index 6ba2cb631c..3842638931 100644 --- a/internal/tools/singlestore/singlestoreexecutesql/singlestoreexecutesql.go +++ b/internal/tools/singlestore/singlestoreexecutesql/singlestoreexecutesql.go @@ -27,11 +27,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "singlestore-execute-sql" +const resourceType string = "singlestore-execute-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -51,7 +51,7 @@ type compatibleSource interface { // Config represents the configuration for the singlestore-execute-sql tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -60,9 +60,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool configuration. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool configuration. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize sets up the Tool using the provided sources map. @@ -99,7 +99,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // Invoke executes the provided SQL query using the tool's database connection and returns the results. func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -115,7 +115,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para if err != nil { return nil, fmt.Errorf("error getting logger: %s", err) } - logger.DebugContext(ctx, "executing `%s` tool query: %s", kind, sql) + logger.DebugContext(ctx, "executing `%s` tool query: %s", resourceType, sql) return source.RunSQL(ctx, sql, nil) } diff --git a/internal/tools/singlestore/singlestoreexecutesql/singlestoreexecutesql_test.go b/internal/tools/singlestore/singlestoreexecutesql/singlestoreexecutesql_test.go index f68455cf42..208a369342 100644 --- a/internal/tools/singlestore/singlestoreexecutesql/singlestoreexecutesql_test.go +++ b/internal/tools/singlestore/singlestoreexecutesql/singlestoreexecutesql_test.go @@ -17,14 +17,13 @@ package singlestoreexecutesql_test import ( "testing" - 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/singlestore/singlestoreexecutesql" ) -func TestParseFromYamlExecuteSql(t *testing.T) { +func TestParseFromYaml(t *testing.T) { ctx, err := testutils.ContextWithNewLogger() if err != nil { t.Fatalf("unexpected error: %s", err) @@ -37,19 +36,19 @@ func TestParseFromYamlExecuteSql(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: singlestore-execute-sql - source: my-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: singlestore-execute-sql + source: my-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": singlestoreexecutesql.Config{ Name: "example_tool", - Kind: "singlestore-execute-sql", + Type: "singlestore-execute-sql", Source: "my-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,15 +58,11 @@ func TestParseFromYamlExecuteSql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/singlestore/singlestoresql/singlestoresql.go b/internal/tools/singlestore/singlestoresql/singlestoresql.go index 2f4be903f6..4334ee2db1 100644 --- a/internal/tools/singlestore/singlestoresql/singlestoresql.go +++ b/internal/tools/singlestore/singlestoresql/singlestoresql.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "singlestore-sql" +const resourceType string = "singlestore-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { // Config defines the configuration for a SingleStore SQL tool. type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Statement string `yaml:"statement" validate:"required"` @@ -62,9 +62,9 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -// ToolConfigKind returns the kind of the tool configuration. -func (cfg Config) ToolConfigKind() string { - return kind +// ToolConfigType returns the type of the tool configuration. +func (cfg Config) ToolConfigType() string { + return resourceType } // Initialize sets up and returns a new Tool instance based on the provided configuration and available sources. @@ -127,7 +127,7 @@ func (t Tool) ToConfig() tools.ToolConfig { // - 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, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/singlestore/singlestoresql/singlestoresql_test.go b/internal/tools/singlestore/singlestoresql/singlestoresql_test.go index a4c7559cf4..e6204d8552 100644 --- a/internal/tools/singlestore/singlestoresql/singlestoresql_test.go +++ b/internal/tools/singlestore/singlestoresql/singlestoresql_test.go @@ -17,7 +17,6 @@ package singlestoresql_test import ( "testing" - 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" @@ -25,7 +24,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -func TestParseFromYamlSingleStore(t *testing.T) { +func TestParseFromYaml(t *testing.T) { ctx, err := testutils.ContextWithNewLogger() if err != nil { t.Fatalf("unexpected error: %s", err) @@ -38,30 +37,30 @@ func TestParseFromYamlSingleStore(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: singlestore-sql - source: my-singlestore-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - authRequired: - - my-google-auth-service - - other-auth-service - parameters: - - name: country - type: string - description: some description - authServices: - - name: my-google-auth-service - field: user_id - - name: other-auth-service - field: user_id + kind: tools + name: example_tool + type: singlestore-sql + source: my-singlestore-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + authRequired: + - my-google-auth-service + - other-auth-service + parameters: + - name: country + type: string + description: some description + authServices: + - name: my-google-auth-service + field: user_id + - name: other-auth-service + field: user_id `, want: server.ToolConfigs{ "example_tool": singlestoresql.Config{ Name: "example_tool", - Kind: "singlestore-sql", + Type: "singlestore-sql", Source: "my-singlestore-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -74,72 +73,44 @@ func TestParseFromYamlSingleStore(t *testing.T) { }, }, }, - } - for _, tc := range tcs { - t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) - if err != nil { - t.Fatalf("unable to unmarshal: %s", err) - } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { - t.Fatalf("incorrect parse: diff %v", diff) - } - }) - } -} - -func TestParseFromYamlWithTemplateParamsSingleStore(t *testing.T) { - ctx, err := testutils.ContextWithNewLogger() - if err != nil { - t.Fatalf("unexpected error: %s", err) - } - tcs := []struct { - desc string - in string - want server.ToolConfigs - }{ { - desc: "basic example", + desc: "with template params", in: ` - tools: - example_tool: - kind: singlestore-sql - source: my-singlestore-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - authRequired: - - my-google-auth-service - - other-auth-service - parameters: - - name: country - type: string - description: some description - authServices: - - name: my-google-auth-service - field: user_id - - name: other-auth-service - field: user_id - templateParameters: - - name: tableName - type: string - description: The table to select hotels from. - - name: fieldArray - type: array - description: The columns to return for the query. - items: - name: column - type: string - description: A column name that will be returned from the query. + kind: tools + name: example_tool + type: singlestore-sql + source: my-singlestore-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + authRequired: + - my-google-auth-service + - other-auth-service + parameters: + - name: country + type: string + description: some description + authServices: + - name: my-google-auth-service + field: user_id + - name: other-auth-service + field: user_id + templateParameters: + - name: tableName + type: string + description: The table to select hotels from. + - name: fieldArray + type: array + description: The columns to return for the query. + items: + name: column + type: string + description: A column name that will be returned from the query. `, want: server.ToolConfigs{ "example_tool": singlestoresql.Config{ Name: "example_tool", - Kind: "singlestore-sql", + Type: "singlestore-sql", Source: "my-singlestore-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -159,15 +130,11 @@ func TestParseFromYamlWithTemplateParamsSingleStore(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/snowflake/snowflakeexecutesql/snowflakeexecutesql.go b/internal/tools/snowflake/snowflakeexecutesql/snowflakeexecutesql.go index 5c33dca606..fcd2c44d12 100644 --- a/internal/tools/snowflake/snowflakeexecutesql/snowflakeexecutesql.go +++ b/internal/tools/snowflake/snowflakeexecutesql/snowflakeexecutesql.go @@ -27,11 +27,11 @@ import ( "github.com/jmoiron/sqlx" ) -const kind string = "snowflake-execute-sql" +const resourceType string = "snowflake-execute-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -59,8 +59,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -90,7 +90,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -106,7 +106,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para if err != nil { return nil, fmt.Errorf("error getting logger: %s", err) } - logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", kind, sql)) + logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", resourceType, sql)) return source.RunSQL(ctx, sql, nil) } diff --git a/internal/tools/snowflake/snowflakeexecutesql/snowflakeexecutesql_test.go b/internal/tools/snowflake/snowflakeexecutesql/snowflakeexecutesql_test.go index b9cd5da63b..9805012701 100644 --- a/internal/tools/snowflake/snowflakeexecutesql/snowflakeexecutesql_test.go +++ b/internal/tools/snowflake/snowflakeexecutesql/snowflakeexecutesql_test.go @@ -17,7 +17,6 @@ package snowflakeexecutesql_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - my-snowflake-tool: - kind: snowflake-execute-sql - source: my-snowflake-source - description: Execute SQL on Snowflake + kind: tools + name: my-snowflake-tool + type: snowflake-execute-sql + source: my-snowflake-source + description: Execute SQL on Snowflake `, want: server.ToolConfigs{ "my-snowflake-tool": snowflakeexecutesql.Config{ Name: "my-snowflake-tool", - Kind: "snowflake-execute-sql", + Type: "snowflake-execute-sql", Source: "my-snowflake-source", Description: "Execute SQL on Snowflake", AuthRequired: []string{}, @@ -56,15 +55,12 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -84,21 +80,18 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "missing required field", in: ` - tools: - my-snowflake-tool: - kind: snowflake-execute-sql - source: my-snowflake-source + kind: tools + name: my-snowflake-tool + type: snowflake-execute-sql + source: my-snowflake-source `, - err: "unable to parse tool \"my-snowflake-tool\" as kind \"snowflake-execute-sql\": Key: 'Config.Description' Error:Field validation for 'Description' failed on the 'required' tag", + err: "error unmarshaling tools: unable to parse tool \"my-snowflake-tool\" as type \"snowflake-execute-sql\": Key: 'Config.Description' Error:Field validation for 'Description' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/snowflake/snowflakesql/snowflakesql.go b/internal/tools/snowflake/snowflakesql/snowflakesql.go index c12de00d7a..4b74033ed8 100644 --- a/internal/tools/snowflake/snowflakesql/snowflakesql.go +++ b/internal/tools/snowflake/snowflakesql/snowflakesql.go @@ -26,11 +26,11 @@ import ( "github.com/jmoiron/sqlx" ) -const kind string = "snowflake-sql" +const resourceType string = "snowflake-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Statement string `yaml:"statement" validate:"required"` @@ -61,8 +61,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -94,7 +94,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/snowflake/snowflakesql/snowflakesql_test.go b/internal/tools/snowflake/snowflakesql/snowflakesql_test.go index 3432108482..520cae3207 100644 --- a/internal/tools/snowflake/snowflakesql/snowflakesql_test.go +++ b/internal/tools/snowflake/snowflakesql/snowflakesql_test.go @@ -17,7 +17,6 @@ package snowflakesql_test import ( "testing" - 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" @@ -37,17 +36,17 @@ func TestParseFromYaml(t *testing.T) { { desc: "basic example", in: ` - tools: - my-snowflake-tool: - kind: snowflake-sql - source: my-snowflake-source - description: Execute parameterized SQL on Snowflake - statement: SELECT * FROM my_table WHERE id = $1 + kind: tools + name: my-snowflake-tool + type: snowflake-sql + source: my-snowflake-source + description: Execute parameterized SQL on Snowflake + statement: SELECT * FROM my_table WHERE id = $1 `, want: server.ToolConfigs{ "my-snowflake-tool": snowflakesql.Config{ Name: "my-snowflake-tool", - Kind: "snowflake-sql", + Type: "snowflake-sql", Source: "my-snowflake-source", Description: "Execute parameterized SQL on Snowflake", Statement: "SELECT * FROM my_table WHERE id = $1", @@ -60,15 +59,12 @@ func TestParseFromYaml(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -88,22 +84,19 @@ func TestFailParseFromYaml(t *testing.T) { { desc: "missing required field", in: ` - tools: - my-snowflake-tool: - kind: snowflake-sql - source: my-snowflake-source - description: Execute parameterized SQL on Snowflake + kind: tools + name: my-snowflake-tool + type: snowflake-sql + source: my-snowflake-source + description: Execute parameterized SQL on Snowflake `, - err: "unable to parse tool \"my-snowflake-tool\" as kind \"snowflake-sql\": Key: 'Config.Statement' Error:Field validation for 'Statement' failed on the 'required' tag", + err: "error unmarshaling tools: unable to parse tool \"my-snowflake-tool\" as type \"snowflake-sql\": Key: 'Config.Statement' Error:Field validation for 'Statement' failed on the 'required' tag", }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expect parsing to fail") } diff --git a/internal/tools/spanner/spannerexecutesql/spannerexecutesql.go b/internal/tools/spanner/spannerexecutesql/spannerexecutesql.go index d97a34e226..2ae5bbc5d3 100644 --- a/internal/tools/spanner/spannerexecutesql/spannerexecutesql.go +++ b/internal/tools/spanner/spannerexecutesql/spannerexecutesql.go @@ -27,11 +27,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "spanner-execute-sql" +const resourceType string = "spanner-execute-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -51,7 +51,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -61,8 +61,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -92,7 +92,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -108,7 +108,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para if err != nil { return nil, fmt.Errorf("error getting logger: %s", err) } - logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", kind, sql)) + logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", resourceType, sql)) return source.RunSQL(ctx, t.ReadOnly, sql, nil) } diff --git a/internal/tools/spanner/spannerexecutesql/spannerexecutesql_test.go b/internal/tools/spanner/spannerexecutesql/spannerexecutesql_test.go index a406b37880..76e98e8346 100644 --- a/internal/tools/spanner/spannerexecutesql/spannerexecutesql_test.go +++ b/internal/tools/spanner/spannerexecutesql/spannerexecutesql_test.go @@ -17,7 +17,6 @@ package spannerexecutesql_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlExecuteSql(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: spanner-execute-sql - source: my-spanner-instance - description: some description + kind: tools + name: example_tool + type: spanner-execute-sql + source: my-spanner-instance + description: some description `, want: server.ToolConfigs{ "example_tool": spannerexecutesql.Config{ Name: "example_tool", - Kind: "spanner-execute-sql", + Type: "spanner-execute-sql", Source: "my-spanner-instance", Description: "some description", AuthRequired: []string{}, @@ -57,17 +56,17 @@ func TestParseFromYamlExecuteSql(t *testing.T) { { desc: "read only set to true", in: ` - tools: - example_tool: - kind: spanner-execute-sql - source: my-spanner-instance - description: some description - readOnly: true + kind: tools + name: example_tool + type: spanner-execute-sql + source: my-spanner-instance + description: some description + readOnly: true `, want: server.ToolConfigs{ "example_tool": spannerexecutesql.Config{ Name: "example_tool", - Kind: "spanner-execute-sql", + Type: "spanner-execute-sql", Source: "my-spanner-instance", Description: "some description", AuthRequired: []string{}, @@ -78,15 +77,12 @@ func TestParseFromYamlExecuteSql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/spanner/spannerlistgraphs/spannerlistgraphs.go b/internal/tools/spanner/spannerlistgraphs/spannerlistgraphs.go index 0a871862b1..2f993b1a98 100644 --- a/internal/tools/spanner/spannerlistgraphs/spannerlistgraphs.go +++ b/internal/tools/spanner/spannerlistgraphs/spannerlistgraphs.go @@ -27,11 +27,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "spanner-list-graphs" +const resourceType string = "spanner-list-graphs" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -51,7 +51,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -60,8 +60,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -106,7 +106,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/spanner/spannerlistgraphs/spannerlistgraphs_test.go b/internal/tools/spanner/spannerlistgraphs/spannerlistgraphs_test.go index eb4cca9e95..1dbdd8caad 100644 --- a/internal/tools/spanner/spannerlistgraphs/spannerlistgraphs_test.go +++ b/internal/tools/spanner/spannerlistgraphs/spannerlistgraphs_test.go @@ -17,7 +17,6 @@ package spannerlistgraphs_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlListGraphs(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: spanner-list-graphs - source: my-spanner-instance - description: Lists graphs in the database + kind: tools + name: example_tool + type: spanner-list-graphs + source: my-spanner-instance + description: Lists graphs in the database `, want: server.ToolConfigs{ "example_tool": spannerlistgraphs.Config{ Name: "example_tool", - Kind: "spanner-list-graphs", + Type: "spanner-list-graphs", Source: "my-spanner-instance", Description: "Lists graphs in the database", AuthRequired: []string{}, @@ -56,19 +55,19 @@ func TestParseFromYamlListGraphs(t *testing.T) { { desc: "with auth required", in: ` - tools: - example_tool: - kind: spanner-list-graphs - source: my-spanner-instance - description: Lists graphs in the database - authRequired: - - auth1 - - auth2 + kind: tools + name: example_tool + type: spanner-list-graphs + source: my-spanner-instance + description: Lists graphs in the database + authRequired: + - auth1 + - auth2 `, want: server.ToolConfigs{ "example_tool": spannerlistgraphs.Config{ Name: "example_tool", - Kind: "spanner-list-graphs", + Type: "spanner-list-graphs", Source: "my-spanner-instance", Description: "Lists graphs in the database", AuthRequired: []string{"auth1", "auth2"}, @@ -78,15 +77,15 @@ func TestParseFromYamlListGraphs(t *testing.T) { { desc: "minimal config", in: ` - tools: - example_tool: - kind: spanner-list-graphs - source: my-spanner-instance + kind: tools + name: example_tool + type: spanner-list-graphs + source: my-spanner-instance `, want: server.ToolConfigs{ "example_tool": spannerlistgraphs.Config{ Name: "example_tool", - Kind: "spanner-list-graphs", + Type: "spanner-list-graphs", Source: "my-spanner-instance", Description: "", AuthRequired: []string{}, @@ -96,15 +95,12 @@ func TestParseFromYamlListGraphs(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/spanner/spannerlisttables/spannerlisttables.go b/internal/tools/spanner/spannerlisttables/spannerlisttables.go index b4d172589b..998609dbf7 100644 --- a/internal/tools/spanner/spannerlisttables/spannerlisttables.go +++ b/internal/tools/spanner/spannerlisttables/spannerlisttables.go @@ -27,11 +27,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "spanner-list-tables" +const resourceType string = "spanner-list-tables" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -51,7 +51,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description"` AuthRequired []string `yaml:"authRequired"` @@ -60,8 +60,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -118,7 +118,7 @@ func getStatement(dialect string) string { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/spanner/spannerlisttables/spannerlisttables_test.go b/internal/tools/spanner/spannerlisttables/spannerlisttables_test.go index da4a9885c5..0bc6fce5cd 100644 --- a/internal/tools/spanner/spannerlisttables/spannerlisttables_test.go +++ b/internal/tools/spanner/spannerlisttables/spannerlisttables_test.go @@ -17,7 +17,6 @@ package spannerlisttables_test import ( "testing" - 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" @@ -37,16 +36,16 @@ func TestParseFromYamlListTables(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: spanner-list-tables - source: my-spanner-instance - description: Lists tables in the database + kind: tools + name: example_tool + type: spanner-list-tables + source: my-spanner-instance + description: Lists tables in the database `, want: server.ToolConfigs{ "example_tool": spannerlisttables.Config{ Name: "example_tool", - Kind: "spanner-list-tables", + Type: "spanner-list-tables", Source: "my-spanner-instance", Description: "Lists tables in the database", AuthRequired: []string{}, @@ -56,19 +55,19 @@ func TestParseFromYamlListTables(t *testing.T) { { desc: "with auth required", in: ` - tools: - example_tool: - kind: spanner-list-tables - source: my-spanner-instance - description: Lists tables in the database - authRequired: - - auth1 - - auth2 + kind: tools + name: example_tool + type: spanner-list-tables + source: my-spanner-instance + description: Lists tables in the database + authRequired: + - auth1 + - auth2 `, want: server.ToolConfigs{ "example_tool": spannerlisttables.Config{ Name: "example_tool", - Kind: "spanner-list-tables", + Type: "spanner-list-tables", Source: "my-spanner-instance", Description: "Lists tables in the database", AuthRequired: []string{"auth1", "auth2"}, @@ -78,15 +77,15 @@ func TestParseFromYamlListTables(t *testing.T) { { desc: "minimal config", in: ` - tools: - example_tool: - kind: spanner-list-tables - source: my-spanner-instance + kind: tools + name: example_tool + type: spanner-list-tables + source: my-spanner-instance `, want: server.ToolConfigs{ "example_tool": spannerlisttables.Config{ Name: "example_tool", - Kind: "spanner-list-tables", + Type: "spanner-list-tables", Source: "my-spanner-instance", Description: "", AuthRequired: []string{}, @@ -96,15 +95,12 @@ func TestParseFromYamlListTables(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/spanner/spannersql/spanner_test.go b/internal/tools/spanner/spannersql/spanner_test.go index 5f86bcae6f..227c21b68a 100644 --- a/internal/tools/spanner/spannersql/spanner_test.go +++ b/internal/tools/spanner/spannersql/spanner_test.go @@ -17,7 +17,6 @@ package spannersql_test import ( "testing" - 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" @@ -38,22 +37,22 @@ func TestParseFromYamlSpanner(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: spanner-sql - source: my-pg-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - parameters: - - name: country - type: string - description: some description + kind: tools + name: example_tool + type: spanner-sql + source: my-pg-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + parameters: + - name: country + type: string + description: some description `, want: server.ToolConfigs{ "example_tool": spannersql.Config{ Name: "example_tool", - Kind: "spanner-sql", + Type: "spanner-sql", Source: "my-pg-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -67,23 +66,23 @@ func TestParseFromYamlSpanner(t *testing.T) { { desc: "read only set to true", in: ` - tools: - example_tool: - kind: spanner-sql - source: my-pg-instance - description: some description - readOnly: true - statement: | - SELECT * FROM SQL_STATEMENT; - parameters: - - name: country - type: string - description: some description + kind: tools + name: example_tool + type: spanner-sql + source: my-pg-instance + description: some description + readOnly: true + statement: | + SELECT * FROM SQL_STATEMENT; + parameters: + - name: country + type: string + description: some description `, want: server.ToolConfigs{ "example_tool": spannersql.Config{ Name: "example_tool", - Kind: "spanner-sql", + Type: "spanner-sql", Source: "my-pg-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -98,15 +97,12 @@ func TestParseFromYamlSpanner(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -127,33 +123,33 @@ func TestParseFromYamlWithTemplateParamsSpanner(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: spanner-sql - source: my-pg-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - parameters: - - name: country - type: string - description: some description - templateParameters: - - name: tableName - type: string - description: The table to select hotels from. - - name: fieldArray - type: array - description: The columns to return for the query. - items: - name: column - type: string - description: A column name that will be returned from the query. + kind: tools + name: example_tool + type: spanner-sql + source: my-pg-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + parameters: + - name: country + type: string + description: some description + templateParameters: + - name: tableName + type: string + description: The table to select hotels from. + - name: fieldArray + type: array + description: The columns to return for the query. + items: + name: column + type: string + description: A column name that will be returned from the query. `, want: server.ToolConfigs{ "example_tool": spannersql.Config{ Name: "example_tool", - Kind: "spanner-sql", + Type: "spanner-sql", Source: "my-pg-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -171,23 +167,23 @@ func TestParseFromYamlWithTemplateParamsSpanner(t *testing.T) { { desc: "read only set to true", in: ` - tools: - example_tool: - kind: spanner-sql - source: my-pg-instance - description: some description - readOnly: true - statement: | - SELECT * FROM SQL_STATEMENT; - parameters: - - name: country - type: string - description: some description + kind: tools + name: example_tool + type: spanner-sql + source: my-pg-instance + description: some description + readOnly: true + statement: | + SELECT * FROM SQL_STATEMENT; + parameters: + - name: country + type: string + description: some description `, want: server.ToolConfigs{ "example_tool": spannersql.Config{ Name: "example_tool", - Kind: "spanner-sql", + Type: "spanner-sql", Source: "my-pg-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -202,15 +198,12 @@ func TestParseFromYamlWithTemplateParamsSpanner(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/spanner/spannersql/spannersql.go b/internal/tools/spanner/spannersql/spannersql.go index 42fd081289..75eb79a3a7 100644 --- a/internal/tools/spanner/spannersql/spannersql.go +++ b/internal/tools/spanner/spannersql/spannersql.go @@ -27,11 +27,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "spanner-sql" +const resourceType string = "spanner-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -51,7 +51,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Statement string `yaml:"statement" validate:"required"` @@ -64,8 +64,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -108,7 +108,7 @@ func getMapParams(params parameters.ParamValues, dialect string) (map[string]int } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/sqlite/sqliteexecutesql/sqliteexecutesql.go b/internal/tools/sqlite/sqliteexecutesql/sqliteexecutesql.go index 6d4d311ab7..49f338d4d5 100644 --- a/internal/tools/sqlite/sqliteexecutesql/sqliteexecutesql.go +++ b/internal/tools/sqlite/sqliteexecutesql/sqliteexecutesql.go @@ -27,11 +27,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "sqlite-execute-sql" +const resourceType string = "sqlite-execute-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -59,8 +59,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -89,7 +89,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -107,7 +107,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para if err != nil { return nil, fmt.Errorf("error getting logger: %s", err) } - logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", kind, sql)) + logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", resourceType, sql)) return source.RunSQL(ctx, sql, nil) } diff --git a/internal/tools/sqlite/sqliteexecutesql/sqliteexecutesql_test.go b/internal/tools/sqlite/sqliteexecutesql/sqliteexecutesql_test.go index 63079a883e..f45402c86d 100644 --- a/internal/tools/sqlite/sqliteexecutesql/sqliteexecutesql_test.go +++ b/internal/tools/sqlite/sqliteexecutesql/sqliteexecutesql_test.go @@ -17,7 +17,6 @@ package sqliteexecutesql_test import ( "testing" - 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" @@ -38,19 +37,19 @@ func TestParseFromYamlExecuteSql(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: sqlite-execute-sql - source: my-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: sqlite-execute-sql + source: my-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": sqliteexecutesql.Config{ Name: "example_tool", - Kind: "sqlite-execute-sql", + Type: "sqlite-execute-sql", Source: "my-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -60,15 +59,12 @@ func TestParseFromYamlExecuteSql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/sqlite/sqlitesql/sqlitesql.go b/internal/tools/sqlite/sqlitesql/sqlitesql.go index a89327d5d1..c8c2da6eb4 100644 --- a/internal/tools/sqlite/sqlitesql/sqlitesql.go +++ b/internal/tools/sqlite/sqlitesql/sqlitesql.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "sqlite-sql" +const resourceType string = "sqlite-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Statement string `yaml:"statement" validate:"required"` @@ -61,8 +61,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -94,7 +94,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/sqlite/sqlitesql/sqlitesql_test.go b/internal/tools/sqlite/sqlitesql/sqlitesql_test.go index eea6fddf4f..6aa2968534 100644 --- a/internal/tools/sqlite/sqlitesql/sqlitesql_test.go +++ b/internal/tools/sqlite/sqlitesql/sqlitesql_test.go @@ -17,7 +17,6 @@ package sqlitesql_test import ( "testing" - 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" @@ -39,30 +38,30 @@ func TestParseFromYamlSQLite(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: sqlite-sql - source: my-sqlite-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - authRequired: - - my-google-auth-service - - other-auth-service - parameters: - - name: country - type: string - description: some description - authServices: - - name: my-google-auth-service - field: user_id - - name: other-auth-service - field: user_id + kind: tools + name: example_tool + type: sqlite-sql + source: my-sqlite-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + authRequired: + - my-google-auth-service + - other-auth-service + parameters: + - name: country + type: string + description: some description + authServices: + - name: my-google-auth-service + field: user_id + - name: other-auth-service + field: user_id `, want: server.ToolConfigs{ "example_tool": sqlitesql.Config{ Name: "example_tool", - Kind: "sqlite-sql", + Type: "sqlite-sql", Source: "my-sqlite-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -78,15 +77,12 @@ func TestParseFromYamlSQLite(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -107,41 +103,41 @@ func TestParseFromYamlWithTemplateSqlite(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: sqlite-sql - source: my-sqlite-db - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - authRequired: - - my-google-auth-service - - other-auth-service - parameters: - - name: country - type: string - description: some description - authServices: - - name: my-google-auth-service - field: user_id - - name: other-auth-service - field: user_id - templateParameters: - - name: tableName - type: string - description: The table to select hotels from. - - name: fieldArray - type: array - description: The columns to return for the query. - items: - name: column - type: string - description: A column name that will be returned from the query. + kind: tools + name: example_tool + type: sqlite-sql + source: my-sqlite-db + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + authRequired: + - my-google-auth-service + - other-auth-service + parameters: + - name: country + type: string + description: some description + authServices: + - name: my-google-auth-service + field: user_id + - name: other-auth-service + field: user_id + templateParameters: + - name: tableName + type: string + description: The table to select hotels from. + - name: fieldArray + type: array + description: The columns to return for the query. + items: + name: column + type: string + description: A column name that will be returned from the query. `, want: server.ToolConfigs{ "example_tool": sqlitesql.Config{ Name: "example_tool", - Kind: "sqlite-sql", + Type: "sqlite-sql", Source: "my-sqlite-db", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -161,15 +157,12 @@ func TestParseFromYamlWithTemplateSqlite(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/tidb/tidbexecutesql/tidbexecutesql.go b/internal/tools/tidb/tidbexecutesql/tidbexecutesql.go index e2ec211c9c..a2fae8251e 100644 --- a/internal/tools/tidb/tidbexecutesql/tidbexecutesql.go +++ b/internal/tools/tidb/tidbexecutesql/tidbexecutesql.go @@ -27,11 +27,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "tidb-execute-sql" +const resourceType string = "tidb-execute-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -50,7 +50,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -59,8 +59,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -90,7 +90,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } @@ -106,7 +106,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para if err != nil { return nil, fmt.Errorf("error getting logger: %s", err) } - logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", kind, sql)) + logger.DebugContext(ctx, fmt.Sprintf("executing `%s` tool query: %s", resourceType, sql)) return source.RunSQL(ctx, sql, nil) } diff --git a/internal/tools/tidb/tidbexecutesql/tidbexecutesql_test.go b/internal/tools/tidb/tidbexecutesql/tidbexecutesql_test.go index 432743dbd9..a8742d373b 100644 --- a/internal/tools/tidb/tidbexecutesql/tidbexecutesql_test.go +++ b/internal/tools/tidb/tidbexecutesql/tidbexecutesql_test.go @@ -17,7 +17,6 @@ package tidbexecutesql_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlExecuteSql(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: tidb-execute-sql - source: my-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: tidb-execute-sql + source: my-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": tidbexecutesql.Config{ Name: "example_tool", - Kind: "tidb-execute-sql", + Type: "tidb-execute-sql", Source: "my-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,15 +58,12 @@ func TestParseFromYamlExecuteSql(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/tidb/tidbsql/tidbsql.go b/internal/tools/tidb/tidbsql/tidbsql.go index bd50acdc7f..8c974c629d 100644 --- a/internal/tools/tidb/tidbsql/tidbsql.go +++ b/internal/tools/tidb/tidbsql/tidbsql.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "tidb-sql" +const resourceType string = "tidb-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Statement string `yaml:"statement" validate:"required"` @@ -61,8 +61,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -94,7 +94,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/tidb/tidbsql/tidbsql_test.go b/internal/tools/tidb/tidbsql/tidbsql_test.go index 4a5c425d03..65ae5a83aa 100644 --- a/internal/tools/tidb/tidbsql/tidbsql_test.go +++ b/internal/tools/tidb/tidbsql/tidbsql_test.go @@ -17,7 +17,6 @@ package tidbsql_test import ( "testing" - 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" @@ -38,30 +37,30 @@ func TestParseFromYamlTiDB(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: tidb-sql - source: my-tidb-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - authRequired: - - my-google-auth-service - - other-auth-service - parameters: - - name: country - type: string - description: some description - authServices: - - name: my-google-auth-service - field: user_id - - name: other-auth-service - field: user_id + kind: tools + name: example_tool + type: tidb-sql + source: my-tidb-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + authRequired: + - my-google-auth-service + - other-auth-service + parameters: + - name: country + type: string + description: some description + authServices: + - name: my-google-auth-service + field: user_id + - name: other-auth-service + field: user_id `, want: server.ToolConfigs{ "example_tool": tidbsql.Config{ Name: "example_tool", - Kind: "tidb-sql", + Type: "tidb-sql", Source: "my-tidb-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -77,15 +76,12 @@ func TestParseFromYamlTiDB(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -105,41 +101,41 @@ func TestParseFromYamlWithTemplateParamsTiDB(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: tidb-sql - source: my-tidb-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - authRequired: - - my-google-auth-service - - other-auth-service - parameters: - - name: country - type: string - description: some description - authServices: - - name: my-google-auth-service - field: user_id - - name: other-auth-service - field: user_id - templateParameters: - - name: tableName - type: string - description: The table to select hotels from. - - name: fieldArray - type: array - description: The columns to return for the query. - items: - name: column - type: string - description: A column name that will be returned from the query. + kind: tools + name: example_tool + type: tidb-sql + source: my-tidb-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + authRequired: + - my-google-auth-service + - other-auth-service + parameters: + - name: country + type: string + description: some description + authServices: + - name: my-google-auth-service + field: user_id + - name: other-auth-service + field: user_id + templateParameters: + - name: tableName + type: string + description: The table to select hotels from. + - name: fieldArray + type: array + description: The columns to return for the query. + items: + name: column + type: string + description: A column name that will be returned from the query. `, want: server.ToolConfigs{ "example_tool": tidbsql.Config{ Name: "example_tool", - Kind: "tidb-sql", + Type: "tidb-sql", Source: "my-tidb-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -159,15 +155,12 @@ func TestParseFromYamlWithTemplateParamsTiDB(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/tools.go b/internal/tools/tools.go index e34d4e26e7..32caac899a 100644 --- a/internal/tools/tools.go +++ b/internal/tools/tools.go @@ -36,34 +36,34 @@ var toolRegistry = make(map[string]ToolConfigFactory) // Register allows individual tool packages to register their configuration // factory function. This is typically called from an init() function in the -// tool's package. It associates a 'kind' string with a function that can +// tool's package. It associates a 'type' string with a function that can // produce the specific ToolConfig type. It returns true if the registration was -// successful, and false if a tool with the same kind was already registered. -func Register(kind string, factory ToolConfigFactory) bool { - if _, exists := toolRegistry[kind]; exists { - // Tool with this kind already exists, do not overwrite. +// successful, and false if a tool with the same type was already registered. +func Register(resourceType string, factory ToolConfigFactory) bool { + if _, exists := toolRegistry[resourceType]; exists { + // Tool with this type already exists, do not overwrite. return false } - toolRegistry[kind] = factory + toolRegistry[resourceType] = factory return true } -// DecodeConfig looks up the registered factory for the given kind and uses it +// DecodeConfig looks up the registered factory for the given type and uses it // to decode the tool configuration. -func DecodeConfig(ctx context.Context, kind string, name string, decoder *yaml.Decoder) (ToolConfig, error) { - factory, found := toolRegistry[kind] +func DecodeConfig(ctx context.Context, resourceType string, name string, decoder *yaml.Decoder) (ToolConfig, error) { + factory, found := toolRegistry[resourceType] if !found { - return nil, fmt.Errorf("unknown tool kind: %q", kind) + return nil, fmt.Errorf("unknown tool type: %q", resourceType) } toolConfig, err := factory(ctx, name, decoder) if err != nil { - return nil, fmt.Errorf("unable to parse tool %q as kind %q: %w", name, kind, err) + return nil, fmt.Errorf("unable to parse tool %q as type %q: %w", name, resourceType, err) } return toolConfig, nil } type ToolConfig interface { - ToolConfigKind() string + ToolConfigType() string Initialize(map[string]sources.Source) (Tool, error) } @@ -161,7 +161,7 @@ func IsAuthorized(authRequiredSources []string, verifiedAuthServices []string) b return false } -func GetCompatibleSource[T any](resourceMgr SourceProvider, sourceName, toolName, toolKind string) (T, error) { +func GetCompatibleSource[T any](resourceMgr SourceProvider, sourceName, toolName, toolType string) (T, error) { var zero T s, ok := resourceMgr.GetSource(sourceName) if !ok { @@ -169,7 +169,7 @@ func GetCompatibleSource[T any](resourceMgr SourceProvider, sourceName, toolName } source, ok := s.(T) if !ok { - return zero, fmt.Errorf("invalid source for %q tool: source %q is not a compatible type", toolKind, sourceName) + return zero, fmt.Errorf("invalid source for %q tool: source %q is not a compatible type", toolType, sourceName) } return source, nil } diff --git a/internal/tools/trino/trinoexecutesql/trinoexecutesql.go b/internal/tools/trino/trinoexecutesql/trinoexecutesql.go index 2c72c20cf2..a263ef2a11 100644 --- a/internal/tools/trino/trinoexecutesql/trinoexecutesql.go +++ b/internal/tools/trino/trinoexecutesql/trinoexecutesql.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "trino-execute-sql" +const resourceType string = "trino-execute-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -58,8 +58,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -89,7 +89,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/trino/trinoexecutesql/trinoexecutesql_test.go b/internal/tools/trino/trinoexecutesql/trinoexecutesql_test.go index 0af7ce1762..372654d0ee 100644 --- a/internal/tools/trino/trinoexecutesql/trinoexecutesql_test.go +++ b/internal/tools/trino/trinoexecutesql/trinoexecutesql_test.go @@ -17,7 +17,6 @@ package trinoexecutesql_test import ( "testing" - 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" @@ -37,19 +36,19 @@ func TestParseFromYamlTrinoExecuteSQL(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: trino-execute-sql - source: my-trino-instance - description: some description - authRequired: - - my-google-auth-service - - other-auth-service + kind: tools + name: example_tool + type: trino-execute-sql + source: my-trino-instance + description: some description + authRequired: + - my-google-auth-service + - other-auth-service `, want: server.ToolConfigs{ "example_tool": trinoexecutesql.Config{ Name: "example_tool", - Kind: "trino-execute-sql", + Type: "trino-execute-sql", Source: "my-trino-instance", Description: "some description", AuthRequired: []string{"my-google-auth-service", "other-auth-service"}, @@ -59,15 +58,11 @@ func TestParseFromYamlTrinoExecuteSQL(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/trino/trinosql/trinosql.go b/internal/tools/trino/trinosql/trinosql.go index 847aa4ef10..798cb8b13f 100644 --- a/internal/tools/trino/trinosql/trinosql.go +++ b/internal/tools/trino/trinosql/trinosql.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "trino-sql" +const resourceType string = "trino-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Statement string `yaml:"statement" validate:"required"` @@ -61,8 +61,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -94,7 +94,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/trino/trinosql/trinosql_test.go b/internal/tools/trino/trinosql/trinosql_test.go index 2974e0dd04..50908a9350 100644 --- a/internal/tools/trino/trinosql/trinosql_test.go +++ b/internal/tools/trino/trinosql/trinosql_test.go @@ -17,7 +17,6 @@ package trinosql_test import ( "testing" - 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" @@ -38,30 +37,30 @@ func TestParseFromYamlTrino(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: trino-sql - source: my-trino-instance - description: some description - statement: | - SELECT * FROM catalog.schema.table WHERE id = ?; - authRequired: - - my-google-auth-service - - other-auth-service - parameters: - - name: id - type: string - description: ID to filter by - authServices: - - name: my-google-auth-service - field: user_id - - name: other-auth-service - field: user_id + kind: tools + name: example_tool + type: trino-sql + source: my-trino-instance + description: some description + statement: | + SELECT * FROM catalog.schema.table WHERE id = ?; + authRequired: + - my-google-auth-service + - other-auth-service + parameters: + - name: id + type: string + description: ID to filter by + authServices: + - name: my-google-auth-service + field: user_id + - name: other-auth-service + field: user_id `, want: server.ToolConfigs{ "example_tool": trinosql.Config{ Name: "example_tool", - Kind: "trino-sql", + Type: "trino-sql", Source: "my-trino-instance", Description: "some description", Statement: "SELECT * FROM catalog.schema.table WHERE id = ?;\n", @@ -77,15 +76,11 @@ func TestParseFromYamlTrino(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -105,47 +100,47 @@ func TestParseFromYamlWithTemplateParamsTrino(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: trino-sql - source: my-trino-instance - description: some description - statement: | - SELECT * FROM {{ .catalog }}.{{ .schema }}.{{ .tableName }} WHERE country = ?; - authRequired: - - my-google-auth-service - - other-auth-service - parameters: - - name: country - type: string - description: some description - authServices: - - name: my-google-auth-service - field: user_id - - name: other-auth-service - field: user_id - templateParameters: - - name: catalog - type: string - description: The catalog to query from. - - name: schema - type: string - description: The schema to query from. - - name: tableName - type: string - description: The table to select data from. - - name: fieldArray - type: array - description: The columns to return for the query. - items: - name: column - type: string - description: A column name that will be returned from the query. + kind: tools + name: example_tool + type: trino-sql + source: my-trino-instance + description: some description + statement: | + SELECT * FROM {{ .catalog }}.{{ .schema }}.{{ .tableName }} WHERE country = ?; + authRequired: + - my-google-auth-service + - other-auth-service + parameters: + - name: country + type: string + description: some description + authServices: + - name: my-google-auth-service + field: user_id + - name: other-auth-service + field: user_id + templateParameters: + - name: catalog + type: string + description: The catalog to query from. + - name: schema + type: string + description: The schema to query from. + - name: tableName + type: string + description: The table to select data from. + - name: fieldArray + type: array + description: The columns to return for the query. + items: + name: column + type: string + description: A column name that will be returned from the query. `, want: server.ToolConfigs{ "example_tool": trinosql.Config{ Name: "example_tool", - Kind: "trino-sql", + Type: "trino-sql", Source: "my-trino-instance", Description: "some description", Statement: "SELECT * FROM {{ .catalog }}.{{ .schema }}.{{ .tableName }} WHERE country = ?;\n", @@ -167,15 +162,11 @@ func TestParseFromYamlWithTemplateParamsTrino(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/utility/wait/wait.go b/internal/tools/utility/wait/wait.go index 157e59f4be..77024098b9 100644 --- a/internal/tools/utility/wait/wait.go +++ b/internal/tools/utility/wait/wait.go @@ -26,11 +26,11 @@ import ( "github.com/googleapis/genai-toolbox/internal/util/parameters" ) -const kind string = "wait" +const resourceType string = "wait" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -44,7 +44,7 @@ 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"` + Type string `yaml:"type" validate:"required"` Description string `yaml:"description" validate:"required"` Timeout string `yaml:"timeout" validate:"required"` AuthRequired []string `yaml:"authRequired"` @@ -52,8 +52,8 @@ type Config struct { var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(_ map[string]sources.Source) (tools.Tool, error) { diff --git a/internal/tools/utility/wait/wait_test.go b/internal/tools/utility/wait/wait_test.go index fcd060ac6b..fb3db875cd 100644 --- a/internal/tools/utility/wait/wait_test.go +++ b/internal/tools/utility/wait/wait_test.go @@ -17,7 +17,6 @@ package wait_test import ( "testing" - 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" @@ -38,18 +37,18 @@ func TestParseFromYamlWait(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: wait - description: some description - timeout: 10s - authRequired: - - my-google-auth-service + kind: tools + name: example_tool + type: wait + description: some description + timeout: 10s + authRequired: + - my-google-auth-service `, want: server.ToolConfigs{ "example_tool": wait.Config{ Name: "example_tool", - Kind: "wait", + Type: "wait", Description: "some description", Timeout: "10s", AuthRequired: []string{"my-google-auth-service"}, @@ -59,15 +58,11 @@ func TestParseFromYamlWait(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/valkey/valkey.go b/internal/tools/valkey/valkey.go index b33c84771f..14b54d15dd 100644 --- a/internal/tools/valkey/valkey.go +++ b/internal/tools/valkey/valkey.go @@ -25,11 +25,11 @@ import ( "github.com/valkey-io/valkey-go" ) -const kind string = "valkey" +const resourceType string = "valkey" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -48,7 +48,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Commands [][]string `yaml:"commands" validate:"required"` @@ -59,8 +59,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -85,7 +85,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/valkey/valkey_test.go b/internal/tools/valkey/valkey_test.go index 8b99471806..2bafe4c3d1 100644 --- a/internal/tools/valkey/valkey_test.go +++ b/internal/tools/valkey/valkey_test.go @@ -17,7 +17,6 @@ package valkey_test import ( "testing" - 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" @@ -38,23 +37,23 @@ func TestParseFromYamlvalkey(t *testing.T) { { desc: "basic example", in: ` - tools: - valkey_tool: - kind: valkey - source: my-valkey-instance - description: some description - commands: - - [SET, greeting, "hello, {{.name}}"] - - [GET, id] - parameters: - - name: name - type: string - description: user name + kind: tools + name: valkey_tool + type: valkey + source: my-valkey-instance + description: some description + commands: + - [SET, greeting, "hello, {{.name}}"] + - [GET, id] + parameters: + - name: name + type: string + description: user name `, want: server.ToolConfigs{ "valkey_tool": valkey.Config{ Name: "valkey_tool", - Kind: "valkey", + Type: "valkey", Source: "my-valkey-instance", Description: "some description", AuthRequired: []string{}, @@ -68,15 +67,11 @@ func TestParseFromYamlvalkey(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/internal/tools/yugabytedbsql/yugabytedbsql.go b/internal/tools/yugabytedbsql/yugabytedbsql.go index 2a1ba58b26..48f9248f15 100644 --- a/internal/tools/yugabytedbsql/yugabytedbsql.go +++ b/internal/tools/yugabytedbsql/yugabytedbsql.go @@ -26,11 +26,11 @@ import ( "github.com/yugabyte/pgx/v5/pgxpool" ) -const kind string = "yugabytedb-sql" +const resourceType string = "yugabytedb-sql" func init() { - if !tools.Register(kind, newConfig) { - panic(fmt.Sprintf("tool kind %q already registered", kind)) + if !tools.Register(resourceType, newConfig) { + panic(fmt.Sprintf("tool type %q already registered", resourceType)) } } @@ -49,7 +49,7 @@ type compatibleSource interface { type Config struct { Name string `yaml:"name" validate:"required"` - Kind string `yaml:"kind" validate:"required"` + Type string `yaml:"type" validate:"required"` Source string `yaml:"source" validate:"required"` Description string `yaml:"description" validate:"required"` Statement string `yaml:"statement" validate:"required"` @@ -61,8 +61,8 @@ type Config struct { // validate interface var _ tools.ToolConfig = Config{} -func (cfg Config) ToolConfigKind() string { - return kind +func (cfg Config) ToolConfigType() string { + return resourceType } func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) { @@ -94,7 +94,7 @@ type Tool struct { } func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { - source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Kind) + source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { return nil, err } diff --git a/internal/tools/yugabytedbsql/yugabytedbsql_test.go b/internal/tools/yugabytedbsql/yugabytedbsql_test.go index e0a9cd1d04..24ff000153 100644 --- a/internal/tools/yugabytedbsql/yugabytedbsql_test.go +++ b/internal/tools/yugabytedbsql/yugabytedbsql_test.go @@ -17,7 +17,6 @@ package yugabytedbsql_test import ( "testing" - 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" @@ -38,30 +37,30 @@ func TestParseFromYamlYugabyteDBSQL(t *testing.T) { { desc: "basic valid config", in: ` - tools: - hotel_search: - kind: yugabytedb-sql - source: yb-source - description: search hotels by city - statement: | - SELECT * FROM hotels WHERE city = $1; - authRequired: - - auth-service-a - - auth-service-b - parameters: - - name: city - type: string - description: city name - authServices: - - name: auth-service-a - field: user_id - - name: auth-service-b - field: user_id + kind: tools + name: hotel_search + type: yugabytedb-sql + source: yb-source + description: search hotels by city + statement: | + SELECT * FROM hotels WHERE city = $1; + authRequired: + - auth-service-a + - auth-service-b + parameters: + - name: city + type: string + description: city name + authServices: + - name: auth-service-a + field: user_id + - name: auth-service-b + field: user_id `, want: server.ToolConfigs{ "hotel_search": yugabytedbsql.Config{ Name: "hotel_search", - Kind: "yugabytedb-sql", + Type: "yugabytedb-sql", Source: "yb-source", Description: "search hotels by city", Statement: "SELECT * FROM hotels WHERE city = $1;\n", @@ -81,14 +80,11 @@ func TestParseFromYamlYugabyteDBSQL(t *testing.T) { for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) @@ -107,32 +103,29 @@ func TestFailParseFromYamlYugabyteDBSQL(t *testing.T) { { desc: "missing required field (statement)", in: ` - tools: - tool1: - kind: yugabytedb-sql - source: yb-source - description: incomplete config + kind: tools + name: tool1 + type: yugabytedb-sql + source: yb-source + description: incomplete config `, }, { desc: "unknown field (foo)", in: ` - tools: - tool2: - kind: yugabytedb-sql - source: yb-source - description: test - statement: SELECT 1; - foo: bar + kind: tools + name: tool2 + type: yugabytedb-sql + source: yb-source + description: test + statement: SELECT 1; + foo: bar `, }, } for _, tc := range cases { t.Run(tc.desc, func(t *testing.T) { - cfg := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &cfg) + _, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err == nil { t.Fatalf("expected error but got none") } @@ -153,33 +146,33 @@ func TestParseFromYamlWithTemplateParamsYugabyteDB(t *testing.T) { { desc: "basic example", in: ` - tools: - example_tool: - kind: yugabytedb-sql - source: my-yb-instance - description: some description - statement: | - SELECT * FROM SQL_STATEMENT; - parameters: - - name: name - type: string - description: some description - templateParameters: - - name: tableName - type: string - description: The table to select hotels from. - - name: fieldArray - type: array - description: The columns to return for the query. - items: - name: column - type: string - description: A column name that will be returned from the query. + kind: tools + name: example_tool + type: yugabytedb-sql + source: my-yb-instance + description: some description + statement: | + SELECT * FROM SQL_STATEMENT; + parameters: + - name: name + type: string + description: some description + templateParameters: + - name: tableName + type: string + description: The table to select hotels from. + - name: fieldArray + type: array + description: The columns to return for the query. + items: + name: column + type: string + description: A column name that will be returned from the query. `, want: server.ToolConfigs{ "example_tool": yugabytedbsql.Config{ Name: "example_tool", - Kind: "yugabytedb-sql", + Type: "yugabytedb-sql", Source: "my-yb-instance", Description: "some description", Statement: "SELECT * FROM SQL_STATEMENT;\n", @@ -197,15 +190,11 @@ func TestParseFromYamlWithTemplateParamsYugabyteDB(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Tools server.ToolConfigs `yaml:"tools"` - }{} - // Parse contents - err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got) + _, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if diff := cmp.Diff(tc.want, got.Tools); diff != "" { + if diff := cmp.Diff(tc.want, got); diff != "" { t.Fatalf("incorrect parse: diff %v", diff) } }) diff --git a/tests/alloydb/alloydb_integration_test.go b/tests/alloydb/alloydb_integration_test.go index 0c2c3bb2e2..52ad7731f3 100644 --- a/tests/alloydb/alloydb_integration_test.go +++ b/tests/alloydb/alloydb_integration_test.go @@ -74,71 +74,71 @@ func getAlloyDBToolsConfig() map[string]any { return map[string]any{ "sources": map[string]any{ "alloydb-admin-source": map[string]any{ - "kind": "alloydb-admin", + "type": "alloydb-admin", }, }, "tools": map[string]any{ // Tool for RunAlloyDBToolGetTest "my-simple-tool": map[string]any{ - "kind": "alloydb-list-clusters", + "type": "alloydb-list-clusters", "source": "alloydb-admin-source", "description": "Simple tool to test end to end functionality.", }, // Tool for MCP test "my-param-tool": map[string]any{ - "kind": "alloydb-list-clusters", + "type": "alloydb-list-clusters", "source": "alloydb-admin-source", "description": "Tool to list clusters", }, // Tool for MCP test that fails "my-fail-tool": map[string]any{ - "kind": "alloydb-list-clusters", + "type": "alloydb-list-clusters", "source": "alloydb-admin-source", "description": "Tool that will fail", }, // AlloyDB specific tools "alloydb-list-clusters": map[string]any{ - "kind": "alloydb-list-clusters", + "type": "alloydb-list-clusters", "source": "alloydb-admin-source", "description": "Lists all AlloyDB clusters in a given project and location.", }, "alloydb-list-users": map[string]any{ - "kind": "alloydb-list-users", + "type": "alloydb-list-users", "source": "alloydb-admin-source", "description": "Lists all AlloyDB users within a specific cluster.", }, "alloydb-list-instances": map[string]any{ - "kind": "alloydb-list-instances", + "type": "alloydb-list-instances", "source": "alloydb-admin-source", "description": "Lists all AlloyDB instances within a specific cluster.", }, "alloydb-get-cluster": map[string]any{ - "kind": "alloydb-get-cluster", + "type": "alloydb-get-cluster", "source": "alloydb-admin-source", "description": "Retrieves details of a specific AlloyDB cluster.", }, "alloydb-get-instance": map[string]any{ - "kind": "alloydb-get-instance", + "type": "alloydb-get-instance", "source": "alloydb-admin-source", "description": "Retrieves details of a specific AlloyDB instance.", }, "alloydb-get-user": map[string]any{ - "kind": "alloydb-get-user", + "type": "alloydb-get-user", "source": "alloydb-admin-source", "description": "Retrieves details of a specific AlloyDB user.", }, "alloydb-create-cluster": map[string]any{ - "kind": "alloydb-create-cluster", + "type": "alloydb-create-cluster", "description": "create cluster", "source": "alloydb-admin-source", }, "alloydb-create-instance": map[string]any{ - "kind": "alloydb-create-instance", + "type": "alloydb-create-instance", "description": "create instance", "source": "alloydb-admin-source", }, "alloydb-create-user": map[string]any{ - "kind": "alloydb-create-user", + "type": "alloydb-create-user", "description": "create user", "source": "alloydb-admin-source", }, diff --git a/tests/alloydb/alloydb_wait_for_operation_test.go b/tests/alloydb/alloydb_wait_for_operation_test.go index 1f027f5568..38dece22d0 100644 --- a/tests/alloydb/alloydb_wait_for_operation_test.go +++ b/tests/alloydb/alloydb_wait_for_operation_test.go @@ -37,7 +37,7 @@ import ( ) var ( - waitToolKind = "alloydb-wait-for-operation" + waitToolType = "alloydb-wait-for-operation" ) type waitForOperationTransport struct { @@ -240,17 +240,17 @@ func getWaitToolsConfig() map[string]any { return map[string]any{ "sources": map[string]any{ "my-alloydb-source": map[string]any{ - "kind": "alloydb-admin", + "type": "alloydb-admin", }, }, "tools": map[string]any{ "wait-for-op1": map[string]any{ - "kind": waitToolKind, + "type": waitToolType, "source": "my-alloydb-source", "description": "wait for op1", }, "wait-for-op2": map[string]any{ - "kind": waitToolKind, + "type": waitToolType, "source": "my-alloydb-source", "description": "wait for op2", }, diff --git a/tests/alloydbainl/alloydb_ai_nl_integration_test.go b/tests/alloydbainl/alloydb_ai_nl_integration_test.go index 4c8754fdf4..1756eeb3f0 100644 --- a/tests/alloydbainl/alloydb_ai_nl_integration_test.go +++ b/tests/alloydbainl/alloydb_ai_nl_integration_test.go @@ -33,8 +33,8 @@ import ( ) var ( - AlloyDBAINLSourceKind = "alloydb-postgres" - AlloyDBAINLToolKind = "alloydb-ai-nl" + AlloyDBAINLSourceType = "alloydb-postgres" + AlloyDBAINLToolType = "alloydb-ai-nl" AlloyDBAINLProject = os.Getenv("ALLOYDB_AI_NL_PROJECT") AlloyDBAINLRegion = os.Getenv("ALLOYDB_AI_NL_REGION") AlloyDBAINLCluster = os.Getenv("ALLOYDB_AI_NL_CLUSTER") @@ -62,7 +62,7 @@ func getAlloyDBAINLVars(t *testing.T) map[string]any { t.Fatal("'ALLOYDB_AI_NL_PASS' not set") } return map[string]any{ - "kind": AlloyDBAINLSourceKind, + "type": AlloyDBAINLSourceType, "project": AlloyDBAINLProject, "cluster": AlloyDBAINLCluster, "instance": AlloyDBAINLInstance, @@ -285,19 +285,19 @@ func getAINLToolsConfig(sourceConfig map[string]any) map[string]any { }, "authServices": map[string]any{ "my-google-auth": map[string]any{ - "kind": "google", + "type": "google", "clientId": tests.ClientId, }, }, "tools": map[string]any{ "my-simple-tool": map[string]any{ - "kind": AlloyDBAINLToolKind, + "type": AlloyDBAINLToolType, "source": "my-instance", "description": "Simple tool to test end to end functionality.", "nlConfig": "my_nl_config", }, "my-auth-tool": map[string]any{ - "kind": AlloyDBAINLToolKind, + "type": AlloyDBAINLToolType, "source": "my-instance", "description": "Tool to test authenticated parameters.", "nlConfig": "my_nl_config", @@ -316,7 +316,7 @@ func getAINLToolsConfig(sourceConfig map[string]any) map[string]any { }, }, "my-auth-required-tool": map[string]any{ - "kind": AlloyDBAINLToolKind, + "type": AlloyDBAINLToolType, "source": "my-instance", "description": "Tool to test auth required invocation.", "nlConfig": "my_nl_config", diff --git a/tests/alloydbpg/alloydb_pg_integration_test.go b/tests/alloydbpg/alloydb_pg_integration_test.go index 32463f1ea0..9254256790 100644 --- a/tests/alloydbpg/alloydb_pg_integration_test.go +++ b/tests/alloydbpg/alloydb_pg_integration_test.go @@ -32,8 +32,8 @@ import ( ) var ( - AlloyDBPostgresSourceKind = "alloydb-postgres" - AlloyDBPostgresToolKind = "postgres-sql" + AlloyDBPostgresSourceType = "alloydb-postgres" + AlloyDBPostgresToolType = "postgres-sql" AlloyDBPostgresProject = os.Getenv("ALLOYDB_POSTGRES_PROJECT") AlloyDBPostgresRegion = os.Getenv("ALLOYDB_POSTGRES_REGION") AlloyDBPostgresCluster = os.Getenv("ALLOYDB_POSTGRES_CLUSTER") @@ -61,7 +61,7 @@ func getAlloyDBPgVars(t *testing.T) map[string]any { t.Fatal("'ALLOYDB_POSTGRES_PASS' not set") } return map[string]any{ - "kind": AlloyDBPostgresSourceKind, + "type": AlloyDBPostgresSourceType, "project": AlloyDBPostgresProject, "cluster": AlloyDBPostgresCluster, "instance": AlloyDBPostgresInstance, @@ -152,14 +152,14 @@ func TestAlloyDBPgToolEndpoints(t *testing.T) { defer tearDownVectorTable(t) // Write config into a file and pass it to command - toolsFile := tests.GetToolsConfig(sourceConfig, AlloyDBPostgresToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) + toolsFile := tests.GetToolsConfig(sourceConfig, AlloyDBPostgresToolType, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) toolsFile = tests.AddExecuteSqlConfig(t, toolsFile, "postgres-execute-sql") tmplSelectCombined, tmplSelectFilterCombined := tests.GetPostgresSQLTmplToolStatement() - toolsFile = tests.AddTemplateParamConfig(t, toolsFile, AlloyDBPostgresToolKind, tmplSelectCombined, tmplSelectFilterCombined, "") + toolsFile = tests.AddTemplateParamConfig(t, toolsFile, AlloyDBPostgresToolType, tmplSelectCombined, tmplSelectFilterCombined, "") // Add semantic search tool config insertStmt, searchStmt := tests.GetPostgresVectorSearchStmts(vectorTableName) - toolsFile = tests.AddSemanticSearchConfig(t, toolsFile, AlloyDBPostgresToolKind, insertStmt, searchStmt) + toolsFile = tests.AddSemanticSearchConfig(t, toolsFile, AlloyDBPostgresToolType, insertStmt, searchStmt) toolsFile = tests.AddPostgresPrebuiltConfig(t, toolsFile) @@ -232,7 +232,7 @@ func TestAlloyDBPgIpConnection(t *testing.T) { for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { sourceConfig["ipType"] = tc.ipType - err := tests.RunSourceConnectionTest(t, sourceConfig, AlloyDBPostgresToolKind) + err := tests.RunSourceConnectionTest(t, sourceConfig, AlloyDBPostgresToolType) if err != nil { t.Fatalf("Connection test failure: %s", err) } @@ -247,7 +247,7 @@ func TestAlloyDBPgIAMConnection(t *testing.T) { serviceAccountEmail := strings.TrimSuffix(tests.ServiceAccountEmail, ".gserviceaccount.com") noPassSourceConfig := map[string]any{ - "kind": AlloyDBPostgresSourceKind, + "type": AlloyDBPostgresSourceType, "project": AlloyDBPostgresProject, "cluster": AlloyDBPostgresCluster, "instance": AlloyDBPostgresInstance, @@ -257,7 +257,7 @@ func TestAlloyDBPgIAMConnection(t *testing.T) { } noUserSourceConfig := map[string]any{ - "kind": AlloyDBPostgresSourceKind, + "type": AlloyDBPostgresSourceType, "project": AlloyDBPostgresProject, "cluster": AlloyDBPostgresCluster, "instance": AlloyDBPostgresInstance, @@ -267,7 +267,7 @@ func TestAlloyDBPgIAMConnection(t *testing.T) { } noUserNoPassSourceConfig := map[string]any{ - "kind": AlloyDBPostgresSourceKind, + "type": AlloyDBPostgresSourceType, "project": AlloyDBPostgresProject, "cluster": AlloyDBPostgresCluster, "instance": AlloyDBPostgresInstance, @@ -297,7 +297,7 @@ func TestAlloyDBPgIAMConnection(t *testing.T) { } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - err := tests.RunSourceConnectionTest(t, tc.sourceConfig, AlloyDBPostgresToolKind) + err := tests.RunSourceConnectionTest(t, tc.sourceConfig, AlloyDBPostgresToolType) if err != nil { if tc.isErr { return diff --git a/tests/bigquery/bigquery_integration_test.go b/tests/bigquery/bigquery_integration_test.go index de5126cd24..6059c190a8 100644 --- a/tests/bigquery/bigquery_integration_test.go +++ b/tests/bigquery/bigquery_integration_test.go @@ -41,8 +41,8 @@ import ( ) var ( - BigquerySourceKind = "bigquery" - BigqueryToolKind = "bigquery-sql" + BigquerySourceType = "bigquery" + BigqueryToolType = "bigquery-sql" BigqueryProject = os.Getenv("BIGQUERY_PROJECT") ) @@ -53,7 +53,7 @@ func getBigQueryVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": BigquerySourceKind, + "type": BigquerySourceType, "project": BigqueryProject, } } @@ -146,12 +146,12 @@ func TestBigQueryToolEndpoints(t *testing.T) { defer teardownTable5(t) // Write config into a file and pass it to command - toolsFile := tests.GetToolsConfig(sourceConfig, BigqueryToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) + toolsFile := tests.GetToolsConfig(sourceConfig, BigqueryToolType, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) toolsFile = addClientAuthSourceConfig(t, toolsFile) toolsFile = addBigQuerySqlToolConfig(t, toolsFile, dataTypeToolStmt, arrayDataTypeToolStmt) toolsFile = addBigQueryPrebuiltToolsConfig(t, toolsFile) tmplSelectCombined, tmplSelectFilterCombined := getBigQueryTmplToolStatement() - toolsFile = tests.AddTemplateParamConfig(t, toolsFile, BigqueryToolKind, tmplSelectCombined, tmplSelectFilterCombined, "") + toolsFile = tests.AddTemplateParamConfig(t, toolsFile, BigqueryToolType, tmplSelectCombined, tmplSelectFilterCombined, "") cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) if err != nil { @@ -286,42 +286,42 @@ func TestBigQueryToolWithDatasetRestriction(t *testing.T) { // Configure tool toolsConfig := map[string]any{ "list-dataset-ids-restricted": map[string]any{ - "kind": "bigquery-list-dataset-ids", + "type": "bigquery-list-dataset-ids", "source": "my-instance", "description": "Tool to list dataset ids", }, "list-table-ids-restricted": map[string]any{ - "kind": "bigquery-list-table-ids", + "type": "bigquery-list-table-ids", "source": "my-instance", "description": "Tool to list table within a dataset", }, "get-dataset-info-restricted": map[string]any{ - "kind": "bigquery-get-dataset-info", + "type": "bigquery-get-dataset-info", "source": "my-instance", "description": "Tool to get dataset info", }, "get-table-info-restricted": map[string]any{ - "kind": "bigquery-get-table-info", + "type": "bigquery-get-table-info", "source": "my-instance", "description": "Tool to get table info", }, "execute-sql-restricted": map[string]any{ - "kind": "bigquery-execute-sql", + "type": "bigquery-execute-sql", "source": "my-instance", "description": "Tool to execute SQL", }, "conversational-analytics-restricted": map[string]any{ - "kind": "bigquery-conversational-analytics", + "type": "bigquery-conversational-analytics", "source": "my-instance", "description": "Tool to ask BigQuery conversational analytics", }, "forecast-restricted": map[string]any{ - "kind": "bigquery-forecast", + "type": "bigquery-forecast", "source": "my-instance", "description": "Tool to forecast", }, "analyze-contribution-restricted": map[string]any{ - "kind": "bigquery-analyze-contribution", + "type": "bigquery-analyze-contribution", "source": "my-instance", "description": "Tool to analyze contribution", }, @@ -398,7 +398,7 @@ func TestBigQueryWriteModeAllowed(t *testing.T) { }, "tools": map[string]any{ "my-exec-sql-tool": map[string]any{ - "kind": "bigquery-execute-sql", + "type": "bigquery-execute-sql", "source": "my-instance", "description": "Tool to execute sql", }, @@ -444,7 +444,7 @@ func TestBigQueryWriteModeBlocked(t *testing.T) { toolsFile := map[string]any{ "sources": map[string]any{"my-instance": sourceConfig}, "tools": map[string]any{ - "my-exec-sql-tool": map[string]any{"kind": "bigquery-execute-sql", "source": "my-instance", "description": "Tool to execute sql"}, + "my-exec-sql-tool": map[string]any{"type": "bigquery-execute-sql", "source": "my-instance", "description": "Tool to execute sql"}, }, } @@ -490,20 +490,20 @@ func TestBigQueryWriteModeProtected(t *testing.T) { toolsFile := map[string]any{ "sources": map[string]any{"my-instance": sourceConfig}, "tools": map[string]any{ - "my-exec-sql-tool": map[string]any{"kind": "bigquery-execute-sql", "source": "my-instance", "description": "Tool to execute sql"}, + "my-exec-sql-tool": map[string]any{"type": "bigquery-execute-sql", "source": "my-instance", "description": "Tool to execute sql"}, "my-sql-tool-protected": map[string]any{ - "kind": "bigquery-sql", + "type": "bigquery-sql", "source": "my-instance", "description": "Tool to query from the session", "statement": "SELECT * FROM my_shared_temp_table", }, "my-forecast-tool-protected": map[string]any{ - "kind": "bigquery-forecast", + "type": "bigquery-forecast", "source": "my-instance", "description": "Tool to forecast from session temp table", }, "my-analyze-contribution-tool-protected": map[string]any{ - "kind": "bigquery-analyze-contribution", + "type": "bigquery-analyze-contribution", "source": "my-instance", "description": "Tool to analyze contribution from session temp table", }, @@ -527,7 +527,7 @@ func TestBigQueryWriteModeProtected(t *testing.T) { runBigQueryWriteModeProtectedTest(t, permanentDatasetName) } -// getBigQueryParamToolInfo returns statements and param for my-tool for bigquery kind +// getBigQueryParamToolInfo returns statements and param for my-tool for bigquery type func getBigQueryParamToolInfo(tableName string) (string, string, string, string, string, string, []bigqueryapi.QueryParameter) { createStatement := fmt.Sprintf(` CREATE TABLE IF NOT EXISTS %s (id INT64, name STRING);`, tableName) @@ -546,7 +546,7 @@ func getBigQueryParamToolInfo(tableName string) (string, string, string, string, return createStatement, insertStatement, toolStatement, idToolStatement, nameToolStatement, arrayToolStatememt, params } -// getBigQueryAuthToolInfo returns statements and param of my-auth-tool for bigquery kind +// getBigQueryAuthToolInfo returns statements and param of my-auth-tool for bigquery type func getBigQueryAuthToolInfo(tableName string) (string, string, string, []bigqueryapi.QueryParameter) { createStatement := fmt.Sprintf(` CREATE TABLE IF NOT EXISTS %s (id INT64, name STRING, email STRING)`, tableName) @@ -616,7 +616,7 @@ func getBigQueryAnalyzeContributionToolInfo(tableName string) (string, string, [ return createStatement, insertStatement, params } -// getBigQueryTmplToolStatement returns statements for template parameter test cases for bigquery kind +// getBigQueryTmplToolStatement returns statements for template parameter test cases for bigquery type func getBigQueryTmplToolStatement() (string, string) { tmplSelectCombined := "SELECT * FROM {{.tableName}} WHERE id = ? ORDER BY id" tmplSelectFilterCombined := "SELECT * FROM {{.tableName}} WHERE {{.columnFilter}} = ? ORDER BY id" @@ -708,12 +708,12 @@ func addBigQueryPrebuiltToolsConfig(t *testing.T, config map[string]any) map[str t.Fatalf("unable to get tools from config") } tools["my-exec-sql-tool"] = map[string]any{ - "kind": "bigquery-execute-sql", + "type": "bigquery-execute-sql", "source": "my-instance", "description": "Tool to execute sql", } tools["my-auth-exec-sql-tool"] = map[string]any{ - "kind": "bigquery-execute-sql", + "type": "bigquery-execute-sql", "source": "my-instance", "description": "Tool to execute sql", "authRequired": []string{ @@ -721,17 +721,17 @@ func addBigQueryPrebuiltToolsConfig(t *testing.T, config map[string]any) map[str }, } tools["my-client-auth-exec-sql-tool"] = map[string]any{ - "kind": "bigquery-execute-sql", + "type": "bigquery-execute-sql", "source": "my-client-auth-source", "description": "Tool to execute sql", } tools["my-forecast-tool"] = map[string]any{ - "kind": "bigquery-forecast", + "type": "bigquery-forecast", "source": "my-instance", "description": "Tool to forecast time series data.", } tools["my-auth-forecast-tool"] = map[string]any{ - "kind": "bigquery-forecast", + "type": "bigquery-forecast", "source": "my-instance", "description": "Tool to forecast time series data with auth.", "authRequired": []string{ @@ -739,17 +739,17 @@ func addBigQueryPrebuiltToolsConfig(t *testing.T, config map[string]any) map[str }, } tools["my-client-auth-forecast-tool"] = map[string]any{ - "kind": "bigquery-forecast", + "type": "bigquery-forecast", "source": "my-client-auth-source", "description": "Tool to forecast time series data with auth.", } tools["my-analyze-contribution-tool"] = map[string]any{ - "kind": "bigquery-analyze-contribution", + "type": "bigquery-analyze-contribution", "source": "my-instance", "description": "Tool to analyze contribution.", } tools["my-auth-analyze-contribution-tool"] = map[string]any{ - "kind": "bigquery-analyze-contribution", + "type": "bigquery-analyze-contribution", "source": "my-instance", "description": "Tool to analyze contribution with auth.", "authRequired": []string{ @@ -757,17 +757,17 @@ func addBigQueryPrebuiltToolsConfig(t *testing.T, config map[string]any) map[str }, } tools["my-client-auth-analyze-contribution-tool"] = map[string]any{ - "kind": "bigquery-analyze-contribution", + "type": "bigquery-analyze-contribution", "source": "my-client-auth-source", "description": "Tool to analyze contribution with auth.", } tools["my-list-dataset-ids-tool"] = map[string]any{ - "kind": "bigquery-list-dataset-ids", + "type": "bigquery-list-dataset-ids", "source": "my-instance", "description": "Tool to list dataset", } tools["my-auth-list-dataset-ids-tool"] = map[string]any{ - "kind": "bigquery-list-dataset-ids", + "type": "bigquery-list-dataset-ids", "source": "my-instance", "description": "Tool to list dataset", "authRequired": []string{ @@ -775,17 +775,17 @@ func addBigQueryPrebuiltToolsConfig(t *testing.T, config map[string]any) map[str }, } tools["my-client-auth-list-dataset-ids-tool"] = map[string]any{ - "kind": "bigquery-list-dataset-ids", + "type": "bigquery-list-dataset-ids", "source": "my-client-auth-source", "description": "Tool to list dataset", } tools["my-get-dataset-info-tool"] = map[string]any{ - "kind": "bigquery-get-dataset-info", + "type": "bigquery-get-dataset-info", "source": "my-instance", "description": "Tool to show dataset metadata", } tools["my-auth-get-dataset-info-tool"] = map[string]any{ - "kind": "bigquery-get-dataset-info", + "type": "bigquery-get-dataset-info", "source": "my-instance", "description": "Tool to show dataset metadata", "authRequired": []string{ @@ -793,17 +793,17 @@ func addBigQueryPrebuiltToolsConfig(t *testing.T, config map[string]any) map[str }, } tools["my-client-auth-get-dataset-info-tool"] = map[string]any{ - "kind": "bigquery-get-dataset-info", + "type": "bigquery-get-dataset-info", "source": "my-client-auth-source", "description": "Tool to show dataset metadata", } tools["my-list-table-ids-tool"] = map[string]any{ - "kind": "bigquery-list-table-ids", + "type": "bigquery-list-table-ids", "source": "my-instance", "description": "Tool to list table within a dataset", } tools["my-auth-list-table-ids-tool"] = map[string]any{ - "kind": "bigquery-list-table-ids", + "type": "bigquery-list-table-ids", "source": "my-instance", "description": "Tool to list table within a dataset", "authRequired": []string{ @@ -811,17 +811,17 @@ func addBigQueryPrebuiltToolsConfig(t *testing.T, config map[string]any) map[str }, } tools["my-client-auth-list-table-ids-tool"] = map[string]any{ - "kind": "bigquery-list-table-ids", + "type": "bigquery-list-table-ids", "source": "my-client-auth-source", "description": "Tool to list table within a dataset", } tools["my-get-table-info-tool"] = map[string]any{ - "kind": "bigquery-get-table-info", + "type": "bigquery-get-table-info", "source": "my-instance", "description": "Tool to show dataset metadata", } tools["my-auth-get-table-info-tool"] = map[string]any{ - "kind": "bigquery-get-table-info", + "type": "bigquery-get-table-info", "source": "my-instance", "description": "Tool to show dataset metadata", "authRequired": []string{ @@ -829,17 +829,17 @@ func addBigQueryPrebuiltToolsConfig(t *testing.T, config map[string]any) map[str }, } tools["my-client-auth-get-table-info-tool"] = map[string]any{ - "kind": "bigquery-get-table-info", + "type": "bigquery-get-table-info", "source": "my-client-auth-source", "description": "Tool to show dataset metadata", } tools["my-conversational-analytics-tool"] = map[string]any{ - "kind": "bigquery-conversational-analytics", + "type": "bigquery-conversational-analytics", "source": "my-instance", "description": "Tool to ask BigQuery conversational analytics", } tools["my-auth-conversational-analytics-tool"] = map[string]any{ - "kind": "bigquery-conversational-analytics", + "type": "bigquery-conversational-analytics", "source": "my-instance", "description": "Tool to ask BigQuery conversational analytics", "authRequired": []string{ @@ -847,17 +847,17 @@ func addBigQueryPrebuiltToolsConfig(t *testing.T, config map[string]any) map[str }, } tools["my-client-auth-conversational-analytics-tool"] = map[string]any{ - "kind": "bigquery-conversational-analytics", + "type": "bigquery-conversational-analytics", "source": "my-client-auth-source", "description": "Tool to ask BigQuery conversational analytics", } tools["my-search-catalog-tool"] = map[string]any{ - "kind": "bigquery-search-catalog", + "type": "bigquery-search-catalog", "source": "my-instance", "description": "Tool to search the BiqQuery catalog", } tools["my-auth-search-catalog-tool"] = map[string]any{ - "kind": "bigquery-search-catalog", + "type": "bigquery-search-catalog", "source": "my-instance", "description": "Tool to search the BiqQuery catalog", "authRequired": []string{ @@ -865,7 +865,7 @@ func addBigQueryPrebuiltToolsConfig(t *testing.T, config map[string]any) map[str }, } tools["my-client-auth-search-catalog-tool"] = map[string]any{ - "kind": "bigquery-search-catalog", + "type": "bigquery-search-catalog", "source": "my-client-auth-source", "description": "Tool to search the BiqQuery catalog", } @@ -879,7 +879,7 @@ func addClientAuthSourceConfig(t *testing.T, config map[string]any) map[string]a t.Fatalf("unable to get sources from config") } sources["my-client-auth-source"] = map[string]any{ - "kind": BigquerySourceKind, + "type": BigquerySourceType, "project": BigqueryProject, "useClientOAuth": true, } @@ -893,7 +893,7 @@ func addBigQuerySqlToolConfig(t *testing.T, config map[string]any, toolStatement t.Fatalf("unable to get tools from config") } tools["my-scalar-datatype-tool"] = map[string]any{ - "kind": "bigquery-sql", + "type": "bigquery-sql", "source": "my-instance", "description": "Tool to test various scalar data types.", "statement": toolStatement, @@ -905,7 +905,7 @@ func addBigQuerySqlToolConfig(t *testing.T, config map[string]any, toolStatement }, } tools["my-array-datatype-tool"] = map[string]any{ - "kind": "bigquery-sql", + "type": "bigquery-sql", "source": "my-instance", "description": "Tool to test various array data types.", "statement": arrayToolStatement, @@ -917,7 +917,7 @@ func addBigQuerySqlToolConfig(t *testing.T, config map[string]any, toolStatement }, } tools["my-client-auth-tool"] = map[string]any{ - "kind": "bigquery-sql", + "type": "bigquery-sql", "source": "my-client-auth-source", "description": "Tool to test client authorization.", "statement": "SELECT 1", diff --git a/tests/bigtable/bigtable_integration_test.go b/tests/bigtable/bigtable_integration_test.go index 12246cf398..49a7ca69c3 100644 --- a/tests/bigtable/bigtable_integration_test.go +++ b/tests/bigtable/bigtable_integration_test.go @@ -35,8 +35,8 @@ import ( ) var ( - BigtableSourceKind = "bigtable" - BigtableToolKind = "bigtable-sql" + BigtableSourceType = "bigtable" + BigtableToolType = "bigtable-sql" BigtableProject = os.Getenv("BIGTABLE_PROJECT") BigtableInstance = os.Getenv("BIGTABLE_INSTANCE") ) @@ -50,7 +50,7 @@ func getBigtableVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": BigtableSourceKind, + "type": BigtableSourceType, "project": BigtableProject, "instance": BigtableInstance, } @@ -99,7 +99,7 @@ func TestBigtableToolEndpoints(t *testing.T) { defer teardownTableTmpl(t) // Write config into a file and pass it to command - toolsFile := tests.GetToolsConfig(sourceConfig, BigtableToolKind, paramTestStatement, idParamTestStatement, nameParamTestStatement, arrayTestStatement, authToolStatement) + toolsFile := tests.GetToolsConfig(sourceConfig, BigtableToolType, paramTestStatement, idParamTestStatement, nameParamTestStatement, arrayTestStatement, authToolStatement) toolsFile = addTemplateParamConfig(t, toolsFile) cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) @@ -291,7 +291,7 @@ func addTemplateParamConfig(t *testing.T, config map[string]any) map[string]any t.Fatalf("unable to get tools from config") } toolsMap["select-templateParams-tool"] = map[string]any{ - "kind": "bigtable-sql", + "type": "bigtable-sql", "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}};", @@ -300,7 +300,7 @@ func addTemplateParamConfig(t *testing.T, config map[string]any) map[string]any }, } toolsMap["select-templateParams-combined-tool"] = map[string]any{ - "kind": "bigtable-sql", + "type": "bigtable-sql", "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;", @@ -310,7 +310,7 @@ func addTemplateParamConfig(t *testing.T, config map[string]any) map[string]any }, } toolsMap["select-fields-templateParams-tool"] = map[string]any{ - "kind": "bigtable-sql", + "type": "bigtable-sql", "source": "my-instance", "description": "Create table tool with template parameters", "statement": "SELECT {{array .fields}}, FROM {{.tableName}};", @@ -320,7 +320,7 @@ func addTemplateParamConfig(t *testing.T, config map[string]any) map[string]any }, } toolsMap["select-filter-templateParams-combined-tool"] = map[string]any{ - "kind": "bigtable-sql", + "type": "bigtable-sql", "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;", diff --git a/tests/cassandra/cassandra_integration_test.go b/tests/cassandra/cassandra_integration_test.go index 21d41beb5f..e1faac4554 100644 --- a/tests/cassandra/cassandra_integration_test.go +++ b/tests/cassandra/cassandra_integration_test.go @@ -31,8 +31,8 @@ import ( ) var ( - CassandraSourceKind = "cassandra" - CassandraToolKind = "cassandra-cql" + CassandraSourceType = "cassandra" + CassandraToolType = "cassandra-cql" Hosts = os.Getenv("CASSANDRA_HOST") Keyspace = "example_keyspace" Username = os.Getenv("CASSANDRA_USER") @@ -49,7 +49,7 @@ func getCassandraVars(t *testing.T) map[string]any { t.Fatal("'Password' not set") } return map[string]any{ - "kind": CassandraSourceKind, + "type": CassandraSourceType, "hosts": strings.Split(Hosts, ","), "keyspace": Keyspace, "username": Username, @@ -204,12 +204,12 @@ func TestCassandra(t *testing.T) { paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt := createParamToolInfo(paramTableName) _, _, authToolStmt := getCassandraAuthToolInfo(tableNameAuth) - toolsFile := tests.GetToolsConfig(sourceConfig, CassandraToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) + toolsFile := tests.GetToolsConfig(sourceConfig, CassandraToolType, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) tmplSelectCombined, tmplSelectFilterCombined := getCassandraTmplToolInfo() tmpSelectAll := "SELECT * FROM {{.tableName}} where id = 1" - toolsFile = tests.AddTemplateParamConfig(t, toolsFile, CassandraToolKind, tmplSelectCombined, tmplSelectFilterCombined, tmpSelectAll) + toolsFile = tests.AddTemplateParamConfig(t, toolsFile, CassandraToolType, tmplSelectCombined, tmplSelectFilterCombined, tmpSelectAll) cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) if err != nil { diff --git a/tests/clickhouse/clickhouse_integration_test.go b/tests/clickhouse/clickhouse_integration_test.go index 058e4d1b1a..911bfdde11 100644 --- a/tests/clickhouse/clickhouse_integration_test.go +++ b/tests/clickhouse/clickhouse_integration_test.go @@ -35,8 +35,8 @@ import ( ) var ( - ClickHouseSourceKind = "clickhouse" - ClickHouseToolKind = "clickhouse-sql" + ClickHouseSourceType = "clickhouse" + ClickHouseToolType = "clickhouse-sql" ClickHouseDatabase = os.Getenv("CLICKHOUSE_DATABASE") ClickHouseHost = os.Getenv("CLICKHOUSE_HOST") ClickHousePort = os.Getenv("CLICKHOUSE_PORT") @@ -64,7 +64,7 @@ func getClickHouseVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": ClickHouseSourceKind, + "type": ClickHouseSourceType, "host": ClickHouseHost, "port": ClickHousePort, "database": ClickHouseDatabase, @@ -126,10 +126,10 @@ func TestClickHouse(t *testing.T) { teardownTable2 := setupClickHouseSQLTable(t, ctx, pool, createAuthTableStmt, insertAuthTableStmt, tableNameAuth, authTestParams) defer teardownTable2(t) - toolsFile := tests.GetToolsConfig(sourceConfig, ClickHouseToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) + toolsFile := tests.GetToolsConfig(sourceConfig, ClickHouseToolType, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) toolsFile = addClickHouseExecuteSqlConfig(t, toolsFile) tmplSelectCombined, tmplSelectFilterCombined := getClickHouseSQLTmplToolStatement() - toolsFile = addClickHouseTemplateParamConfig(t, toolsFile, ClickHouseToolKind, tmplSelectCombined, tmplSelectFilterCombined) + toolsFile = addClickHouseTemplateParamConfig(t, toolsFile, ClickHouseToolType, tmplSelectCombined, tmplSelectFilterCombined) cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) if err != nil { @@ -162,12 +162,12 @@ func addClickHouseExecuteSqlConfig(t *testing.T, config map[string]any) map[stri t.Fatalf("unable to get tools from config") } tools["my-exec-sql-tool"] = map[string]any{ - "kind": "clickhouse-execute-sql", + "type": "clickhouse-execute-sql", "source": "my-instance", "description": "Tool to execute sql", } tools["my-auth-exec-sql-tool"] = map[string]any{ - "kind": "clickhouse-execute-sql", + "type": "clickhouse-execute-sql", "source": "my-instance", "description": "Tool to execute sql", "authRequired": []string{ @@ -178,7 +178,7 @@ func addClickHouseExecuteSqlConfig(t *testing.T, config map[string]any) map[stri return config } -func addClickHouseTemplateParamConfig(t *testing.T, config map[string]any, toolKind, tmplSelectCombined, tmplSelectFilterCombined string) map[string]any { +func addClickHouseTemplateParamConfig(t *testing.T, config map[string]any, toolType, tmplSelectCombined, tmplSelectFilterCombined string) map[string]any { toolsMap, ok := config["tools"].(map[string]any) if !ok { t.Fatalf("unable to get tools from config") @@ -186,7 +186,7 @@ func addClickHouseTemplateParamConfig(t *testing.T, config map[string]any, toolK // ClickHouse-specific template parameter tools with compatible syntax toolsMap["create-table-templateParams-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Create table tool with template parameters", "statement": "CREATE TABLE {{.tableName}} ({{array .columns}}) ORDER BY id", @@ -196,7 +196,7 @@ func addClickHouseTemplateParamConfig(t *testing.T, config map[string]any, toolK }, } toolsMap["insert-table-templateParams-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Insert table tool with template parameters", "statement": "INSERT INTO {{.tableName}} ({{array .columns}}) VALUES ({{.values}})", @@ -207,7 +207,7 @@ func addClickHouseTemplateParamConfig(t *testing.T, config map[string]any, toolK }, } toolsMap["select-templateParams-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "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", @@ -216,7 +216,7 @@ func addClickHouseTemplateParamConfig(t *testing.T, config map[string]any, toolK }, } toolsMap["select-templateParams-combined-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Select table tool with combined template parameters", "statement": tmplSelectCombined, @@ -228,7 +228,7 @@ func addClickHouseTemplateParamConfig(t *testing.T, config map[string]any, toolK }, } toolsMap["select-fields-templateParams-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Select specific fields tool with template parameters", "statement": "SELECT name AS \"name\" FROM {{.tableName}} ORDER BY id", @@ -237,7 +237,7 @@ func addClickHouseTemplateParamConfig(t *testing.T, config map[string]any, toolK }, } toolsMap["select-filter-templateParams-combined-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Select table tool with filter template parameters", "statement": tmplSelectFilterCombined, @@ -251,7 +251,7 @@ func addClickHouseTemplateParamConfig(t *testing.T, config map[string]any, toolK } // Firebird uses simple DROP TABLE syntax without IF EXISTS toolsMap["drop-table-templateParams-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Drop table tool with template parameters", "statement": "DROP TABLE {{.tableName}}", @@ -310,7 +310,7 @@ func TestClickHouseBasicConnection(t *testing.T) { }, "tools": map[string]any{ "my-simple-tool": map[string]any{ - "kind": ClickHouseToolKind, + "type": ClickHouseToolType, "source": "my-instance", "description": "Simple tool to test end to end functionality.", "statement": "SELECT 1;", @@ -386,13 +386,13 @@ func TestClickHouseSQLTool(t *testing.T) { }, "tools": map[string]any{ "test-select": map[string]any{ - "kind": ClickHouseToolKind, + "type": ClickHouseToolType, "source": "my-instance", "description": "Test select query", "statement": fmt.Sprintf("SELECT * FROM %s ORDER BY id", tableName), }, "test-param-query": map[string]any{ - "kind": ClickHouseToolKind, + "type": ClickHouseToolType, "source": "my-instance", "description": "Test parameterized query", "statement": fmt.Sprintf("SELECT * FROM %s WHERE age > ? ORDER BY id", tableName), @@ -401,7 +401,7 @@ func TestClickHouseSQLTool(t *testing.T) { }, }, "test-empty-result": map[string]any{ - "kind": ClickHouseToolKind, + "type": ClickHouseToolType, "source": "my-instance", "description": "Test query with no results", "statement": fmt.Sprintf("SELECT * FROM %s WHERE id = ?", tableName), @@ -410,7 +410,7 @@ func TestClickHouseSQLTool(t *testing.T) { }, }, "test-invalid-sql": map[string]any{ - "kind": ClickHouseToolKind, + "type": ClickHouseToolType, "source": "my-instance", "description": "Test invalid SQL", "statement": "SELEC * FROM nonexistent_table", // Typo in SELECT @@ -522,7 +522,7 @@ func TestClickHouseExecuteSQLTool(t *testing.T) { }, "tools": map[string]any{ "execute-sql-tool": map[string]any{ - "kind": "clickhouse-execute-sql", + "type": "clickhouse-execute-sql", "source": "my-instance", "description": "Test create table", }, @@ -640,18 +640,18 @@ func TestClickHouseEdgeCases(t *testing.T) { }, "tools": map[string]any{ "execute-sql-tool": map[string]any{ - "kind": "clickhouse-execute-sql", + "type": "clickhouse-execute-sql", "source": "my-instance", "description": "Test create table", }, "test-null-values": map[string]any{ - "kind": "clickhouse-sql", + "type": "clickhouse-sql", "source": "my-instance", "description": "Test null values", "statement": fmt.Sprintf("SELECT * FROM %s ORDER BY id", tableName), }, "test-concurrent": map[string]any{ - "kind": "clickhouse-sql", + "type": "clickhouse-sql", "source": "my-instance", "description": "Test concurrent queries", "statement": "SELECT number FROM system.numbers LIMIT ?", @@ -818,7 +818,7 @@ func TestClickHouseEdgeCases(t *testing.T) { t.Logf("âś… Edge case tests completed successfully") } -// getClickHouseSQLParamToolInfo returns statements and param for my-tool clickhouse-sql kind +// getClickHouseSQLParamToolInfo returns statements and param for my-tool clickhouse-sql type func getClickHouseSQLParamToolInfo(tableName string) (string, string, string, string, string, string, []any) { createStatement := fmt.Sprintf("CREATE TABLE %s (id UInt32, name String) ENGINE = Memory", tableName) insertStatement := fmt.Sprintf("INSERT INTO %s (id, name) VALUES (?, ?), (?, ?), (?, ?), (?, ?)", tableName) @@ -830,7 +830,7 @@ func getClickHouseSQLParamToolInfo(tableName string) (string, string, string, st return createStatement, insertStatement, paramStatement, idParamStatement, nameParamStatement, arrayStatement, params } -// getClickHouseSQLAuthToolInfo returns statements and param of my-auth-tool for clickhouse-sql kind +// getClickHouseSQLAuthToolInfo returns statements and param of my-auth-tool for clickhouse-sql type func getClickHouseSQLAuthToolInfo(tableName string) (string, string, string, []any) { createStatement := fmt.Sprintf("CREATE TABLE %s (id UInt32, name String, email String) ENGINE = Memory", tableName) insertStatement := fmt.Sprintf("INSERT INTO %s (id, name, email) VALUES (?, ?, ?), (?, ?, ?)", tableName) @@ -839,7 +839,7 @@ func getClickHouseSQLAuthToolInfo(tableName string) (string, string, string, []a return createStatement, insertStatement, authStatement, params } -// getClickHouseSQLTmplToolStatement returns statements and param for template parameter test cases for clickhouse-sql kind +// getClickHouseSQLTmplToolStatement returns statements and param for template parameter test cases for clickhouse-sql type func getClickHouseSQLTmplToolStatement() (string, string) { tmplSelectCombined := "SELECT * FROM {{.tableName}} WHERE id = ?" tmplSelectFilterCombined := "SELECT * FROM {{.tableName}} WHERE {{.columnFilter}} = ?" @@ -902,12 +902,12 @@ func TestClickHouseListDatabasesTool(t *testing.T) { }, "tools": map[string]any{ "test-list-databases": map[string]any{ - "kind": "clickhouse-list-databases", + "type": "clickhouse-list-databases", "source": "my-instance", "description": "Test listing databases", }, "test-invalid-source": map[string]any{ - "kind": "clickhouse-list-databases", + "type": "clickhouse-list-databases", "source": "non-existent-source", "description": "Test with invalid source", }, @@ -1031,12 +1031,12 @@ func TestClickHouseListTablesTool(t *testing.T) { }, "tools": map[string]any{ "test-list-tables": map[string]any{ - "kind": "clickhouse-list-tables", + "type": "clickhouse-list-tables", "source": "my-instance", "description": "Test listing tables", }, "test-invalid-source": map[string]any{ - "kind": "clickhouse-list-tables", + "type": "clickhouse-list-tables", "source": "non-existent-source", "description": "Test with invalid source", }, diff --git a/tests/cloudgda/cloud_gda_integration_test.go b/tests/cloudgda/cloud_gda_integration_test.go index 343973f147..24c0cab1cb 100644 --- a/tests/cloudgda/cloud_gda_integration_test.go +++ b/tests/cloudgda/cloud_gda_integration_test.go @@ -33,7 +33,7 @@ import ( ) var ( - cloudGdaToolKind = "cloud-gemini-data-analytics-query" + cloudGdaToolType = "cloud-gemini-data-analytics-query" ) type cloudGdaTransport struct { @@ -205,13 +205,13 @@ func getCloudGdaToolsConfig() map[string]any { return map[string]any{ "sources": map[string]any{ "my-gda-source": map[string]any{ - "kind": "cloud-gemini-data-analytics", + "type": "cloud-gemini-data-analytics", "projectId": "test-project", }, }, "tools": map[string]any{ "cloud-gda-query": map[string]any{ - "kind": cloudGdaToolKind, + "type": cloudGdaToolType, "source": "my-gda-source", "description": "Test GDA Tool", "location": "us-central1", diff --git a/tests/cloudhealthcare/cloud_healthcare_integration_test.go b/tests/cloudhealthcare/cloud_healthcare_integration_test.go index 4fdddcb84a..72dac07928 100644 --- a/tests/cloudhealthcare/cloud_healthcare_integration_test.go +++ b/tests/cloudhealthcare/cloud_healthcare_integration_test.go @@ -41,22 +41,22 @@ import ( ) var ( - healthcareSourceKind = "cloud-healthcare" - getDatasetToolKind = "cloud-healthcare-get-dataset" - listFHIRStoresToolKind = "cloud-healthcare-list-fhir-stores" - listDICOMStoresToolKind = "cloud-healthcare-list-dicom-stores" - getFHIRStoreToolKind = "cloud-healthcare-get-fhir-store" - getFHIRStoreMetricsToolKind = "cloud-healthcare-get-fhir-store-metrics" - getFHIRResourceToolKind = "cloud-healthcare-get-fhir-resource" - fhirPatientSearchToolKind = "cloud-healthcare-fhir-patient-search" - fhirPatientEverythingToolKind = "cloud-healthcare-fhir-patient-everything" - fhirFetchPageToolKind = "cloud-healthcare-fhir-fetch-page" - getDICOMStoreToolKind = "cloud-healthcare-get-dicom-store" - getDICOMStoreMetricsToolKind = "cloud-healthcare-get-dicom-store-metrics" - searchDICOMStudiesToolKind = "cloud-healthcare-search-dicom-studies" - searchDICOMSeriesToolKind = "cloud-healthcare-search-dicom-series" - searchDICOMInstancesToolKind = "cloud-healthcare-search-dicom-instances" - retrieveRenderedDICOMInstanceToolKind = "cloud-healthcare-retrieve-rendered-dicom-instance" + healthcareSourceType = "cloud-healthcare" + getDatasetToolType = "cloud-healthcare-get-dataset" + listFHIRStoresToolType = "cloud-healthcare-list-fhir-stores" + listDICOMStoresToolType = "cloud-healthcare-list-dicom-stores" + getFHIRStoreToolType = "cloud-healthcare-get-fhir-store" + getFHIRStoreMetricsToolType = "cloud-healthcare-get-fhir-store-metrics" + getFHIRResourceToolType = "cloud-healthcare-get-fhir-resource" + fhirPatientSearchToolType = "cloud-healthcare-fhir-patient-search" + fhirPatientEverythingToolType = "cloud-healthcare-fhir-patient-everything" + fhirFetchPageToolType = "cloud-healthcare-fhir-fetch-page" + getDICOMStoreToolType = "cloud-healthcare-get-dicom-store" + getDICOMStoreMetricsToolType = "cloud-healthcare-get-dicom-store-metrics" + searchDICOMStudiesToolType = "cloud-healthcare-search-dicom-studies" + searchDICOMSeriesToolType = "cloud-healthcare-search-dicom-series" + searchDICOMInstancesToolType = "cloud-healthcare-search-dicom-instances" + retrieveRenderedDICOMInstanceToolType = "cloud-healthcare-retrieve-rendered-dicom-instance" healthcareProject = os.Getenv("HEALTHCARE_PROJECT") healthcareRegion = os.Getenv("HEALTHCARE_REGION") healthcareDataset = os.Getenv("HEALTHCARE_DATASET") @@ -92,7 +92,7 @@ func getHealthcareVars(t *testing.T) map[string]any { t.Fatal("'HEALTHCARE_PREPOPULATED_DICOM_STORE' not set") } return map[string]any{ - "kind": healthcareSourceKind, + "type": healthcareSourceType, "project": healthcareProject, "region": healthcareRegion, "dataset": healthcareDataset, @@ -182,12 +182,12 @@ func TestHealthcareToolWithStoreRestriction(t *testing.T) { // Configure tool toolsConfig := map[string]any{ "list-fhir-stores-restricted": map[string]any{ - "kind": "cloud-healthcare-list-fhir-stores", + "type": "cloud-healthcare-list-fhir-stores", "source": "my-instance", "description": "Tool to list fhir stores", }, "list-dicom-stores-restricted": map[string]any{ - "kind": "cloud-healthcare-list-dicom-stores", + "type": "cloud-healthcare-list-dicom-stores", "source": "my-instance", "description": "Tool to list dicom stores", }, @@ -336,157 +336,157 @@ func getToolsConfig(sourceConfig map[string]any) map[string]any { }, "tools": map[string]any{ "my-get-dataset-tool": map[string]any{ - "kind": getDatasetToolKind, + "type": getDatasetToolType, "source": "my-instance", "description": "Tool to get a healthcare dataset", }, "my-list-fhir-stores-tool": map[string]any{ - "kind": listFHIRStoresToolKind, + "type": listFHIRStoresToolType, "source": "my-instance", "description": "Tool to list FHIR stores", }, "my-list-dicom-stores-tool": map[string]any{ - "kind": listDICOMStoresToolKind, + "type": listDICOMStoresToolType, "source": "my-instance", "description": "Tool to list DICOM stores", }, "my-get-fhir-store-tool": map[string]any{ - "kind": getFHIRStoreToolKind, + "type": getFHIRStoreToolType, "source": "my-instance", "description": "Tool to get a FHIR store", }, "my-get-fhir-store-metrics-tool": map[string]any{ - "kind": getFHIRStoreMetricsToolKind, + "type": getFHIRStoreMetricsToolType, "source": "my-instance", "description": "Tool to get FHIR store metrics", }, "my-get-fhir-resource-tool": map[string]any{ - "kind": getFHIRResourceToolKind, + "type": getFHIRResourceToolType, "source": "my-instance", "description": "Tool to get FHIR resource", }, "my-fhir-patient-search-tool": map[string]any{ - "kind": fhirPatientSearchToolKind, + "type": fhirPatientSearchToolType, "source": "my-instance", "description": "Tool to search for patients", }, "my-fhir-patient-everything-tool": map[string]any{ - "kind": fhirPatientEverythingToolKind, + "type": fhirPatientEverythingToolType, "source": "my-instance", "description": "Tool for patient everything", }, "my-fhir-fetch-page-tool": map[string]any{ - "kind": fhirFetchPageToolKind, + "type": fhirFetchPageToolType, "source": "my-instance", "description": "Tool to fetch a page of FHIR resources", }, "my-get-dicom-store-tool": map[string]any{ - "kind": getDICOMStoreToolKind, + "type": getDICOMStoreToolType, "source": "my-instance", "description": "Tool to get a DICOM store", }, "my-get-dicom-store-metrics-tool": map[string]any{ - "kind": getDICOMStoreMetricsToolKind, + "type": getDICOMStoreMetricsToolType, "source": "my-instance", "description": "Tool to get DICOM store metrics", }, "my-search-dicom-studies-tool": map[string]any{ - "kind": searchDICOMStudiesToolKind, + "type": searchDICOMStudiesToolType, "source": "my-instance", "description": "Tool to search DICOM studies", }, "my-search-dicom-series-tool": map[string]any{ - "kind": searchDICOMSeriesToolKind, + "type": searchDICOMSeriesToolType, "source": "my-instance", "description": "Tool to search DICOM series", }, "my-search-dicom-instances-tool": map[string]any{ - "kind": searchDICOMInstancesToolKind, + "type": searchDICOMInstancesToolType, "source": "my-instance", "description": "Tool to search DICOM instances", }, "my-retrieve-rendered-dicom-instance-tool": map[string]any{ - "kind": retrieveRenderedDICOMInstanceToolKind, + "type": retrieveRenderedDICOMInstanceToolType, "source": "my-instance", "description": "Tool to retrieve rendered DICOM instance", }, "my-client-auth-get-dataset-tool": map[string]any{ - "kind": getDatasetToolKind, + "type": getDatasetToolType, "source": "my-client-auth-source", "description": "Tool to get a healthcare dataset", }, "my-client-auth-list-fhir-stores-tool": map[string]any{ - "kind": listFHIRStoresToolKind, + "type": listFHIRStoresToolType, "source": "my-client-auth-source", "description": "Tool to list FHIR stores", }, "my-client-auth-list-dicom-stores-tool": map[string]any{ - "kind": listDICOMStoresToolKind, + "type": listDICOMStoresToolType, "source": "my-client-auth-source", "description": "Tool to list DICOM stores", }, "my-client-auth-get-fhir-store-tool": map[string]any{ - "kind": getFHIRStoreToolKind, + "type": getFHIRStoreToolType, "source": "my-client-auth-source", "description": "Tool to get a FHIR store", }, "my-client-auth-get-fhir-store-metrics-tool": map[string]any{ - "kind": getFHIRStoreMetricsToolKind, + "type": getFHIRStoreMetricsToolType, "source": "my-client-auth-source", "description": "Tool to get FHIR store metrics", }, "my-client-auth-get-fhir-resource-tool": map[string]any{ - "kind": getFHIRResourceToolKind, + "type": getFHIRResourceToolType, "source": "my-client-auth-source", "description": "Tool to get FHIR resource", }, "my-client-auth-fhir-patient-search-tool": map[string]any{ - "kind": fhirPatientSearchToolKind, + "type": fhirPatientSearchToolType, "source": "my-client-auth-source", "description": "Tool to search for patients", }, "my-client-auth-fhir-patient-everything-tool": map[string]any{ - "kind": fhirPatientEverythingToolKind, + "type": fhirPatientEverythingToolType, "source": "my-client-auth-source", "description": "Tool for patient everything", }, "my-client-auth-fhir-fetch-page-tool": map[string]any{ - "kind": fhirFetchPageToolKind, + "type": fhirFetchPageToolType, "source": "my-client-auth-source", "description": "Tool to fetch a page of FHIR resources", }, "my-client-auth-get-dicom-store-tool": map[string]any{ - "kind": getDICOMStoreToolKind, + "type": getDICOMStoreToolType, "source": "my-client-auth-source", "description": "Tool to get a DICOM store", }, "my-client-auth-get-dicom-store-metrics-tool": map[string]any{ - "kind": getDICOMStoreMetricsToolKind, + "type": getDICOMStoreMetricsToolType, "source": "my-client-auth-source", "description": "Tool to get DICOM store metrics", }, "my-client-auth-search-dicom-studies-tool": map[string]any{ - "kind": searchDICOMStudiesToolKind, + "type": searchDICOMStudiesToolType, "source": "my-client-auth-source", "description": "Tool to search DICOM studies", }, "my-client-auth-search-dicom-series-tool": map[string]any{ - "kind": searchDICOMSeriesToolKind, + "type": searchDICOMSeriesToolType, "source": "my-client-auth-source", "description": "Tool to search DICOM series", }, "my-client-auth-search-dicom-instances-tool": map[string]any{ - "kind": searchDICOMInstancesToolKind, + "type": searchDICOMInstancesToolType, "source": "my-client-auth-source", "description": "Tool to search DICOM instances", }, "my-client-auth-retrieve-rendered-dicom-instance-tool": map[string]any{ - "kind": retrieveRenderedDICOMInstanceToolKind, + "type": retrieveRenderedDICOMInstanceToolType, "source": "my-client-auth-source", "description": "Tool to retrieve rendered DICOM instance", }, "my-auth-get-dataset-tool": map[string]any{ - "kind": getDatasetToolKind, + "type": getDatasetToolType, "source": "my-instance", "description": "Tool to get a healthcare dataset with auth", "authRequired": []string{ @@ -494,7 +494,7 @@ func getToolsConfig(sourceConfig map[string]any) map[string]any { }, }, "my-auth-list-fhir-stores-tool": map[string]any{ - "kind": listFHIRStoresToolKind, + "type": listFHIRStoresToolType, "source": "my-instance", "description": "Tool to list FHIR stores with auth", "authRequired": []string{ @@ -502,7 +502,7 @@ func getToolsConfig(sourceConfig map[string]any) map[string]any { }, }, "my-auth-list-dicom-stores-tool": map[string]any{ - "kind": listDICOMStoresToolKind, + "type": listDICOMStoresToolType, "source": "my-instance", "description": "Tool to list DICOM stores with auth", "authRequired": []string{ @@ -510,7 +510,7 @@ func getToolsConfig(sourceConfig map[string]any) map[string]any { }, }, "my-auth-get-fhir-store-tool": map[string]any{ - "kind": getFHIRStoreToolKind, + "type": getFHIRStoreToolType, "source": "my-instance", "description": "Tool to get a FHIR store", "authRequired": []string{ @@ -518,7 +518,7 @@ func getToolsConfig(sourceConfig map[string]any) map[string]any { }, }, "my-auth-get-fhir-store-metrics-tool": map[string]any{ - "kind": getFHIRStoreMetricsToolKind, + "type": getFHIRStoreMetricsToolType, "source": "my-instance", "description": "Tool to get FHIR store metrics", "authRequired": []string{ @@ -526,7 +526,7 @@ func getToolsConfig(sourceConfig map[string]any) map[string]any { }, }, "my-auth-get-fhir-resource-tool": map[string]any{ - "kind": getFHIRResourceToolKind, + "type": getFHIRResourceToolType, "source": "my-instance", "description": "Tool to get FHIR resource", "authRequired": []string{ @@ -534,7 +534,7 @@ func getToolsConfig(sourceConfig map[string]any) map[string]any { }, }, "my-auth-fhir-patient-search-tool": map[string]any{ - "kind": fhirPatientSearchToolKind, + "type": fhirPatientSearchToolType, "source": "my-instance", "description": "Tool to search for patients", "authRequired": []string{ @@ -542,7 +542,7 @@ func getToolsConfig(sourceConfig map[string]any) map[string]any { }, }, "my-auth-fhir-patient-everything-tool": map[string]any{ - "kind": fhirPatientEverythingToolKind, + "type": fhirPatientEverythingToolType, "source": "my-instance", "description": "Tool for patient everything", "authRequired": []string{ @@ -550,7 +550,7 @@ func getToolsConfig(sourceConfig map[string]any) map[string]any { }, }, "my-auth-fhir-fetch-page-tool": map[string]any{ - "kind": fhirFetchPageToolKind, + "type": fhirFetchPageToolType, "source": "my-instance", "description": "Tool to fetch a page of FHIR resources", "authRequired": []string{ @@ -558,7 +558,7 @@ func getToolsConfig(sourceConfig map[string]any) map[string]any { }, }, "my-auth-get-dicom-store-tool": map[string]any{ - "kind": getDICOMStoreToolKind, + "type": getDICOMStoreToolType, "source": "my-instance", "description": "Tool to get a DICOM store", "authRequired": []string{ @@ -566,7 +566,7 @@ func getToolsConfig(sourceConfig map[string]any) map[string]any { }, }, "my-auth-get-dicom-store-metrics-tool": map[string]any{ - "kind": getDICOMStoreMetricsToolKind, + "type": getDICOMStoreMetricsToolType, "source": "my-instance", "description": "Tool to get DICOM store metrics", "authRequired": []string{ @@ -574,7 +574,7 @@ func getToolsConfig(sourceConfig map[string]any) map[string]any { }, }, "my-auth-search-dicom-studies-tool": map[string]any{ - "kind": searchDICOMStudiesToolKind, + "type": searchDICOMStudiesToolType, "source": "my-instance", "description": "Tool to search DICOM studies", "authRequired": []string{ @@ -582,7 +582,7 @@ func getToolsConfig(sourceConfig map[string]any) map[string]any { }, }, "my-auth-search-dicom-series-tool": map[string]any{ - "kind": searchDICOMSeriesToolKind, + "type": searchDICOMSeriesToolType, "source": "my-instance", "description": "Tool to search DICOM series", "authRequired": []string{ @@ -590,7 +590,7 @@ func getToolsConfig(sourceConfig map[string]any) map[string]any { }, }, "my-auth-search-dicom-instances-tool": map[string]any{ - "kind": searchDICOMInstancesToolKind, + "type": searchDICOMInstancesToolType, "source": "my-instance", "description": "Tool to search DICOM instances", "authRequired": []string{ @@ -598,7 +598,7 @@ func getToolsConfig(sourceConfig map[string]any) map[string]any { }, }, "my-auth-retrieve-rendered-dicom-instance-tool": map[string]any{ - "kind": retrieveRenderedDICOMInstanceToolKind, + "type": retrieveRenderedDICOMInstanceToolType, "source": "my-instance", "description": "Tool to retrieve rendered DICOM instance", "authRequired": []string{ @@ -608,7 +608,7 @@ func getToolsConfig(sourceConfig map[string]any) map[string]any { }, "authServices": map[string]any{ "my-google-auth": map[string]any{ - "kind": "google", + "type": "google", "clientId": tests.ClientId, }, }, @@ -622,7 +622,7 @@ func addClientAuthSourceConfig(t *testing.T, config map[string]any) map[string]a t.Fatalf("unable to get sources from config") } sources["my-client-auth-source"] = map[string]any{ - "kind": healthcareSourceKind, + "type": healthcareSourceType, "project": healthcareProject, "region": healthcareRegion, "dataset": healthcareDataset, diff --git a/tests/cloudmonitoring/cloud_monitoring_integration_test.go b/tests/cloudmonitoring/cloud_monitoring_integration_test.go index f5833244a6..54295cf5fb 100644 --- a/tests/cloudmonitoring/cloud_monitoring_integration_test.go +++ b/tests/cloudmonitoring/cloud_monitoring_integration_test.go @@ -49,7 +49,7 @@ func TestTool_Invoke(t *testing.T) { tool := cloudmonitoring.Tool{ Config: cloudmonitoring.Config{ Name: "test-cloudmonitoring", - Kind: "cloud-monitoring-query-prometheus", + Type: "cloud-monitoring-query-prometheus", Description: "Test Cloudmonitoring Tool", }, AllParams: parameters.Parameters{}, @@ -93,7 +93,7 @@ func TestTool_Invoke_Error(t *testing.T) { tool := cloudmonitoring.Tool{ Config: cloudmonitoring.Config{ Name: "test-cloudmonitoring", - Kind: "clou-monitoring-query-prometheus", + Type: "clou-monitoring-query-prometheus", Description: "Test Cloudmonitoring Tool", }, AllParams: parameters.Parameters{}, diff --git a/tests/cloudsql/cloud_sql_clone_instance_test.go b/tests/cloudsql/cloud_sql_clone_instance_test.go index f41062cb9a..024c24d153 100644 --- a/tests/cloudsql/cloud_sql_clone_instance_test.go +++ b/tests/cloudsql/cloud_sql_clone_instance_test.go @@ -38,7 +38,7 @@ import ( ) var ( - cloneInstanceToolKind = "cloud-sql-clone-instance" + cloneInstanceToolType = "cloud-sql-clone-instance" ) type cloneInstanceTransport struct { @@ -231,12 +231,12 @@ func getCloneInstanceToolsConfig() map[string]any { return map[string]any{ "sources": map[string]any{ "my-cloud-sql-source": map[string]any{ - "kind": "cloud-sql-admin", + "type": "cloud-sql-admin", }, }, "tools": map[string]any{ "clone-instance": map[string]any{ - "kind": cloneInstanceToolKind, + "type": cloneInstanceToolType, "source": "my-cloud-sql-source", }, }, diff --git a/tests/cloudsql/cloud_sql_create_backup_test.go b/tests/cloudsql/cloud_sql_create_backup_test.go index d9b7d05264..daebe9a732 100644 --- a/tests/cloudsql/cloud_sql_create_backup_test.go +++ b/tests/cloudsql/cloud_sql_create_backup_test.go @@ -36,7 +36,7 @@ import ( ) var ( - createBackupToolKind = "cloud-sql-create-backup" + createBackupToolType = "cloud-sql-create-backup" ) type createBackupTransport struct { @@ -219,12 +219,12 @@ func getCreateBackupToolsConfig() map[string]any { return map[string]any{ "sources": map[string]any{ "my-cloud-sql-source": map[string]any{ - "kind": "cloud-sql-admin", + "type": "cloud-sql-admin", }, }, "tools": map[string]any{ "create-backup": map[string]any{ - "kind": createBackupToolKind, + "type": createBackupToolType, "source": "my-cloud-sql-source", }, }, diff --git a/tests/cloudsql/cloud_sql_create_database_test.go b/tests/cloudsql/cloud_sql_create_database_test.go index a87bc8200b..c68d7dfb12 100644 --- a/tests/cloudsql/cloud_sql_create_database_test.go +++ b/tests/cloudsql/cloud_sql_create_database_test.go @@ -35,7 +35,7 @@ import ( ) var ( - createDatabaseToolKind = "cloud-sql-create-database" + createDatabaseToolType = "cloud-sql-create-database" ) type createDatabaseTransport struct { @@ -217,12 +217,12 @@ func getCreateDatabaseToolsConfig() map[string]any { return map[string]any{ "sources": map[string]any{ "my-cloud-sql-source": map[string]any{ - "kind": "cloud-sql-admin", + "type": "cloud-sql-admin", }, }, "tools": map[string]any{ "create-database": map[string]any{ - "kind": createDatabaseToolKind, + "type": createDatabaseToolType, "source": "my-cloud-sql-source", }, }, diff --git a/tests/cloudsql/cloud_sql_create_users_test.go b/tests/cloudsql/cloud_sql_create_users_test.go index 39cc4320f1..77978c4506 100644 --- a/tests/cloudsql/cloud_sql_create_users_test.go +++ b/tests/cloudsql/cloud_sql_create_users_test.go @@ -35,7 +35,7 @@ import ( ) var ( - createUserToolKind = "cloud-sql-create-users" + createUserToolType = "cloud-sql-create-users" ) type createUsersTransport struct { @@ -229,12 +229,12 @@ func getCreateUsersToolsConfig() map[string]any { return map[string]any{ "sources": map[string]any{ "my-cloud-sql-source": map[string]any{ - "kind": "cloud-sql-admin", + "type": "cloud-sql-admin", }, }, "tools": map[string]any{ "create-user": map[string]any{ - "kind": createUserToolKind, + "type": createUserToolType, "source": "my-cloud-sql-source", }, }, diff --git a/tests/cloudsql/cloud_sql_get_instances_test.go b/tests/cloudsql/cloud_sql_get_instances_test.go index dc920a80dd..709a501450 100644 --- a/tests/cloudsql/cloud_sql_get_instances_test.go +++ b/tests/cloudsql/cloud_sql_get_instances_test.go @@ -35,7 +35,7 @@ import ( ) var ( - getInstancesToolKind = "cloud-sql-get-instance" + getInstancesToolType = "cloud-sql-get-instance" ) type getInstancesTransport struct { @@ -231,21 +231,21 @@ func getToolsConfig() map[string]any { return map[string]any{ "sources": map[string]any{ "my-cloud-sql-source": map[string]any{ - "kind": "cloud-sql-admin", + "type": "cloud-sql-admin", }, "my-invalid-cloud-sql-source": map[string]any{ - "kind": "cloud-sql-admin", + "type": "cloud-sql-admin", "useClientOAuth": true, }, }, "tools": map[string]any{ "get-instance-1": map[string]any{ - "kind": getInstancesToolKind, + "type": getInstancesToolType, "description": "get instance 1", "source": "my-cloud-sql-source", }, "get-instance-2": map[string]any{ - "kind": getInstancesToolKind, + "type": getInstancesToolType, "description": "get instance 2", "source": "my-invalid-cloud-sql-source", }, diff --git a/tests/cloudsql/cloud_sql_list_databases_test.go b/tests/cloudsql/cloud_sql_list_databases_test.go index 6ee0f9b9eb..34719d2b03 100644 --- a/tests/cloudsql/cloud_sql_list_databases_test.go +++ b/tests/cloudsql/cloud_sql_list_databases_test.go @@ -34,7 +34,7 @@ import ( ) var ( - listDatabasesToolKind = "cloud-sql-list-databases" + listDatabasesToolType = "cloud-sql-list-databases" ) type listDatabasesTransport struct { @@ -200,12 +200,12 @@ func getListDatabasesToolsConfig() map[string]any { return map[string]any{ "sources": map[string]any{ "my-cloud-sql-source": map[string]any{ - "kind": "cloud-sql-admin", + "type": "cloud-sql-admin", }, }, "tools": map[string]any{ "list-databases": map[string]any{ - "kind": listDatabasesToolKind, + "type": listDatabasesToolType, "source": "my-cloud-sql-source", }, }, diff --git a/tests/cloudsql/cloudsql_list_instances_test.go b/tests/cloudsql/cloudsql_list_instances_test.go index 093765dfeb..7978fa5f65 100644 --- a/tests/cloudsql/cloudsql_list_instances_test.go +++ b/tests/cloudsql/cloudsql_list_instances_test.go @@ -171,20 +171,20 @@ func getListInstanceToolsConfig() map[string]any { return map[string]any{ "sources": map[string]any{ "my-cloud-sql-source": map[string]any{ - "kind": "cloud-sql-admin", + "type": "cloud-sql-admin", }, "my-invalid-cloud-sql-source": map[string]any{ - "kind": "cloud-sql-admin", + "type": "cloud-sql-admin", "useClientOAuth": true, }, }, "tools": map[string]any{ "list-instances": map[string]any{ - "kind": "cloud-sql-list-instances", + "type": "cloud-sql-list-instances", "source": "my-cloud-sql-source", }, "list-instances-fail": map[string]any{ - "kind": "cloud-sql-list-instances", + "type": "cloud-sql-list-instances", "description": "list instances", "source": "my-invalid-cloud-sql-source", }, diff --git a/tests/cloudsql/cloudsql_wait_for_operation_test.go b/tests/cloudsql/cloudsql_wait_for_operation_test.go index ab8cab808e..33c48077f2 100644 --- a/tests/cloudsql/cloudsql_wait_for_operation_test.go +++ b/tests/cloudsql/cloudsql_wait_for_operation_test.go @@ -37,7 +37,7 @@ import ( ) var ( - cloudsqlWaitToolKind = "cloud-sql-wait-for-operation" + cloudsqlWaitToolType = "cloud-sql-wait-for-operation" ) type waitForOperationTransport struct { @@ -291,22 +291,22 @@ func getCloudSQLWaitToolsConfig() map[string]any { return map[string]any{ "sources": map[string]any{ "my-cloud-sql-source": map[string]any{ - "kind": "cloud-sql-admin", + "type": "cloud-sql-admin", }, }, "tools": map[string]any{ "wait-for-op1": map[string]any{ - "kind": cloudsqlWaitToolKind, + "type": cloudsqlWaitToolType, "source": "my-cloud-sql-source", "description": "wait for op1", }, "wait-for-op2": map[string]any{ - "kind": cloudsqlWaitToolKind, + "type": cloudsqlWaitToolType, "source": "my-cloud-sql-source", "description": "wait for op2", }, "wait-for-op3": map[string]any{ - "kind": cloudsqlWaitToolKind, + "type": cloudsqlWaitToolType, "source": "my-cloud-sql-source", "description": "wait for op3", }, diff --git a/tests/cloudsqlmssql/cloud_sql_mssql_create_instance_integration_test.go b/tests/cloudsqlmssql/cloud_sql_mssql_create_instance_integration_test.go index 05bbe2d8e5..f468869656 100644 --- a/tests/cloudsqlmssql/cloud_sql_mssql_create_instance_integration_test.go +++ b/tests/cloudsqlmssql/cloud_sql_mssql_create_instance_integration_test.go @@ -36,7 +36,7 @@ import ( ) var ( - createInstanceToolKind = "cloud-sql-mssql-create-instance" + createInstanceToolType = "cloud-sql-mssql-create-instance" ) type createInstanceTransport struct { @@ -260,16 +260,16 @@ func getCreateInstanceToolsConfig() map[string]any { return map[string]any{ "sources": map[string]any{ "my-cloud-sql-source": map[string]any{ - "kind": "cloud-sql-admin", + "type": "cloud-sql-admin", }, }, "tools": map[string]any{ "create-instance-prod": map[string]any{ - "kind": createInstanceToolKind, + "type": createInstanceToolType, "source": "my-cloud-sql-source", }, "create-instance-dev": map[string]any{ - "kind": createInstanceToolKind, + "type": createInstanceToolType, "source": "my-cloud-sql-source", }, }, diff --git a/tests/cloudsqlmssql/cloud_sql_mssql_integration_test.go b/tests/cloudsqlmssql/cloud_sql_mssql_integration_test.go index b53ca030ce..aac0819715 100644 --- a/tests/cloudsqlmssql/cloud_sql_mssql_integration_test.go +++ b/tests/cloudsqlmssql/cloud_sql_mssql_integration_test.go @@ -34,8 +34,8 @@ import ( ) var ( - CloudSQLMSSQLSourceKind = "cloud-sql-mssql" - CloudSQLMSSQLToolKind = "mssql-sql" + CloudSQLMSSQLSourceType = "cloud-sql-mssql" + CloudSQLMSSQLToolType = "mssql-sql" CloudSQLMSSQLProject = os.Getenv("CLOUD_SQL_MSSQL_PROJECT") CloudSQLMSSQLRegion = os.Getenv("CLOUD_SQL_MSSQL_REGION") CloudSQLMSSQLInstance = os.Getenv("CLOUD_SQL_MSSQL_INSTANCE") @@ -61,7 +61,7 @@ func getCloudSQLMSSQLVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": CloudSQLMSSQLSourceKind, + "type": CloudSQLMSSQLSourceType, "project": CloudSQLMSSQLProject, "instance": CloudSQLMSSQLInstance, "region": CloudSQLMSSQLRegion, @@ -137,10 +137,10 @@ func TestCloudSQLMSSQLToolEndpoints(t *testing.T) { defer teardownTable2(t) // Write config into a file and pass it to command - toolsFile := tests.GetToolsConfig(sourceConfig, CloudSQLMSSQLToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) + toolsFile := tests.GetToolsConfig(sourceConfig, CloudSQLMSSQLToolType, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) toolsFile = tests.AddMSSQLExecuteSqlConfig(t, toolsFile) tmplSelectCombined, tmplSelectFilterCombined := tests.GetMSSQLTmplToolStatement() - toolsFile = tests.AddTemplateParamConfig(t, toolsFile, CloudSQLMSSQLToolKind, tmplSelectCombined, tmplSelectFilterCombined, "") + toolsFile = tests.AddTemplateParamConfig(t, toolsFile, CloudSQLMSSQLToolType, tmplSelectCombined, tmplSelectFilterCombined, "") toolsFile = tests.AddMSSQLPrebuiltToolConfig(t, toolsFile) cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) @@ -191,7 +191,7 @@ func TestCloudSQLMSSQLIpConnection(t *testing.T) { for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { sourceConfig["ipType"] = tc.ipType - err := tests.RunSourceConnectionTest(t, sourceConfig, CloudSQLMSSQLToolKind) + err := tests.RunSourceConnectionTest(t, sourceConfig, CloudSQLMSSQLToolType) if err != nil { t.Fatalf("Connection test failure: %s", err) } diff --git a/tests/cloudsqlmysql/cloud_sql_mysql_create_instance_integration_test.go b/tests/cloudsqlmysql/cloud_sql_mysql_create_instance_integration_test.go index 7ddec92faa..4af92f7648 100644 --- a/tests/cloudsqlmysql/cloud_sql_mysql_create_instance_integration_test.go +++ b/tests/cloudsqlmysql/cloud_sql_mysql_create_instance_integration_test.go @@ -36,7 +36,7 @@ import ( ) var ( - createInstanceToolKind = "cloud-sql-mysql-create-instance" + createInstanceToolType = "cloud-sql-mysql-create-instance" ) type createInstanceTransport struct { @@ -261,16 +261,16 @@ func getCreateInstanceToolsConfig() map[string]any { return map[string]any{ "sources": map[string]any{ "my-cloud-sql-source": map[string]any{ - "kind": "cloud-sql-admin", + "type": "cloud-sql-admin", }, }, "tools": map[string]any{ "create-instance-prod": map[string]any{ - "kind": createInstanceToolKind, + "type": createInstanceToolType, "source": "my-cloud-sql-source", }, "create-instance-dev": map[string]any{ - "kind": createInstanceToolKind, + "type": createInstanceToolType, "source": "my-cloud-sql-source", }, }, diff --git a/tests/cloudsqlmysql/cloud_sql_mysql_integration_test.go b/tests/cloudsqlmysql/cloud_sql_mysql_integration_test.go index 55b3035868..b60e78fc72 100644 --- a/tests/cloudsqlmysql/cloud_sql_mysql_integration_test.go +++ b/tests/cloudsqlmysql/cloud_sql_mysql_integration_test.go @@ -33,8 +33,8 @@ import ( ) var ( - CloudSQLMySQLSourceKind = "cloud-sql-mysql" - CloudSQLMySQLToolKind = "mysql-sql" + CloudSQLMySQLSourceType = "cloud-sql-mysql" + CloudSQLMySQLToolType = "mysql-sql" CloudSQLMySQLProject = os.Getenv("CLOUD_SQL_MYSQL_PROJECT") CloudSQLMySQLRegion = os.Getenv("CLOUD_SQL_MYSQL_REGION") CloudSQLMySQLInstance = os.Getenv("CLOUD_SQL_MYSQL_INSTANCE") @@ -60,7 +60,7 @@ func getCloudSQLMySQLVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": CloudSQLMySQLSourceKind, + "type": CloudSQLMySQLSourceType, "project": CloudSQLMySQLProject, "instance": CloudSQLMySQLInstance, "region": CloudSQLMySQLRegion, @@ -129,10 +129,10 @@ func TestCloudSQLMySQLToolEndpoints(t *testing.T) { defer teardownTable2(t) // Write config into a file and pass it to command - toolsFile := tests.GetToolsConfig(sourceConfig, CloudSQLMySQLToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) + toolsFile := tests.GetToolsConfig(sourceConfig, CloudSQLMySQLToolType, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) toolsFile = tests.AddMySqlExecuteSqlConfig(t, toolsFile) tmplSelectCombined, tmplSelectFilterCombined := tests.GetMySQLTmplToolStatement() - toolsFile = tests.AddTemplateParamConfig(t, toolsFile, CloudSQLMySQLToolKind, tmplSelectCombined, tmplSelectFilterCombined, "") + toolsFile = tests.AddTemplateParamConfig(t, toolsFile, CloudSQLMySQLToolType, tmplSelectCombined, tmplSelectFilterCombined, "") toolsFile = tests.AddMySQLPrebuiltToolConfig(t, toolsFile) cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) @@ -186,7 +186,7 @@ func TestCloudSQLMySQLIpConnection(t *testing.T) { for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { sourceConfig["ipType"] = tc.ipType - err := tests.RunSourceConnectionTest(t, sourceConfig, CloudSQLMySQLToolKind) + err := tests.RunSourceConnectionTest(t, sourceConfig, CloudSQLMySQLToolType) if err != nil { t.Fatalf("Connection test failure: %s", err) } @@ -200,7 +200,7 @@ func TestCloudSQLMySQLIAMConnection(t *testing.T) { serviceAccountEmail, _, _ := strings.Cut(tests.ServiceAccountEmail, "@") noPassSourceConfig := map[string]any{ - "kind": CloudSQLMySQLSourceKind, + "type": CloudSQLMySQLSourceType, "project": CloudSQLMySQLProject, "instance": CloudSQLMySQLInstance, "region": CloudSQLMySQLRegion, @@ -208,7 +208,7 @@ func TestCloudSQLMySQLIAMConnection(t *testing.T) { "user": serviceAccountEmail, } noUserSourceConfig := map[string]any{ - "kind": CloudSQLMySQLSourceKind, + "type": CloudSQLMySQLSourceType, "project": CloudSQLMySQLProject, "instance": CloudSQLMySQLInstance, "region": CloudSQLMySQLRegion, @@ -216,7 +216,7 @@ func TestCloudSQLMySQLIAMConnection(t *testing.T) { "password": "random", } noUserNoPassSourceConfig := map[string]any{ - "kind": CloudSQLMySQLSourceKind, + "type": CloudSQLMySQLSourceType, "project": CloudSQLMySQLProject, "instance": CloudSQLMySQLInstance, "region": CloudSQLMySQLRegion, @@ -260,7 +260,7 @@ func TestCloudSQLMySQLIAMConnection(t *testing.T) { }, "tools": map[string]any{ "my-simple-tool": map[string]any{ - "kind": CloudSQLMySQLToolKind, + "type": CloudSQLMySQLToolType, "source": uniqueSourceName, "description": "Simple tool to test end to end functionality.", "statement": "SELECT 1;", diff --git a/tests/cloudsqlpg/cloud_sql_pg_create_instances_test.go b/tests/cloudsqlpg/cloud_sql_pg_create_instances_test.go index 85fb011085..aaef8f5bcc 100644 --- a/tests/cloudsqlpg/cloud_sql_pg_create_instances_test.go +++ b/tests/cloudsqlpg/cloud_sql_pg_create_instances_test.go @@ -36,7 +36,7 @@ import ( ) var ( - createInstanceToolKind = "cloud-sql-postgres-create-instance" + createInstanceToolType = "cloud-sql-postgres-create-instance" ) type createInstanceTransport struct { @@ -262,16 +262,16 @@ func getCreateInstanceToolsConfig() map[string]any { return map[string]any{ "sources": map[string]any{ "my-cloud-sql-source": map[string]any{ - "kind": "cloud-sql-admin", + "type": "cloud-sql-admin", }, }, "tools": map[string]any{ "create-instance-prod": map[string]any{ - "kind": createInstanceToolKind, + "type": createInstanceToolType, "source": "my-cloud-sql-source", }, "create-instance-dev": map[string]any{ - "kind": createInstanceToolKind, + "type": createInstanceToolType, "source": "my-cloud-sql-source", }, }, diff --git a/tests/cloudsqlpg/cloud_sql_pg_integration_test.go b/tests/cloudsqlpg/cloud_sql_pg_integration_test.go index dc8ecb27bf..e6340cb871 100644 --- a/tests/cloudsqlpg/cloud_sql_pg_integration_test.go +++ b/tests/cloudsqlpg/cloud_sql_pg_integration_test.go @@ -32,8 +32,8 @@ import ( ) var ( - CloudSQLPostgresSourceKind = "cloud-sql-postgres" - CloudSQLPostgresToolKind = "postgres-sql" + CloudSQLPostgresSourceType = "cloud-sql-postgres" + CloudSQLPostgresToolType = "postgres-sql" CloudSQLPostgresProject = os.Getenv("CLOUD_SQL_POSTGRES_PROJECT") CloudSQLPostgresRegion = os.Getenv("CLOUD_SQL_POSTGRES_REGION") CloudSQLPostgresInstance = os.Getenv("CLOUD_SQL_POSTGRES_INSTANCE") @@ -59,7 +59,7 @@ func getCloudSQLPgVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": CloudSQLPostgresSourceKind, + "type": CloudSQLPostgresSourceType, "project": CloudSQLPostgresProject, "instance": CloudSQLPostgresInstance, "region": CloudSQLPostgresRegion, @@ -137,14 +137,14 @@ func TestCloudSQLPgSimpleToolEndpoints(t *testing.T) { defer tearDownVectorTable(t) // Write config into a file and pass it to command - toolsFile := tests.GetToolsConfig(sourceConfig, CloudSQLPostgresToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) + toolsFile := tests.GetToolsConfig(sourceConfig, CloudSQLPostgresToolType, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) toolsFile = tests.AddExecuteSqlConfig(t, toolsFile, "postgres-execute-sql") tmplSelectCombined, tmplSelectFilterCombined := tests.GetPostgresSQLTmplToolStatement() - toolsFile = tests.AddTemplateParamConfig(t, toolsFile, CloudSQLPostgresToolKind, tmplSelectCombined, tmplSelectFilterCombined, "") + toolsFile = tests.AddTemplateParamConfig(t, toolsFile, CloudSQLPostgresToolType, tmplSelectCombined, tmplSelectFilterCombined, "") // Add semantic search tool config insertStmt, searchStmt := tests.GetPostgresVectorSearchStmts(vectorTableName) - toolsFile = tests.AddSemanticSearchConfig(t, toolsFile, CloudSQLPostgresToolKind, insertStmt, searchStmt) + toolsFile = tests.AddSemanticSearchConfig(t, toolsFile, CloudSQLPostgresToolType, insertStmt, searchStmt) toolsFile = tests.AddPostgresPrebuiltConfig(t, toolsFile) cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) @@ -217,7 +217,7 @@ func TestCloudSQLPgIpConnection(t *testing.T) { for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { sourceConfig["ipType"] = tc.ipType - err := tests.RunSourceConnectionTest(t, sourceConfig, CloudSQLPostgresToolKind) + err := tests.RunSourceConnectionTest(t, sourceConfig, CloudSQLPostgresToolType) if err != nil { t.Fatalf("Connection test failure: %s", err) } @@ -231,7 +231,7 @@ func TestCloudSQLPgIAMConnection(t *testing.T) { serviceAccountEmail := strings.TrimSuffix(tests.ServiceAccountEmail, ".gserviceaccount.com") noPassSourceConfig := map[string]any{ - "kind": CloudSQLPostgresSourceKind, + "type": CloudSQLPostgresSourceType, "project": CloudSQLPostgresProject, "instance": CloudSQLPostgresInstance, "region": CloudSQLPostgresRegion, @@ -240,7 +240,7 @@ func TestCloudSQLPgIAMConnection(t *testing.T) { } noUserSourceConfig := map[string]any{ - "kind": CloudSQLPostgresSourceKind, + "type": CloudSQLPostgresSourceType, "project": CloudSQLPostgresProject, "instance": CloudSQLPostgresInstance, "region": CloudSQLPostgresRegion, @@ -249,7 +249,7 @@ func TestCloudSQLPgIAMConnection(t *testing.T) { } noUserNoPassSourceConfig := map[string]any{ - "kind": CloudSQLPostgresSourceKind, + "type": CloudSQLPostgresSourceType, "project": CloudSQLPostgresProject, "instance": CloudSQLPostgresInstance, "region": CloudSQLPostgresRegion, @@ -278,7 +278,7 @@ func TestCloudSQLPgIAMConnection(t *testing.T) { } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - err := tests.RunSourceConnectionTest(t, tc.sourceConfig, CloudSQLPostgresToolKind) + err := tests.RunSourceConnectionTest(t, tc.sourceConfig, CloudSQLPostgresToolType) if err != nil { if tc.isErr { return diff --git a/tests/cloudsqlpg/cloud_sql_pg_upgrade_precheck_test.go b/tests/cloudsqlpg/cloud_sql_pg_upgrade_precheck_test.go index 7db191f5be..881e4bee15 100644 --- a/tests/cloudsqlpg/cloud_sql_pg_upgrade_precheck_test.go +++ b/tests/cloudsqlpg/cloud_sql_pg_upgrade_precheck_test.go @@ -35,7 +35,7 @@ import ( ) var ( - preCheckToolKind = "postgres-upgrade-precheck" + preCheckToolType = "postgres-upgrade-precheck" ) type preCheckTransport struct { @@ -264,13 +264,13 @@ func TestPreCheckToolEndpoints(t *testing.T) { name: "successful precheck - with warnings", toolName: "precheck-tool", body: `{"project": "p1", "instance": "instance-warnings", "targetDatabaseVersion": "POSTGRES_18"}`, - want: `{"preCheckResponse":[{"actionsRequired":["Check documentation."],"kind":"","message":"This is a warning.","messageType":"WARNING"}]}`, + want: `{"preCheckResponse":[{"actionsRequired":["Check documentation."],"type":"","message":"This is a warning.","messageType":"WARNING"}]}`, }, { name: "successful precheck - with errors", toolName: "precheck-tool", body: `{"project": "p1", "instance": "instance-errors", "targetDatabaseVersion": "POSTGRES_18"}`, - want: `{"preCheckResponse":[{"actionsRequired":["Fix this now."],"kind":"","message":"This is a critical error.","messageType":"ERROR"}]}`, + want: `{"preCheckResponse":[{"actionsRequired":["Fix this now."],"type":"","message":"This is a critical error.","messageType":"ERROR"}]}`, }, { name: "instance not found", @@ -368,12 +368,12 @@ func getPreCheckToolsConfig() map[string]any { return map[string]any{ "sources": map[string]any{ "my-cloud-sql-source": map[string]any{ - "kind": "cloud-sql-admin", + "type": "cloud-sql-admin", }, }, "tools": map[string]any{ "precheck-tool": map[string]any{ - "kind": preCheckToolKind, + "type": preCheckToolType, "source": "my-cloud-sql-source", "authRequired": []string{ "https://www.googleapis.com/auth/cloud-platform", diff --git a/tests/common.go b/tests/common.go index a567b5eae8..fb56159e51 100644 --- a/tests/common.go +++ b/tests/common.go @@ -24,7 +24,6 @@ import ( "strings" "testing" - "github.com/goccy/go-yaml" "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlmysql" @@ -34,7 +33,7 @@ import ( ) // GetToolsConfig returns a mock tools config file -func GetToolsConfig(sourceConfig map[string]any, toolKind, paramToolStatement, idParamToolStmt, nameParamToolStmt, arrayToolStatement, authToolStatement string) map[string]any { +func GetToolsConfig(sourceConfig map[string]any, toolType, paramToolStatement, idParamToolStmt, nameParamToolStmt, arrayToolStatement, authToolStatement string) map[string]any { // Write config into a file and pass it to command toolsFile := map[string]any{ "sources": map[string]any{ @@ -42,19 +41,19 @@ func GetToolsConfig(sourceConfig map[string]any, toolKind, paramToolStatement, i }, "authServices": map[string]any{ "my-google-auth": map[string]any{ - "kind": "google", + "type": "google", "clientId": ClientId, }, }, "tools": map[string]any{ "my-simple-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Simple tool to test end to end functionality.", "statement": "SELECT 1", }, "my-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test invocation with params.", "statement": paramToolStatement, @@ -72,7 +71,7 @@ func GetToolsConfig(sourceConfig map[string]any, toolKind, paramToolStatement, i }, }, "my-tool-by-id": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test invocation with params.", "statement": idParamToolStmt, @@ -85,7 +84,7 @@ func GetToolsConfig(sourceConfig map[string]any, toolKind, paramToolStatement, i }, }, "my-tool-by-name": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test invocation with params.", "statement": nameParamToolStmt, @@ -99,7 +98,7 @@ func GetToolsConfig(sourceConfig map[string]any, toolKind, paramToolStatement, i }, }, "my-array-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test invocation with array params.", "statement": arrayToolStatement, @@ -127,7 +126,7 @@ func GetToolsConfig(sourceConfig map[string]any, toolKind, paramToolStatement, i }, }, "my-auth-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test authenticated parameters.", // statement to auto-fill authenticated parameter @@ -147,7 +146,7 @@ func GetToolsConfig(sourceConfig map[string]any, toolKind, paramToolStatement, i }, }, "my-auth-required-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test auth required invocation.", "statement": "SELECT 1", @@ -156,7 +155,7 @@ func GetToolsConfig(sourceConfig map[string]any, toolKind, paramToolStatement, i }, }, "my-fail-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test statement with incorrect syntax.", "statement": "SELEC 1;", @@ -168,18 +167,18 @@ func GetToolsConfig(sourceConfig map[string]any, toolKind, paramToolStatement, i } // AddExecuteSqlConfig gets the tools config for `execute-sql` tools -func AddExecuteSqlConfig(t *testing.T, config map[string]any, toolKind string) map[string]any { +func AddExecuteSqlConfig(t *testing.T, config map[string]any, toolType string) map[string]any { tools, ok := config["tools"].(map[string]any) if !ok { t.Fatalf("unable to get tools from config") } tools["my-exec-sql-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to execute sql", } tools["my-auth-exec-sql-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to execute sql", "authRequired": []string{ @@ -192,28 +191,28 @@ func AddExecuteSqlConfig(t *testing.T, config map[string]any, toolKind string) m func AddPostgresPrebuiltConfig(t *testing.T, config map[string]any) map[string]any { var ( - PostgresListSchemasToolKind = "postgres-list-schemas" - PostgresListTablesToolKind = "postgres-list-tables" - PostgresListActiveQueriesToolKind = "postgres-list-active-queries" - PostgresListInstalledExtensionsToolKind = "postgres-list-installed-extensions" - PostgresListAvailableExtensionsToolKind = "postgres-list-available-extensions" - PostgresListViewsToolKind = "postgres-list-views" - PostgresDatabaseOverviewToolKind = "postgres-database-overview" - PostgresListTriggersToolKind = "postgres-list-triggers" - PostgresListIndexesToolKind = "postgres-list-indexes" - PostgresListSequencesToolKind = "postgres-list-sequences" - PostgresLongRunningTransactionsToolKind = "postgres-long-running-transactions" - PostgresListLocksToolKind = "postgres-list-locks" - PostgresReplicationStatsToolKind = "postgres-replication-stats" - PostgresListQueryStatsToolKind = "postgres-list-query-stats" - PostgresGetColumnCardinalityToolKind = "postgres-get-column-cardinality" + PostgresListSchemasToolType = "postgres-list-schemas" + PostgresListTablesToolType = "postgres-list-tables" + PostgresListActiveQueriesToolType = "postgres-list-active-queries" + PostgresListInstalledExtensionsToolType = "postgres-list-installed-extensions" + PostgresListAvailableExtensionsToolType = "postgres-list-available-extensions" + PostgresListViewsToolType = "postgres-list-views" + PostgresDatabaseOverviewToolType = "postgres-database-overview" + PostgresListTriggersToolType = "postgres-list-triggers" + PostgresListIndexesToolType = "postgres-list-indexes" + PostgresListSequencesToolType = "postgres-list-sequences" + PostgresLongRunningTransactionsToolType = "postgres-long-running-transactions" + PostgresListLocksToolType = "postgres-list-locks" + PostgresReplicationStatsToolType = "postgres-replication-stats" + PostgresListQueryStatsToolType = "postgres-list-query-stats" + PostgresGetColumnCardinalityToolType = "postgres-get-column-cardinality" PostgresListTableStats = "postgres-list-table-stats" - PostgresListPublicationTablesToolKind = "postgres-list-publication-tables" - PostgresListTablespacesToolKind = "postgres-list-tablespaces" - PostgresListPGSettingsToolKind = "postgres-list-pg-settings" - PostgresListDatabaseStatsToolKind = "postgres-list-database-stats" - PostgresListRolesToolKind = "postgres-list-roles" - PostgresListStoredProcedureToolKind = "postgres-list-stored-procedure" + PostgresListPublicationTablesToolType = "postgres-list-publication-tables" + PostgresListTablespacesToolType = "postgres-list-tablespaces" + PostgresListPGSettingsToolType = "postgres-list-pg-settings" + PostgresListDatabaseStatsToolType = "postgres-list-database-stats" + PostgresListRolesToolType = "postgres-list-roles" + PostgresListStoredProcedureToolType = "postgres-list-stored-procedure" ) tools, ok := config["tools"].(map[string]any) @@ -221,106 +220,106 @@ func AddPostgresPrebuiltConfig(t *testing.T, config map[string]any) map[string]a t.Fatalf("unable to get tools from config") } tools["list_tables"] = map[string]any{ - "kind": PostgresListTablesToolKind, + "type": PostgresListTablesToolType, "source": "my-instance", "description": "Lists tables in the database.", } tools["list_active_queries"] = map[string]any{ - "kind": PostgresListActiveQueriesToolKind, + "type": PostgresListActiveQueriesToolType, "source": "my-instance", "description": "Lists active queries in the database.", } tools["list_installed_extensions"] = map[string]any{ - "kind": PostgresListInstalledExtensionsToolKind, + "type": PostgresListInstalledExtensionsToolType, "source": "my-instance", "description": "Lists installed extensions in the database.", } tools["list_available_extensions"] = map[string]any{ - "kind": PostgresListAvailableExtensionsToolKind, + "type": PostgresListAvailableExtensionsToolType, "source": "my-instance", "description": "Lists available extensions in the database.", } tools["list_views"] = map[string]any{ - "kind": PostgresListViewsToolKind, + "type": PostgresListViewsToolType, "source": "my-instance", } tools["list_schemas"] = map[string]any{ - "kind": PostgresListSchemasToolKind, + "type": PostgresListSchemasToolType, "source": "my-instance", } tools["database_overview"] = map[string]any{ - "kind": PostgresDatabaseOverviewToolKind, + "type": PostgresDatabaseOverviewToolType, "source": "my-instance", } tools["list_triggers"] = map[string]any{ - "kind": PostgresListTriggersToolKind, + "type": PostgresListTriggersToolType, "source": "my-instance", } tools["list_indexes"] = map[string]any{ - "kind": PostgresListIndexesToolKind, + "type": PostgresListIndexesToolType, "source": "my-instance", } tools["list_sequences"] = map[string]any{ - "kind": PostgresListSequencesToolKind, + "type": PostgresListSequencesToolType, "source": "my-instance", } tools["list_publication_tables"] = map[string]any{ - "kind": PostgresListPublicationTablesToolKind, + "type": PostgresListPublicationTablesToolType, "source": "my-instance", } tools["long_running_transactions"] = map[string]any{ - "kind": PostgresLongRunningTransactionsToolKind, + "type": PostgresLongRunningTransactionsToolType, "source": "my-instance", } tools["list_locks"] = map[string]any{ - "kind": PostgresListLocksToolKind, + "type": PostgresListLocksToolType, "source": "my-instance", } tools["replication_stats"] = map[string]any{ - "kind": PostgresReplicationStatsToolKind, + "type": PostgresReplicationStatsToolType, "source": "my-instance", } tools["list_query_stats"] = map[string]any{ - "kind": PostgresListQueryStatsToolKind, + "type": PostgresListQueryStatsToolType, "source": "my-instance", } tools["get_column_cardinality"] = map[string]any{ - "kind": PostgresGetColumnCardinalityToolKind, + "type": PostgresGetColumnCardinalityToolType, "source": "my-instance", } tools["list_table_stats"] = map[string]any{ - "kind": PostgresListTableStats, + "type": PostgresListTableStats, "source": "my-instance", } tools["list_tablespaces"] = map[string]any{ - "kind": PostgresListTablespacesToolKind, + "type": PostgresListTablespacesToolType, "source": "my-instance", } tools["list_pg_settings"] = map[string]any{ - "kind": PostgresListPGSettingsToolKind, + "type": PostgresListPGSettingsToolType, "source": "my-instance", } tools["list_database_stats"] = map[string]any{ - "kind": PostgresListDatabaseStatsToolKind, + "type": PostgresListDatabaseStatsToolType, "source": "my-instance", } tools["list_roles"] = map[string]any{ - "kind": PostgresListRolesToolKind, + "type": PostgresListRolesToolType, "source": "my-instance", } tools["list_stored_procedure"] = map[string]any{ - "kind": PostgresListStoredProcedureToolKind, + "type": PostgresListStoredProcedureToolType, "source": "my-instance", } config["tools"] = tools return config } -func AddTemplateParamConfig(t *testing.T, config map[string]any, toolKind, tmplSelectCombined, tmplSelectFilterCombined string, tmplSelectAll string) map[string]any { +func AddTemplateParamConfig(t *testing.T, config map[string]any, toolType, tmplSelectCombined, tmplSelectFilterCombined string, tmplSelectAll string) map[string]any { toolsMap, ok := config["tools"].(map[string]any) if !ok { t.Fatalf("unable to get tools from config") @@ -332,7 +331,7 @@ func AddTemplateParamConfig(t *testing.T, config map[string]any, toolKind, tmplS } toolsMap["create-table-templateParams-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Create table tool with template parameters", "statement": "CREATE TABLE {{.tableName}} ({{array .columns}})", @@ -342,7 +341,7 @@ func AddTemplateParamConfig(t *testing.T, config map[string]any, toolKind, tmplS }, } toolsMap["insert-table-templateParams-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Insert tool with template parameters", "statement": "INSERT INTO {{.tableName}} ({{array .columns}}) VALUES ({{.values}})", @@ -353,7 +352,7 @@ func AddTemplateParamConfig(t *testing.T, config map[string]any, toolKind, tmplS }, } toolsMap["select-templateParams-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Create table tool with template parameters", "statement": selectAll, @@ -362,7 +361,7 @@ func AddTemplateParamConfig(t *testing.T, config map[string]any, toolKind, tmplS }, } toolsMap["select-templateParams-combined-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Create table tool with template parameters", "statement": tmplSelectCombined, @@ -372,7 +371,7 @@ func AddTemplateParamConfig(t *testing.T, config map[string]any, toolKind, tmplS }, } toolsMap["select-fields-templateParams-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Create table tool with template parameters", "statement": "SELECT {{array .fields}} FROM {{.tableName}} ORDER BY id", @@ -382,7 +381,7 @@ func AddTemplateParamConfig(t *testing.T, config map[string]any, toolKind, tmplS }, } toolsMap["select-filter-templateParams-combined-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Create table tool with template parameters", "statement": tmplSelectFilterCombined, @@ -393,7 +392,7 @@ func AddTemplateParamConfig(t *testing.T, config map[string]any, toolKind, tmplS }, } toolsMap["drop-table-templateParams-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Drop table tool with template parameters", "statement": "DROP TABLE IF EXISTS {{.tableName}}", @@ -412,12 +411,12 @@ func AddMySqlExecuteSqlConfig(t *testing.T, config map[string]any) map[string]an t.Fatalf("unable to get tools from config") } tools["my-exec-sql-tool"] = map[string]any{ - "kind": "mysql-execute-sql", + "type": "mysql-execute-sql", "source": "my-instance", "description": "Tool to execute sql", } tools["my-auth-exec-sql-tool"] = map[string]any{ - "kind": "mysql-execute-sql", + "type": "mysql-execute-sql", "source": "my-instance", "description": "Tool to execute sql", "authRequired": []string{ @@ -435,27 +434,27 @@ func AddMySQLPrebuiltToolConfig(t *testing.T, config map[string]any) map[string] t.Fatalf("unable to get tools from config") } tools["list_tables"] = map[string]any{ - "kind": "mysql-list-tables", + "type": "mysql-list-tables", "source": "my-instance", "description": "Lists tables in the database.", } tools["list_active_queries"] = map[string]any{ - "kind": "mysql-list-active-queries", + "type": "mysql-list-active-queries", "source": "my-instance", "description": "Lists active queries in the database.", } tools["list_tables_missing_unique_indexes"] = map[string]any{ - "kind": "mysql-list-tables-missing-unique-indexes", + "type": "mysql-list-tables-missing-unique-indexes", "source": "my-instance", "description": "Lists tables that do not have primary or unique indexes in the database.", } tools["list_table_fragmentation"] = map[string]any{ - "kind": "mysql-list-table-fragmentation", + "type": "mysql-list-table-fragmentation", "source": "my-instance", "description": "Lists table fragmentation in the database.", } tools["get_query_plan"] = map[string]any{ - "kind": "mysql-get-query-plan", + "type": "mysql-get-query-plan", "source": "my-instance", "description": "Gets the query plan for a SQL statement.", } @@ -470,12 +469,12 @@ func AddMSSQLExecuteSqlConfig(t *testing.T, config map[string]any) map[string]an t.Fatalf("unable to get tools from config") } tools["my-exec-sql-tool"] = map[string]any{ - "kind": "mssql-execute-sql", + "type": "mssql-execute-sql", "source": "my-instance", "description": "Tool to execute sql", } tools["my-auth-exec-sql-tool"] = map[string]any{ - "kind": "mssql-execute-sql", + "type": "mssql-execute-sql", "source": "my-instance", "description": "Tool to execute sql", "authRequired": []string{ @@ -493,7 +492,7 @@ func AddMSSQLPrebuiltToolConfig(t *testing.T, config map[string]any) map[string] t.Fatalf("unable to get tools from config") } tools["list_tables"] = map[string]any{ - "kind": "mssql-list-tables", + "type": "mssql-list-tables", "source": "my-instance", "description": "Lists tables in the database.", } @@ -501,7 +500,7 @@ func AddMSSQLPrebuiltToolConfig(t *testing.T, config map[string]any) map[string] return config } -// GetPostgresSQLParamToolInfo returns statements and param for my-tool postgres-sql kind +// GetPostgresSQLParamToolInfo returns statements and param for my-tool postgres-sql type func GetPostgresSQLParamToolInfo(tableName string) (string, string, string, string, string, string, []any) { createStatement := fmt.Sprintf("CREATE TABLE %s (id SERIAL PRIMARY KEY, name TEXT);", tableName) insertStatement := fmt.Sprintf("INSERT INTO %s (name) VALUES ($1), ($2), ($3), ($4);", tableName) @@ -513,7 +512,7 @@ func GetPostgresSQLParamToolInfo(tableName string) (string, string, string, stri return createStatement, insertStatement, toolStatement, idParamStatement, nameParamStatement, arrayToolStatement, params } -// GetPostgresSQLAuthToolInfo returns statements and param of my-auth-tool for postgres-sql kind +// GetPostgresSQLAuthToolInfo returns statements and param of my-auth-tool for postgres-sql type func GetPostgresSQLAuthToolInfo(tableName string) (string, string, string, []any) { createStatement := fmt.Sprintf("CREATE TABLE %s (id SERIAL PRIMARY KEY, name TEXT, email TEXT);", tableName) insertStatement := fmt.Sprintf("INSERT INTO %s (name, email) VALUES ($1, $2), ($3, $4)", tableName) @@ -522,14 +521,14 @@ func GetPostgresSQLAuthToolInfo(tableName string) (string, string, string, []any return createStatement, insertStatement, toolStatement, params } -// GetPostgresSQLTmplToolStatement returns statements and param for template parameter test cases for postgres-sql kind +// GetPostgresSQLTmplToolStatement returns statements and param for template parameter test cases for postgres-sql type func GetPostgresSQLTmplToolStatement() (string, string) { tmplSelectCombined := "SELECT * FROM {{.tableName}} WHERE id = $1" tmplSelectFilterCombined := "SELECT * FROM {{.tableName}} WHERE {{.columnFilter}} = $1" return tmplSelectCombined, tmplSelectFilterCombined } -// GetMSSQLParamToolInfo returns statements and param for my-tool mssql-sql kind +// GetMSSQLParamToolInfo returns statements and param for my-tool mssql-sql type func GetMSSQLParamToolInfo(tableName string) (string, string, string, string, string, string, []any) { createStatement := fmt.Sprintf("CREATE TABLE %s (id INT IDENTITY(1,1) PRIMARY KEY, name VARCHAR(255));", tableName) insertStatement := fmt.Sprintf("INSERT INTO %s (name) VALUES (@alice), (@jane), (@sid), (@nil);", tableName) @@ -541,7 +540,7 @@ func GetMSSQLParamToolInfo(tableName string) (string, string, string, string, st return createStatement, insertStatement, toolStatement, idParamStatement, nameParamStatement, arrayToolStatement, params } -// GetMSSQLAuthToolInfo returns statements and param of my-auth-tool for mssql-sql kind +// GetMSSQLAuthToolInfo returns statements and param of my-auth-tool for mssql-sql type func GetMSSQLAuthToolInfo(tableName string) (string, string, string, []any) { createStatement := fmt.Sprintf("CREATE TABLE %s (id INT IDENTITY(1,1) PRIMARY KEY, name VARCHAR(255), email VARCHAR(255));", tableName) insertStatement := fmt.Sprintf("INSERT INTO %s (name, email) VALUES (@alice, @aliceemail), (@jane, @janeemail);", tableName) @@ -550,14 +549,14 @@ func GetMSSQLAuthToolInfo(tableName string) (string, string, string, []any) { return createStatement, insertStatement, toolStatement, params } -// GetMSSQLTmplToolStatement returns statements and param for template parameter test cases for mysql-sql kind +// GetMSSQLTmplToolStatement returns statements and param for template parameter test cases for mysql-sql type func GetMSSQLTmplToolStatement() (string, string) { tmplSelectCombined := "SELECT * FROM {{.tableName}} WHERE id = @id" tmplSelectFilterCombined := "SELECT * FROM {{.tableName}} WHERE {{.columnFilter}} = @name" return tmplSelectCombined, tmplSelectFilterCombined } -// GetMySQLParamToolInfo returns statements and param for my-tool mysql-sql kind +// GetMySQLParamToolInfo returns statements and param for my-tool mysql-sql type func GetMySQLParamToolInfo(tableName string) (string, string, string, string, string, string, []any) { createStatement := fmt.Sprintf("CREATE TABLE %s (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255));", tableName) insertStatement := fmt.Sprintf("INSERT INTO %s (name) VALUES (?), (?), (?), (?);", tableName) @@ -569,7 +568,7 @@ func GetMySQLParamToolInfo(tableName string) (string, string, string, string, st return createStatement, insertStatement, toolStatement, idParamStatement, nameParamStatement, arrayToolStatement, params } -// GetMySQLAuthToolInfo returns statements and param of my-auth-tool for mysql-sql kind +// GetMySQLAuthToolInfo returns statements and param of my-auth-tool for mysql-sql type func GetMySQLAuthToolInfo(tableName string) (string, string, string, []any) { createStatement := fmt.Sprintf("CREATE TABLE %s (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), email VARCHAR(255));", tableName) insertStatement := fmt.Sprintf("INSERT INTO %s (name, email) VALUES (?, ?), (?, ?)", tableName) @@ -578,7 +577,7 @@ func GetMySQLAuthToolInfo(tableName string) (string, string, string, []any) { return createStatement, insertStatement, toolStatement, params } -// GetMySQLTmplToolStatement returns statements and param for template parameter test cases for mysql-sql kind +// GetMySQLTmplToolStatement returns statements and param for template parameter test cases for mysql-sql type func GetMySQLTmplToolStatement() (string, string) { tmplSelectCombined := "SELECT * FROM {{.tableName}} WHERE id = ?" tmplSelectFilterCombined := "SELECT * FROM {{.tableName}} WHERE {{.columnFilter}} = ?" @@ -711,26 +710,26 @@ func GetRedisValkeyWants() (string, string, string, string, string, string, stri return select1Want, mcpMyFailToolWant, invokeParamWant, invokeIdNullWant, nullWant, mcpSelect1Want, mcpInvokeParamWant } -func GetRedisValkeyToolsConfig(sourceConfig map[string]any, toolKind string) map[string]any { +func GetRedisValkeyToolsConfig(sourceConfig map[string]any, toolType string) map[string]any { toolsFile := map[string]any{ "sources": map[string]any{ "my-instance": sourceConfig, }, "authServices": map[string]any{ "my-google-auth": map[string]any{ - "kind": "google", + "type": "google", "clientId": ClientId, }, }, "tools": map[string]any{ "my-simple-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Simple tool to test end to end functionality.", "commands": [][]string{{"PING"}}, }, "my-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test invocation with params.", "commands": [][]string{{"HGETALL", "row1"}, {"HGETALL", "row3"}}, @@ -748,7 +747,7 @@ func GetRedisValkeyToolsConfig(sourceConfig map[string]any, toolKind string) map }, }, "my-tool-by-id": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test invocation with params.", "commands": [][]string{{"HGETALL", "row4"}}, @@ -761,7 +760,7 @@ func GetRedisValkeyToolsConfig(sourceConfig map[string]any, toolKind string) map }, }, "my-tool-by-name": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test invocation with params.", "commands": [][]string{{"GET", "null"}}, @@ -775,7 +774,7 @@ func GetRedisValkeyToolsConfig(sourceConfig map[string]any, toolKind string) map }, }, "my-array-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test invocation with array params.", "commands": [][]string{{"HGETALL", "row1"}, {"$cmdArray"}}, @@ -793,7 +792,7 @@ func GetRedisValkeyToolsConfig(sourceConfig map[string]any, toolKind string) map }, }, "my-auth-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test authenticated parameters.", // statement to auto-fill authenticated parameter @@ -813,7 +812,7 @@ func GetRedisValkeyToolsConfig(sourceConfig map[string]any, toolKind string) map }, }, "my-auth-required-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test auth required invocation.", "commands": [][]string{{"PING"}}, @@ -822,7 +821,7 @@ func GetRedisValkeyToolsConfig(sourceConfig map[string]any, toolKind string) map }, }, "my-fail-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test statement with incorrect syntax.", "commands": [][]string{{"SELEC 1;"}}, @@ -843,20 +842,20 @@ func TestCloudSQLMySQL_IPTypeParsingFromYAML(t *testing.T) { { desc: "IPType Defaulting to Public", in: ` - sources: - my-mysql-instance: - kind: cloud-sql-mysql - project: my-project - region: my-region - instance: my-instance - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-mysql-instance + type: cloud-sql-mysql + project: my-project + region: my-region + instance: my-instance + database: my_db + user: my_user + password: my_pass `, want: server.SourceConfigs{ "my-mysql-instance": cloudsqlmysql.Config{ Name: "my-mysql-instance", - Kind: cloudsqlmysql.SourceKind, + Type: cloudsqlmysql.SourceType, Project: "my-project", Region: "my-region", Instance: "my-instance", @@ -870,21 +869,21 @@ func TestCloudSQLMySQL_IPTypeParsingFromYAML(t *testing.T) { { desc: "IPType Explicit Public", in: ` - sources: - my-mysql-instance: - kind: cloud-sql-mysql - project: my-project - region: my-region - instance: my-instance - ipType: Public - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-mysql-instance + type: cloud-sql-mysql + project: my-project + region: my-region + instance: my-instance + ipType: Public + database: my_db + user: my_user + password: my_pass `, want: server.SourceConfigs{ "my-mysql-instance": cloudsqlmysql.Config{ Name: "my-mysql-instance", - Kind: cloudsqlmysql.SourceKind, + Type: cloudsqlmysql.SourceType, Project: "my-project", Region: "my-region", Instance: "my-instance", @@ -898,21 +897,21 @@ func TestCloudSQLMySQL_IPTypeParsingFromYAML(t *testing.T) { { desc: "IPType Explicit Private", in: ` - sources: - my-mysql-instance: - kind: cloud-sql-mysql - project: my-project - region: my-region - instance: my-instance - ipType: private - database: my_db - user: my_user - password: my_pass + kind: sources + name: my-mysql-instance + type: cloud-sql-mysql + project: my-project + region: my-region + instance: my-instance + ipType: private + database: my_db + user: my_user + password: my_pass `, want: server.SourceConfigs{ "my-mysql-instance": cloudsqlmysql.Config{ Name: "my-mysql-instance", - Kind: cloudsqlmysql.SourceKind, + Type: cloudsqlmysql.SourceType, Project: "my-project", Region: "my-region", Instance: "my-instance", @@ -926,16 +925,12 @@ func TestCloudSQLMySQL_IPTypeParsingFromYAML(t *testing.T) { } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) { - got := struct { - Sources server.SourceConfigs `yaml:"sources"` - }{} - // Parse contents - err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got) + got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in)) if err != nil { t.Fatalf("unable to unmarshal: %s", err) } - if !cmp.Equal(tc.want, got.Sources) { - t.Fatalf("incorrect parse: diff (-want +got):\n%s", cmp.Diff(tc.want, got.Sources)) + if !cmp.Equal(tc.want, got) { + t.Fatalf("incorrect parse: diff (-want +got):\n%s", cmp.Diff(tc.want, got)) } }) } diff --git a/tests/couchbase/couchbase_integration_test.go b/tests/couchbase/couchbase_integration_test.go index fcb0493c32..d78c71b82d 100644 --- a/tests/couchbase/couchbase_integration_test.go +++ b/tests/couchbase/couchbase_integration_test.go @@ -30,8 +30,8 @@ import ( ) const ( - couchbaseSourceKind = "couchbase" - couchbaseToolKind = "couchbase-sql" + couchbaseSourceType = "couchbase" + couchbaseToolType = "couchbase-sql" ) var ( @@ -58,7 +58,7 @@ func getCouchbaseVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": couchbaseSourceKind, + "type": couchbaseSourceType, "connectionString": couchbaseConnection, "bucket": couchbaseBucket, "scope": couchbaseScope, @@ -118,8 +118,8 @@ func TestCouchbaseToolEndpoints(t *testing.T) { defer teardownCollection3(t) // Write config into a file and pass it to command - toolsFile := tests.GetToolsConfig(sourceConfig, couchbaseToolKind, paramToolStatement, idParamToolStmt, nameParamToolStmt, arrayToolStatement, authToolStatement) - toolsFile = tests.AddTemplateParamConfig(t, toolsFile, couchbaseToolKind, tmplSelectCombined, tmplSelectFilterCombined, tmplSelectAll) + toolsFile := tests.GetToolsConfig(sourceConfig, couchbaseToolType, paramToolStatement, idParamToolStmt, nameParamToolStmt, arrayToolStatement, authToolStatement) + toolsFile = tests.AddTemplateParamConfig(t, toolsFile, couchbaseToolType, tmplSelectCombined, tmplSelectFilterCombined, tmplSelectAll) cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) if err != nil { @@ -231,7 +231,7 @@ func setupCouchbaseCollection(t *testing.T, ctx context.Context, cluster *gocb.C } } -// getCouchbaseParamToolInfo returns statements and params for my-tool couchbase-sql kind +// getCouchbaseParamToolInfo returns statements and params for my-tool couchbase-sql type func getCouchbaseParamToolInfo(collectionName string) (string, string, string, string, []map[string]any) { // N1QL uses positional or named parameters with $ prefix toolStatement := fmt.Sprintf("SELECT TONUMBER(meta().id) as id, "+ @@ -254,7 +254,7 @@ func getCouchbaseParamToolInfo(collectionName string) (string, string, string, s return toolStatement, idToolStatement, nameToolStatement, arrayToolStatemnt, params } -// getCouchbaseAuthToolInfo returns statements and param of my-auth-tool for couchbase-sql kind +// getCouchbaseAuthToolInfo returns statements and param of my-auth-tool for couchbase-sql type func getCouchbaseAuthToolInfo(collectionName string) (string, []map[string]any) { toolStatement := fmt.Sprintf("SELECT name FROM %s WHERE email = $email", collectionName) diff --git a/tests/dataform/dataform_integration_test.go b/tests/dataform/dataform_integration_test.go index c7218f1d02..d235998359 100644 --- a/tests/dataform/dataform_integration_test.go +++ b/tests/dataform/dataform_integration_test.go @@ -69,7 +69,7 @@ func TestDataformCompileTool(t *testing.T) { toolsFile := map[string]any{ "tools": map[string]any{ "my-dataform-compiler": map[string]any{ - "kind": "dataform-compile-local", + "type": "dataform-compile-local", "description": "Tool to compile dataform projects", }, }, diff --git a/tests/dataplex/dataplex_integration_test.go b/tests/dataplex/dataplex_integration_test.go index 4466a50cf8..1dcd72aeb3 100644 --- a/tests/dataplex/dataplex_integration_test.go +++ b/tests/dataplex/dataplex_integration_test.go @@ -40,10 +40,10 @@ import ( ) var ( - DataplexSourceKind = "dataplex" - DataplexSearchEntriesToolKind = "dataplex-search-entries" - DataplexLookupEntryToolKind = "dataplex-lookup-entry" - DataplexSearchAspectTypesToolKind = "dataplex-search-aspect-types" + DataplexSourceType = "dataplex" + DataplexSearchEntriesToolType = "dataplex-search-entries" + DataplexLookupEntryToolType = "dataplex-lookup-entry" + DataplexSearchAspectTypesToolType = "dataplex-search-aspect-types" DataplexProject = os.Getenv("DATAPLEX_PROJECT") ) @@ -53,7 +53,7 @@ func getDataplexVars(t *testing.T) map[string]any { t.Fatal("'DATAPLEX_PROJECT' not set") } return map[string]any{ - "kind": DataplexSourceKind, + "type": DataplexSourceType, "project": DataplexProject, } } @@ -283,40 +283,40 @@ func getDataplexToolsConfig(sourceConfig map[string]any) map[string]any { }, "authServices": map[string]any{ "my-google-auth": map[string]any{ - "kind": "google", + "type": "google", "clientId": tests.ClientId, }, }, "tools": map[string]any{ "my-dataplex-search-entries-tool": map[string]any{ - "kind": DataplexSearchEntriesToolKind, + "type": DataplexSearchEntriesToolType, "source": "my-dataplex-instance", "description": "Simple dataplex search entries tool to test end to end functionality.", }, "my-auth-dataplex-search-entries-tool": map[string]any{ - "kind": DataplexSearchEntriesToolKind, + "type": DataplexSearchEntriesToolType, "source": "my-dataplex-instance", "description": "Simple dataplex search entries tool to test end to end functionality.", "authRequired": []string{"my-google-auth"}, }, "my-dataplex-lookup-entry-tool": map[string]any{ - "kind": DataplexLookupEntryToolKind, + "type": DataplexLookupEntryToolType, "source": "my-dataplex-instance", "description": "Simple dataplex lookup entry tool to test end to end functionality.", }, "my-auth-dataplex-lookup-entry-tool": map[string]any{ - "kind": DataplexLookupEntryToolKind, + "type": DataplexLookupEntryToolType, "source": "my-dataplex-instance", "description": "Simple dataplex lookup entry tool to test end to end functionality.", "authRequired": []string{"my-google-auth"}, }, "my-dataplex-search-aspect-types-tool": map[string]any{ - "kind": DataplexSearchAspectTypesToolKind, + "type": DataplexSearchAspectTypesToolType, "source": "my-dataplex-instance", "description": "Simple dataplex search aspect types tool to test end to end functionality.", }, "my-auth-dataplex-search-aspect-types-tool": map[string]any{ - "kind": DataplexSearchAspectTypesToolKind, + "type": DataplexSearchAspectTypesToolType, "source": "my-dataplex-instance", "description": "Simple dataplex search aspect types tool to test end to end functionality.", "authRequired": []string{"my-google-auth"}, diff --git a/tests/dgraph/dgraph_integration_test.go b/tests/dgraph/dgraph_integration_test.go index f27cd8dab1..17e17358ba 100644 --- a/tests/dgraph/dgraph_integration_test.go +++ b/tests/dgraph/dgraph_integration_test.go @@ -31,7 +31,7 @@ import ( ) var ( - DgraphSourceKind = "dgraph" + DgraphSourceType = "dgraph" DgraphApiKey = "api-key" DgraphUrl = os.Getenv("DGRAPH_URL") ) @@ -41,7 +41,7 @@ func getDgraphVars(t *testing.T) map[string]any { t.Fatal("'DGRAPH_URL' not set") } return map[string]any{ - "kind": DgraphSourceKind, + "type": DgraphSourceType, "dgraphUrl": DgraphUrl, "apiKey": DgraphApiKey, } @@ -61,7 +61,7 @@ func TestDgraphToolEndpoints(t *testing.T) { }, "tools": map[string]any{ "my-simple-dql-tool": map[string]any{ - "kind": "dgraph-dql", + "type": "dgraph-dql", "source": "my-dgraph-instance", "description": "Simple tool to test end to end functionality.", "statement": "{result(func: uid(0x0)) {constant: math(1)}}", diff --git a/tests/elasticsearch/elasticsearch_integration_test.go b/tests/elasticsearch/elasticsearch_integration_test.go index 16a7b39b7b..bd451339c5 100644 --- a/tests/elasticsearch/elasticsearch_integration_test.go +++ b/tests/elasticsearch/elasticsearch_integration_test.go @@ -31,8 +31,8 @@ import ( ) var ( - ElasticsearchSourceKind = "elasticsearch" - ElasticsearchToolKind = "elasticsearch-esql" + ElasticsearchSourceType = "elasticsearch" + ElasticsearchToolType = "elasticsearch-esql" EsAddress = os.Getenv("ELASTICSEARCH_HOST") EsUser = os.Getenv("ELASTICSEARCH_USER") EsPass = os.Getenv("ELASTICSEARCH_PASS") @@ -43,7 +43,7 @@ func getElasticsearchVars(t *testing.T) map[string]any { t.Fatal("'ELASTICSEARCH_HOST' not set") } return map[string]any{ - "kind": ElasticsearchSourceKind, + "type": ElasticsearchSourceType, "addresses": []string{EsAddress}, "username": EsUser, "password": EsPass, @@ -72,7 +72,7 @@ func TestElasticsearchToolEndpoints(t *testing.T) { paramToolStatement, idParamToolStatement, nameParamToolStatement, arrayParamToolStatement, authToolStatement := getElasticsearchQueries(index) - toolsConfig := getElasticsearchToolsConfig(sourceConfig, ElasticsearchToolKind, paramToolStatement, idParamToolStatement, nameParamToolStatement, arrayParamToolStatement, authToolStatement) + toolsConfig := getElasticsearchToolsConfig(sourceConfig, ElasticsearchToolType, paramToolStatement, idParamToolStatement, nameParamToolStatement, arrayParamToolStatement, authToolStatement) cmd, cleanup, err := tests.StartCmd(ctx, toolsConfig, args...) if err != nil { @@ -177,26 +177,26 @@ func getElasticsearchWants() ElasticsearchWants { } } -func getElasticsearchToolsConfig(sourceConfig map[string]any, toolKind, paramToolStatement, idParamToolStmt, nameParamToolStmt, arrayToolStatement, authToolStatement string) map[string]any { +func getElasticsearchToolsConfig(sourceConfig map[string]any, toolType, paramToolStatement, idParamToolStmt, nameParamToolStmt, arrayToolStatement, authToolStatement string) map[string]any { toolsFile := map[string]any{ "sources": map[string]any{ "my-instance": sourceConfig, }, "authServices": map[string]any{ "my-google-auth": map[string]any{ - "kind": "google", + "type": "google", "clientId": tests.ClientId, }, }, "tools": map[string]any{ "my-simple-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Simple tool to test end to end functionality.", "query": "FROM test-index | SORT id ASC", }, "my-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test invocation with params.", "query": paramToolStatement, @@ -214,7 +214,7 @@ func getElasticsearchToolsConfig(sourceConfig map[string]any, toolKind, paramToo }, }, "my-tool-by-id": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test invocation with params.", "query": idParamToolStmt, @@ -227,7 +227,7 @@ func getElasticsearchToolsConfig(sourceConfig map[string]any, toolKind, paramToo }, }, "my-tool-by-name": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test invocation with params.", "query": nameParamToolStmt, @@ -241,7 +241,7 @@ func getElasticsearchToolsConfig(sourceConfig map[string]any, toolKind, paramToo }, }, "my-array-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test invocation with array params.", "query": arrayToolStatement, @@ -269,7 +269,7 @@ func getElasticsearchToolsConfig(sourceConfig map[string]any, toolKind, paramToo }, }, "my-auth-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test authenticated parameters.", // statement to auto-fill authenticated parameter @@ -289,7 +289,7 @@ func getElasticsearchToolsConfig(sourceConfig map[string]any, toolKind, paramToo }, }, "my-auth-required-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test auth required invocation.", "query": "FROM test-index | SORT id ASC", @@ -298,7 +298,7 @@ func getElasticsearchToolsConfig(sourceConfig map[string]any, toolKind, paramToo }, }, "my-fail-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test statement with incorrect syntax.", "query": "SELEC 1;", diff --git a/tests/firebird/firebird_integration_test.go b/tests/firebird/firebird_integration_test.go index af0246d11c..256b6e7e66 100644 --- a/tests/firebird/firebird_integration_test.go +++ b/tests/firebird/firebird_integration_test.go @@ -32,8 +32,8 @@ import ( ) var ( - FirebirdSourceKind = "firebird" - FirebirdToolKind = "firebird-sql" + FirebirdSourceType = "firebird" + FirebirdToolType = "firebird-sql" FirebirdDatabase = os.Getenv("FIREBIRD_DATABASE") FirebirdHost = os.Getenv("FIREBIRD_HOST") FirebirdPort = os.Getenv("FIREBIRD_PORT") @@ -56,7 +56,7 @@ func getFirebirdVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": FirebirdSourceKind, + "type": FirebirdSourceType, "host": FirebirdHost, "port": FirebirdPort, "database": FirebirdDatabase, @@ -107,10 +107,10 @@ func TestFirebirdToolEndpoints(t *testing.T) { teardownTable2 := setupFirebirdTable(t, ctx, db, createAuthTableStmts, insertAuthTableStmt, tableNameAuth, authTestParams) defer teardownTable2(t) - toolsFile := getFirebirdToolsConfig(sourceConfig, FirebirdToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) + toolsFile := getFirebirdToolsConfig(sourceConfig, FirebirdToolType, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) toolsFile = addFirebirdExecuteSqlConfig(t, toolsFile) tmplSelectCombined, tmplSelectFilterCombined := getFirebirdTmplToolStatement() - toolsFile = addFirebirdTemplateParamConfig(t, toolsFile, FirebirdToolKind, tmplSelectCombined, tmplSelectFilterCombined) + toolsFile = addFirebirdTemplateParamConfig(t, toolsFile, FirebirdToolType, tmplSelectCombined, tmplSelectFilterCombined) cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) if err != nil { @@ -311,8 +311,8 @@ func getFirebirdWants() (string, string, string, string) { return select1Want, mcpMyFailToolWant, createTableStatement, mcpSelect1Want } -func getFirebirdToolsConfig(sourceConfig map[string]any, toolKind, paramToolStatement, idParamToolStmt, nameParamToolStmt, arrayToolStatement, authToolStatement string) map[string]any { - toolsFile := tests.GetToolsConfig(sourceConfig, toolKind, paramToolStatement, idParamToolStmt, nameParamToolStmt, arrayToolStatement, authToolStatement) +func getFirebirdToolsConfig(sourceConfig map[string]any, toolType, paramToolStatement, idParamToolStmt, nameParamToolStmt, arrayToolStatement, authToolStatement string) map[string]any { + toolsFile := tests.GetToolsConfig(sourceConfig, toolType, paramToolStatement, idParamToolStmt, nameParamToolStmt, arrayToolStatement, authToolStatement) toolsMap, ok := toolsFile["tools"].(map[string]any) if !ok { @@ -350,7 +350,7 @@ func getFirebirdToolsConfig(sourceConfig map[string]any, toolKind, paramToolStat return toolsFile } -func addFirebirdTemplateParamConfig(t *testing.T, config map[string]any, toolKind, tmplSelectCombined, tmplSelectFilterCombined string) map[string]any { +func addFirebirdTemplateParamConfig(t *testing.T, config map[string]any, toolType, tmplSelectCombined, tmplSelectFilterCombined string) map[string]any { toolsMap, ok := config["tools"].(map[string]any) if !ok { t.Fatalf("unable to get tools from config") @@ -358,7 +358,7 @@ func addFirebirdTemplateParamConfig(t *testing.T, config map[string]any, toolKin // Firebird-specific template parameter tools with compatible syntax toolsMap["create-table-templateParams-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Create table tool with template parameters", "statement": "CREATE TABLE {{.tableName}} ({{array .columns}})", @@ -368,7 +368,7 @@ func addFirebirdTemplateParamConfig(t *testing.T, config map[string]any, toolKin }, } toolsMap["insert-table-templateParams-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Insert table tool with template parameters", "statement": "INSERT INTO {{.tableName}} ({{array .columns}}) VALUES ({{.values}})", @@ -379,7 +379,7 @@ func addFirebirdTemplateParamConfig(t *testing.T, config map[string]any, toolKin }, } toolsMap["select-templateParams-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Select table tool with template parameters", "statement": "SELECT id AS \"id\", name AS \"name\", age AS \"age\" FROM {{.tableName}}", @@ -388,7 +388,7 @@ func addFirebirdTemplateParamConfig(t *testing.T, config map[string]any, toolKin }, } toolsMap["select-templateParams-combined-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Select table tool with combined template parameters", "statement": tmplSelectCombined, @@ -400,7 +400,7 @@ func addFirebirdTemplateParamConfig(t *testing.T, config map[string]any, toolKin }, } toolsMap["select-fields-templateParams-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Select specific fields tool with template parameters", "statement": "SELECT name AS \"name\" FROM {{.tableName}}", @@ -409,7 +409,7 @@ func addFirebirdTemplateParamConfig(t *testing.T, config map[string]any, toolKin }, } toolsMap["select-filter-templateParams-combined-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Select table tool with filter template parameters", "statement": tmplSelectFilterCombined, @@ -423,7 +423,7 @@ func addFirebirdTemplateParamConfig(t *testing.T, config map[string]any, toolKin } // Firebird uses simple DROP TABLE syntax without IF EXISTS toolsMap["drop-table-templateParams-tool"] = map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Drop table tool with template parameters", "statement": "DROP TABLE {{.tableName}}", @@ -441,12 +441,12 @@ func addFirebirdExecuteSqlConfig(t *testing.T, config map[string]any) map[string t.Fatalf("unable to get tools from config") } tools["my-exec-sql-tool"] = map[string]any{ - "kind": "firebird-execute-sql", + "type": "firebird-execute-sql", "source": "my-instance", "description": "Tool to execute sql", } tools["my-auth-exec-sql-tool"] = map[string]any{ - "kind": "firebird-execute-sql", + "type": "firebird-execute-sql", "source": "my-instance", "description": "Tool to execute sql", "authRequired": []string{ diff --git a/tests/firestore/firestore_integration_test.go b/tests/firestore/firestore_integration_test.go index 5b1610e01a..53bf90f657 100644 --- a/tests/firestore/firestore_integration_test.go +++ b/tests/firestore/firestore_integration_test.go @@ -37,7 +37,7 @@ import ( ) var ( - FirestoreSourceKind = "firestore" + FirestoreSourceType = "firestore" FirestoreProject = os.Getenv("FIRESTORE_PROJECT") FirestoreDatabase = os.Getenv("FIRESTORE_DATABASE") // Optional, defaults to "(default)" ) @@ -48,7 +48,7 @@ func getFirestoreVars(t *testing.T) map[string]any { } vars := map[string]any{ - "kind": FirestoreSourceKind, + "type": FirestoreSourceType, "project": FirestoreProject, } @@ -527,45 +527,45 @@ func getFirestoreToolsConfig(sourceConfig map[string]any) map[string]any { tools := map[string]any{ // Tool for RunToolGetTest "my-simple-tool": map[string]any{ - "kind": "firestore-get-documents", + "type": "firestore-get-documents", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, // Tool for MCP test - this will get documents "my-param-tool": map[string]any{ - "kind": "firestore-get-documents", + "type": "firestore-get-documents", "source": "my-instance", "description": "Tool to get documents by paths", }, // Tool for MCP test that fails "my-fail-tool": map[string]any{ - "kind": "firestore-get-documents", + "type": "firestore-get-documents", "source": "my-instance", "description": "Tool that will fail", }, // Firestore specific tools "firestore-get-docs": map[string]any{ - "kind": "firestore-get-documents", + "type": "firestore-get-documents", "source": "my-instance", "description": "Get multiple documents from Firestore", }, "firestore-list-colls": map[string]any{ - "kind": "firestore-list-collections", + "type": "firestore-list-collections", "source": "my-instance", "description": "List Firestore collections", }, "firestore-delete-docs": map[string]any{ - "kind": "firestore-delete-documents", + "type": "firestore-delete-documents", "source": "my-instance", "description": "Delete documents from Firestore", }, "firestore-query-coll": map[string]any{ - "kind": "firestore-query-collection", + "type": "firestore-query-collection", "source": "my-instance", "description": "Query a Firestore collection", }, "firestore-query-param": map[string]any{ - "kind": "firestore-query", + "type": "firestore-query", "source": "my-instance", "description": "Query a Firestore collection with parameterizable filters", "collectionPath": "{{.collection}}", @@ -595,7 +595,7 @@ func getFirestoreToolsConfig(sourceConfig map[string]any) map[string]any { }, }, "firestore-query-select-array": map[string]any{ - "kind": "firestore-query", + "type": "firestore-query", "source": "my-instance", "description": "Query with array-based select fields", "collectionPath": "{{.collection}}", @@ -622,22 +622,22 @@ func getFirestoreToolsConfig(sourceConfig map[string]any) map[string]any { }, }, "firestore-get-rules": map[string]any{ - "kind": "firestore-get-rules", + "type": "firestore-get-rules", "source": "my-instance", "description": "Get Firestore security rules", }, "firestore-validate-rules": map[string]any{ - "kind": "firestore-validate-rules", + "type": "firestore-validate-rules", "source": "my-instance", "description": "Validate Firestore security rules", }, "firestore-add-docs": map[string]any{ - "kind": "firestore-add-documents", + "type": "firestore-add-documents", "source": "my-instance", "description": "Add documents to Firestore", }, "firestore-update-doc": map[string]any{ - "kind": "firestore-update-document", + "type": "firestore-update-document", "source": "my-instance", "description": "Update a document in Firestore", }, diff --git a/tests/http/http_integration_test.go b/tests/http/http_integration_test.go index dcaab03011..eb928f3d8d 100644 --- a/tests/http/http_integration_test.go +++ b/tests/http/http_integration_test.go @@ -34,8 +34,8 @@ import ( ) var ( - HttpSourceKind = "http" - HttpToolKind = "http" + HttpSourceType = "http" + HttpToolType = "http" ) func getHTTPSourceConfig(t *testing.T) map[string]any { @@ -46,7 +46,7 @@ func getHTTPSourceConfig(t *testing.T) map[string]any { idToken = "Bearer " + idToken return map[string]any{ - "kind": HttpSourceKind, + "type": HttpSourceType, "headers": map[string]string{"Authorization": idToken}, } } @@ -309,7 +309,7 @@ func TestHttpToolEndpoints(t *testing.T) { var args []string - toolsFile := getHTTPToolsConfig(sourceConfig, HttpToolKind) + toolsFile := getHTTPToolsConfig(sourceConfig, HttpToolType) cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) if err != nil { t.Fatalf("command initialization returned an error: %s", err) @@ -475,7 +475,7 @@ func runAdvancedHTTPInvokeTest(t *testing.T) { } // getHTTPToolsConfig returns a mock HTTP tool's config file -func getHTTPToolsConfig(sourceConfig map[string]any, toolKind string) map[string]any { +func getHTTPToolsConfig(sourceConfig map[string]any, toolType string) map[string]any { // Write config into a file and pass it to command otherSourceConfig := make(map[string]any) for k, v := range sourceConfig { @@ -491,13 +491,13 @@ func getHTTPToolsConfig(sourceConfig map[string]any, toolKind string) map[string }, "authServices": map[string]any{ "my-google-auth": map[string]any{ - "kind": "google", + "type": "google", "clientId": tests.ClientId, }, }, "tools": map[string]any{ "my-simple-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "path": "/tool0", "method": "POST", "source": "my-instance", @@ -505,7 +505,7 @@ func getHTTPToolsConfig(sourceConfig map[string]any, toolKind string) map[string "description": "Simple tool to test end to end functionality.", }, "my-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "method": "GET", "path": "/tool1", @@ -521,7 +521,7 @@ func getHTTPToolsConfig(sourceConfig map[string]any, toolKind string) map[string "headers": map[string]string{"Content-Type": "application/json"}, }, "my-tool-by-id": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "method": "GET", "path": "/tool1id", @@ -531,7 +531,7 @@ func getHTTPToolsConfig(sourceConfig map[string]any, toolKind string) map[string "headers": map[string]string{"Content-Type": "application/json"}, }, "my-tool-by-name": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "method": "GET", "path": "/tool1name", @@ -541,7 +541,7 @@ func getHTTPToolsConfig(sourceConfig map[string]any, toolKind string) map[string "headers": map[string]string{"Content-Type": "application/json"}, }, "my-query-param-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "method": "GET", "path": "/toolQueryTest", @@ -553,7 +553,7 @@ func getHTTPToolsConfig(sourceConfig map[string]any, toolKind string) map[string }, }, "my-auth-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "method": "GET", "path": "/tool2", @@ -565,7 +565,7 @@ func getHTTPToolsConfig(sourceConfig map[string]any, toolKind string) map[string }, }, "my-auth-required-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "method": "POST", "path": "/tool0", @@ -574,7 +574,7 @@ func getHTTPToolsConfig(sourceConfig map[string]any, toolKind string) map[string "authRequired": []string{"my-google-auth"}, }, "my-advanced-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "other-instance", "method": "get", "path": "/{{.path}}?id=2", diff --git a/tests/looker/looker_integration_test.go b/tests/looker/looker_integration_test.go index c360455907..944cbcb926 100644 --- a/tests/looker/looker_integration_test.go +++ b/tests/looker/looker_integration_test.go @@ -36,7 +36,7 @@ import ( ) var ( - LookerSourceKind = "looker" + LookerSourceType = "looker" LookerBaseUrl = os.Getenv("LOOKER_BASE_URL") LookerVerifySsl = os.Getenv("LOOKER_VERIFY_SSL") LookerClientId = os.Getenv("LOOKER_CLIENT_ID") @@ -62,7 +62,7 @@ func getLookerVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": LookerSourceKind, + "type": LookerSourceType, "base_url": LookerBaseUrl, "verify_ssl": (LookerVerifySsl == "true"), "client_id": LookerClientId, @@ -93,162 +93,162 @@ func TestLooker(t *testing.T) { }, "tools": map[string]any{ "get_models": map[string]any{ - "kind": "looker-get-models", + "type": "looker-get-models", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "get_explores": map[string]any{ - "kind": "looker-get-explores", + "type": "looker-get-explores", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "get_dimensions": map[string]any{ - "kind": "looker-get-dimensions", + "type": "looker-get-dimensions", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "get_measures": map[string]any{ - "kind": "looker-get-measures", + "type": "looker-get-measures", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "get_filters": map[string]any{ - "kind": "looker-get-filters", + "type": "looker-get-filters", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "get_parameters": map[string]any{ - "kind": "looker-get-parameters", + "type": "looker-get-parameters", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "query": map[string]any{ - "kind": "looker-query", + "type": "looker-query", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "query_sql": map[string]any{ - "kind": "looker-query-sql", + "type": "looker-query-sql", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "query_url": map[string]any{ - "kind": "looker-query-url", + "type": "looker-query-url", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "get_looks": map[string]any{ - "kind": "looker-get-looks", + "type": "looker-get-looks", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "make_look": map[string]any{ - "kind": "looker-make-look", + "type": "looker-make-look", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "get_dashboards": map[string]any{ - "kind": "looker-get-dashboards", + "type": "looker-get-dashboards", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "make_dashboard": map[string]any{ - "kind": "looker-make-dashboard", + "type": "looker-make-dashboard", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "add_dashboard_filter": map[string]any{ - "kind": "looker-add-dashboard-filter", + "type": "looker-add-dashboard-filter", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "add_dashboard_element": map[string]any{ - "kind": "looker-add-dashboard-element", + "type": "looker-add-dashboard-element", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "conversational_analytics": map[string]any{ - "kind": "looker-conversational-analytics", + "type": "looker-conversational-analytics", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "health_pulse": map[string]any{ - "kind": "looker-health-pulse", + "type": "looker-health-pulse", "source": "my-instance", "description": "Checks the health of a Looker instance by running a series of checks on the system.", }, "health_analyze": map[string]any{ - "kind": "looker-health-analyze", + "type": "looker-health-analyze", "source": "my-instance", "description": "Provides analysis of a Looker instance's projects, models, or explores.", }, "health_vacuum": map[string]any{ - "kind": "looker-health-vacuum", + "type": "looker-health-vacuum", "source": "my-instance", "description": "Vacuums unused content from a Looker instance.", }, "dev_mode": map[string]any{ - "kind": "looker-dev-mode", + "type": "looker-dev-mode", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "get_projects": map[string]any{ - "kind": "looker-get-projects", + "type": "looker-get-projects", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "get_project_files": map[string]any{ - "kind": "looker-get-project-files", + "type": "looker-get-project-files", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "get_project_file": map[string]any{ - "kind": "looker-get-project-file", + "type": "looker-get-project-file", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "create_project_file": map[string]any{ - "kind": "looker-create-project-file", + "type": "looker-create-project-file", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "update_project_file": map[string]any{ - "kind": "looker-update-project-file", + "type": "looker-update-project-file", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "delete_project_file": map[string]any{ - "kind": "looker-delete-project-file", + "type": "looker-delete-project-file", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "generate_embed_url": map[string]any{ - "kind": "looker-generate-embed-url", + "type": "looker-generate-embed-url", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "get_connections": map[string]any{ - "kind": "looker-get-connections", + "type": "looker-get-connections", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "get_connection_schemas": map[string]any{ - "kind": "looker-get-connection-schemas", + "type": "looker-get-connection-schemas", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "get_connection_databases": map[string]any{ - "kind": "looker-get-connection-databases", + "type": "looker-get-connection-databases", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "get_connection_tables": map[string]any{ - "kind": "looker-get-connection-tables", + "type": "looker-get-connection-tables", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, "get_connection_table_columns": map[string]any{ - "kind": "looker-get-connection-table-columns", + "type": "looker-get-connection-table-columns", "source": "my-instance", "description": "Simple tool to test end to end functionality.", }, diff --git a/tests/mariadb/mariadb_integration_test.go b/tests/mariadb/mariadb_integration_test.go index 60d734ace7..df3f4fb60c 100644 --- a/tests/mariadb/mariadb_integration_test.go +++ b/tests/mariadb/mariadb_integration_test.go @@ -36,8 +36,8 @@ import ( ) var ( - MariaDBSourceKind = "mysql" - MariaDBToolKind = "mysql-sql" + MariaDBSourceType = "mysql" + MariaDBToolType = "mysql-sql" MariaDBDatabase = os.Getenv("MARIADB_DATABASE") MariaDBHost = os.Getenv("MARIADB_HOST") MariaDBPort = os.Getenv("MARIADB_PORT") @@ -60,7 +60,7 @@ func getMariaDBVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": MariaDBSourceKind, + "type": MariaDBSourceType, "host": MariaDBHost, "port": MariaDBPort, "database": MariaDBDatabase, @@ -112,10 +112,10 @@ func TestMySQLToolEndpoints(t *testing.T) { defer teardownTable2(t) // Write config into a file and pass it to command - toolsFile := tests.GetToolsConfig(sourceConfig, MariaDBToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) + toolsFile := tests.GetToolsConfig(sourceConfig, MariaDBToolType, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) toolsFile = tests.AddMySqlExecuteSqlConfig(t, toolsFile) tmplSelectCombined, tmplSelectFilterCombined := tests.GetMySQLTmplToolStatement() - toolsFile = tests.AddTemplateParamConfig(t, toolsFile, MariaDBToolKind, tmplSelectCombined, tmplSelectFilterCombined, "") + toolsFile = tests.AddTemplateParamConfig(t, toolsFile, MariaDBToolType, tmplSelectCombined, tmplSelectFilterCombined, "") toolsFile = tests.AddMySQLPrebuiltToolConfig(t, toolsFile) diff --git a/tests/mindsdb/mindsdb_integration_test.go b/tests/mindsdb/mindsdb_integration_test.go index cbebce8238..18a8cb71f8 100644 --- a/tests/mindsdb/mindsdb_integration_test.go +++ b/tests/mindsdb/mindsdb_integration_test.go @@ -33,8 +33,8 @@ import ( ) var ( - MindsDBSourceKind = "mindsdb" - MindsDBToolKind = "mindsdb-sql" + MindsDBSourceType = "mindsdb" + MindsDBToolType = "mindsdb-sql" MindsDBDatabase = os.Getenv("MINDSDB_DATABASE") MindsDBHost = os.Getenv("MINDSDB_HOST") MindsDBPort = os.Getenv("MINDSDB_PORT") @@ -66,7 +66,7 @@ func getMindsDBVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": MindsDBSourceKind, + "type": MindsDBSourceType, "host": MindsDBHost, "port": MindsDBPort, "database": MindsDBDatabase, @@ -107,19 +107,19 @@ func TestMindsDBToolEndpoints(t *testing.T) { }, "authServices": map[string]any{ "my-google-auth": map[string]any{ - "kind": "google", + "type": "google", "clientId": tests.ClientId, }, }, "tools": map[string]any{ "my-simple-tool": map[string]any{ - "kind": MindsDBToolKind, + "type": MindsDBToolType, "source": "my-instance", "description": "Simple tool to test end to end functionality.", "statement": "SELECT 1", }, "my-tool": map[string]any{ - "kind": MindsDBToolKind, + "type": MindsDBToolType, "source": "my-instance", "description": "Tool to test invocation with params.", "statement": paramToolStmt, @@ -137,7 +137,7 @@ func TestMindsDBToolEndpoints(t *testing.T) { }, }, "my-tool-by-id": map[string]any{ - "kind": MindsDBToolKind, + "type": MindsDBToolType, "source": "my-instance", "description": "Tool to test invocation with params.", "statement": idParamToolStmt, @@ -150,7 +150,7 @@ func TestMindsDBToolEndpoints(t *testing.T) { }, }, "my-tool-by-name": map[string]any{ - "kind": MindsDBToolKind, + "type": MindsDBToolType, "source": "my-instance", "description": "Tool to test invocation with params.", "statement": nameParamToolStmt, @@ -164,13 +164,13 @@ func TestMindsDBToolEndpoints(t *testing.T) { }, }, "my-array-tool": map[string]any{ - "kind": MindsDBToolKind, + "type": MindsDBToolType, "source": "my-instance", "description": "Tool to test invocation with array params.", "statement": "SELECT 1 as id, 'Alice' as name UNION SELECT 3 as id, 'Sid' as name", }, "my-auth-tool": map[string]any{ - "kind": MindsDBToolKind, + "type": MindsDBToolType, "source": "my-instance", "description": "Tool to test authenticated parameters.", "statement": authToolStmt, @@ -189,7 +189,7 @@ func TestMindsDBToolEndpoints(t *testing.T) { }, }, "my-auth-required-tool": map[string]any{ - "kind": MindsDBToolKind, + "type": MindsDBToolType, "source": "my-instance", "description": "Tool to test auth required invocation.", "statement": "SELECT 1", @@ -198,18 +198,18 @@ func TestMindsDBToolEndpoints(t *testing.T) { }, }, "my-fail-tool": map[string]any{ - "kind": MindsDBToolKind, + "type": MindsDBToolType, "source": "my-instance", "description": "Tool to test statement with incorrect syntax.", "statement": "INVALID SQL STATEMENT", }, "my-exec-sql-tool": map[string]any{ - "kind": "mindsdb-execute-sql", + "type": "mindsdb-execute-sql", "source": "my-instance", "description": "Tool to execute sql", }, "my-auth-exec-sql-tool": map[string]any{ - "kind": "mindsdb-execute-sql", + "type": "mindsdb-execute-sql", "source": "my-instance", "description": "Tool to execute sql with auth", "authRequired": []string{ diff --git a/tests/mongodb/mongodb_integration_test.go b/tests/mongodb/mongodb_integration_test.go index 3d84837de8..b3675dbd32 100644 --- a/tests/mongodb/mongodb_integration_test.go +++ b/tests/mongodb/mongodb_integration_test.go @@ -33,8 +33,8 @@ import ( ) var ( - MongoDbSourceKind = "mongodb" - MongoDbToolKind = "mongodb-find" + MongoDbSourceType = "mongodb" + MongoDbToolType = "mongodb-find" MongoDbUri = os.Getenv("MONGODB_URI") MongoDbDatabase = os.Getenv("MONGODB_DATABASE") ServiceAccountEmail = os.Getenv("SERVICE_ACCOUNT_EMAIL") @@ -48,7 +48,7 @@ func getMongoDBVars(t *testing.T) map[string]any { t.Fatal("'MongoDbDatabase' not set") } return map[string]any{ - "kind": MongoDbSourceKind, + "type": MongoDbSourceType, "uri": MongoDbUri, } } @@ -83,7 +83,7 @@ func TestMongoDBToolEndpoints(t *testing.T) { defer teardownDB(t) // Write config into a file and pass it to command - toolsFile := getMongoDBToolsConfig(sourceConfig, MongoDbToolKind) + toolsFile := getMongoDBToolsConfig(sourceConfig, MongoDbToolType) cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) if err != nil { @@ -482,20 +482,20 @@ func setupMongoDB(t *testing.T, ctx context.Context, database *mongo.Database) f } -func getMongoDBToolsConfig(sourceConfig map[string]any, toolKind string) map[string]any { +func getMongoDBToolsConfig(sourceConfig map[string]any, toolType string) map[string]any { toolsFile := map[string]any{ "sources": map[string]any{ "my-instance": sourceConfig, }, "authServices": map[string]any{ "my-google-auth": map[string]any{ - "kind": "google", + "type": "google", "clientId": tests.ClientId, }, }, "tools": map[string]any{ "my-simple-tool": map[string]any{ - "kind": "mongodb-find-one", + "type": "mongodb-find-one", "source": "my-instance", "description": "Simple tool to test end to end functionality.", "collection": "test_collection", @@ -505,7 +505,7 @@ func getMongoDBToolsConfig(sourceConfig map[string]any, toolKind string) map[str "database": MongoDbDatabase, }, "my-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test invocation with params.", "authRequired": []string{}, @@ -528,7 +528,7 @@ func getMongoDBToolsConfig(sourceConfig map[string]any, toolKind string) map[str "limit": 10, }, "my-tool-by-id": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test invocation with params.", "authRequired": []string{}, @@ -546,7 +546,7 @@ func getMongoDBToolsConfig(sourceConfig map[string]any, toolKind string) map[str "limit": 10, }, "my-tool-by-name": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test invocation with params.", "authRequired": []string{}, @@ -565,7 +565,7 @@ func getMongoDBToolsConfig(sourceConfig map[string]any, toolKind string) map[str "limit": 10, }, "my-array-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test invocation with array.", "authRequired": []string{}, @@ -587,7 +587,7 @@ func getMongoDBToolsConfig(sourceConfig map[string]any, toolKind string) map[str "limit": 10, }, "my-auth-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test authenticated parameters.", "authRequired": []string{}, @@ -611,7 +611,7 @@ func getMongoDBToolsConfig(sourceConfig map[string]any, toolKind string) map[str "limit": 10, }, "my-auth-required-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test auth required invocation.", "authRequired": []string{ @@ -624,7 +624,7 @@ func getMongoDBToolsConfig(sourceConfig map[string]any, toolKind string) map[str "limit": 10, }, "my-fail-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Tool to test statement with incorrect syntax.", "authRequired": []string{}, @@ -635,7 +635,7 @@ func getMongoDBToolsConfig(sourceConfig map[string]any, toolKind string) map[str "limit": 10, }, "my-delete-one-tool": map[string]any{ - "kind": "mongodb-delete-one", + "type": "mongodb-delete-one", "source": "my-instance", "description": "Tool to test deleting an entry.", "authRequired": []string{}, @@ -645,7 +645,7 @@ func getMongoDBToolsConfig(sourceConfig map[string]any, toolKind string) map[str "database": MongoDbDatabase, }, "my-delete-many-tool": map[string]any{ - "kind": "mongodb-delete-many", + "type": "mongodb-delete-many", "source": "my-instance", "description": "Tool to test deleting multiple entries.", "authRequired": []string{}, @@ -655,7 +655,7 @@ func getMongoDBToolsConfig(sourceConfig map[string]any, toolKind string) map[str "database": MongoDbDatabase, }, "my-insert-one-tool": map[string]any{ - "kind": "mongodb-insert-one", + "type": "mongodb-insert-one", "source": "my-instance", "description": "Tool to test inserting an entry.", "authRequired": []string{}, @@ -664,7 +664,7 @@ func getMongoDBToolsConfig(sourceConfig map[string]any, toolKind string) map[str "database": MongoDbDatabase, }, "my-insert-many-tool": map[string]any{ - "kind": "mongodb-insert-many", + "type": "mongodb-insert-many", "source": "my-instance", "description": "Tool to test inserting multiple entries.", "authRequired": []string{}, @@ -673,7 +673,7 @@ func getMongoDBToolsConfig(sourceConfig map[string]any, toolKind string) map[str "database": MongoDbDatabase, }, "my-update-one-tool": map[string]any{ - "kind": "mongodb-update-one", + "type": "mongodb-update-one", "source": "my-instance", "description": "Tool to test updating an entry.", "authRequired": []string{}, @@ -698,7 +698,7 @@ func getMongoDBToolsConfig(sourceConfig map[string]any, toolKind string) map[str "database": MongoDbDatabase, }, "my-update-many-tool": map[string]any{ - "kind": "mongodb-update-many", + "type": "mongodb-update-many", "source": "my-instance", "description": "Tool to test updating multiple entries.", "authRequired": []string{}, @@ -723,7 +723,7 @@ func getMongoDBToolsConfig(sourceConfig map[string]any, toolKind string) map[str "database": MongoDbDatabase, }, "my-aggregate-tool": map[string]any{ - "kind": "mongodb-aggregate", + "type": "mongodb-aggregate", "source": "my-instance", "description": "Tool to test an aggregation.", "authRequired": []string{}, @@ -740,7 +740,7 @@ func getMongoDBToolsConfig(sourceConfig map[string]any, toolKind string) map[str "database": MongoDbDatabase, }, "my-read-only-aggregate-tool": map[string]any{ - "kind": "mongodb-aggregate", + "type": "mongodb-aggregate", "source": "my-instance", "description": "Tool to test an aggregation.", "authRequired": []string{}, @@ -758,7 +758,7 @@ func getMongoDBToolsConfig(sourceConfig map[string]any, toolKind string) map[str "database": MongoDbDatabase, }, "my-read-write-aggregate-tool": map[string]any{ - "kind": "mongodb-aggregate", + "type": "mongodb-aggregate", "source": "my-instance", "description": "Tool to test an aggregation.", "authRequired": []string{}, diff --git a/tests/mssql/mssql_integration_test.go b/tests/mssql/mssql_integration_test.go index b9dbe4712a..d3430f5a04 100644 --- a/tests/mssql/mssql_integration_test.go +++ b/tests/mssql/mssql_integration_test.go @@ -32,8 +32,8 @@ import ( ) var ( - MSSQLSourceKind = "mssql" - MSSQLToolKind = "mssql-sql" + MSSQLSourceType = "mssql" + MSSQLToolType = "mssql-sql" MSSQLDatabase = os.Getenv("MSSQL_DATABASE") MSSQLHost = os.Getenv("MSSQL_HOST") MSSQLPort = os.Getenv("MSSQL_PORT") @@ -56,7 +56,7 @@ func getMsSQLVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": MSSQLSourceKind, + "type": MSSQLSourceType, "host": MSSQLHost, "port": MSSQLPort, "database": MSSQLDatabase, @@ -116,10 +116,10 @@ func TestMSSQLToolEndpoints(t *testing.T) { defer teardownTable2(t) // Write config into a file and pass it to command - toolsFile := tests.GetToolsConfig(sourceConfig, MSSQLToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) + toolsFile := tests.GetToolsConfig(sourceConfig, MSSQLToolType, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) toolsFile = tests.AddMSSQLExecuteSqlConfig(t, toolsFile) tmplSelectCombined, tmplSelectFilterCombined := tests.GetMSSQLTmplToolStatement() - toolsFile = tests.AddTemplateParamConfig(t, toolsFile, MSSQLToolKind, tmplSelectCombined, tmplSelectFilterCombined, "") + toolsFile = tests.AddTemplateParamConfig(t, toolsFile, MSSQLToolType, tmplSelectCombined, tmplSelectFilterCombined, "") toolsFile = tests.AddMSSQLPrebuiltToolConfig(t, toolsFile) cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) diff --git a/tests/mysql/mysql_integration_test.go b/tests/mysql/mysql_integration_test.go index 113767fd1d..3f9558181f 100644 --- a/tests/mysql/mysql_integration_test.go +++ b/tests/mysql/mysql_integration_test.go @@ -30,8 +30,8 @@ import ( ) var ( - MySQLSourceKind = "mysql" - MySQLToolKind = "mysql-sql" + MySQLSourceType = "mysql" + MySQLToolType = "mysql-sql" MySQLDatabase = os.Getenv("MYSQL_DATABASE") MySQLHost = os.Getenv("MYSQL_HOST") MySQLPort = os.Getenv("MYSQL_PORT") @@ -54,7 +54,7 @@ func getMySQLVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": MySQLSourceKind, + "type": MySQLSourceType, "host": MySQLHost, "port": MySQLPort, "database": MySQLDatabase, @@ -106,10 +106,10 @@ func TestMySQLToolEndpoints(t *testing.T) { defer teardownTable2(t) // Write config into a file and pass it to command - toolsFile := tests.GetToolsConfig(sourceConfig, MySQLToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) + toolsFile := tests.GetToolsConfig(sourceConfig, MySQLToolType, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) toolsFile = tests.AddMySqlExecuteSqlConfig(t, toolsFile) tmplSelectCombined, tmplSelectFilterCombined := tests.GetMySQLTmplToolStatement() - toolsFile = tests.AddTemplateParamConfig(t, toolsFile, MySQLToolKind, tmplSelectCombined, tmplSelectFilterCombined, "") + toolsFile = tests.AddTemplateParamConfig(t, toolsFile, MySQLToolType, tmplSelectCombined, tmplSelectFilterCombined, "") toolsFile = tests.AddMySQLPrebuiltToolConfig(t, toolsFile) diff --git a/tests/neo4j/neo4j_integration_test.go b/tests/neo4j/neo4j_integration_test.go index 5f2f357b4f..a9d41babcc 100644 --- a/tests/neo4j/neo4j_integration_test.go +++ b/tests/neo4j/neo4j_integration_test.go @@ -34,7 +34,7 @@ import ( ) var ( - Neo4jSourceKind = "neo4j" + Neo4jSourceType = "neo4j" Neo4jDatabase = os.Getenv("NEO4J_DATABASE") Neo4jUri = os.Getenv("NEO4J_URI") Neo4jUser = os.Getenv("NEO4J_USER") @@ -56,7 +56,7 @@ func getNeo4jVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": Neo4jSourceKind, + "type": Neo4jSourceType, "uri": Neo4jUri, "database": Neo4jDatabase, "user": Neo4jUser, @@ -81,35 +81,35 @@ func TestNeo4jToolEndpoints(t *testing.T) { }, "tools": map[string]any{ "my-simple-cypher-tool": map[string]any{ - "kind": "neo4j-cypher", + "type": "neo4j-cypher", "source": "my-neo4j-instance", "description": "Simple tool to test end to end functionality.", "statement": "RETURN 1 as a;", }, "my-simple-execute-cypher-tool": map[string]any{ - "kind": "neo4j-execute-cypher", + "type": "neo4j-execute-cypher", "source": "my-neo4j-instance", "description": "Simple tool to test end to end functionality.", }, "my-readonly-execute-cypher-tool": map[string]any{ - "kind": "neo4j-execute-cypher", + "type": "neo4j-execute-cypher", "source": "my-neo4j-instance", "description": "A readonly cypher execution tool.", "readOnly": true, }, "my-schema-tool": map[string]any{ - "kind": "neo4j-schema", + "type": "neo4j-schema", "source": "my-neo4j-instance", "description": "A tool to get the Neo4j schema.", }, "my-schema-tool-with-cache": map[string]any{ - "kind": "neo4j-schema", + "type": "neo4j-schema", "source": "my-neo4j-instance", "description": "A schema tool with a custom cache expiration.", "cacheExpireMinutes": 10, }, "my-populated-schema-tool": map[string]any{ - "kind": "neo4j-schema", + "type": "neo4j-schema", "source": "my-neo4j-instance", "description": "A tool to get the Neo4j schema from a populated DB.", }, diff --git a/tests/oceanbase/oceanbase_integration_test.go b/tests/oceanbase/oceanbase_integration_test.go index e7691808fb..c81f96db07 100644 --- a/tests/oceanbase/oceanbase_integration_test.go +++ b/tests/oceanbase/oceanbase_integration_test.go @@ -32,8 +32,8 @@ import ( ) var ( - OceanBaseSourceKind = "oceanbase" - OceanBaseToolKind = "oceanbase-sql" + OceanBaseSourceType = "oceanbase" + OceanBaseToolType = "oceanbase-sql" OceanBaseDatabase = os.Getenv("OCEANBASE_DATABASE") OceanBaseHost = os.Getenv("OCEANBASE_HOST") OceanBasePort = os.Getenv("OCEANBASE_PORT") @@ -56,7 +56,7 @@ func getOceanBaseVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": OceanBaseSourceKind, + "type": OceanBaseSourceType, "host": OceanBaseHost, "port": OceanBasePort, "database": OceanBaseDatabase, @@ -105,10 +105,10 @@ func TestOceanBaseToolEndpoints(t *testing.T) { defer teardownTable2(t) // Write config into a file and pass it to command - toolsFile := tests.GetToolsConfig(sourceConfig, OceanBaseToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) + toolsFile := tests.GetToolsConfig(sourceConfig, OceanBaseToolType, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) toolsFile = addOceanBaseExecuteSqlConfig(t, toolsFile) tmplSelectCombined, tmplSelectFilterCombined := getOceanBaseTmplToolStatement() - toolsFile = tests.AddTemplateParamConfig(t, toolsFile, OceanBaseToolKind, tmplSelectCombined, tmplSelectFilterCombined, "") + toolsFile = tests.AddTemplateParamConfig(t, toolsFile, OceanBaseToolType, tmplSelectCombined, tmplSelectFilterCombined, "") cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) if err != nil { @@ -179,12 +179,12 @@ func addOceanBaseExecuteSqlConfig(t *testing.T, config map[string]any) map[strin t.Fatalf("unable to get tools from config") } tools["my-exec-sql-tool"] = map[string]any{ - "kind": "oceanbase-execute-sql", + "type": "oceanbase-execute-sql", "source": "my-instance", "description": "Tool to execute sql", } tools["my-auth-exec-sql-tool"] = map[string]any{ - "kind": "oceanbase-execute-sql", + "type": "oceanbase-execute-sql", "source": "my-instance", "description": "Tool to execute sql", "authRequired": []string{ diff --git a/tests/oracle/oracle_integration_test.go b/tests/oracle/oracle_integration_test.go index 0021679e9e..75f5fc00de 100644 --- a/tests/oracle/oracle_integration_test.go +++ b/tests/oracle/oracle_integration_test.go @@ -18,8 +18,8 @@ import ( ) var ( - OracleSourceKind = "oracle" - OracleToolKind = "oracle-sql" + OracleSourceType = "oracle" + OracleToolType = "oracle-sql" OracleHost = os.Getenv("ORACLE_HOST") OracleUser = os.Getenv("ORACLE_USER") OraclePass = os.Getenv("ORACLE_PASS") @@ -41,7 +41,7 @@ func getOracleVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": OracleSourceKind, + "type": OracleSourceType, "connectionString": OracleConnStr, "useOCI": true, "user": OracleUser, @@ -98,10 +98,10 @@ func TestOracleSimpleToolEndpoints(t *testing.T) { defer teardownTable2(t) // Write config into a file and pass it to command - toolsFile := tests.GetToolsConfig(sourceConfig, OracleToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) + toolsFile := tests.GetToolsConfig(sourceConfig, OracleToolType, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) toolsFile = tests.AddExecuteSqlConfig(t, toolsFile, "oracle-execute-sql") tmplSelectCombined, tmplSelectFilterCombined := tests.GetMySQLTmplToolStatement() - toolsFile = tests.AddTemplateParamConfig(t, toolsFile, OracleToolKind, tmplSelectCombined, tmplSelectFilterCombined, "") + toolsFile = tests.AddTemplateParamConfig(t, toolsFile, OracleToolType, tmplSelectCombined, tmplSelectFilterCombined, "") cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) if err != nil { diff --git a/tests/postgres/postgres_integration_test.go b/tests/postgres/postgres_integration_test.go index ea34a4a8bc..06cb19310d 100644 --- a/tests/postgres/postgres_integration_test.go +++ b/tests/postgres/postgres_integration_test.go @@ -31,8 +31,8 @@ import ( ) var ( - PostgresSourceKind = "postgres" - PostgresToolKind = "postgres-sql" + PostgresSourceType = "postgres" + PostgresToolType = "postgres-sql" PostgresDatabase = os.Getenv("POSTGRES_DATABASE") PostgresHost = os.Getenv("POSTGRES_HOST") PostgresPort = os.Getenv("POSTGRES_PORT") @@ -55,7 +55,7 @@ func getPostgresVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": PostgresSourceKind, + "type": PostgresSourceType, "host": PostgresHost, "port": PostgresPort, "database": PostgresDatabase, @@ -116,15 +116,15 @@ func TestPostgres(t *testing.T) { defer tearDownVectorTable(t) // Write config into a file and pass it to command - toolsFile := tests.GetToolsConfig(sourceConfig, PostgresToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) + toolsFile := tests.GetToolsConfig(sourceConfig, PostgresToolType, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) toolsFile = tests.AddExecuteSqlConfig(t, toolsFile, "postgres-execute-sql") tmplSelectCombined, tmplSelectFilterCombined := tests.GetPostgresSQLTmplToolStatement() - toolsFile = tests.AddTemplateParamConfig(t, toolsFile, PostgresToolKind, tmplSelectCombined, tmplSelectFilterCombined, "") + toolsFile = tests.AddTemplateParamConfig(t, toolsFile, PostgresToolType, tmplSelectCombined, tmplSelectFilterCombined, "") toolsFile = tests.AddPostgresPrebuiltConfig(t, toolsFile) // Add semantic search tool config insertStmt, searchStmt := tests.GetPostgresVectorSearchStmts(vectorTableName) - toolsFile = tests.AddSemanticSearchConfig(t, toolsFile, PostgresToolKind, insertStmt, searchStmt) + toolsFile = tests.AddSemanticSearchConfig(t, toolsFile, PostgresToolType, insertStmt, searchStmt) cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) if err != nil { diff --git a/tests/redis/redis_test.go b/tests/redis/redis_test.go index 6ee611da51..1fdace25ae 100644 --- a/tests/redis/redis_test.go +++ b/tests/redis/redis_test.go @@ -28,8 +28,8 @@ import ( ) var ( - RedisSourceKind = "redis" - RedisToolKind = "redis" + RedisSourceType = "redis" + RedisToolType = "redis" RedisAddress = os.Getenv("REDIS_ADDRESS") RedisPass = os.Getenv("REDIS_PASS") ) @@ -42,7 +42,7 @@ func getRedisVars(t *testing.T) map[string]any { t.Fatal("'REDIS_PASS' not set") } return map[string]any{ - "kind": RedisSourceKind, + "type": RedisSourceType, "address": []string{RedisAddress}, "password": RedisPass, } @@ -81,7 +81,7 @@ func TestRedisToolEndpoints(t *testing.T) { defer teardownDB(t) // Write config into a file and pass it to command - toolsFile := tests.GetRedisValkeyToolsConfig(sourceConfig, RedisToolKind) + toolsFile := tests.GetRedisValkeyToolsConfig(sourceConfig, RedisToolType) cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) if err != nil { diff --git a/tests/serverlessspark/serverless_spark_integration_test.go b/tests/serverlessspark/serverless_spark_integration_test.go index 12545a87aa..5ac8df1b1b 100644 --- a/tests/serverlessspark/serverless_spark_integration_test.go +++ b/tests/serverlessspark/serverless_spark_integration_test.go @@ -64,7 +64,7 @@ func getServerlessSparkVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": "serverless-spark", + "type": "serverless-spark", "project": serverlessSparkProject, "location": serverlessSparkLocation, } @@ -81,40 +81,40 @@ func TestServerlessSparkToolEndpoints(t *testing.T) { }, "authServices": map[string]any{ "my-google-auth": map[string]any{ - "kind": "google", + "type": "google", "clientId": tests.ClientId, }, }, "tools": map[string]any{ "list-batches": map[string]any{ - "kind": "serverless-spark-list-batches", + "type": "serverless-spark-list-batches", "source": "my-spark", }, "list-batches-with-auth": map[string]any{ - "kind": "serverless-spark-list-batches", + "type": "serverless-spark-list-batches", "source": "my-spark", "authRequired": []string{"my-google-auth"}, }, "get-batch": map[string]any{ - "kind": "serverless-spark-get-batch", + "type": "serverless-spark-get-batch", "source": "my-spark", }, "get-batch-with-auth": map[string]any{ - "kind": "serverless-spark-get-batch", + "type": "serverless-spark-get-batch", "source": "my-spark", "authRequired": []string{"my-google-auth"}, }, "cancel-batch": map[string]any{ - "kind": "serverless-spark-cancel-batch", + "type": "serverless-spark-cancel-batch", "source": "my-spark", }, "cancel-batch-with-auth": map[string]any{ - "kind": "serverless-spark-cancel-batch", + "type": "serverless-spark-cancel-batch", "source": "my-spark", "authRequired": []string{"my-google-auth"}, }, "create-pyspark-batch": map[string]any{ - "kind": "serverless-spark-create-pyspark-batch", + "type": "serverless-spark-create-pyspark-batch", "source": "my-spark", "environmentConfig": map[string]any{ "executionConfig": map[string]any{ @@ -123,7 +123,7 @@ func TestServerlessSparkToolEndpoints(t *testing.T) { }, }, "create-pyspark-batch-2-3": map[string]any{ - "kind": "serverless-spark-create-pyspark-batch", + "type": "serverless-spark-create-pyspark-batch", "source": "my-spark", "runtimeConfig": map[string]any{"version": "2.3"}, "environmentConfig": map[string]any{ @@ -133,12 +133,12 @@ func TestServerlessSparkToolEndpoints(t *testing.T) { }, }, "create-pyspark-batch-with-auth": map[string]any{ - "kind": "serverless-spark-create-pyspark-batch", + "type": "serverless-spark-create-pyspark-batch", "source": "my-spark", "authRequired": []string{"my-google-auth"}, }, "create-spark-batch": map[string]any{ - "kind": "serverless-spark-create-spark-batch", + "type": "serverless-spark-create-spark-batch", "source": "my-spark", "environmentConfig": map[string]any{ "executionConfig": map[string]any{ @@ -147,7 +147,7 @@ func TestServerlessSparkToolEndpoints(t *testing.T) { }, }, "create-spark-batch-2-3": map[string]any{ - "kind": "serverless-spark-create-spark-batch", + "type": "serverless-spark-create-spark-batch", "source": "my-spark", "runtimeConfig": map[string]any{"version": "2.3"}, "environmentConfig": map[string]any{ @@ -157,7 +157,7 @@ func TestServerlessSparkToolEndpoints(t *testing.T) { }, }, "create-spark-batch-with-auth": map[string]any{ - "kind": "serverless-spark-create-spark-batch", + "type": "serverless-spark-create-spark-batch", "source": "my-spark", "authRequired": []string{"my-google-auth"}, }, diff --git a/tests/singlestore/singlestore_integration_test.go b/tests/singlestore/singlestore_integration_test.go index 28419d49f3..5ada56d6f5 100644 --- a/tests/singlestore/singlestore_integration_test.go +++ b/tests/singlestore/singlestore_integration_test.go @@ -30,8 +30,8 @@ import ( ) var ( - SingleStoreSourceKind = "singlestore" - SingleStoreToolKind = "singlestore-sql" + SingleStoreSourceType = "singlestore" + SingleStoreToolType = "singlestore-sql" SingleStoreDatabase = os.Getenv("SINGLESTORE_DATABASE") SingleStoreHost = os.Getenv("SINGLESTORE_HOST") SingleStorePort = os.Getenv("SINGLESTORE_PORT") @@ -54,7 +54,7 @@ func getSingleStoreVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": SingleStoreSourceKind, + "type": SingleStoreSourceType, "host": SingleStoreHost, "port": SingleStorePort, "database": SingleStoreDatabase, @@ -85,7 +85,7 @@ func getSingleStoreAuthToolInfo(tableName string) (string, string, string, []any return createStatement, insertStatement, toolStatement, params } -// getSingleStoreTmplToolStatement returns statements and param for template parameter test cases for singlestore-sql kind +// getSingleStoreTmplToolStatement returns statements and param for template parameter test cases for singlestore-sql type func getSingleStoreTmplToolStatement() (string, string) { tmplSelectCombined := "SELECT * FROM {{.tableName}} WHERE id = ?" tmplSelectFilterCombined := "SELECT * FROM {{.tableName}} WHERE {{.columnFilter}} = ?" @@ -130,8 +130,8 @@ func setupSingleStoreTable(t *testing.T, ctx context.Context, pool *sql.DB, crea } } -func getSingleStoreToolsConfig(sourceConfig map[string]any, toolKind, paramToolStatement, idParamToolStmt, nameParamToolStmt, arrayToolStatement, authToolStatement string) map[string]any { - toolsFile := tests.GetToolsConfig(sourceConfig, toolKind, paramToolStatement, idParamToolStmt, nameParamToolStmt, arrayToolStatement, authToolStatement) +func getSingleStoreToolsConfig(sourceConfig map[string]any, toolType, paramToolStatement, idParamToolStmt, nameParamToolStmt, arrayToolStatement, authToolStatement string) map[string]any { + toolsFile := tests.GetToolsConfig(sourceConfig, toolType, paramToolStatement, idParamToolStmt, nameParamToolStmt, arrayToolStatement, authToolStatement) toolsMap, ok := toolsFile["tools"].(map[string]any) if !ok { @@ -151,12 +151,12 @@ func addSingleStoreExecuteSQLConfig(t *testing.T, config map[string]any) map[str t.Fatalf("unable to get tools from config") } tools["my-exec-sql-tool"] = map[string]any{ - "kind": "singlestore-execute-sql", + "type": "singlestore-execute-sql", "source": "my-instance", "description": "Tool to execute sql", } tools["my-auth-exec-sql-tool"] = map[string]any{ - "kind": "singlestore-execute-sql", + "type": "singlestore-execute-sql", "source": "my-instance", "description": "Tool to execute sql", "authRequired": []string{ @@ -207,10 +207,10 @@ func TestSingleStoreToolEndpoints(t *testing.T) { defer teardownTable2(t) // Write config into a file and pass it to command - toolsFile := getSingleStoreToolsConfig(sourceConfig, SingleStoreToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) + toolsFile := getSingleStoreToolsConfig(sourceConfig, SingleStoreToolType, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) toolsFile = addSingleStoreExecuteSQLConfig(t, toolsFile) tmplSelectCombined, tmplSelectFilterCombined := getSingleStoreTmplToolStatement() - toolsFile = tests.AddTemplateParamConfig(t, toolsFile, SingleStoreToolKind, tmplSelectCombined, tmplSelectFilterCombined, "") + toolsFile = tests.AddTemplateParamConfig(t, toolsFile, SingleStoreToolType, tmplSelectCombined, tmplSelectFilterCombined, "") cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) if err != nil { diff --git a/tests/snowflake/snowflake_integration_test.go b/tests/snowflake/snowflake_integration_test.go index cd81c8289f..ee07a86107 100644 --- a/tests/snowflake/snowflake_integration_test.go +++ b/tests/snowflake/snowflake_integration_test.go @@ -31,8 +31,8 @@ import ( ) var ( - SnowflakeSourceKind = "snowflake" - SnowflakeToolKind = "snowflake-sql" + SnowflakeSourceType = "snowflake" + SnowflakeToolType = "snowflake-sql" SnowflakeAccount = os.Getenv("SNOWFLAKE_ACCOUNT") SnowflakeUser = os.Getenv("SNOWFLAKE_USER") SnowflakePassword = os.Getenv("SNOWFLAKE_PASS") @@ -65,7 +65,7 @@ func getSnowflakeVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": SnowflakeSourceKind, + "type": SnowflakeSourceType, "account": SnowflakeAccount, "user": SnowflakeUser, "password": SnowflakePassword, @@ -125,10 +125,10 @@ func TestSnowflake(t *testing.T) { t.Logf("Test table setup complete.") // Write config into a file and pass it to command - toolsFile := tests.GetToolsConfig(sourceConfig, SnowflakeToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) + toolsFile := tests.GetToolsConfig(sourceConfig, SnowflakeToolType, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) toolsFile = addSnowflakeExecuteSqlConfig(t, toolsFile) tmplSelectCombined, tmplSelectFilterCombined := getSnowflakeTmplToolStatement() - toolsFile = tests.AddTemplateParamConfig(t, toolsFile, SnowflakeToolKind, tmplSelectCombined, tmplSelectFilterCombined, "") + toolsFile = tests.AddTemplateParamConfig(t, toolsFile, SnowflakeToolType, tmplSelectCombined, tmplSelectFilterCombined, "") cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) if err != nil { @@ -173,13 +173,13 @@ func addSnowflakeExecuteSqlConfig(t *testing.T, config map[string]any) map[strin } tools["my-exec-sql-tool"] = map[string]any{ - "kind": "snowflake-execute-sql", + "type": "snowflake-execute-sql", "source": "my-instance", "description": "Tool to execute sql", } tools["my-auth-exec-sql-tool"] = map[string]any{ - "kind": "snowflake-execute-sql", + "type": "snowflake-execute-sql", "source": "my-instance", "description": "Tool to execute sql", "authRequired": []string{ @@ -190,7 +190,7 @@ func addSnowflakeExecuteSqlConfig(t *testing.T, config map[string]any) map[strin return config } -// getSnowflakeParamToolInfo returns statements and param for my-param-tool snowflake-sql kind +// getSnowflakeParamToolInfo returns statements and param for my-param-tool snowflake-sql type func getSnowflakeParamToolInfo(tableName string) (string, string, string, string, string, string, []any) { createStatement := fmt.Sprintf("CREATE TABLE %s (id INTEGER AUTOINCREMENT PRIMARY KEY, name STRING);", tableName) insertStatement := fmt.Sprintf("INSERT INTO %s (name) VALUES (?), (?), (?), (?);", tableName) @@ -202,7 +202,7 @@ func getSnowflakeParamToolInfo(tableName string) (string, string, string, string return createStatement, insertStatement, toolStatement, idParamStatement, nameParamStatement, arrayToolStatement, params } -// getSnowflakeAuthToolInfo returns statements and param of my-auth-tool for snowflake-sql kind +// getSnowflakeAuthToolInfo returns statements and param of my-auth-tool for snowflake-sql type func getSnowflakeAuthToolInfo(tableName string) (string, string, string, []any) { createStatement := fmt.Sprintf("CREATE TABLE %s (id INTEGER AUTOINCREMENT PRIMARY KEY, name STRING, email STRING);", tableName) insertStatement := fmt.Sprintf("INSERT INTO %s (name, email) VALUES (?, ?), (?, ?)", tableName) @@ -211,7 +211,7 @@ func getSnowflakeAuthToolInfo(tableName string) (string, string, string, []any) return createStatement, insertStatement, toolStatement, params } -// getSnowflakeTmplToolStatement returns statements and param for template parameter test cases for snowflake-sql kind +// getSnowflakeTmplToolStatement returns statements and param for template parameter test cases for snowflake-sql type func getSnowflakeTmplToolStatement() (string, string) { tmplSelectCombined := "SELECT * FROM {{.tableName}} WHERE id = ?" tmplSelectFilterCombined := "SELECT * FROM {{.tableName}} WHERE {{.columnFilter}} = ?" diff --git a/tests/source.go b/tests/source.go index 6ef647f823..6750dad490 100644 --- a/tests/source.go +++ b/tests/source.go @@ -30,7 +30,7 @@ import ( ) // RunSourceConnection test for source connection -func RunSourceConnectionTest(t *testing.T, sourceConfig map[string]any, toolKind string) error { +func RunSourceConnectionTest(t *testing.T, sourceConfig map[string]any, toolType string) error { ctx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() @@ -43,7 +43,7 @@ func RunSourceConnectionTest(t *testing.T, sourceConfig map[string]any, toolKind }, "tools": map[string]any{ "my-simple-tool": map[string]any{ - "kind": toolKind, + "type": toolType, "source": "my-instance", "description": "Simple tool to test end to end functionality.", "statement": "SELECT 1;", diff --git a/tests/spanner/spanner_integration_test.go b/tests/spanner/spanner_integration_test.go index 4daf87a27e..265b84d89e 100644 --- a/tests/spanner/spanner_integration_test.go +++ b/tests/spanner/spanner_integration_test.go @@ -37,8 +37,8 @@ import ( ) var ( - SpannerSourceKind = "spanner" - SpannerToolKind = "spanner-sql" + SpannerSourceType = "spanner" + SpannerToolType = "spanner-sql" SpannerProject = os.Getenv("SPANNER_PROJECT") SpannerDatabase = os.Getenv("SPANNER_DATABASE") SpannerInstance = os.Getenv("SPANNER_INSTANCE") @@ -55,7 +55,7 @@ func getSpannerVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": SpannerSourceKind, + "type": SpannerSourceType, "project": SpannerProject, "instance": SpannerInstance, "database": SpannerDatabase, @@ -163,7 +163,7 @@ func TestSpannerToolEndpoints(t *testing.T) { defer teardownGraph(t) // Write config into a file and pass it to command - toolsFile := tests.GetToolsConfig(sourceConfig, SpannerToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) + toolsFile := tests.GetToolsConfig(sourceConfig, SpannerToolType, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) toolsFile = addSpannerExecuteSqlConfig(t, toolsFile) toolsFile = addSpannerReadOnlyConfig(t, toolsFile) toolsFile = addTemplateParamConfig(t, toolsFile) @@ -215,7 +215,7 @@ func TestSpannerToolEndpoints(t *testing.T) { runSpannerListGraphsTest(t, graphName) } -// getSpannerToolInfo returns statements and param for my-tool for spanner-sql kind +// getSpannerToolInfo returns statements and param for my-tool for spanner-sql type func getSpannerParamToolInfo(tableName string) (string, string, string, string, string, string, map[string]any) { createStatement := fmt.Sprintf("CREATE TABLE %s (id INT64, name STRING(MAX)) PRIMARY KEY (id)", tableName) insertStatement := fmt.Sprintf("INSERT INTO %s (id, name) VALUES (1, @name1), (2, @name2), (3, @name3), (4, @name4)", tableName) @@ -227,7 +227,7 @@ func getSpannerParamToolInfo(tableName string) (string, string, string, string, return createStatement, insertStatement, toolStatement, idToolStatement, nameToolStatement, arrayToolStatement, params } -// getSpannerAuthToolInfo returns statements and param of my-auth-tool for spanner-sql kind +// getSpannerAuthToolInfo returns statements and param of my-auth-tool for spanner-sql type func getSpannerAuthToolInfo(tableName string) (string, string, string, map[string]any) { createStatement := fmt.Sprintf("CREATE TABLE %s (id INT64, name STRING(MAX), email STRING(MAX)) PRIMARY KEY (id)", tableName) insertStatement := fmt.Sprintf("INSERT INTO %s (id, name, email) VALUES (1, @name1, @email1), (2, @name2, @email2)", tableName) @@ -331,18 +331,18 @@ func addSpannerExecuteSqlConfig(t *testing.T, config map[string]any) map[string] t.Fatalf("unable to get tools from config") } tools["my-exec-sql-tool-read-only"] = map[string]any{ - "kind": "spanner-execute-sql", + "type": "spanner-execute-sql", "source": "my-instance", "description": "Tool to execute sql", "readOnly": true, } tools["my-exec-sql-tool"] = map[string]any{ - "kind": "spanner-execute-sql", + "type": "spanner-execute-sql", "source": "my-instance", "description": "Tool to execute sql", } tools["my-auth-exec-sql-tool"] = map[string]any{ - "kind": "spanner-execute-sql", + "type": "spanner-execute-sql", "source": "my-instance", "description": "Tool to execute sql", "authRequired": []string{ @@ -359,14 +359,14 @@ func addSpannerReadOnlyConfig(t *testing.T, config map[string]any) map[string]an t.Fatalf("unable to get tools from config") } tools["access-schema-read-only"] = map[string]any{ - "kind": "spanner-sql", + "type": "spanner-sql", "source": "my-instance", "description": "Tool to access information schema in read-only mode.", "statement": "SELECT schema_name FROM `INFORMATION_SCHEMA`.SCHEMATA WHERE schema_name='INFORMATION_SCHEMA';", "readOnly": true, } tools["access-schema"] = map[string]any{ - "kind": "spanner-sql", + "type": "spanner-sql", "source": "my-instance", "description": "Tool to access information schema.", "statement": "SELECT schema_name FROM `INFORMATION_SCHEMA`.SCHEMATA WHERE schema_name='INFORMATION_SCHEMA';", @@ -384,7 +384,7 @@ func addSpannerListTablesConfig(t *testing.T, config map[string]any) map[string] // Add spanner-list-tables tool tools["list-tables-tool"] = map[string]any{ - "kind": "spanner-list-tables", + "type": "spanner-list-tables", "source": "my-instance", "description": "Lists tables with their schema information", } @@ -402,7 +402,7 @@ func addSpannerListGraphsConfig(t *testing.T, config map[string]any) map[string] // Add spanner-list-graphs tool tools["list-graphs-tool"] = map[string]any{ - "kind": "spanner-list-graphs", + "type": "spanner-list-graphs", "source": "my-instance", "description": "Lists graphs with their schema information", } @@ -417,7 +417,7 @@ func addTemplateParamConfig(t *testing.T, config map[string]any) map[string]any t.Fatalf("unable to get tools from config") } toolsMap["insert-table-templateParams-tool"] = map[string]any{ - "kind": "spanner-sql", + "type": "spanner-sql", "source": "my-instance", "description": "Insert tool with template parameters", "statement": "INSERT INTO {{.tableName}} ({{array .columns}}) VALUES ({{.values}})", @@ -428,7 +428,7 @@ func addTemplateParamConfig(t *testing.T, config map[string]any) map[string]any }, } toolsMap["select-templateParams-tool"] = map[string]any{ - "kind": "spanner-sql", + "type": "spanner-sql", "source": "my-instance", "description": "Create table tool with template parameters", "statement": "SELECT * FROM {{.tableName}}", @@ -437,7 +437,7 @@ func addTemplateParamConfig(t *testing.T, config map[string]any) map[string]any }, } toolsMap["select-templateParams-combined-tool"] = map[string]any{ - "kind": "spanner-sql", + "type": "spanner-sql", "source": "my-instance", "description": "Create table tool with template parameters", "statement": "SELECT * FROM {{.tableName}} WHERE id = @id", @@ -447,7 +447,7 @@ func addTemplateParamConfig(t *testing.T, config map[string]any) map[string]any }, } toolsMap["select-fields-templateParams-tool"] = map[string]any{ - "kind": "spanner-sql", + "type": "spanner-sql", "source": "my-instance", "description": "Create table tool with template parameters", "statement": "SELECT {{array .fields}} FROM {{.tableName}}", @@ -457,7 +457,7 @@ func addTemplateParamConfig(t *testing.T, config map[string]any) map[string]any }, } toolsMap["select-filter-templateParams-combined-tool"] = map[string]any{ - "kind": "spanner-sql", + "type": "spanner-sql", "source": "my-instance", "description": "Create table tool with template parameters", "statement": "SELECT * FROM {{.tableName}} WHERE {{.columnFilter}} = @name", diff --git a/tests/sqlite/sqlite_integration_test.go b/tests/sqlite/sqlite_integration_test.go index 730e70f4f5..ac01cbd0ca 100644 --- a/tests/sqlite/sqlite_integration_test.go +++ b/tests/sqlite/sqlite_integration_test.go @@ -32,14 +32,14 @@ import ( ) var ( - SQLiteSourceKind = "sqlite" - SQLiteToolKind = "sqlite-sql" + SQLiteSourceType = "sqlite" + SQLiteToolType = "sqlite-sql" SQLiteDatabase = os.Getenv("SQLITE_DATABASE") ) func getSQLiteVars(t *testing.T) map[string]any { return map[string]any{ - "kind": SQLiteSourceKind, + "type": SQLiteSourceType, "database": SQLiteDatabase, } } @@ -137,9 +137,9 @@ func TestSQLiteToolEndpoint(t *testing.T) { setupSQLiteTestDB(t, ctx, db, createAuthTableStmt, insertAuthTableStmt, tableNameAuth, authTestParams) // Write config into a file and pass it to command - toolsFile := tests.GetToolsConfig(sourceConfig, SQLiteToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) + toolsFile := tests.GetToolsConfig(sourceConfig, SQLiteToolType, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) tmplSelectCombined, tmplSelectFilterCombined := getSQLiteTmplToolStatement() - toolsFile = tests.AddTemplateParamConfig(t, toolsFile, SQLiteToolKind, tmplSelectCombined, tmplSelectFilterCombined, "") + toolsFile = tests.AddTemplateParamConfig(t, toolsFile, SQLiteToolType, tmplSelectCombined, tmplSelectFilterCombined, "") cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) if err != nil { @@ -191,7 +191,7 @@ func TestSQLiteExecuteSqlTool(t *testing.T) { toolConfig := map[string]any{ "tools": map[string]any{ "my-exec-sql-tool": map[string]any{ - "kind": "sqlite-execute-sql", + "type": "sqlite-execute-sql", "source": "my-instance", "description": "Tool to execute SQL statements", }, diff --git a/tests/tidb/tidb_integration_test.go b/tests/tidb/tidb_integration_test.go index 29efca8f35..8e9c5f6c7f 100644 --- a/tests/tidb/tidb_integration_test.go +++ b/tests/tidb/tidb_integration_test.go @@ -30,8 +30,8 @@ import ( ) var ( - TiDBSourceKind = "tidb" - TiDBToolKind = "tidb-sql" + TiDBSourceType = "tidb" + TiDBToolType = "tidb-sql" TiDBDatabase = os.Getenv("TIDB_DATABASE") TiDBHost = os.Getenv("TIDB_HOST") TiDBPort = os.Getenv("TIDB_PORT") @@ -54,7 +54,7 @@ func getTiDBVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": TiDBSourceKind, + "type": TiDBSourceType, "host": TiDBHost, "port": TiDBPort, "database": TiDBDatabase, @@ -91,12 +91,12 @@ func addTiDBExecuteSqlConfig(t *testing.T, config map[string]any) map[string]any t.Fatalf("unable to get tools from config") } tools["my-exec-sql-tool"] = map[string]any{ - "kind": "tidb-execute-sql", + "type": "tidb-execute-sql", "source": "my-instance", "description": "Tool to execute sql", } tools["my-auth-exec-sql-tool"] = map[string]any{ - "kind": "tidb-execute-sql", + "type": "tidb-execute-sql", "source": "my-instance", "description": "Tool to execute sql", "authRequired": []string{ @@ -135,10 +135,10 @@ func TestTiDBToolEndpoints(t *testing.T) { defer teardownTable2(t) // Write config into a file and pass it to command - toolsFile := tests.GetToolsConfig(sourceConfig, TiDBToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) + toolsFile := tests.GetToolsConfig(sourceConfig, TiDBToolType, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) toolsFile = addTiDBExecuteSqlConfig(t, toolsFile) tmplSelectCombined, tmplSelectFilterCombined := tests.GetMySQLTmplToolStatement() - toolsFile = tests.AddTemplateParamConfig(t, toolsFile, TiDBToolKind, tmplSelectCombined, tmplSelectFilterCombined, "") + toolsFile = tests.AddTemplateParamConfig(t, toolsFile, TiDBToolType, tmplSelectCombined, tmplSelectFilterCombined, "") cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) if err != nil { diff --git a/tests/trino/trino_integration_test.go b/tests/trino/trino_integration_test.go index 126e887b22..6006caf2bb 100644 --- a/tests/trino/trino_integration_test.go +++ b/tests/trino/trino_integration_test.go @@ -31,8 +31,8 @@ import ( ) var ( - TrinoSourceKind = "trino" - TrinoToolKind = "trino-sql" + TrinoSourceType = "trino" + TrinoToolType = "trino-sql" TrinoHost = os.Getenv("TRINO_HOST") TrinoPort = os.Getenv("TRINO_PORT") TrinoUser = os.Getenv("TRINO_USER") @@ -55,7 +55,7 @@ func getTrinoVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": TrinoSourceKind, + "type": TrinoSourceType, "host": TrinoHost, "port": TrinoPort, "user": TrinoUser, @@ -119,7 +119,7 @@ func buildTrinoDSN(host, port, user, password, catalog, schema, queryTimeout, ac return dsn, nil } -// getTrinoParamToolInfo returns statements and param for my-tool trino-sql kind +// getTrinoParamToolInfo returns statements and param for my-tool trino-sql type func getTrinoParamToolInfo(tableName string) (string, string, string, string, string, string, []any) { createStatement := fmt.Sprintf("CREATE TABLE %s (id BIGINT NOT NULL, name VARCHAR(255))", tableName) insertStatement := fmt.Sprintf("INSERT INTO %s (id, name) VALUES (1, ?), (2, ?), (3, ?), (4, ?)", tableName) @@ -131,7 +131,7 @@ func getTrinoParamToolInfo(tableName string) (string, string, string, string, st return createStatement, insertStatement, toolStatement, idParamStatement, nameParamStatement, arrayToolStatement, params } -// getTrinoAuthToolInfo returns statements and param of my-auth-tool for trino-sql kind +// getTrinoAuthToolInfo returns statements and param of my-auth-tool for trino-sql type func getTrinoAuthToolInfo(tableName string) (string, string, string, []any) { createStatement := fmt.Sprintf("CREATE TABLE %s (id BIGINT NOT NULL, name VARCHAR(255), email VARCHAR(255))", tableName) insertStatement := fmt.Sprintf("INSERT INTO %s (id, name, email) VALUES (1, ?, ?), (2, ?, ?)", tableName) @@ -140,7 +140,7 @@ func getTrinoAuthToolInfo(tableName string) (string, string, string, []any) { return createStatement, insertStatement, toolStatement, params } -// getTrinoTmplToolStatement returns statements and param for template parameter test cases for trino-sql kind +// getTrinoTmplToolStatement returns statements and param for template parameter test cases for trino-sql type func getTrinoTmplToolStatement() (string, string) { tmplSelectCombined := "SELECT * FROM {{.tableName}} WHERE id = ?" tmplSelectFilterCombined := "SELECT * FROM {{.tableName}} WHERE {{.columnFilter}} = ?" @@ -192,12 +192,12 @@ func addTrinoExecuteSqlConfig(t *testing.T, config map[string]any) map[string]an t.Fatalf("unable to get tools from config") } tools["my-exec-sql-tool"] = map[string]any{ - "kind": "trino-execute-sql", + "type": "trino-execute-sql", "source": "my-instance", "description": "Tool to execute sql", } tools["my-auth-exec-sql-tool"] = map[string]any{ - "kind": "trino-execute-sql", + "type": "trino-execute-sql", "source": "my-instance", "description": "Tool to execute sql", "authRequired": []string{ @@ -236,10 +236,10 @@ func TestTrinoToolEndpoints(t *testing.T) { defer teardownTable2(t) // Write config into a file and pass it to command - toolsFile := tests.GetToolsConfig(sourceConfig, TrinoToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) + toolsFile := tests.GetToolsConfig(sourceConfig, TrinoToolType, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt) toolsFile = addTrinoExecuteSqlConfig(t, toolsFile) tmplSelectCombined, tmplSelectFilterCombined := getTrinoTmplToolStatement() - toolsFile = tests.AddTemplateParamConfig(t, toolsFile, TrinoToolKind, tmplSelectCombined, tmplSelectFilterCombined, "") + toolsFile = tests.AddTemplateParamConfig(t, toolsFile, TrinoToolType, tmplSelectCombined, tmplSelectFilterCombined, "") cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) if err != nil { diff --git a/tests/utility/wait_integration_test.go b/tests/utility/wait_integration_test.go index c7891592c2..9485b4ea40 100644 --- a/tests/utility/wait_integration_test.go +++ b/tests/utility/wait_integration_test.go @@ -37,7 +37,7 @@ func RunWaitTool(t *testing.T) { toolsFile := map[string]any{ "tools": map[string]any{ "my-wait-for-tool": map[string]any{ - "kind": "wait", + "type": "wait", "description": "Wait for a specified duration.", "timeout": "30s", }, diff --git a/tests/valkey/valkey_test.go b/tests/valkey/valkey_test.go index 23f2b09df2..a159694bdd 100644 --- a/tests/valkey/valkey_test.go +++ b/tests/valkey/valkey_test.go @@ -28,8 +28,8 @@ import ( ) var ( - ValkeySourceKind = "valkey" - ValkeyToolKind = "valkey" + ValkeySourceType = "valkey" + ValkeyToolType = "valkey" ValkeyAddress = os.Getenv("VALKEY_ADDRESS") ) @@ -39,7 +39,7 @@ func getValkeyVars(t *testing.T) map[string]any { t.Fatal("'VALKEY_ADDRESS' not set") } return map[string]any{ - "kind": ValkeySourceKind, + "type": ValkeySourceType, "address": []string{ValkeyAddress}, "disableCache": true, } @@ -84,7 +84,7 @@ func TestValkeyToolEndpoints(t *testing.T) { defer teardownDB(t) // Write config into a file and pass it to command - toolsFile := tests.GetRedisValkeyToolsConfig(sourceConfig, ValkeyToolKind) + toolsFile := tests.GetRedisValkeyToolsConfig(sourceConfig, ValkeyToolType) cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...) if err != nil { diff --git a/tests/yugabytedb/yugabytedb_integration_test.go b/tests/yugabytedb/yugabytedb_integration_test.go index 04483f3d13..60dcb6cd6e 100644 --- a/tests/yugabytedb/yugabytedb_integration_test.go +++ b/tests/yugabytedb/yugabytedb_integration_test.go @@ -58,7 +58,7 @@ func getYBVars(t *testing.T) map[string]any { } return map[string]any{ - "kind": YBDB_SOURCE_KIND, + "type": YBDB_SOURCE_KIND, "host": YBDB_HOST, "port": YBDB_PORT, "database": YBDB_DATABASE,