Compare commits

...

6 Commits

Author SHA1 Message Date
Prerna Kakkar
1a91378cb3 resolve comments 2025-08-08 12:35:01 +00:00
Prerna Kakkar
627dcd5c8c Merge branch 'main' into generate-bearer-token 2025-08-08 11:54:05 +00:00
Prerna Kakkar
f31126e07e add documentation 2025-08-07 17:41:45 +00:00
Prerna Kakkar
708ece08e0 Merge branch 'main' into generate-bearer-token 2025-08-07 17:39:44 +00:00
Prerna Kakkar
b3ca5858bc Merge branch 'main' into generate-bearer-token 2025-08-07 17:39:23 +00:00
Prerna Kakkar
56d725ad7a feat(tools/http): Add bearer token support from code 2025-08-05 13:54:10 +00:00
4 changed files with 79 additions and 18 deletions

View File

@@ -139,6 +139,27 @@ my-http-tool:
type: integer
```
### Google Cloud OAuth2 Token
Toolbox can automatically generate and add a Google Cloud OAuth2 token to the
`Authorization` header using Google Application Default Credentials.
This is useful for authenticating with Google Cloud APIs.
To enable this, set the `googleCloudOAuth2` field to `true`:
```yaml
my-http-tool:
kind: http
source: my-http-source
method: GET
path: /some/google/cloud/api
description: A tool that calls a Google Cloud API
googleCloudOAuth2: true
```
When `googleCloudOAuth2` is `true`, Toolbox will obtain an OAuth2 token and set the
`Authorization` header to `Bearer <token>`. This will override any static
`Authorization` header you may have set in the `headers` field.
### Request body
The request body payload is a string that supports parameter replacement
@@ -247,17 +268,18 @@ my-http-tool:
## Reference
| **field** | **type** | **required** | **description** |
|--------------|:------------------------------------------:|:------------:|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| kind | 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. |
| method | string | true | The HTTP method to use (e.g., GET, POST, PUT, DELETE). |
| headers | map[string]string | false | A map of headers to include in the HTTP request (overrides source headers). |
| requestBody | string | false | The request body payload. Use [go template][go-template-doc] with the parameter name as the placeholder (e.g., `{{.id}}` will be replaced with the value of the parameter that has name `id` in the `bodyParams` section). |
| queryParams | [parameters](../#specifying-parameters) | false | List of [parameters](../#specifying-parameters) that will be inserted into the query string. |
| bodyParams | [parameters](../#specifying-parameters) | false | List of [parameters](../#specifying-parameters) that will be inserted into the request body payload. |
| headerParams | [parameters](../#specifying-parameters) | false | List of [parameters](../#specifying-parameters) that will be inserted as the request headers. |
| **field** | **type** | **required** | **description** |
| ----------------- | :-------------------------------------: | :----------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| kind | 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. |
| method | string | true | The HTTP method to use (e.g., GET, POST, PUT, DELETE). |
| headers | map[string]string | false | A map of headers to include in the HTTP request (overrides source headers). |
| requestBody | string | false | The request body payload. Use [go template][go-template-doc] with the parameter name as the placeholder (e.g., `{{.id}}` will be replaced with the value of the parameter that has name `id` in the `bodyParams` section). |
| queryParams | [parameters](../#specifying-parameters) | false | List of [parameters](../#specifying-parameters) that will be inserted into the query string. |
| bodyParams | [parameters](../#specifying-parameters) | false | List of [parameters](../#specifying-parameters) that will be inserted into the request body payload. |
| headerParams | [parameters](../#specifying-parameters) | false | List of [parameters](../#specifying-parameters) that will be inserted as the request headers. |
| googleCloudOAuth2 | boolean | false | When `true`, automatically generates and adds a Google Cloud OAuth2 token to the `Authorization` header using Google Application Default Credentials. |
[go-template-doc]: <https://pkg.go.dev/text/template#pkg-overview>

View File

@@ -10,6 +10,7 @@ tools:
kind: http
source: alloydb-api-source
method: POST
googleCloudOAuth2: true
path: /v1/projects/{{.projectId}}/locations/{{.locationId}}/clusters
description: "Create a new AlloyDB cluster. This is a long-running operation, but the API call returns quickly. This will return operation id to be used by get operations tool. Take all parameters from user in one go."
pathParams:
@@ -60,6 +61,7 @@ tools:
kind: http
source: alloydb-api-source
method: POST
googleCloudOAuth2: true
path: /v1/projects/{{.projectId}}/locations/{{.locationId}}/clusters/{{.clusterId}}/instances
description: "Creates a new AlloyDB instance (PRIMARY, READ_POOL, or SECONDARY) within a cluster. This is a long-running operation. Take all parameters from user in one go. This will return operation id to be used by get operations tool."
pathParams:

View File

@@ -32,6 +32,7 @@ import (
httpsrc "github.com/googleapis/genai-toolbox/internal/sources/http"
"github.com/googleapis/genai-toolbox/internal/tools"
"github.com/googleapis/genai-toolbox/internal/util"
"golang.org/x/oauth2/google"
)
const kind string = "http"
@@ -64,6 +65,10 @@ type Config struct {
QueryParams tools.Parameters `yaml:"queryParams"`
BodyParams tools.Parameters `yaml:"bodyParams"`
HeaderParams tools.Parameters `yaml:"headerParams"`
// GoogleCloudOAuth2, when true, automatically generates and adds a Google Cloud
// OAuth2 token to the Authorization header using Google Application
// Default Credentials.
GoogleCloudOAuth2 bool `yaml:"googleCloudOAuth2"`
}
// validate interface
@@ -178,6 +183,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
AllParams: allParameters,
manifest: tools.Manifest{Description: cfg.Description, Parameters: paramManifest, AuthRequired: cfg.AuthRequired},
mcpManifest: mcpManifest,
GoogleCloudOAuth2: cfg.GoogleCloudOAuth2,
}, nil
}
@@ -196,12 +202,13 @@ type Tool struct {
Headers map[string]string `yaml:"headers"`
DefaultQueryParams map[string]string `yaml:"defaultQueryParams"`
RequestBody string `yaml:"requestBody"`
PathParams tools.Parameters `yaml:"pathParams"`
QueryParams tools.Parameters `yaml:"queryParams"`
BodyParams tools.Parameters `yaml:"bodyParams"`
HeaderParams tools.Parameters `yaml:"headerParams"`
AllParams tools.Parameters `yaml:"allParams"`
RequestBody string `yaml:"requestBody"`
PathParams tools.Parameters `yaml:"pathParams"`
QueryParams tools.Parameters `yaml:"queryParams"`
BodyParams tools.Parameters `yaml:"bodyParams"`
HeaderParams tools.Parameters `yaml:"headerParams"`
AllParams tools.Parameters `yaml:"allParams"`
GoogleCloudOAuth2 bool
Client *http.Client
manifest tools.Manifest
@@ -309,6 +316,25 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues) (any, error)
if err != nil {
return nil, fmt.Errorf("error populating request headers: %s", err)
}
// If GoogleCloudOAuth2 is true, generate an OAuth2 token and set the Authorization header.
// This will override any static Authorization header in the configuration.
if t.GoogleCloudOAuth2 {
// This uses Application Default Credentials to generate an OAuth2 token.
// It assumes the tool is being run in an environment with appropriate credentials
// (e.g., a GCE VM, or with `gcloud auth application-default login`).
// The default scope is for Google Cloud Platform services.
tokenSource, err := google.DefaultTokenSource(ctx, "https://www.googleapis.com/auth/cloud-platform")
if err != nil {
return nil, fmt.Errorf("error creating token source: %w", err)
}
token, err := tokenSource.Token()
if err != nil {
return nil, fmt.Errorf("error retrieving token: %w", err)
}
allHeaders["Authorization"] = "Bearer " + token.AccessToken
}
// Set request headers
for k, v := range allHeaders {
req.Header.Set(k, v)

View File

@@ -31,6 +31,7 @@ import (
httpsrc "github.com/googleapis/genai-toolbox/internal/sources/http"
"github.com/googleapis/genai-toolbox/internal/tools"
"github.com/googleapis/genai-toolbox/internal/util"
"golang.org/x/oauth2/google"
)
const kind string = "alloydb-wait-for-operation"
@@ -256,6 +257,16 @@ func (t *Tool) Invoke(ctx context.Context, params tools.ParamValues) (any, error
req.Header.Set(k, v)
}
tokenSource, err := google.DefaultTokenSource(ctx, "https://www.googleapis.com/auth/cloud-platform")
if err != nil {
return nil, fmt.Errorf("error creating token source: %w", err)
}
token, err := tokenSource.Token()
if err != nil {
return nil, fmt.Errorf("error retrieving token: %w", err)
}
req.Header.Set("Authorization", "Bearer "+token.AccessToken)
if ua, err := util.UserAgentFromContext(ctx); err == nil {
req.Header.Set("User-Agent", ua)
}