diff --git a/internal/tools/firestore/firestorequerycollection/firestorequerycollection.go b/internal/tools/firestore/firestorequerycollection/firestorequerycollection.go index 9f8eb29007..31f0907abc 100644 --- a/internal/tools/firestore/firestorequerycollection/firestorequerycollection.go +++ b/internal/tools/firestore/firestorequerycollection/firestorequerycollection.go @@ -18,6 +18,7 @@ import ( "context" "encoding/json" "fmt" + "net/http" // Added for http.StatusInternalServerError "strings" firestoreapi "cloud.google.com/go/firestore" @@ -25,7 +26,8 @@ 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/tools/firestore/util" + 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/parameters" ) @@ -230,16 +232,16 @@ 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) { +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) } // Parse parameters queryParams, err := t.parseQueryParameters(params) if err != nil { - return nil, err + return nil, util.NewAgentError(fmt.Sprintf("failed to parse query parameters: %v", err), err) } var filter firestoreapi.EntityFilter @@ -270,9 +272,13 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para // Build the query query, err := source.BuildQuery(queryParams.CollectionPath, filter, nil, orderByField, orderByDirection, queryParams.Limit, queryParams.AnalyzeQuery) if err != nil { - return nil, err + return nil, util.ProecessGcpError(err) } - return source.ExecuteQuery(ctx, query, queryParams.AnalyzeQuery) + resp, err := source.ExecuteQuery(ctx, query, queryParams.AnalyzeQuery) + if err != nil { + return nil, util.ProecessGcpError(err) + } + return resp, nil } // queryParameters holds all parsed query parameters @@ -295,7 +301,7 @@ func (t Tool) parseQueryParameters(params parameters.ParamValues) (*queryParamet } // Validate collection path - if err := util.ValidateCollectionPath(collectionPath); err != nil { + if err := fsUtil.ValidateCollectionPath(collectionPath); err != nil { return nil, fmt.Errorf("invalid collection path: %w", err) } diff --git a/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument.go b/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument.go index b059d28e91..0de0bd4f50 100644 --- a/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument.go +++ b/internal/tools/firestore/firestoreupdatedocument/firestoreupdatedocument.go @@ -17,6 +17,7 @@ package firestoreupdatedocument import ( "context" "fmt" + "net/http" // Added for http.StatusInternalServerError "strings" firestoreapi "cloud.google.com/go/firestore" @@ -24,7 +25,8 @@ 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/tools/firestore/util" + 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/parameters" ) @@ -138,10 +140,10 @@ 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) } mapParams := params.AsMap() @@ -149,18 +151,18 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para // Get document path documentPath, ok := mapParams[documentPathKey].(string) if !ok || documentPath == "" { - return nil, fmt.Errorf("invalid or missing '%s' parameter", documentPathKey) + return nil, util.NewAgentError(fmt.Sprintf("invalid or missing '%s' parameter", documentPathKey), nil) } // Validate document path - if err := util.ValidateDocumentPath(documentPath); err != nil { - return nil, fmt.Errorf("invalid document path: %w", err) + if err := fsUtil.ValidateDocumentPath(documentPath); err != nil { + return nil, util.NewAgentError(fmt.Sprintf("invalid document path: %v", err), err) } // Get document data documentDataRaw, ok := mapParams[documentDataKey] if !ok { - return nil, fmt.Errorf("invalid or missing '%s' parameter", documentDataKey) + return nil, util.NewAgentError(fmt.Sprintf("invalid or missing '%s' parameter", documentDataKey), nil) } // Get update mask if provided @@ -170,11 +172,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para // Use ConvertAnySliceToTyped to convert the slice typedSlice, err := parameters.ConvertAnySliceToTyped(updateMaskArray, "string") if err != nil { - return nil, fmt.Errorf("failed to convert update mask: %w", err) + return nil, util.NewAgentError(fmt.Sprintf("failed to convert update mask: %v", err), err) } updatePaths, ok = typedSlice.([]string) if !ok { - return nil, fmt.Errorf("unexpected type conversion error for update mask") + return nil, util.NewAgentError("unexpected type conversion error for update mask", nil) } } } @@ -184,15 +186,15 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para if len(updatePaths) > 0 { // Convert document data without delete markers - dataMap, err := util.JSONToFirestoreValue(documentDataRaw, source.FirestoreClient()) + dataMap, err := fsUtil.JSONToFirestoreValue(documentDataRaw, source.FirestoreClient()) if err != nil { - return nil, fmt.Errorf("failed to convert document data: %w", err) + return nil, util.NewAgentError(fmt.Sprintf("failed to convert document data: %v", err), err) } // Ensure it's a map dataMapTyped, ok := dataMap.(map[string]interface{}) if !ok { - return nil, fmt.Errorf("document data must be a map") + return nil, util.NewAgentError("document data must be a map", nil) } for _, path := range updatePaths { @@ -210,9 +212,9 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para } } else { // Update all fields in the document data (merge) - documentData, err = util.JSONToFirestoreValue(documentDataRaw, source.FirestoreClient()) + documentData, err = fsUtil.JSONToFirestoreValue(documentDataRaw, source.FirestoreClient()) if err != nil { - return nil, fmt.Errorf("failed to convert document data: %w", err) + return nil, util.NewAgentError(fmt.Sprintf("failed to convert document data: %v", err), err) } } @@ -221,7 +223,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para if val, ok := mapParams[returnDocumentDataKey].(bool); ok { returnData = val } - return source.UpdateDocument(ctx, documentPath, updates, documentData, returnData) + resp, err := source.UpdateDocument(ctx, documentPath, updates, documentData, returnData) + if err != nil { + return nil, util.ProecessGcpError(err) + } + return resp, nil } // getFieldValue retrieves a value from a nested map using a dot-separated path diff --git a/internal/tools/firestore/firestorevalidaterules/firestorevalidaterules.go b/internal/tools/firestore/firestorevalidaterules/firestorevalidaterules.go index 617ad80c5b..7142e91f69 100644 --- a/internal/tools/firestore/firestorevalidaterules/firestorevalidaterules.go +++ b/internal/tools/firestore/firestorevalidaterules/firestorevalidaterules.go @@ -17,11 +17,13 @@ package firestorevalidaterules import ( "context" "fmt" + "net/http" // Added for http.StatusInternalServerError 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/parameters" "google.golang.org/api/firebaserules/v1" ) @@ -106,10 +108,10 @@ 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) } mapParams := params.AsMap() @@ -117,9 +119,13 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para // Get source parameter sourceParam, ok := mapParams[sourceKey].(string) if !ok || sourceParam == "" { - return nil, fmt.Errorf("invalid or missing '%s' parameter", sourceKey) + return nil, util.NewAgentError(fmt.Sprintf("invalid or missing '%s' parameter", sourceKey), nil) } - return source.ValidateRules(ctx, sourceParam) + resp, err := source.ValidateRules(ctx, sourceParam) + if err != nil { + return nil, util.ProecessGcpError(err) + } + return resp, nil } func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {