diff --git a/internal/tools/firestore/firestorequerycollection/firestorequerycollection.go b/internal/tools/firestore/firestorequerycollection/firestorequerycollection.go index 31f0907abc..6066560a78 100644 --- a/internal/tools/firestore/firestorequerycollection/firestorequerycollection.go +++ b/internal/tools/firestore/firestorequerycollection/firestorequerycollection.go @@ -18,7 +18,7 @@ import ( "context" "encoding/json" "fmt" - "net/http" // Added for http.StatusInternalServerError + "net/http" "strings" firestoreapi "cloud.google.com/go/firestore" @@ -27,7 +27,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/tools" fsUtil "github.com/googleapis/genai-toolbox/internal/tools/firestore/util" - "github.com/googleapis/genai-toolbox/internal/util" // Added for util.ToolboxError + "github.com/googleapis/genai-toolbox/internal/util" "github.com/googleapis/genai-toolbox/internal/util/parameters" ) diff --git a/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument.go b/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument.go index 0de0bd4f50..c81c204806 100644 --- a/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument.go +++ b/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument.go @@ -17,7 +17,7 @@ package firestoreupdatedocument import ( "context" "fmt" - "net/http" // Added for http.StatusInternalServerError + "net/http" "strings" firestoreapi "cloud.google.com/go/firestore" @@ -26,7 +26,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/tools" fsUtil "github.com/googleapis/genai-toolbox/internal/tools/firestore/util" - "github.com/googleapis/genai-toolbox/internal/util" // Added for util.ToolboxError + "github.com/googleapis/genai-toolbox/internal/util" "github.com/googleapis/genai-toolbox/internal/util/parameters" ) diff --git a/internal/tools/firestore/firestorevalidaterules/firestorevalidaterules.go b/internal/tools/firestore/firestorevalidaterules/firestorevalidaterules.go index 7142e91f69..aee3ac60ff 100644 --- a/internal/tools/firestore/firestorevalidaterules/firestorevalidaterules.go +++ b/internal/tools/firestore/firestorevalidaterules/firestorevalidaterules.go @@ -17,13 +17,13 @@ package firestorevalidaterules import ( "context" "fmt" - "net/http" // Added for http.StatusInternalServerError + "net/http" yaml "github.com/goccy/go-yaml" "github.com/googleapis/genai-toolbox/internal/embeddingmodels" "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/tools" - "github.com/googleapis/genai-toolbox/internal/util" // Added for util.ToolboxError + "github.com/googleapis/genai-toolbox/internal/util" "github.com/googleapis/genai-toolbox/internal/util/parameters" "google.golang.org/api/firebaserules/v1" ) diff --git a/internal/tools/looker/lookergetfilters/lookergetfilters.go b/internal/tools/looker/lookergetfilters/lookergetfilters.go index 49e86d338d..20db21c0b5 100644 --- a/internal/tools/looker/lookergetfilters/lookergetfilters.go +++ b/internal/tools/looker/lookergetfilters/lookergetfilters.go @@ -16,6 +16,7 @@ package lookergetfilters import ( "context" "fmt" + "net/http" yaml "github.com/goccy/go-yaml" "github.com/googleapis/genai-toolbox/internal/embeddingmodels" @@ -109,25 +110,25 @@ func (t Tool) ToConfig() tools.ToolConfig { return t.Config } -func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, util.ToolboxError) { source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { - return nil, err + return nil, util.NewClientServerError("source used is not compatible with the tool", http.StatusInternalServerError, err) } logger, err := util.LoggerFromContext(ctx) if err != nil { - return nil, fmt.Errorf("unable to get logger from ctx: %s", err) + return nil, util.NewClientServerError("unable to get logger from ctx", http.StatusInternalServerError, err) } model, explore, err := lookercommon.ProcessFieldArgs(ctx, params) if err != nil { - return nil, fmt.Errorf("error processing model or explore: %w", err) + return nil, util.NewAgentError(fmt.Sprintf("error processing model or explore: %v", err), err) } fields := lookercommon.FiltersFields sdk, err := source.GetLookerSDK(string(accessToken)) if err != nil { - return nil, fmt.Errorf("error getting sdk: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error getting sdk: %v", err), http.StatusInternalServerError, err) } req := v4.RequestLookmlModelExplore{ LookmlModelName: *model, @@ -136,16 +137,16 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para } resp, err := sdk.LookmlModelExplore(req, source.LookerApiSettings()) if err != nil { - return nil, fmt.Errorf("error making get_filters request: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error making get_filters request: %v", err), http.StatusInternalServerError, err) } if err := lookercommon.CheckLookerExploreFields(&resp); err != nil { - return nil, fmt.Errorf("error processing get_filters response: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error processing get_filters response: %v", err), http.StatusInternalServerError, err) } data, err := lookercommon.ExtractLookerFieldProperties(ctx, resp.Fields.Filters, source.LookerShowHiddenFields()) if err != nil { - return nil, fmt.Errorf("error extracting get_filters response: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error extracting get_filters response: %v", err), http.StatusInternalServerError, err) } logger.DebugContext(ctx, "data = ", data) diff --git a/internal/tools/looker/lookergetlooks/lookergetlooks.go b/internal/tools/looker/lookergetlooks/lookergetlooks.go index 877a5c8586..f6642c5772 100644 --- a/internal/tools/looker/lookergetlooks/lookergetlooks.go +++ b/internal/tools/looker/lookergetlooks/lookergetlooks.go @@ -16,6 +16,7 @@ package lookergetlooks import ( "context" "fmt" + "net/http" yaml "github.com/goccy/go-yaml" "github.com/googleapis/genai-toolbox/internal/embeddingmodels" @@ -116,23 +117,29 @@ func (t Tool) ToConfig() tools.ToolConfig { return t.Config } -func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, util.ToolboxError) { source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { - return nil, err + return nil, util.NewClientServerError("source used is not compatible with the tool", http.StatusInternalServerError, err) } logger, err := util.LoggerFromContext(ctx) if err != nil { - return nil, fmt.Errorf("unable to get logger from ctx: %s", err) + return nil, util.NewClientServerError("unable to get logger from ctx", http.StatusInternalServerError, err) } paramsMap := params.AsMap() - title := paramsMap["title"].(string) + title, ok := paramsMap["title"].(string) + if !ok { + return nil, util.NewAgentError("missing or invalid 'title' parameter", nil) + } title_ptr := &title if *title_ptr == "" { title_ptr = nil } - desc := paramsMap["desc"].(string) + desc, ok := paramsMap["desc"].(string) + if !ok { + return nil, util.NewAgentError("missing or invalid 'desc' parameter", nil) + } desc_ptr := &desc if *desc_ptr == "" { desc_ptr = nil @@ -142,7 +149,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para sdk, err := source.GetLookerSDK(string(accessToken)) if err != nil { - return nil, fmt.Errorf("error getting sdk: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error getting sdk: %v", err), http.StatusInternalServerError, err) } req := v4.RequestSearchLooks{ Title: title_ptr, @@ -152,7 +159,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para } resp, err := sdk.SearchLooks(req, source.LookerApiSettings()) if err != nil { - return nil, fmt.Errorf("error making get_looks request: %s", err) + return nil, util.NewClientServerError(fmt.Sprintf("error making get_looks request: %s", err), http.StatusInternalServerError, err) } var data []any diff --git a/internal/tools/looker/lookergetmeasures/lookergetmeasures.go b/internal/tools/looker/lookergetmeasures/lookergetmeasures.go index 5d5ed52e75..d326c55909 100644 --- a/internal/tools/looker/lookergetmeasures/lookergetmeasures.go +++ b/internal/tools/looker/lookergetmeasures/lookergetmeasures.go @@ -16,6 +16,7 @@ package lookergetmeasures import ( "context" "fmt" + "net/http" yaml "github.com/goccy/go-yaml" "github.com/googleapis/genai-toolbox/internal/embeddingmodels" @@ -109,25 +110,25 @@ func (t Tool) ToConfig() tools.ToolConfig { return t.Config } -func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, util.ToolboxError) { source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { - return nil, err + return nil, util.NewClientServerError("source used is not compatible with the tool", http.StatusInternalServerError, err) } logger, err := util.LoggerFromContext(ctx) if err != nil { - return nil, fmt.Errorf("unable to get logger from ctx: %s", err) + return nil, util.NewClientServerError("unable to get logger from ctx", http.StatusInternalServerError, err) } model, explore, err := lookercommon.ProcessFieldArgs(ctx, params) if err != nil { - return nil, fmt.Errorf("error processing model or explore: %w", err) + return nil, util.NewAgentError(fmt.Sprintf("error processing model or explore: %v", err), err) } fields := lookercommon.MeasuresFields sdk, err := source.GetLookerSDK(string(accessToken)) if err != nil { - return nil, fmt.Errorf("error getting sdk: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error getting sdk: %v", err), http.StatusInternalServerError, err) } req := v4.RequestLookmlModelExplore{ LookmlModelName: *model, @@ -136,16 +137,16 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para } resp, err := sdk.LookmlModelExplore(req, source.LookerApiSettings()) if err != nil { - return nil, fmt.Errorf("error making get_measures request: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error making get_measures request: %v", err), http.StatusInternalServerError, err) } if err := lookercommon.CheckLookerExploreFields(&resp); err != nil { - return nil, fmt.Errorf("error processing get_measures response: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error processing get_measures response: %v", err), http.StatusInternalServerError, err) } data, err := lookercommon.ExtractLookerFieldProperties(ctx, resp.Fields.Measures, source.LookerShowHiddenFields()) if err != nil { - return nil, fmt.Errorf("error extracting get_measures response: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error extracting get_measures response: %v", err), http.StatusInternalServerError, err) } logger.DebugContext(ctx, "data = ", data) diff --git a/internal/tools/looker/lookergetmodels/lookergetmodels.go b/internal/tools/looker/lookergetmodels/lookergetmodels.go index 2caf1d1efc..221570f652 100644 --- a/internal/tools/looker/lookergetmodels/lookergetmodels.go +++ b/internal/tools/looker/lookergetmodels/lookergetmodels.go @@ -16,6 +16,7 @@ package lookergetmodels import ( "context" "fmt" + "net/http" yaml "github.com/goccy/go-yaml" "github.com/googleapis/genai-toolbox/internal/embeddingmodels" @@ -108,15 +109,15 @@ func (t Tool) ToConfig() tools.ToolConfig { return t.Config } -func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, util.ToolboxError) { source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { - return nil, err + return nil, util.NewClientServerError("source used is not compatible with the tool", http.StatusInternalServerError, err) } logger, err := util.LoggerFromContext(ctx) if err != nil { - return nil, fmt.Errorf("unable to get logger from ctx: %s", err) + return nil, util.NewClientServerError("unable to get logger from ctx", http.StatusInternalServerError, err) } excludeEmpty := false @@ -125,7 +126,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para sdk, err := source.GetLookerSDK(string(accessToken)) if err != nil { - return nil, fmt.Errorf("error getting sdk: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error getting sdk: %v", err), http.StatusInternalServerError, err) } req := v4.RequestAllLookmlModels{ ExcludeEmpty: &excludeEmpty, @@ -134,7 +135,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para } resp, err := sdk.AllLookmlModels(req, source.LookerApiSettings()) if err != nil { - return nil, fmt.Errorf("error making get_models request: %s", err) + return nil, util.NewClientServerError(fmt.Sprintf("error making get_models request: %s", err), http.StatusInternalServerError, err) } var data []any diff --git a/internal/tools/looker/lookergetparameters/lookergetparameters.go b/internal/tools/looker/lookergetparameters/lookergetparameters.go index 13d6e9b8d0..172c6d0cdf 100644 --- a/internal/tools/looker/lookergetparameters/lookergetparameters.go +++ b/internal/tools/looker/lookergetparameters/lookergetparameters.go @@ -7,7 +7,7 @@ // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, +// distributed under the License is distributed under an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. @@ -16,6 +16,7 @@ package lookergetparameters import ( "context" "fmt" + "net/http" yaml "github.com/goccy/go-yaml" "github.com/googleapis/genai-toolbox/internal/embeddingmodels" @@ -109,25 +110,25 @@ func (t Tool) ToConfig() tools.ToolConfig { return t.Config } -func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, util.ToolboxError) { source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { - return nil, err + return nil, util.NewClientServerError("source used is not compatible with the tool", http.StatusInternalServerError, err) } logger, err := util.LoggerFromContext(ctx) if err != nil { - return nil, fmt.Errorf("unable to get logger from ctx: %s", err) + return nil, util.NewClientServerError("unable to get logger from ctx", http.StatusInternalServerError, err) } model, explore, err := lookercommon.ProcessFieldArgs(ctx, params) if err != nil { - return nil, fmt.Errorf("error processing model or explore: %w", err) + return nil, util.NewAgentError(fmt.Sprintf("error processing model or explore: %v", err), err) } fields := lookercommon.ParametersFields sdk, err := source.GetLookerSDK(string(accessToken)) if err != nil { - return nil, fmt.Errorf("error getting sdk: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error getting sdk: %v", err), http.StatusInternalServerError, err) } req := v4.RequestLookmlModelExplore{ LookmlModelName: *model, @@ -136,16 +137,16 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para } resp, err := sdk.LookmlModelExplore(req, source.LookerApiSettings()) if err != nil { - return nil, fmt.Errorf("error making get_parameters request: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error making get_parameters request: %v", err), http.StatusInternalServerError, err) } if err := lookercommon.CheckLookerExploreFields(&resp); err != nil { - return nil, fmt.Errorf("error processing get_parameters response: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error processing get_parameters response: %v", err), http.StatusInternalServerError, err) } data, err := lookercommon.ExtractLookerFieldProperties(ctx, resp.Fields.Parameters, source.LookerShowHiddenFields()) if err != nil { - return nil, fmt.Errorf("error extracting get_parameters response: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error extracting get_parameters response: %v", err), http.StatusInternalServerError, err) } logger.DebugContext(ctx, "data = ", data) diff --git a/internal/tools/looker/lookergetprojectfile/lookergetprojectfile.go b/internal/tools/looker/lookergetprojectfile/lookergetprojectfile.go index bc2ced3e2b..378111b754 100644 --- a/internal/tools/looker/lookergetprojectfile/lookergetprojectfile.go +++ b/internal/tools/looker/lookergetprojectfile/lookergetprojectfile.go @@ -16,6 +16,7 @@ package lookergetprojectfile import ( "context" "fmt" + "net/http" yaml "github.com/goccy/go-yaml" "github.com/googleapis/genai-toolbox/internal/embeddingmodels" @@ -110,35 +111,35 @@ func (t Tool) ToConfig() tools.ToolConfig { return t.Config } -func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, util.ToolboxError) { source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { - return nil, err + return nil, util.NewClientServerError("source used is not compatible with the tool", http.StatusInternalServerError, err) } logger, err := util.LoggerFromContext(ctx) if err != nil { - return nil, fmt.Errorf("unable to get logger from ctx: %s", err) + return nil, util.NewClientServerError("unable to get logger from ctx", http.StatusInternalServerError, err) } sdk, err := source.GetLookerSDK(string(accessToken)) if err != nil { - return nil, fmt.Errorf("error getting sdk: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error getting sdk: %v", err), http.StatusInternalServerError, err) } mapParams := params.AsMap() projectId, ok := mapParams["project_id"].(string) if !ok { - return nil, fmt.Errorf("'project_id' must be a string, got %T", mapParams["project_id"]) + return nil, util.NewAgentError(fmt.Sprintf("'project_id' must be a string, got %T", mapParams["project_id"]), nil) } filePath, ok := mapParams["file_path"].(string) if !ok { - return nil, fmt.Errorf("'file_path' must be a string, got %T", mapParams["file_path"]) + return nil, util.NewAgentError(fmt.Sprintf("'file_path' must be a string, got %T", mapParams["file_path"]), nil) } resp, err := lookercommon.GetProjectFileContent(sdk, projectId, filePath, source.LookerApiSettings()) if err != nil { - return nil, fmt.Errorf("error making get_project_file request: %s", err) + return nil, util.NewClientServerError(fmt.Sprintf("error making get_project_file request: %s", err), http.StatusInternalServerError, err) } logger.DebugContext(ctx, "Got response of %v\n", resp) diff --git a/internal/tools/looker/lookergetprojectfiles/lookergetprojectfiles.go b/internal/tools/looker/lookergetprojectfiles/lookergetprojectfiles.go index 9ba42e5916..b2a05ff626 100644 --- a/internal/tools/looker/lookergetprojectfiles/lookergetprojectfiles.go +++ b/internal/tools/looker/lookergetprojectfiles/lookergetprojectfiles.go @@ -16,6 +16,7 @@ package lookergetprojectfiles import ( "context" "fmt" + "net/http" yaml "github.com/goccy/go-yaml" "github.com/googleapis/genai-toolbox/internal/embeddingmodels" @@ -108,31 +109,31 @@ func (t Tool) ToConfig() tools.ToolConfig { return t.Config } -func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, util.ToolboxError) { source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { - return nil, err + return nil, util.NewClientServerError("source used is not compatible with the tool", http.StatusInternalServerError, err) } logger, err := util.LoggerFromContext(ctx) if err != nil { - return nil, fmt.Errorf("unable to get logger from ctx: %s", err) + return nil, util.NewClientServerError("unable to get logger from ctx", http.StatusInternalServerError, err) } sdk, err := source.GetLookerSDK(string(accessToken)) if err != nil { - return nil, fmt.Errorf("error getting sdk: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error getting sdk: %v", err), http.StatusInternalServerError, err) } mapParams := params.AsMap() projectId, ok := mapParams["project_id"].(string) if !ok { - return nil, fmt.Errorf("'project_id' must be a string, got %T", mapParams["project_id"]) + return nil, util.NewAgentError(fmt.Sprintf("'project_id' must be a string, got %T", mapParams["project_id"]), nil) } resp, err := sdk.AllProjectFiles(projectId, "", source.LookerApiSettings()) if err != nil { - return nil, fmt.Errorf("error making get_project_files request: %s", err) + return nil, util.NewClientServerError(fmt.Sprintf("error making get_project_files request: %s", err), http.StatusInternalServerError, err) } var data []any diff --git a/internal/tools/looker/lookergetprojects/lookergetprojects.go b/internal/tools/looker/lookergetprojects/lookergetprojects.go index ae93d87790..74118951a6 100644 --- a/internal/tools/looker/lookergetprojects/lookergetprojects.go +++ b/internal/tools/looker/lookergetprojects/lookergetprojects.go @@ -16,6 +16,7 @@ package lookergetprojects import ( "context" "fmt" + "net/http" yaml "github.com/goccy/go-yaml" "github.com/googleapis/genai-toolbox/internal/embeddingmodels" @@ -107,25 +108,25 @@ func (t Tool) ToConfig() tools.ToolConfig { return t.Config } -func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, util.ToolboxError) { source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { - return nil, err + return nil, util.NewClientServerError("source used is not compatible with the tool", http.StatusInternalServerError, err) } logger, err := util.LoggerFromContext(ctx) if err != nil { - return nil, fmt.Errorf("unable to get logger from ctx: %s", err) + return nil, util.NewClientServerError("unable to get logger from ctx", http.StatusInternalServerError, err) } sdk, err := source.GetLookerSDK(string(accessToken)) if err != nil { - return nil, fmt.Errorf("error getting sdk: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error getting sdk: %v", err), http.StatusInternalServerError, err) } resp, err := sdk.AllProjects("id,name", source.LookerApiSettings()) if err != nil { - return nil, fmt.Errorf("error making get_models request: %s", err) + return nil, util.NewClientServerError(fmt.Sprintf("error making get_models request: %s", err), http.StatusInternalServerError, err) } var data []any diff --git a/internal/tools/looker/lookerhealthanalyze/lookerhealthanalyze.go b/internal/tools/looker/lookerhealthanalyze/lookerhealthanalyze.go index 140842f0b3..9e23061e44 100644 --- a/internal/tools/looker/lookerhealthanalyze/lookerhealthanalyze.go +++ b/internal/tools/looker/lookerhealthanalyze/lookerhealthanalyze.go @@ -17,6 +17,7 @@ import ( "context" "encoding/json" "fmt" + "net/http" "regexp" "strings" @@ -125,20 +126,20 @@ func (t Tool) ToConfig() tools.ToolConfig { return t.Config } -func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, util.ToolboxError) { source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { - return nil, err + return nil, util.NewClientServerError("source used is not compatible with the tool", http.StatusInternalServerError, err) } logger, err := util.LoggerFromContext(ctx) if err != nil { - return nil, fmt.Errorf("unable to get logger from ctx: %s", err) + return nil, util.NewClientServerError("unable to get logger from ctx", http.StatusInternalServerError, err) } sdk, err := source.GetLookerSDK(string(accessToken)) if err != nil { - return nil, fmt.Errorf("error getting sdk: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error getting sdk: %v", err), http.StatusInternalServerError, err) } paramsMap := params.AsMap() @@ -159,7 +160,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para action, ok := paramsMap["action"].(string) if !ok { - return nil, fmt.Errorf("action parameter not found") + return nil, util.NewAgentError("action parameter not found", nil) } switch action { @@ -167,7 +168,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para projectId, _ := paramsMap["project"].(string) result, err := analyzeTool.projects(ctx, projectId) if err != nil { - return nil, fmt.Errorf("error analyzing projects: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error analyzing projects: %v", err), http.StatusInternalServerError, err) } logger.DebugContext(ctx, "result = ", result) return result, nil @@ -176,7 +177,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para modelName, _ := paramsMap["model"].(string) result, err := analyzeTool.models(ctx, projectName, modelName) if err != nil { - return nil, fmt.Errorf("error analyzing models: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error analyzing models: %v", err), http.StatusInternalServerError, err) } logger.DebugContext(ctx, "result = ", result) return result, nil @@ -185,12 +186,12 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para exploreName, _ := paramsMap["explore"].(string) result, err := analyzeTool.explores(ctx, modelName, exploreName) if err != nil { - return nil, fmt.Errorf("error analyzing explores: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error analyzing explores: %v", err), http.StatusInternalServerError, err) } logger.DebugContext(ctx, "result = ", result) return result, nil default: - return nil, fmt.Errorf("unknown action: %s", action) + return nil, util.NewAgentError(fmt.Sprintf("unknown action: %s", action), nil) } } @@ -231,23 +232,23 @@ type analyzeTool struct { minQueries int } -func (t *analyzeTool) projects(ctx context.Context, id string) ([]map[string]interface{}, error) { +func (t *analyzeTool) projects(ctx context.Context, id string) ([]map[string]interface{}, util.ToolboxError) { logger, err := util.LoggerFromContext(ctx) if err != nil { - return nil, fmt.Errorf("unable to get logger from ctx: %s", err) + return nil, util.NewClientServerError("unable to get logger from ctx", http.StatusInternalServerError, err) } var projects []*v4.Project if id != "" { p, err := t.SdkClient.Project(id, "", nil) if err != nil { - return nil, fmt.Errorf("error fetching project %s: %w", id, err) + return nil, util.NewClientServerError(fmt.Sprintf("error fetching project %s: %v", id, err), http.StatusInternalServerError, err) } projects = append(projects, &p) } else { allProjects, err := t.SdkClient.AllProjects("", nil) if err != nil { - return nil, fmt.Errorf("error fetching all projects: %w", err) + return nil, util.NewClientServerError(fmt.Sprintf("error fetching all projects: %v", err), http.StatusInternalServerError, err) } for i := range allProjects { projects = append(projects, &allProjects[i]) @@ -256,13 +257,19 @@ func (t *analyzeTool) projects(ctx context.Context, id string) ([]map[string]int var results []map[string]interface{} for _, p := range projects { + if p.Name == nil { + return nil, util.NewAgentError("project name is nil", nil) + } pName := *p.Name + if p.Id == nil { + return nil, util.NewAgentError("project ID is nil", nil) + } pID := *p.Id logger.InfoContext(ctx, fmt.Sprintf("Analyzing project: %s", pName)) projectFiles, err := t.SdkClient.AllProjectFiles(pID, "", nil) if err != nil { - return nil, fmt.Errorf("error fetching files for project %s: %w", pName, err) + return nil, util.NewClientServerError(fmt.Sprintf("error fetching files for project %s: %v", pName, err), http.StatusInternalServerError, err) } modelCount := 0 @@ -285,6 +292,13 @@ func (t *analyzeTool) projects(ctx context.Context, id string) ([]map[string]int gitConnectionStatus = "Bare repo, no tests required" } + if p.PullRequestMode == nil { + return nil, util.NewAgentError("pull request mode is nil", nil) + } + if p.ValidationRequired == nil { + return nil, util.NewAgentError("validation required is nil", nil) + } + results = append(results, map[string]interface{}{ "Project": pName, "# Models": modelCount, @@ -297,21 +311,21 @@ func (t *analyzeTool) projects(ctx context.Context, id string) ([]map[string]int return results, nil } -func (t *analyzeTool) models(ctx context.Context, project, model string) ([]map[string]interface{}, error) { +func (t *analyzeTool) models(ctx context.Context, project, model string) ([]map[string]interface{}, util.ToolboxError) { logger, err := util.LoggerFromContext(ctx) if err != nil { - return nil, fmt.Errorf("unable to get logger from ctx: %s", err) + return nil, util.NewClientServerError("unable to get logger from ctx", http.StatusInternalServerError, err) } logger.InfoContext(ctx, "Analyzing models...") usedModels, err := t.getUsedModels(ctx) if err != nil { - return nil, err + return nil, util.NewClientServerError("error getting used models", http.StatusInternalServerError, err) } lookmlModels, err := t.SdkClient.AllLookmlModels(v4.RequestAllLookmlModels{}, nil) if err != nil { - return nil, fmt.Errorf("error fetching LookML models: %w", err) + return nil, util.NewClientServerError("error fetching LookML models", http.StatusInternalServerError, err) } var results []map[string]interface{} diff --git a/internal/tools/utility/wait/wait.go b/internal/tools/utility/wait/wait.go index e6638da2fc..32e752d113 100644 --- a/internal/tools/utility/wait/wait.go +++ b/internal/tools/utility/wait/wait.go @@ -23,6 +23,7 @@ import ( "github.com/googleapis/genai-toolbox/internal/embeddingmodels" "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util" "github.com/googleapis/genai-toolbox/internal/util/parameters" ) @@ -81,17 +82,17 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, util.ToolboxError) { paramsMap := params.AsMap() durationStr, ok := paramsMap["duration"].(string) if !ok { - return nil, fmt.Errorf("duration parameter is not a string") + return nil, util.NewAgentError("duration parameter is not a string", nil) } totalDuration, err := time.ParseDuration(durationStr) if err != nil { - return nil, fmt.Errorf("invalid duration format: %w", err) + return nil, util.NewAgentError("invalid duration format", err) } time.Sleep(totalDuration) diff --git a/internal/tools/valkey/valkey.go b/internal/tools/valkey/valkey.go index 46be19f886..95c7674832 100644 --- a/internal/tools/valkey/valkey.go +++ b/internal/tools/valkey/valkey.go @@ -16,11 +16,13 @@ package valkey import ( "context" "fmt" + "net/http" yaml "github.com/goccy/go-yaml" "github.com/googleapis/genai-toolbox/internal/embeddingmodels" "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util" "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/valkey-io/valkey-go" ) @@ -84,18 +86,22 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, util.ToolboxError) { source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { - return nil, err + return nil, util.NewClientServerError("source not compatible with this tool", http.StatusInternalServerError, nil) } // Replace parameters commands, err := replaceCommandsParams(t.Commands, t.Parameters, params) if err != nil { - return nil, fmt.Errorf("error replacing commands' parameters: %s", err) + return nil, util.NewAgentError("error replacing commands' parameters", err) } - return source.RunCommand(ctx, commands) + res, err := source.RunCommand(ctx, commands) + if err != nil { + return nil, util.ProcessGeneralError(err) + } + return res, nil } // replaceCommandsParams is a helper function to replace parameters in the commands diff --git a/internal/tools/yugabytedbsql/yugabytedbsql.go b/internal/tools/yugabytedbsql/yugabytedbsql.go index d97fd1dea2..6eb3f51f6c 100644 --- a/internal/tools/yugabytedbsql/yugabytedbsql.go +++ b/internal/tools/yugabytedbsql/yugabytedbsql.go @@ -17,11 +17,13 @@ package yugabytedbsql import ( "context" "fmt" + "net/http" yaml "github.com/goccy/go-yaml" embeddingmodels "github.com/googleapis/genai-toolbox/internal/embeddingmodels" "github.com/googleapis/genai-toolbox/internal/sources" "github.com/googleapis/genai-toolbox/internal/tools" + "github.com/googleapis/genai-toolbox/internal/util" "github.com/googleapis/genai-toolbox/internal/util/parameters" "github.com/yugabyte/pgx/v5/pgxpool" ) @@ -93,24 +95,28 @@ type Tool struct { mcpManifest tools.McpManifest } -func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) { +func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, util.ToolboxError) { source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type) if err != nil { - return nil, err + return nil, util.NewClientServerError("source not compatible with this tool", http.StatusInternalServerError, nil) } paramsMap := params.AsMap() newStatement, err := parameters.ResolveTemplateParams(t.TemplateParameters, t.Statement, paramsMap) if err != nil { - return nil, fmt.Errorf("unable to extract template params %w", err) + return nil, util.NewAgentError("unable to extract template params", err) } newParams, err := parameters.GetParams(t.Parameters, paramsMap) if err != nil { - return nil, fmt.Errorf("unable to extract standard params %w", err) + return nil, util.NewAgentError("unable to extract standard params", err) } sliceParams := newParams.AsSlice() - return source.RunSQL(ctx, newStatement, sliceParams) + res, err := source.RunSQL(ctx, newStatement, sliceParams) + if err != nil { + return nil, util.ProcessGeneralError(err) + } + return res, nil } func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {