Compare commits

..

23 Commits

Author SHA1 Message Date
gRedHeadphone
caa33d41b2 chore: fix for configuration file changes 2026-01-28 09:35:41 +00:00
gRedHeadphone
668ca5da8a Merge branch 'main' into spanner-create-instance 2026-01-28 12:39:43 +05:30
gRedHeadphone
a7d0f19716 Merge branch 'main' into spanner-create-instance 2026-01-23 12:33:55 +05:30
gRedHeadphone
de7c65eb1c chore: header update + main merge fixes 2026-01-09 05:21:19 +00:00
gRedHeadphone
589059ed3f Merge branch 'main' into spanner-create-instance 2026-01-09 10:37:09 +05:30
gRedHeadphone
6d43488ddf Merge branch 'main' into spanner-create-instance 2025-12-31 13:16:30 +05:30
gRedHeadphone
3a317a3455 Merge branch 'main' into spanner-create-instance 2025-12-29 13:28:07 +05:30
gRedHeadphone
af62ddf9c1 chore: minor fixes 2025-12-22 05:49:49 +00:00
gRedHeadphone
1475b4d092 Merge branch 'main' into spanner-create-instance 2025-12-22 10:56:47 +05:30
gRedHeadphone
c67b0cf0fc Update internal/tools/spanneradmin/spannercreateinstance/spannercreateinstance.go
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
2025-12-22 10:56:20 +05:30
gRedHeadphone
511c4651f3 Update internal/tools/spanneradmin/spannercreateinstance/spannercreateinstance.go
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
2025-12-22 10:56:08 +05:30
gRedHeadphone
62095feadb Update internal/tools/spanneradmin/spannercreateinstance/spannercreateinstance.go
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
2025-12-22 10:55:45 +05:30
gRedHeadphone
f9f34b1005 Update internal/tools/spanneradmin/spannercreateinstance/spannercreateinstance.go
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
2025-12-22 10:55:26 +05:30
gRedHeadphone
4170fe309f Update internal/tools/spanneradmin/spannercreateinstance/spannercreateinstance.go
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
2025-12-22 10:54:58 +05:30
gRedHeadphone
a9edd5e32d Update internal/tools/spanneradmin/spannercreateinstance/spannercreateinstance.go
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
2025-12-22 10:54:40 +05:30
gRedHeadphone
09c979d8db Update internal/tools/spanneradmin/spannercreateinstance/spannercreateinstance.go
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
2025-12-22 10:54:26 +05:30
gRedHeadphone
7d79f4909a Update internal/tools/spanneradmin/spannercreateinstance/spannercreateinstance.go
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
2025-12-22 10:53:43 +05:30
gRedHeadphone
330dd843bf Update internal/tools/spanneradmin/spannercreateinstance/spannercreateinstance.go
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
2025-12-22 10:53:30 +05:30
gRedHeadphone
e831f71421 Update internal/tools/spanneradmin/spannercreateinstance/spannercreateinstance.go
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
2025-12-22 10:53:12 +05:30
gRedHeadphone
4f62db499d Update internal/tools/spanneradmin/spannercreateinstance/spannercreateinstance.go
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
2025-12-22 10:52:38 +05:30
gRedHeadphone
e6de2170cf Update internal/sources/spanneradmin/spanneradmin.go
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
2025-12-22 10:52:11 +05:30
gRedHeadphone
5b7f5a3039 chore: update parameter description & format docs table spanner create instance 2025-12-19 10:10:59 +00:00
gRedHeadphone
302b564ca1 feat(spanner-admin): spanner admin source + create instance tool 2025-12-19 09:59:05 +00:00
229 changed files with 1679 additions and 2050 deletions

View File

@@ -295,25 +295,6 @@ steps:
cloudhealthcare \ cloudhealthcare \
cloudhealthcare cloudhealthcare
- id: "cloud-logging-admin"
name: golang:1
waitFor: ["compile-test-binary"]
entrypoint: /bin/bash
env:
- "GOPATH=/gopath"
- "LOGADMIN_PROJECT=$PROJECT_ID"
secretEnv: ["CLIENT_ID"]
volumes:
- name: "go"
path: "/gopath"
args:
- -c
- |
.ci/test_with_coverage.sh \
"Cloud Logging Admin" \
cloudloggingadmin \
cloudloggingadmin
- id: "postgres" - id: "postgres"
name: golang:1 name: golang:1
waitFor: ["compile-test-binary"] waitFor: ["compile-test-binary"]
@@ -359,6 +340,26 @@ steps:
spanner \ spanner \
spanner || echo "Integration tests failed." # ignore test failures spanner || echo "Integration tests failed." # ignore test failures
- id: "spanner-admin"
name: golang:1
waitFor: ["compile-test-binary"]
entrypoint: /bin/bash
env:
- "GOPATH=/gopath"
- "SPANNER_PROJECT=$PROJECT_ID"
- "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
secretEnv: ["CLIENT_ID"]
volumes:
- name: "go"
path: "/gopath"
args:
- -c
- |
.ci/test_with_coverage.sh \
"Spanner Admin" \
spanneradmin \
spanneradmin || echo "Integration tests failed."
- id: "neo4j" - id: "neo4j"
name: golang:1 name: golang:1
waitFor: ["compile-test-binary"] waitFor: ["compile-test-binary"]

View File

@@ -107,7 +107,7 @@ redeploying your application.
## Getting Started ## Getting Started
### Quickstart: Running Toolbox using NPX ### (Non-production) Running Toolbox
You can run Toolbox directly with a [configuration file](#configuration): You can run Toolbox directly with a [configuration file](#configuration):

View File

@@ -1,36 +0,0 @@
// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// 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,
// 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.
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
func newInvokeCmd(root *Command) *cobra.Command {
return &cobra.Command{
Use: "invoke",
Short: "Invoke a tool",
Run: func(cmd *cobra.Command, args []string) {
invoke(root)
},
}
}
func invoke(cmd *Command) {
fmt.Println("Hello, World! Here is one of my flags" + cmd.cfg.Address)
}

View File

@@ -91,9 +91,6 @@ import (
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaresearchdicominstances" _ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaresearchdicominstances"
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomseries" _ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomseries"
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomstudies" _ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomstudies"
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudloggingadmin/cloudloggingadminlistlognames"
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudloggingadmin/cloudloggingadminlistresourcetypes"
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudloggingadmin/cloudloggingadminquerylogs"
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudmonitoring" _ "github.com/googleapis/genai-toolbox/internal/tools/cloudmonitoring"
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsql/cloudsqlcloneinstance" _ "github.com/googleapis/genai-toolbox/internal/tools/cloudsql/cloudsqlcloneinstance"
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsql/cloudsqlcreatebackup" _ "github.com/googleapis/genai-toolbox/internal/tools/cloudsql/cloudsqlcreatebackup"
@@ -227,6 +224,7 @@ import (
_ "github.com/googleapis/genai-toolbox/internal/tools/spanner/spannerlistgraphs" _ "github.com/googleapis/genai-toolbox/internal/tools/spanner/spannerlistgraphs"
_ "github.com/googleapis/genai-toolbox/internal/tools/spanner/spannerlisttables" _ "github.com/googleapis/genai-toolbox/internal/tools/spanner/spannerlisttables"
_ "github.com/googleapis/genai-toolbox/internal/tools/spanner/spannersql" _ "github.com/googleapis/genai-toolbox/internal/tools/spanner/spannersql"
_ "github.com/googleapis/genai-toolbox/internal/tools/spanneradmin/spannercreateinstance"
_ "github.com/googleapis/genai-toolbox/internal/tools/sqlite/sqliteexecutesql" _ "github.com/googleapis/genai-toolbox/internal/tools/sqlite/sqliteexecutesql"
_ "github.com/googleapis/genai-toolbox/internal/tools/sqlite/sqlitesql" _ "github.com/googleapis/genai-toolbox/internal/tools/sqlite/sqlitesql"
_ "github.com/googleapis/genai-toolbox/internal/tools/tidb/tidbexecutesql" _ "github.com/googleapis/genai-toolbox/internal/tools/tidb/tidbexecutesql"
@@ -247,7 +245,6 @@ import (
_ "github.com/googleapis/genai-toolbox/internal/sources/clickhouse" _ "github.com/googleapis/genai-toolbox/internal/sources/clickhouse"
_ "github.com/googleapis/genai-toolbox/internal/sources/cloudgda" _ "github.com/googleapis/genai-toolbox/internal/sources/cloudgda"
_ "github.com/googleapis/genai-toolbox/internal/sources/cloudhealthcare" _ "github.com/googleapis/genai-toolbox/internal/sources/cloudhealthcare"
_ "github.com/googleapis/genai-toolbox/internal/sources/cloudloggingadmin"
_ "github.com/googleapis/genai-toolbox/internal/sources/cloudmonitoring" _ "github.com/googleapis/genai-toolbox/internal/sources/cloudmonitoring"
_ "github.com/googleapis/genai-toolbox/internal/sources/cloudsqladmin" _ "github.com/googleapis/genai-toolbox/internal/sources/cloudsqladmin"
_ "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlmssql" _ "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlmssql"
@@ -274,6 +271,7 @@ import (
_ "github.com/googleapis/genai-toolbox/internal/sources/singlestore" _ "github.com/googleapis/genai-toolbox/internal/sources/singlestore"
_ "github.com/googleapis/genai-toolbox/internal/sources/snowflake" _ "github.com/googleapis/genai-toolbox/internal/sources/snowflake"
_ "github.com/googleapis/genai-toolbox/internal/sources/spanner" _ "github.com/googleapis/genai-toolbox/internal/sources/spanner"
_ "github.com/googleapis/genai-toolbox/internal/sources/spanneradmin"
_ "github.com/googleapis/genai-toolbox/internal/sources/sqlite" _ "github.com/googleapis/genai-toolbox/internal/sources/sqlite"
_ "github.com/googleapis/genai-toolbox/internal/sources/tidb" _ "github.com/googleapis/genai-toolbox/internal/sources/tidb"
_ "github.com/googleapis/genai-toolbox/internal/sources/trino" _ "github.com/googleapis/genai-toolbox/internal/sources/trino"
@@ -396,8 +394,6 @@ func NewCommand(opts ...Option) *Command {
// wrap RunE command so that we have access to original Command object // wrap RunE command so that we have access to original Command object
cmd.RunE = func(*cobra.Command, []string) error { return run(cmd) } cmd.RunE = func(*cobra.Command, []string) error { return run(cmd) }
baseCmd.AddCommand(newInvokeCmd(cmd))
return cmd return cmd
} }
@@ -1003,6 +999,9 @@ func run(cmd *Command) error {
return err return err
} }
// Update version string
cmd.cfg.Version += "+prebuilt." + configName
// Parse into ToolsFile struct // Parse into ToolsFile struct
parsed, err := parseToolsFile(ctx, buf) parsed, err := parseToolsFile(ctx, buf)
if err != nil { if err != nil {
@@ -1069,18 +1068,6 @@ func run(cmd *Command) error {
allToolsFiles = append(allToolsFiles, customTools) allToolsFiles = append(allToolsFiles, customTools)
} }
// Modify version string based on loaded configurations
if len(cmd.prebuiltConfigs) > 0 {
tag := "prebuilt"
if isCustomConfigured {
tag = "custom"
}
// cmd.prebuiltConfigs is already sorted above
for _, configName := range cmd.prebuiltConfigs {
cmd.cfg.Version += fmt.Sprintf("+%s.%s", tag, configName)
}
}
// Merge Everything // Merge Everything
// This will error if custom tools collide with prebuilt tools // This will error if custom tools collide with prebuilt tools
finalToolsFile, err := mergeToolsFiles(allToolsFiles...) finalToolsFile, err := mergeToolsFiles(allToolsFiles...)

View File

@@ -0,0 +1,59 @@
# Cloud Spanner Admin MCP Server
The Cloud Spanner Admin Model Context Protocol (MCP) Server gives AI-powered development tools the ability to manage your Google Cloud Spanner infrastructure. It supports creating instances.
## Features
An editor configured to use the Cloud Spanner Admin MCP server can use its AI capabilities to help you:
- **Provision & Manage Infrastructure** - Create Cloud Spanner instances
## Prerequisites
* [Node.js](https://nodejs.org/) installed.
* A Google Cloud project with the **Cloud Spanner Admin API** enabled.
* Ensure [Application Default Credentials](https://cloud.google.com/docs/authentication/gcloud) are available in your environment.
* IAM Permissions:
* Cloud Spanner Admin (`roles/spanner.admin`)
## Install & Configuration
In the Antigravity MCP Store, click the "Install" button.
You'll now be able to see all enabled tools in the "Tools" tab.
> [!NOTE]
> If you encounter issues with Windows Defender blocking the execution, you may need to configure an allowlist. See [Configure exclusions for Microsoft Defender Antivirus](https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/configure-exclusions-microsoft-defender-antivirus?view=o365-worldwide) for more details.
## Usage
Once configured, the MCP server will automatically provide Cloud Spanner Admin capabilities to your AI assistant. You can:
* "Create a new Spanner instance named 'my-spanner-instance' in the 'my-gcp-project' project with config 'regional-us-central1', edition 'ENTERPRISE', and 1 node."
## Server Capabilities
The Cloud Spanner Admin MCP server provides the following tools:
| Tool Name | Description |
|:------------------|:---------------------------------|
| `create_instance` | Create a Cloud Spanner instance. |
## Custom MCP Server Configuration
Add the following configuration to your MCP client (e.g., `settings.json` for Gemini CLI, `mcp_config.json` for Antigravity):
```json
{
"mcpServers": {
"spanner-admin": {
"command": "npx",
"args": ["-y", "@toolbox-sdk/server", "--prebuilt", "spanner-admin", "--stdio"]
}
}
}
```
## Documentation
For more information, visit the [Cloud Spanner Admin API documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.instance.v1).

View File

@@ -77,7 +77,7 @@ redeploying your application.
## Getting Started ## Getting Started
### Quickstart: Running Toolbox using NPX ### (Non-production) Running Toolbox
You can run Toolbox directly with a [configuration file](../configure.md): You can run Toolbox directly with a [configuration file](../configure.md):

View File

@@ -1,71 +0,0 @@
---
title: "Cloud Logging Admin"
type: docs
weight: 1
description: >
The Cloud Logging Admin source enables tools to interact with the Cloud Logging API, allowing for the retrieval of log names, monitored resource types, and the querying of log data.
---
## About
The Cloud Logging Admin source provides a client to interact with the [Google
Cloud Logging API](https://cloud.google.com/logging/docs). This allows tools to list log names, monitored resource types, and query log entries.
Authentication can be handled in two ways:
1. **Application Default Credentials (ADC):** By default, the source uses ADC
to authenticate with the API.
2. **Client-side OAuth:** If `useClientOAuth` is set to `true`, the source will
expect an OAuth 2.0 access token to be provided by the client (e.g., a web
browser) for each request.
## Available Tools
- [`cloud-logging-admin-list-log-names`](../tools/cloudloggingadmin/cloud-logging-admin-list-log-names.md)
Lists the log names in the project.
- [`cloud-logging-admin-list-resource-types`](../tools/cloudloggingadmin/cloud-logging-admin-list-resource-types.md)
Lists the monitored resource types.
- [`cloud-logging-admin-query-logs`](../tools/cloudloggingadmin/cloud-logging-admin-query-logs.md)
Queries log entries.
## Example
Initialize a Cloud Logging Admin source that uses ADC:
```yaml
kind: sources
name: my-cloud-logging
type: cloud-logging-admin
project: my-project-id
```
Initialize a Cloud Logging Admin source that uses client-side OAuth:
```yaml
kind: sources
name: my-oauth-cloud-logging
type: cloud-logging-admin
project: my-project-id
useClientOAuth: true
```
Initialize a Cloud Logging Admin source that uses service account impersonation:
```yaml
kind: sources
name: my-impersonated-cloud-logging
type: cloud-logging-admin
project: my-project-id
impersonateServiceAccount: "my-service-account@my-project.iam.gserviceaccount.com"
```
## Reference
| **field** | **type** | **required** | **description** |
|-----------------------------|:--------:|:------------:|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| type | string | true | Must be "cloud-logging-admin". |
| project | string | true | ID of the GCP project. |
| useClientOAuth | boolean | false | If true, the source will use client-side OAuth for authorization. Otherwise, it will use Application Default Credentials. Defaults to `false`. Cannot be used with `impersonateServiceAccount`. |
| impersonateServiceAccount | string | false | The service account to impersonate for API calls. Cannot be used with `useClientOAuth`. |

View File

@@ -0,0 +1,43 @@
---
title: Spanner Admin
type: docs
weight: 1
description: "A \"spanner-admin\" source provides a client for the Cloud Spanner Admin API.\n"
alias: [/resources/sources/spanner-admin]
---
## About
The `spanner-admin` source provides a client to interact with the [Google
Cloud Spanner Admin API](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.instance.v1). This
allows tools to perform administrative tasks on Spanner instances, such as
creating instances.
Authentication can be handled in two ways:
1. **Application Default Credentials (ADC):** By default, the source uses ADC
to authenticate with the API.
2. **Client-side OAuth:** If `useClientOAuth` is set to `true`, the source will
expect an OAuth 2.0 access token to be provided by the client (e.g., a web
browser) for each request.
## Example
```yaml
kind: sources
name: my-spanner-admin
type: spanner-admin
---
kind: sources
name: my-oauth-spanner-admin
type: spanner-admin
useClientOAuth: true
```
## Reference
| **field** | **type** | **required** | **description** |
| -------------- | :------: | :----------: | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| type | string | true | Must be "spanner-admin". |
| defaultProject | string | false | The Google Cloud project ID to use for Spanner 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`. |

View File

@@ -1,39 +0,0 @@
---
title: "cloud-logging-admin-list-log-names"
type: docs
description: >
A "cloud-logging-admin-list-log-names" tool lists the log names in the project.
aliases:
- /resources/tools/cloud-logging-admin-list-log-names
---
## About
The `cloud-logging-admin-list-log-names` tool lists the log names available in the Google Cloud project.
It's compatible with the following sources:
- [cloud-logging-admin](../../sources/cloud-logging-admin.md)
## Example
```yaml
kind: tools
name: list_log_names
type: cloud-logging-admin-list-log-names
source: my-cloud-logging
description: Lists all log names in the project.
```
## Reference
| **field** | **type** | **required** | **description** |
|-------------|:--------:|:------------:|----------------------------------------------------|
| type | string | true | Must be "cloud-logging-admin-list-log-names". |
| source | string | true | Name of the cloud-logging-admin source. |
| description | string | true | Description of the tool that is passed to the LLM. |
### Parameters
| **parameter** | **type** | **required** | **description** |
|:--------------|:--------:|:------------:|:----------------|
| limit | integer | false | Maximum number of log entries to return (default: 200). |

View File

@@ -1,34 +0,0 @@
---
title: "cloud-logging-admin-list-resource-types"
type: docs
description: >
A "cloud-logging-admin-list-resource-types" tool lists the monitored resource types.
aliases:
- /resources/tools/cloud-logging-admin-list-resource-types
---
## About
The `cloud-logging-admin-list-resource-types` tool lists the monitored resource types available in Google Cloud Logging.
It's compatible with the following sources:
- [cloud-logging-admin](../../sources/cloud-logging-admin.md)
## Example
```yaml
kind: tools
name: list_resource_types
type: cloud-logging-admin-list-resource-types
source: my-cloud-logging
description: Lists monitored resource types.
```
## Reference
| **field** | **type** | **required** | **description** |
|-------------|:--------:|:------------:|----------------------------------------------------|
| type | string | true | Must be "cloud-logging-admin-list-resource-types".|
| source | string | true | Name of the cloud-logging-admin source. |
| description | string | true | Description of the tool that is passed to the LLM. |

View File

@@ -1,44 +0,0 @@
---
title: "cloud-logging-admin-query-logs"
type: docs
description: >
A "cloud-logging-admin-query-logs" tool queries log entries.
aliases:
- /resources/tools/cloud-logging-admin-query-logs
---
## About
The `cloud-logging-admin-query-logs` tool allows you to query log entries from Google Cloud Logging using the advanced logs filter syntax.
It's compatible with the following sources:
- [cloud-logging-admin](../../sources/cloud-logging-admin.md)
## Example
```yaml
kind: tools
name: query_logs
type: cloud-logging-admin-query-logs
source: my-cloud-logging
description: Queries log entries from Cloud Logging.
```
## Reference
| **field** | **type** | **required** | **description** |
|-------------|:--------:|:------------:|----------------------------------------------------|
| type | string | true | Must be "cloud-logging-admin-query-logs". |
| source | string | true | Name of the cloud-logging-admin source. |
| description | string | true | Description of the tool that is passed to the LLM. |
### Parameters
| **parameter** | **type** | **required** | **description** |
|:--------------|:--------:|:------------:|:----------------|
| filter | string | false | Cloud Logging filter query. Common fields: resource.type, resource.labels.*, logName, severity, textPayload, jsonPayload.*, protoPayload.*, labels.*, httpRequest.*. Operators: =, !=, <, <=, >, >=, :, =~, AND, OR, NOT. |
| newestFirst | boolean | false | Set to true for newest logs first. Defaults to oldest first. |
| startTime | string | false | Start time in RFC3339 format (e.g., 2025-12-09T00:00:00Z). Defaults to 30 days ago. |
| endTime | string | false | End time in RFC3339 format (e.g., 2025-12-09T23:59:59Z). Defaults to now. |
| verbose | boolean | false | Include additional fields (insertId, trace, spanId, httpRequest, labels, operation, sourceLocation). Defaults to false. |
| limit | integer | false | Maximum number of log entries to return. Default: `200`. |

View File

@@ -8,7 +8,7 @@ description: "Restores a backup of a Cloud SQL instance."
The `cloud-sql-restore-backup` tool restores a backup on a Cloud SQL instance using the Cloud SQL Admin API. The `cloud-sql-restore-backup` tool restores a backup on a Cloud SQL instance using the Cloud SQL Admin API.
{{< notice info dd>}} {{< notice info dd>}}
This tool uses a `source` of type `cloud-sql-admin`. This tool uses a `source` of kind `cloud-sql-admin`.
{{< /notice >}} {{< /notice >}}
## Examples ## Examples
@@ -16,11 +16,11 @@ This tool uses a `source` of type `cloud-sql-admin`.
Basic backup restore Basic backup restore
```yaml ```yaml
kind: tools tools:
name: backup-restore-basic backup-restore-basic:
type: cloud-sql-restore-backup kind: cloud-sql-restore-backup
source: cloud-sql-admin-source source: cloud-sql-admin-source
description: "Restores a backup onto the given Cloud SQL instance." description: "Restores a backup onto the given Cloud SQL instance."
``` ```
## Reference ## Reference
@@ -28,7 +28,7 @@ description: "Restores a backup onto the given Cloud SQL instance."
### Tool Configuration ### Tool Configuration
| **field** | **type** | **required** | **description** | | **field** | **type** | **required** | **description** |
| -------------- | :------: | :----------: | ------------------------------------------------ | | -------------- | :------: | :----------: | ------------------------------------------------ |
| type | string | true | Must be "cloud-sql-restore-backup". | | kind | string | true | Must be "cloud-sql-restore-backup". |
| source | string | true | The name of the `cloud-sql-admin` source to use. | | source | string | true | The name of the `cloud-sql-admin` source to use. |
| description | string | false | A description of the tool. | | description | string | false | A description of the tool. |

View File

@@ -0,0 +1,52 @@
---
title: spanner-create-instance
type: docs
weight: 2
description: "Create a Cloud Spanner instance."
---
The `spanner-create-instance` tool creates a new Cloud Spanner instance in a
specified Google Cloud project.
{{< notice info >}}
This tool uses the `spanner-admin` source.
{{< /notice >}}
## Configuration
Here is an example of how to configure the `spanner-create-instance` tool in
your `tools.yaml` file:
```yaml
kind: sources
name: my-spanner-admin-source
type: spanner-admin
---
kind: tools
name: create_my_spanner_instance
type: spanner-create-instance
source: my-spanner-admin-source
description: "Creates a Spanner instance."
```
## Parameters
The `spanner-create-instance` tool has the following parameters:
| **field** | **type** | **required** | **description** |
| --------------- | :------: | :----------: | ------------------------------------------------------------------------------------ |
| project | string | true | The Google Cloud project ID. |
| instanceId | string | true | The ID of the instance to create. |
| displayName | string | true | The display name of the instance. |
| config | string | true | The instance configuration (e.g., `regional-us-central1`). |
| nodeCount | integer | true | The number of nodes. Mutually exclusive with `processingUnits` (one must be 0). |
| processingUnits | integer | true | The number of processing units. Mutually exclusive with `nodeCount` (one must be 0). |
| edition | string | false | The edition of the instance (`STANDARD`, `ENTERPRISE`, `ENTERPRISE_PLUS`). |
## Reference
| **field** | **type** | **required** | **description** |
| ----------- | :------: | :----------: | ------------------------------------------------------------ |
| type | string | true | Must be `spanner-create-instance`. |
| source | string | true | The name of the `spanner-admin` source to use for this tool. |
| description | string | false | A description of the tool that is passed to the agent. |

1
go.mod
View File

@@ -13,7 +13,6 @@ require (
cloud.google.com/go/dataproc/v2 v2.15.0 cloud.google.com/go/dataproc/v2 v2.15.0
cloud.google.com/go/firestore v1.20.0 cloud.google.com/go/firestore v1.20.0
cloud.google.com/go/geminidataanalytics v0.3.0 cloud.google.com/go/geminidataanalytics v0.3.0
cloud.google.com/go/logging v1.13.1
cloud.google.com/go/longrunning v0.7.0 cloud.google.com/go/longrunning v0.7.0
cloud.google.com/go/spanner v1.86.1 cloud.google.com/go/spanner v1.86.1
github.com/ClickHouse/clickhouse-go/v2 v2.40.3 github.com/ClickHouse/clickhouse-go/v2 v2.40.3

4
go.sum
View File

@@ -370,8 +370,8 @@ cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6
cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo= cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo=
cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw=
cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M= cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M=
cloud.google.com/go/logging v1.13.1 h1:O7LvmO0kGLaHY/gq8cV7T0dyp6zJhYAOtZPX4TF3QtY= cloud.google.com/go/logging v1.13.0 h1:7j0HgAp0B94o1YRDqiqm26w4q1rDMH7XNRU34lJXHYc=
cloud.google.com/go/logging v1.13.1/go.mod h1:XAQkfkMBxQRjQek96WLPNze7vsOmay9H5PqfsNYDqvw= cloud.google.com/go/logging v1.13.0/go.mod h1:36CoKh6KA/M0PbhPKMq6/qety2DCAErbhXT62TuXALA=
cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE=
cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc=
cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo=

View File

@@ -50,6 +50,7 @@ var expectedToolSources = []string{
"serverless-spark", "serverless-spark",
"singlestore", "singlestore",
"snowflake", "snowflake",
"spanner-admin",
"spanner-postgres", "spanner-postgres",
"spanner", "spanner",
"sqlite", "sqlite",

View File

@@ -0,0 +1,27 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# 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,
# 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.
sources:
spanner-admin-source:
kind: spanner-admin
defaultProject: ${SPANNER_PROJECT:}
tools:
create_instance:
kind: spanner-create-instance
source: spanner-admin-source
toolsets:
spanner_admin_tools:
- create_instance

View File

@@ -26,7 +26,6 @@ import (
"github.com/go-chi/render" "github.com/go-chi/render"
"github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools"
"github.com/googleapis/genai-toolbox/internal/util" "github.com/googleapis/genai-toolbox/internal/util"
"github.com/googleapis/genai-toolbox/internal/util/parameters"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric"
@@ -232,7 +231,7 @@ func toolInvokeHandler(s *Server, w http.ResponseWriter, r *http.Request) {
return return
} }
params, err := parameters.ParseParams(tool.GetParameters(), data, claimsFromAuth) params, err := tool.ParseParams(data, claimsFromAuth)
if err != nil { if err != nil {
// If auth error, return 401 // If auth error, return 401
if errors.Is(err, util.ErrUnauthorized) { if errors.Is(err, util.ErrUnauthorized) {

View File

@@ -28,7 +28,6 @@ import (
"github.com/googleapis/genai-toolbox/internal/server/resources" "github.com/googleapis/genai-toolbox/internal/server/resources"
"github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools"
"github.com/googleapis/genai-toolbox/internal/util" "github.com/googleapis/genai-toolbox/internal/util"
"github.com/googleapis/genai-toolbox/internal/util/parameters"
) )
// ProcessMethod returns a response for the request. // ProcessMethod returns a response for the request.
@@ -177,7 +176,7 @@ func toolsCallHandler(ctx context.Context, id jsonrpc.RequestId, resourceMgr *re
} }
logger.DebugContext(ctx, "tool invocation authorized") logger.DebugContext(ctx, "tool invocation authorized")
params, err := parameters.ParseParams(tool.GetParameters(), data, claimsFromAuth) params, err := tool.ParseParams(data, claimsFromAuth)
if err != nil { if err != nil {
err = fmt.Errorf("provided parameters were invalid: %w", err) err = fmt.Errorf("provided parameters were invalid: %w", err)
return jsonrpc.NewError(id, jsonrpc.INVALID_PARAMS, err.Error(), nil), err return jsonrpc.NewError(id, jsonrpc.INVALID_PARAMS, err.Error(), nil), err

View File

@@ -28,7 +28,6 @@ import (
"github.com/googleapis/genai-toolbox/internal/server/resources" "github.com/googleapis/genai-toolbox/internal/server/resources"
"github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools"
"github.com/googleapis/genai-toolbox/internal/util" "github.com/googleapis/genai-toolbox/internal/util"
"github.com/googleapis/genai-toolbox/internal/util/parameters"
) )
// ProcessMethod returns a response for the request. // ProcessMethod returns a response for the request.
@@ -177,7 +176,7 @@ func toolsCallHandler(ctx context.Context, id jsonrpc.RequestId, resourceMgr *re
} }
logger.DebugContext(ctx, "tool invocation authorized") logger.DebugContext(ctx, "tool invocation authorized")
params, err := parameters.ParseParams(tool.GetParameters(), data, claimsFromAuth) params, err := tool.ParseParams(data, claimsFromAuth)
if err != nil { if err != nil {
err = fmt.Errorf("provided parameters were invalid: %w", err) err = fmt.Errorf("provided parameters were invalid: %w", err)
return jsonrpc.NewError(id, jsonrpc.INVALID_PARAMS, err.Error(), nil), err return jsonrpc.NewError(id, jsonrpc.INVALID_PARAMS, err.Error(), nil), err

View File

@@ -28,7 +28,6 @@ import (
"github.com/googleapis/genai-toolbox/internal/server/resources" "github.com/googleapis/genai-toolbox/internal/server/resources"
"github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools"
"github.com/googleapis/genai-toolbox/internal/util" "github.com/googleapis/genai-toolbox/internal/util"
"github.com/googleapis/genai-toolbox/internal/util/parameters"
) )
// ProcessMethod returns a response for the request. // ProcessMethod returns a response for the request.
@@ -170,7 +169,7 @@ func toolsCallHandler(ctx context.Context, id jsonrpc.RequestId, resourceMgr *re
} }
logger.DebugContext(ctx, "tool invocation authorized") logger.DebugContext(ctx, "tool invocation authorized")
params, err := parameters.ParseParams(tool.GetParameters(), data, claimsFromAuth) params, err := tool.ParseParams(data, claimsFromAuth)
if err != nil { if err != nil {
err = fmt.Errorf("provided parameters were invalid: %w", err) err = fmt.Errorf("provided parameters were invalid: %w", err)
return jsonrpc.NewError(id, jsonrpc.INVALID_PARAMS, err.Error(), nil), err return jsonrpc.NewError(id, jsonrpc.INVALID_PARAMS, err.Error(), nil), err

View File

@@ -28,7 +28,6 @@ import (
"github.com/googleapis/genai-toolbox/internal/server/resources" "github.com/googleapis/genai-toolbox/internal/server/resources"
"github.com/googleapis/genai-toolbox/internal/tools" "github.com/googleapis/genai-toolbox/internal/tools"
"github.com/googleapis/genai-toolbox/internal/util" "github.com/googleapis/genai-toolbox/internal/util"
"github.com/googleapis/genai-toolbox/internal/util/parameters"
) )
// ProcessMethod returns a response for the request. // ProcessMethod returns a response for the request.
@@ -170,7 +169,7 @@ func toolsCallHandler(ctx context.Context, id jsonrpc.RequestId, resourceMgr *re
} }
logger.DebugContext(ctx, "tool invocation authorized") logger.DebugContext(ctx, "tool invocation authorized")
params, err := parameters.ParseParams(tool.GetParameters(), data, claimsFromAuth) params, err := tool.ParseParams(data, claimsFromAuth)
if err != nil { if err != nil {
err = fmt.Errorf("provided parameters were invalid: %w", err) err = fmt.Errorf("provided parameters were invalid: %w", err)
return jsonrpc.NewError(id, jsonrpc.INVALID_PARAMS, err.Error(), nil), err return jsonrpc.NewError(id, jsonrpc.INVALID_PARAMS, err.Error(), nil), err

View File

@@ -12,8 +12,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { escapeHtml } from './sanitize.js';
/** /**
* Renders the Google Sign-In button using the GIS library. * Renders the Google Sign-In button using the GIS library.
* @param {string} toolId The ID of the tool. * @param {string} toolId The ID of the tool.
@@ -114,14 +112,13 @@ function handleCredentialResponse(response, toolId, authProfileName) {
// creates the Google Auth method dropdown // creates the Google Auth method dropdown
export function createGoogleAuthMethodItem(toolId, authProfileName) { export function createGoogleAuthMethodItem(toolId, authProfileName) {
const safeProfileName = escapeHtml(authProfileName);
const UNIQUE_ID_BASE = `${toolId}-${authProfileName}`; const UNIQUE_ID_BASE = `${toolId}-${authProfileName}`;
const item = document.createElement('div'); const item = document.createElement('div');
item.className = 'auth-method-item'; item.className = 'auth-method-item';
item.innerHTML = ` item.innerHTML = `
<div class="auth-method-header"> <div class="auth-method-header">
<span class="auth-method-label">Google ID Token (${safeProfileName})</span> <span class="auth-method-label">Google ID Token (${authProfileName})</span>
<button class="toggle-details-tab">Auto Setup</button> <button class="toggle-details-tab">Auto Setup</button>
</div> </div>
<div class="auth-method-details" id="google-auth-details-${UNIQUE_ID_BASE}" style="display: none;"> <div class="auth-method-details" id="google-auth-details-${UNIQUE_ID_BASE}" style="display: none;">

View File

@@ -13,7 +13,6 @@
// limitations under the License. // limitations under the License.
import { renderToolInterface } from "./toolDisplay.js"; import { renderToolInterface } from "./toolDisplay.js";
import { escapeHtml } from "./sanitize.js";
let toolDetailsAbortController = null; let toolDetailsAbortController = null;
@@ -35,7 +34,7 @@ export async function loadTools(secondNavContent, toolDisplayArea, toolsetName)
renderToolList(apiResponse, secondNavContent, toolDisplayArea); renderToolList(apiResponse, secondNavContent, toolDisplayArea);
} catch (error) { } catch (error) {
console.error('Failed to load tools:', error); console.error('Failed to load tools:', error);
secondNavContent.innerHTML = `<p class="error">Failed to load tools: <pre><code>${escapeHtml(String(error))}</code></pre></p>`; secondNavContent.innerHTML = `<p class="error">Failed to load tools: <pre><code>${error}</code></pre></p>`;
} }
} }
@@ -169,7 +168,7 @@ async function fetchToolDetails(toolName, toolDisplayArea) {
console.debug("Previous fetch was aborted, expected behavior."); console.debug("Previous fetch was aborted, expected behavior.");
} else { } else {
console.error(`Failed to load details for tool "${toolName}":`, error); console.error(`Failed to load details for tool "${toolName}":`, error);
toolDisplayArea.innerHTML = `<p class="error">Failed to load details for ${escapeHtml(toolName)}. ${escapeHtml(error.message)}</p>`; toolDisplayArea.innerHTML = `<p class="error">Failed to load details for ${toolName}. ${error.message}</p>`;
} }
} }
} }

View File

@@ -1,43 +0,0 @@
// 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.
// You may obtain a copy of the License at
//
// 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,
// 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.
/**
* Escapes special characters for safe rendering in HTML text contexts.
*
* This utility encodes user-controlled values to avoid unintended script
* execution when rendering content as HTML. It is intended as a defensive
* measure and does not perform HTML sanitization.
*
* @param {*} input The value to escape.
* @return {string} The escaped string safe for HTML rendering.
*/
const htmlEscapes = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#x27;',
'`': '&#x60;'
};
const escapeCharsRegex = /[&<>"'`]/g;
export function escapeHtml(input) {
if (input === null || input === undefined) {
return '';
}
const str = String(input);
return str.replace(escapeCharsRegex, (char) => htmlEscapes[char]);
}

View File

@@ -14,7 +14,6 @@
import { handleRunTool, displayResults } from './runTool.js'; import { handleRunTool, displayResults } from './runTool.js';
import { createGoogleAuthMethodItem } from './auth.js' import { createGoogleAuthMethodItem } from './auth.js'
import { escapeHtml } from './sanitize.js'
/** /**
* Helper function to create form inputs for parameters. * Helper function to create form inputs for parameters.
@@ -358,9 +357,9 @@ export function renderToolInterface(tool, containerElement) {
const descBox = document.createElement('div'); const descBox = document.createElement('div');
nameBox.className = 'tool-box tool-name'; nameBox.className = 'tool-box tool-name';
nameBox.innerHTML = `<h5>Name:</h5><p>${escapeHtml(tool.name)}</p>`; nameBox.innerHTML = `<h5>Name:</h5><p>${tool.name}</p>`;
descBox.className = 'tool-box tool-description'; descBox.className = 'tool-box tool-description';
descBox.innerHTML = `<h5>Description:</h5><p>${escapeHtml(tool.description)}</p>`; descBox.innerHTML = `<h5>Description:</h5><p>${tool.description}</p>`;
toolInfoContainer.className = 'tool-info'; toolInfoContainer.className = 'tool-info';
toolInfoContainer.appendChild(nameBox); toolInfoContainer.appendChild(nameBox);

View File

@@ -236,9 +236,9 @@ func setupClientCaching(s *Source, baseCreator BigqueryClientCreator) {
} }
// Initialize caches // Initialize caches
s.bqClientCache = sources.NewCache(onBqEvict) s.bqClientCache = NewCache(onBqEvict)
s.bqRestCache = sources.NewCache(nil) s.bqRestCache = NewCache(nil)
s.dataplexCache = sources.NewCache(onDataplexEvict) s.dataplexCache = NewCache(onDataplexEvict)
// Create the caching wrapper for the client creator // Create the caching wrapper for the client creator
s.ClientCreator = func(tokenString string, wantRestService bool) (*bigqueryapi.Client, *bigqueryrestapi.Service, error) { s.ClientCreator = func(tokenString string, wantRestService bool) (*bigqueryapi.Client, *bigqueryrestapi.Service, error) {
@@ -289,9 +289,9 @@ type Source struct {
Session *Session Session *Session
// Caches for OAuth clients // Caches for OAuth clients
bqClientCache *sources.Cache bqClientCache *Cache
bqRestCache *sources.Cache bqRestCache *Cache
dataplexCache *sources.Cache dataplexCache *Cache
} }
type Session struct { type Session struct {

View File

@@ -11,7 +11,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package sources package bigquery
import ( import (
"sync" "sync"

View File

@@ -1,439 +0,0 @@
// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// 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,
// 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.
package cloudloggingadmin
import (
"context"
"fmt"
"slices"
"strings"
"time"
"cloud.google.com/go/logging"
"cloud.google.com/go/logging/logadmin"
"github.com/goccy/go-yaml"
"github.com/googleapis/genai-toolbox/internal/sources"
"github.com/googleapis/genai-toolbox/internal/util"
"go.opentelemetry.io/otel/trace"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/api/impersonate"
"google.golang.org/api/iterator"
"google.golang.org/api/option"
)
const SourceType string = "cloud-logging-admin"
var _ sources.SourceConfig = Config{}
func init() {
if !sources.Register(SourceType, newConfig) {
panic(fmt.Sprintf("source type %q already registered", SourceType))
}
}
func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources.SourceConfig, error) {
actual := Config{Name: name}
if err := decoder.DecodeContext(ctx, &actual); err != nil {
return nil, err
}
return actual, nil
}
type Config struct {
Name string `yaml:"name" validate:"required"`
Type string `yaml:"type" validate:"required"`
Project string `yaml:"project" validate:"required"`
UseClientOAuth bool `yaml:"useClientOAuth"`
ImpersonateServiceAccount string `yaml:"impersonateServiceAccount"`
}
func (r Config) SourceConfigType() string {
return SourceType
}
func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) {
if r.UseClientOAuth && r.ImpersonateServiceAccount != "" {
return nil, fmt.Errorf("useClientOAuth cannot be used with impersonateServiceAccount")
}
var client *logadmin.Client
var tokenSource oauth2.TokenSource
var clientCreator LogAdminClientCreator
var err error
s := &Source{
Config: r,
Client: client,
TokenSource: tokenSource,
ClientCreator: clientCreator,
}
if r.UseClientOAuth {
// use client OAuth
baseClientCreator, err := newLogAdminClientCreator(ctx, tracer, r.Project, r.Name)
if err != nil {
return nil, fmt.Errorf("error constructing client creator: %w", err)
}
setupClientCaching(s, baseClientCreator)
} else {
client, tokenSource, err = initLogAdminConnection(ctx, tracer, r.Name, r.Project, r.ImpersonateServiceAccount)
if err != nil {
return nil, fmt.Errorf("error creating client from ADC %w", err)
}
s.Client = client
s.TokenSource = tokenSource
}
return s, nil
}
var _ sources.Source = &Source{}
type LogAdminClientCreator func(tokenString string) (*logadmin.Client, error)
type Source struct {
Config
Client *logadmin.Client
TokenSource oauth2.TokenSource
ClientCreator LogAdminClientCreator
// Caches for OAuth clients
logadminClientCache *sources.Cache
}
func (s *Source) SourceType() string {
// Returns logadmin source type
return SourceType
}
func (s *Source) ToConfig() sources.SourceConfig {
return s.Config
}
func (s *Source) UseClientAuthorization() bool {
return s.UseClientOAuth
}
func (s *Source) LogAdminClient() *logadmin.Client {
return s.Client
}
func (s *Source) LogAdminTokenSource() oauth2.TokenSource {
return s.TokenSource
}
func (s *Source) LogAdminClientCreator() LogAdminClientCreator {
return s.ClientCreator
}
func (s *Source) GetProject() string {
return s.Project
}
// getClient returns the appropriate client based on authentication mode
func (s *Source) getClient(accessToken string) (*logadmin.Client, error) {
if s.UseClientOAuth {
if s.ClientCreator == nil {
return nil, fmt.Errorf("client creator is not initialized")
}
return s.ClientCreator(accessToken)
}
if s.Client == nil {
return nil, fmt.Errorf("source client is not initialized")
}
return s.Client, nil
}
// ListLogNames lists all log names in the project
func (s *Source) ListLogNames(ctx context.Context, limit int, accessToken string) ([]string, error) {
client, err := s.getClient(accessToken)
if err != nil {
return nil, err
}
it := client.Logs(ctx)
var logNames []string
for len(logNames) < limit {
logName, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
return nil, err
}
logNames = append(logNames, logName)
}
return logNames, nil
}
// ListResourceTypes lists all resource types in the project
func (s *Source) ListResourceTypes(ctx context.Context, accessToken string) ([]string, error) {
client, err := s.getClient(accessToken)
if err != nil {
return nil, err
}
it := client.ResourceDescriptors(ctx)
var types []string
for {
desc, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
return nil, fmt.Errorf("failed to list resource descriptors: %w", err)
}
types = append(types, desc.Type)
}
slices.Sort(types)
return types, nil
}
// QueryLogsParams contains the parameters for querying logs
type QueryLogsParams struct {
Filter string
NewestFirst bool
StartTime string
EndTime string
Verbose bool
Limit int
}
// QueryLogs queries log entries based on the provided parameters
func (s *Source) QueryLogs(ctx context.Context, params QueryLogsParams, accessToken string) ([]map[string]any, error) {
client, err := s.getClient(accessToken)
if err != nil {
return nil, err
}
// Build filter
var filterParts []string
if params.Filter != "" {
filterParts = append(filterParts, params.Filter)
}
// Add timestamp filter
startTime := params.StartTime
if startTime != "" {
filterParts = append(filterParts, fmt.Sprintf(`timestamp>="%s"`, startTime))
}
if params.EndTime != "" {
filterParts = append(filterParts, fmt.Sprintf(`timestamp<="%s"`, params.EndTime))
}
combinedFilter := strings.Join(filterParts, " AND ")
// Add opts
opts := []logadmin.EntriesOption{
logadmin.Filter(combinedFilter),
}
// Set order
if params.NewestFirst {
opts = append(opts, logadmin.NewestFirst())
}
// Set up iterator
it := client.Entries(ctx, opts...)
var results []map[string]any
for len(results) < params.Limit {
entry, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
return nil, fmt.Errorf("failed to iterate entries: %w", err)
}
result := map[string]any{
"logName": entry.LogName,
"timestamp": entry.Timestamp.Format(time.RFC3339),
"severity": entry.Severity.String(),
"resource": map[string]any{
"type": entry.Resource.Type,
"labels": entry.Resource.Labels,
},
}
if entry.Payload != nil {
result["payload"] = entry.Payload
}
if params.Verbose {
result["insertId"] = entry.InsertID
if len(entry.Labels) > 0 {
result["labels"] = entry.Labels
}
if entry.HTTPRequest != nil {
httpRequestMap := map[string]any{
"status": entry.HTTPRequest.Status,
"latency": entry.HTTPRequest.Latency.String(),
"remoteIp": entry.HTTPRequest.RemoteIP,
}
if req := entry.HTTPRequest.Request; req != nil {
httpRequestMap["requestMethod"] = req.Method
httpRequestMap["requestUrl"] = req.URL.String()
httpRequestMap["userAgent"] = req.UserAgent()
}
result["httpRequest"] = httpRequestMap
}
if entry.Trace != "" {
result["trace"] = entry.Trace
}
if entry.SpanID != "" {
result["spanId"] = entry.SpanID
}
if entry.Operation != nil {
result["operation"] = map[string]any{
"id": entry.Operation.Id,
"producer": entry.Operation.Producer,
"first": entry.Operation.First,
"last": entry.Operation.Last,
}
}
if entry.SourceLocation != nil {
result["sourceLocation"] = map[string]any{
"file": entry.SourceLocation.File,
"line": entry.SourceLocation.Line,
"function": entry.SourceLocation.Function,
}
}
}
results = append(results, result)
}
return results, nil
}
func setupClientCaching(s *Source, baseCreator LogAdminClientCreator) {
onEvict := func(key string, value interface{}) {
if client, ok := value.(*logadmin.Client); ok && client != nil {
client.Close()
}
}
s.logadminClientCache = sources.NewCache(onEvict)
s.ClientCreator = func(tokenString string) (*logadmin.Client, error) {
if val, found := s.logadminClientCache.Get(tokenString); found {
return val.(*logadmin.Client), nil
}
client, err := baseCreator(tokenString)
if err != nil {
return nil, err
}
s.logadminClientCache.Set(tokenString, client)
return client, nil
}
}
func initLogAdminConnection(
ctx context.Context,
tracer trace.Tracer,
name string,
project string,
impersonateServiceAccount string,
) (*logadmin.Client, oauth2.TokenSource, error) {
ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name)
defer span.End()
userAgent, err := util.UserAgentFromContext(ctx)
if err != nil {
return nil, nil, err
}
var tokenSource oauth2.TokenSource
var opts []option.ClientOption
if impersonateServiceAccount != "" {
// Create impersonated credentials token source with cloud-platform scope
// This broader scope is needed for tools like conversational analytics
cloudPlatformTokenSource, err := impersonate.CredentialsTokenSource(ctx, impersonate.CredentialsConfig{
TargetPrincipal: impersonateServiceAccount,
Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"},
})
if err != nil {
return nil, nil, fmt.Errorf("failed to create impersonated credentials for %q: %w", impersonateServiceAccount, err)
}
tokenSource = cloudPlatformTokenSource
opts = []option.ClientOption{
option.WithUserAgent(userAgent),
option.WithTokenSource(cloudPlatformTokenSource),
}
} else {
// Use default credentials
cred, err := google.FindDefaultCredentials(ctx, logging.AdminScope)
if err != nil {
return nil, nil, fmt.Errorf("failed to find default Google Cloud credentials with scope %q: %w", logging.AdminScope, err)
}
tokenSource = cred.TokenSource
opts = []option.ClientOption{
option.WithUserAgent(userAgent),
option.WithCredentials(cred),
}
}
client, err := logadmin.NewClient(ctx, project, opts...)
if err != nil {
return nil, nil, fmt.Errorf("failed to create Cloud Logging Admin client for project %q: %w", project, err)
}
return client, tokenSource, nil
}
func initLogAdminConnectionWithOAuthToken(
ctx context.Context,
tracer trace.Tracer,
project, name, userAgent, tokenString string,
) (*logadmin.Client, error) {
ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name)
defer span.End()
token := &oauth2.Token{
AccessToken: string(tokenString),
}
ts := oauth2.StaticTokenSource(token)
// Initialize the logadmin client with tokenSource
client, err := logadmin.NewClient(ctx, project, option.WithUserAgent(userAgent), option.WithTokenSource(ts))
if err != nil {
return nil, fmt.Errorf("failed to create logadmin client for project %q: %w", project, err)
}
return client, nil
}
func newLogAdminClientCreator(
ctx context.Context,
tracer trace.Tracer,
project, name string,
) (LogAdminClientCreator, error) {
userAgent, err := util.UserAgentFromContext(ctx)
if err != nil {
return nil, err
}
return func(tokenString string) (*logadmin.Client, error) {
return initLogAdminConnectionWithOAuthToken(ctx, tracer, project, name, userAgent, tokenString)
}, nil
}

View File

@@ -0,0 +1,120 @@
// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// 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,
// 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.
package spanneradmin
import (
"context"
"fmt"
instance "cloud.google.com/go/spanner/admin/instance/apiv1"
"github.com/goccy/go-yaml"
"github.com/googleapis/genai-toolbox/internal/sources"
"github.com/googleapis/genai-toolbox/internal/util"
"go.opentelemetry.io/otel/trace"
"golang.org/x/oauth2"
"google.golang.org/api/option"
)
const SourceType string = "spanner-admin"
// validate interface
var _ sources.SourceConfig = Config{}
func init() {
if !sources.Register(SourceType, newConfig) {
panic(fmt.Sprintf("source type %q already registered", SourceType))
}
}
func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources.SourceConfig, error) {
actual := Config{Name: name}
if err := decoder.DecodeContext(ctx, &actual); err != nil {
return nil, err
}
return actual, nil
}
type Config struct {
Name string `yaml:"name" validate:"required"`
Type string `yaml:"type" validate:"required"`
DefaultProject string `yaml:"defaultProject"`
UseClientOAuth bool `yaml:"useClientOAuth"`
}
func (r Config) SourceConfigType() string {
return SourceType
}
// Initialize initializes a Spanner Admin Source instance.
func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) {
var client *instance.InstanceAdminClient
if !r.UseClientOAuth {
ua, err := util.UserAgentFromContext(ctx)
if err != nil {
return nil, fmt.Errorf("error in User Agent retrieval: %s", err)
}
// Use Application Default Credentials
client, err = instance.NewInstanceAdminClient(ctx, option.WithUserAgent(ua))
if err != nil {
return nil, fmt.Errorf("error creating new spanner instance admin client: %w", err)
}
}
s := &Source{
Config: r,
Client: client,
}
return s, nil
}
var _ sources.Source = &Source{}
type Source struct {
Config
Client *instance.InstanceAdminClient
}
func (s *Source) SourceType() string {
return SourceType
}
func (s *Source) ToConfig() sources.SourceConfig {
return s.Config
}
func (s *Source) GetDefaultProject() string {
return s.DefaultProject
}
func (s *Source) GetClient(ctx context.Context, accessToken string) (*instance.InstanceAdminClient, error) {
if s.UseClientOAuth {
token := &oauth2.Token{AccessToken: accessToken}
ua, err := util.UserAgentFromContext(ctx)
if err != nil {
return nil, err
}
client, err := instance.NewInstanceAdminClient(ctx, option.WithTokenSource(oauth2.StaticTokenSource(token)), option.WithUserAgent(ua))
if err != nil {
return nil, fmt.Errorf("error creating new spanner instance admin client: %w", err)
}
return client, nil
}
return s.Client, nil
}
func (s *Source) UseClientAuthorization() bool {
return s.UseClientOAuth
}

View File

@@ -4,14 +4,15 @@
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
// You may obtain a copy of the License at // You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, software // 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 on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package cloudloggingadmin_test
package spanneradmin_test
import ( import (
"context" "context"
@@ -19,11 +20,12 @@ import (
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
"github.com/googleapis/genai-toolbox/internal/server" "github.com/googleapis/genai-toolbox/internal/server"
"github.com/googleapis/genai-toolbox/internal/sources/cloudloggingadmin" "github.com/googleapis/genai-toolbox/internal/sources"
"github.com/googleapis/genai-toolbox/internal/sources/spanneradmin"
"github.com/googleapis/genai-toolbox/internal/testutils" "github.com/googleapis/genai-toolbox/internal/testutils"
) )
func TestParseFromYamlCloudLoggingAdmin(t *testing.T) { func TestParseFromYamlSpannerAdmin(t *testing.T) {
tcs := []struct { tcs := []struct {
desc string desc string
in string in string
@@ -33,54 +35,33 @@ func TestParseFromYamlCloudLoggingAdmin(t *testing.T) {
desc: "basic example", desc: "basic example",
in: ` in: `
kind: sources kind: sources
name: my-instance name: my-spanner-admin-instance
type: cloud-logging-admin type: spanner-admin
project: my-project
`, `,
want: server.SourceConfigs{ want: map[string]sources.SourceConfig{
"my-instance": cloudloggingadmin.Config{ "my-spanner-admin-instance": spanneradmin.Config{
Name: "my-instance", Name: "my-spanner-admin-instance",
Type: cloudloggingadmin.SourceType, Type: spanneradmin.SourceType,
Project: "my-project", UseClientOAuth: false,
}, },
}, },
}, },
{ {
desc: "with client oauth", desc: "use client auth example",
in: ` in: `
kind: sources kind: sources
name: my-instance name: my-spanner-admin-instance
type: cloud-logging-admin type: spanner-admin
project: my-project
useClientOAuth: true useClientOAuth: true
`, `,
want: server.SourceConfigs{ want: map[string]sources.SourceConfig{
"my-instance": cloudloggingadmin.Config{ "my-spanner-admin-instance": spanneradmin.Config{
Name: "my-instance", Name: "my-spanner-admin-instance",
Type: cloudloggingadmin.SourceType, Type: spanneradmin.SourceType,
Project: "my-project",
UseClientOAuth: true, UseClientOAuth: true,
}, },
}, },
}, },
{
desc: "with service account impersonation",
in: `
kind: sources
name: my-instance
type: cloud-logging-admin
project: my-project
impersonateServiceAccount: service-account@my-project.iam.gserviceaccount.com
`,
want: server.SourceConfigs{
"my-instance": cloudloggingadmin.Config{
Name: "my-instance",
Type: cloudloggingadmin.SourceType,
Project: "my-project",
ImpersonateServiceAccount: "service-account@my-project.iam.gserviceaccount.com",
},
},
},
} }
for _, tc := range tcs { for _, tc := range tcs {
t.Run(tc.desc, func(t *testing.T) { t.Run(tc.desc, func(t *testing.T) {
@@ -96,6 +77,7 @@ func TestParseFromYamlCloudLoggingAdmin(t *testing.T) {
} }
func TestFailParseFromYaml(t *testing.T) { func TestFailParseFromYaml(t *testing.T) {
t.Parallel()
tcs := []struct { tcs := []struct {
desc string desc string
in string in string
@@ -105,21 +87,24 @@ func TestFailParseFromYaml(t *testing.T) {
desc: "extra field", desc: "extra field",
in: ` in: `
kind: sources kind: sources
name: my-instance name: my-spanner-admin-instance
type: cloud-logging-admin type: spanner-admin
project: my-project project: test-project
foo: bar
`, `,
err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"cloud-logging-admin\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | name: my-instance\n 3 | project: my-project\n 4 | type: cloud-logging-admin", err: `error unmarshaling sources: unable to parse source "my-spanner-admin-instance" as "spanner-admin": [2:1] unknown field "project"
1 | name: my-spanner-admin-instance
> 2 | project: test-project
^
3 | type: spanner-admin`,
}, },
{ {
desc: "missing required field", desc: "missing required field",
in: ` in: `
kind: sources kind: sources
name: my-instance name: my-spanner-admin-instance
type: cloud-logging-admin useClientOAuth: true
`, `,
err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"cloud-logging-admin\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag", err: "error unmarshaling sources: missing 'type' field or it is not a string",
}, },
} }
for _, tc := range tcs { for _, tc := range tcs {

View File

@@ -162,6 +162,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.CreateCluster(ctx, project, location, network, user, password, clusterID, string(accessToken)) return source.CreateCluster(ctx, project, location, network, user, password, clusterID, string(accessToken))
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -168,6 +168,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.CreateInstance(ctx, project, location, cluster, instanceID, instanceType, displayName, nodeCount, string(accessToken)) return source.CreateInstance(ctx, project, location, cluster, instanceID, instanceType, displayName, nodeCount, string(accessToken))
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -173,6 +173,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.CreateUser(ctx, userType, password, roles, string(accessToken), project, location, cluster, userID) return source.CreateUser(ctx, userType, password, roles, string(accessToken), project, location, cluster, userID)
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -144,6 +144,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.GetCluster(ctx, project, location, cluster, string(accessToken)) return source.GetCluster(ctx, project, location, cluster, string(accessToken))
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -148,6 +148,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.GetInstance(ctx, project, location, cluster, instance, string(accessToken)) return source.GetInstance(ctx, project, location, cluster, instance, string(accessToken))
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -148,6 +148,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.GetUsers(ctx, project, location, cluster, user, string(accessToken)) return source.GetUsers(ctx, project, location, cluster, user, string(accessToken))
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -138,6 +138,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.ListCluster(ctx, project, location, string(accessToken)) return source.ListCluster(ctx, project, location, string(accessToken))
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -143,6 +143,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.ListInstance(ctx, project, location, cluster, string(accessToken)) return source.ListInstance(ctx, project, location, cluster, string(accessToken))
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -143,6 +143,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.ListUsers(ctx, project, location, cluster, string(accessToken)) return source.ListUsers(ctx, project, location, cluster, string(accessToken))
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -267,6 +267,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return nil, fmt.Errorf("exceeded max retries waiting for operation") return nil, fmt.Errorf("exceeded max retries waiting for operation")
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -148,6 +148,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return resp, nil return resp, nil
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -308,6 +308,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.RunSQL(ctx, bqClient, getInsightsSQL, "SELECT", nil, connProps) return source.RunSQL(ctx, bqClient, getInsightsSQL, "SELECT", nil, connProps)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -264,6 +264,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return response, nil return response, nil
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -281,6 +281,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.RunSQL(ctx, bqClient, sql, statementType, nil, connProps) return source.RunSQL(ctx, bqClient, sql, statementType, nil, connProps)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -271,6 +271,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.RunSQL(ctx, bqClient, sql, "SELECT", nil, connProps) return source.RunSQL(ctx, bqClient, sql, "SELECT", nil, connProps)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -157,6 +157,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return metadata, nil return metadata, nil
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -167,6 +167,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return metadata, nil return metadata, nil
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -163,6 +163,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return datasetIds, nil return datasetIds, nil
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -174,6 +174,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return tableIds, nil return tableIds, nil
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -258,6 +258,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return results, nil return results, nil
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
// Parse parameters from the provided data
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -213,6 +213,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.RunSQL(ctx, bqClient, newStatement, statementType, highLevelParams, connProps) return source.RunSQL(ctx, bqClient, newStatement, statementType, highLevelParams, connProps)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -116,6 +116,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.RunSQL(ctx, newStatement, t.Parameters, newParams) return source.RunSQL(ctx, newStatement, t.Parameters, newParams)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -136,6 +136,11 @@ func (t Tool) McpManifest() tools.McpManifest {
return t.mcpManifest return t.mcpManifest
} }
// ParseParams implements tools.Tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -101,6 +101,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.RunSQL(ctx, sql, nil) return source.RunSQL(ctx, sql, nil)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -103,6 +103,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return out, nil return out, nil
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -81,7 +81,7 @@ func TestListDatabasesToolParseParams(t *testing.T) {
}, },
} }
params, err := parameters.ParseParams(tool.GetParameters(), map[string]any{}, map[string]map[string]any{}) params, err := tool.ParseParams(map[string]any{}, map[string]map[string]any{})
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }

View File

@@ -125,6 +125,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return tables, nil return tables, nil
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }
@@ -150,5 +154,5 @@ func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string,
} }
func (t Tool) GetParameters() parameters.Parameters { func (t Tool) GetParameters() parameters.Parameters {
return t.AllParams return t.Parameters
} }

View File

@@ -83,7 +83,7 @@ func TestListTablesToolParseParams(t *testing.T) {
AllParams: parameters.Parameters{databaseParam}, AllParams: parameters.Parameters{databaseParam},
} }
params, err := parameters.ParseParams(tool.GetParameters(), map[string]any{"database": "test_db"}, map[string]map[string]any{}) params, err := tool.ParseParams(map[string]any{"database": "test_db"}, map[string]map[string]any{})
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }

View File

@@ -108,6 +108,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.RunSQL(ctx, newStatement, newParams) return source.RunSQL(ctx, newStatement, newParams)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -159,6 +159,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.RunQuery(ctx, tokenStr, bodyBytes) return source.RunQuery(ctx, tokenStr, bodyBytes)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -113,6 +113,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.FHIRFetchPage(ctx, url, tokenStr) return source.FHIRFetchPage(ctx, url, tokenStr)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -165,6 +165,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.FHIRPatientEverything(storeID, patientID, tokenStr, opts) return source.FHIRPatientEverything(storeID, patientID, tokenStr, opts)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -238,6 +238,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.FHIRPatientSearch(storeID, tokenStr, opts) return source.FHIRPatientSearch(storeID, tokenStr, opts)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -105,6 +105,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.GetDataset(tokenStr) return source.GetDataset(tokenStr)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -126,6 +126,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.GetDICOMStore(storeID, tokenStr) return source.GetDICOMStore(storeID, tokenStr)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -126,6 +126,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.GetDICOMStoreMetrics(storeID, tokenStr) return source.GetDICOMStoreMetrics(storeID, tokenStr)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -140,6 +140,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.GetFHIRResource(storeID, resType, resID, tokenStr) return source.GetFHIRResource(storeID, resType, resID, tokenStr)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -126,6 +126,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.GetFHIRStore(storeID, tokenStr) return source.GetFHIRStore(storeID, tokenStr)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -126,6 +126,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.GetFHIRStoreMetrics(storeID, tokenStr) return source.GetFHIRStoreMetrics(storeID, tokenStr)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -105,6 +105,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.ListDICOMStores(tokenStr) return source.ListDICOMStores(tokenStr)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -105,6 +105,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.ListFHIRStores(tokenStr) return source.ListFHIRStores(tokenStr)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -153,6 +153,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.RetrieveRenderedDICOMInstance(storeID, study, series, sop, frame, tokenStr) return source.RetrieveRenderedDICOMInstance(storeID, study, series, sop, frame, tokenStr)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -179,6 +179,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.SearchDICOM(t.Type, 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) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -164,6 +164,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.SearchDICOM(t.Type, 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) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -148,6 +148,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.SearchDICOM(t.Type, 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) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -1,155 +0,0 @@
// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// 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,
// 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.
package cloudloggingadminlistlognames
import (
"context"
"fmt"
"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/parameters"
)
const resourceType string = "cloud-logging-admin-list-log-names"
const defaultLimit int = 200
func init() {
if !tools.Register(resourceType, newConfig) {
panic(fmt.Sprintf("tool type %q already registered", resourceType))
}
}
func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.ToolConfig, error) {
actual := Config{Name: name}
if err := decoder.DecodeContext(ctx, &actual); err != nil {
return nil, err
}
return actual, nil
}
type compatibleSource interface {
UseClientAuthorization() bool
ListLogNames(ctx context.Context, limit int, accessToken string) ([]string, error)
}
type Config struct {
Name string `yaml:"name" 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 interface
var _ tools.ToolConfig = Config{}
func (cfg Config) ToolConfigType() string {
return resourceType
}
func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) {
limitDescription := fmt.Sprintf("Maximum number of log entries to return. Default: %d.", defaultLimit)
params := parameters.Parameters{
parameters.NewIntParameterWithRequired("limit", limitDescription, false),
}
mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params, nil)
t := Tool{
Config: cfg,
manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired},
mcpManifest: mcpManifest,
Parameters: params,
}
return t, nil
}
// validate interface
var _ tools.Tool = Tool{}
type Tool struct {
Config
manifest tools.Manifest
mcpManifest tools.McpManifest
Parameters parameters.Parameters `yaml:"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.Type)
if err != nil {
return nil, err
}
limit := defaultLimit
paramsMap := params.AsMap()
if val, ok := paramsMap["limit"].(int); ok && val > 0 {
limit = val
} else if ok && val < 0 {
return nil, fmt.Errorf("limit must be greater than or equal to 1")
}
tokenString := ""
if source.UseClientAuthorization() {
tokenString, err = accessToken.ParseBearerToken()
if err != nil {
return nil, fmt.Errorf("failed to parse access token: %w", err)
}
}
return source.ListLogNames(ctx, limit, tokenString)
}
func (t Tool) ParseParams(data map[string]any, claimsMap map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claimsMap)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return paramValues, nil
}
func (t Tool) Manifest() tools.Manifest {
return t.manifest
}
func (t Tool) McpManifest() tools.McpManifest {
return t.mcpManifest
}
func (t Tool) Authorized(verifiedAuthServices []string) bool {
return tools.IsAuthorized(t.AuthRequired, verifiedAuthServices)
}
func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) {
source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type)
if err != nil {
return false, err
}
return source.UseClientAuthorization(), nil
}
func (t Tool) ToConfig() tools.ToolConfig {
return t.Config
}
func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) {
return "Authorization", nil
}
func (t Tool) GetParameters() parameters.Parameters {
return t.Parameters
}

View File

@@ -1,122 +0,0 @@
// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// 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,
// 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.
package cloudloggingadminlistlognames_test
import (
"context"
"strings"
"testing"
"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/cloudloggingadmin/cloudloggingadminlistlognames"
)
func TestParseFromYaml(t *testing.T) {
tcs := []struct {
desc string
in string
want server.ToolConfigs
}{
{
desc: "basic example",
in: `
kind: tools
name: example_tool
type: cloud-logging-admin-list-log-names
source: my-logging-admin-source
description: list log names
authRequired:
- my-google-auth-service
`,
want: server.ToolConfigs{
"example_tool": cloudloggingadminlistlognames.Config{
Name: "example_tool",
Type: "cloud-logging-admin-list-log-names",
Source: "my-logging-admin-source",
Description: "list log names",
AuthRequired: []string{"my-google-auth-service"},
},
},
},
}
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 diff := cmp.Diff(tc.want, got); diff != "" {
t.Fatalf("incorrect parse: diff %v", diff)
}
})
}
}
func TestFailParseFromYaml(t *testing.T) {
ctx, err := testutils.ContextWithNewLogger()
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
tcs := []struct {
desc string
in string
err string
}{
{
desc: "Invalid type",
in: `
kind: tools
name: example_tool
type: invalid-type
source: my-instance
description: some description
`,
err: `unknown tool type: "invalid-type"`,
},
{
desc: "missing source",
in: `
kind: tools
name: example_tool
type: cloud-logging-admin-list-log-names
description: some description
`,
err: `Key: 'Config.Source' Error:Field validation for 'Source' failed on the 'required' tag`,
},
{
desc: "missing description",
in: `
kind: tools
name: example_tool
type: cloud-logging-admin-list-log-names
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) {
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in))
if err == nil {
t.Fatalf("expect parsing to fail")
}
errStr := err.Error()
if !strings.Contains(errStr, tc.err) {
t.Fatalf("unexpected error string: got %q, want substring %q", errStr, tc.err)
}
})
}
}

View File

@@ -1,142 +0,0 @@
// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// 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,
// 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.
package cloudloggingadminlistresourcetypes
import (
"context"
"fmt"
"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/parameters"
)
const resourceType string = "cloud-logging-admin-list-resource-types"
func init() {
if !tools.Register(resourceType, newConfig) {
panic(fmt.Sprintf("tool type %q already registered", resourceType))
}
}
func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.ToolConfig, error) {
actual := Config{Name: name}
if err := decoder.DecodeContext(ctx, &actual); err != nil {
return nil, err
}
return actual, nil
}
type compatibleSource interface {
UseClientAuthorization() bool
ListResourceTypes(ctx context.Context, accessToken string) ([]string, error)
}
type Config struct {
Name string `yaml:"name" 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 interface
var _ tools.ToolConfig = Config{}
func (cfg Config) ToolConfigType() string {
return resourceType
}
func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) {
// No parameters for this tool
var params parameters.Parameters
mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params, nil)
t := Tool{
Config: cfg,
Parameters: params,
manifest: tools.Manifest{Description: cfg.Description, AuthRequired: cfg.AuthRequired},
mcpManifest: mcpManifest,
}
return t, nil
}
// validate interface
var _ tools.Tool = Tool{}
type Tool struct {
Config
Parameters parameters.Parameters `yaml:"parameters"`
manifest tools.Manifest
mcpManifest tools.McpManifest
}
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.Type)
if err != nil {
return nil, err
}
tokenString := ""
if source.UseClientAuthorization() {
tokenString, err = accessToken.ParseBearerToken()
if err != nil {
return nil, fmt.Errorf("failed to parse access token: %w", err)
}
}
return source.ListResourceTypes(ctx, tokenString)
}
func (t Tool) ParseParams(data map[string]any, claimsMap map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParamValues{}, nil
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return paramValues, nil
}
func (t Tool) Manifest() tools.Manifest {
return t.manifest
}
func (t Tool) McpManifest() tools.McpManifest {
return t.mcpManifest
}
func (t Tool) Authorized(verifiedAuthServices []string) bool {
return tools.IsAuthorized(t.AuthRequired, verifiedAuthServices)
}
func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) {
source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type)
if err != nil {
return false, err
}
return source.UseClientAuthorization(), nil
}
func (t Tool) ToConfig() tools.ToolConfig {
return t.Config
}
func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) {
return "Authorization", nil
}
func (t Tool) GetParameters() parameters.Parameters {
return t.Parameters
}

View File

@@ -1,122 +0,0 @@
// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// 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,
// 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.
package cloudloggingadminlistresourcetypes_test
import (
"context"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/googleapis/genai-toolbox/internal/server"
"github.com/googleapis/genai-toolbox/internal/testutils"
cloudloggingadminlistresourcetypes "github.com/googleapis/genai-toolbox/internal/tools/cloudloggingadmin/cloudloggingadminlistresourcetypes"
)
func TestParseFromYaml(t *testing.T) {
tcs := []struct {
desc string
in string
want server.ToolConfigs
}{
{
desc: "basic example",
in: `
kind: tools
name: example_tool
type: cloud-logging-admin-list-resource-types
source: my-logging-admin-source
description: list resource types
authRequired:
- my-google-auth-service
`,
want: server.ToolConfigs{
"example_tool": cloudloggingadminlistresourcetypes.Config{
Name: "example_tool",
Type: "cloud-logging-admin-list-resource-types",
Source: "my-logging-admin-source",
Description: "list resource types",
AuthRequired: []string{"my-google-auth-service"},
},
},
},
}
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 diff := cmp.Diff(tc.want, got); diff != "" {
t.Fatalf("incorrect parse: diff %v", diff)
}
})
}
}
func TestFailParseFromYaml(t *testing.T) {
ctx, err := testutils.ContextWithNewLogger()
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
tcs := []struct {
desc string
in string
err string
}{
{
desc: "Invalid type",
in: `
kind: tools
name: example_tool
type: invalid-type
source: my-instance
description: some description
`,
err: `unknown tool type: "invalid-type"`,
},
{
desc: "missing source",
in: `
kind: tools
name: example_tool
type: cloud-logging-admin-list-resource-types
description: some description
`,
err: `Key: 'Config.Source' Error:Field validation for 'Source' failed on the 'required' tag`,
},
{
desc: "missing description",
in: `
kind: tools
name: example_tool
type: cloud-logging-admin-list-resource-types
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) {
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in))
if err == nil {
t.Fatalf("expect parsing to fail")
}
errStr := err.Error()
if !strings.Contains(errStr, tc.err) {
t.Fatalf("unexpected error string: got %q, want substring %q", errStr, tc.err)
}
})
}
}

View File

@@ -1,215 +0,0 @@
// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// 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,
// 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.
package cloudloggingadminquerylogs
import (
"context"
"fmt"
"time"
"github.com/goccy/go-yaml"
"github.com/googleapis/genai-toolbox/internal/embeddingmodels"
"github.com/googleapis/genai-toolbox/internal/sources"
cla "github.com/googleapis/genai-toolbox/internal/sources/cloudloggingadmin"
"github.com/googleapis/genai-toolbox/internal/tools"
"github.com/googleapis/genai-toolbox/internal/util/parameters"
)
const (
resourceType string = "cloud-logging-admin-query-logs"
defaultLimit int = 200
defaultStartTimeOffsetDays int = 30
)
func init() {
if !tools.Register(resourceType, newConfig) {
panic(fmt.Sprintf("tool type %q already registered", resourceType))
}
}
func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.ToolConfig, error) {
actual := Config{Name: name}
if err := decoder.DecodeContext(ctx, &actual); err != nil {
return nil, err
}
return actual, nil
}
type compatibleSource interface {
UseClientAuthorization() bool
QueryLogs(ctx context.Context, params cla.QueryLogsParams, accessToken string) ([]map[string]any, error)
}
type Config struct {
Name string `yaml:"name" 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 interface
var _ tools.ToolConfig = Config{}
func (cfg Config) ToolConfigType() string {
return resourceType
}
func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) {
startTimeDescription := fmt.Sprintf("Start time in RFC3339 format (e.g., 2025-12-09T00:00:00Z). Defaults to %d days ago.", defaultStartTimeOffsetDays)
limitDescription := fmt.Sprintf("Maximum number of log entries to return. Default: %d.", defaultLimit)
params := parameters.Parameters{
parameters.NewStringParameterWithRequired(
"filter",
"Cloud Logging filter query. Common fields: resource.type, resource.labels.*, logName, severity, textPayload, jsonPayload.*, protoPayload.*, labels.*, httpRequest.*. Operators: =, !=, <, <=, >, >=, :, =~, AND, OR, NOT.",
false,
),
parameters.NewBooleanParameterWithRequired("newestFirst", "Set to true for newest logs first. Defaults to oldest first.", false),
parameters.NewStringParameterWithRequired("startTime", startTimeDescription, false),
parameters.NewStringParameterWithRequired("endTime", "End time in RFC3339 format (e.g., 2025-12-09T23:59:59Z). Defaults to now.", false),
parameters.NewBooleanParameterWithRequired("verbose", "Include additional fields (insertId, trace, spanId, httpRequest, labels, operation, sourceLocation). Defaults to false.", false),
parameters.NewIntParameterWithRequired("limit", limitDescription, false),
}
mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params, nil)
t := Tool{
Config: cfg,
manifest: tools.Manifest{Description: cfg.Description, Parameters: params.Manifest(), AuthRequired: cfg.AuthRequired},
mcpManifest: mcpManifest,
Parameters: params,
}
return t, nil
}
// validate interface
var _ tools.Tool = Tool{}
type Tool struct {
Config
Parameters parameters.Parameters `yaml:"parameters"`
manifest tools.Manifest
mcpManifest tools.McpManifest
}
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.Type)
if err != nil {
return nil, err
}
// Parse parameters
limit := defaultLimit
paramsMap := params.AsMap()
newestFirst, _ := paramsMap["newestFirst"].(bool)
// Check and set limit
if val, ok := paramsMap["limit"].(int); ok && val > 0 {
limit = val
} else if ok && val < 0 {
return nil, fmt.Errorf("limit must be greater than or equal to 1")
}
// Check for verbosity of output
verbose, _ := paramsMap["verbose"].(bool)
// Build filter
var filter string
if f, ok := paramsMap["filter"].(string); ok {
if len(f) == 0 {
return nil, fmt.Errorf("filter cannot be empty if provided")
}
filter = f
}
// Parse start time
var startTime string
if val, ok := paramsMap["startTime"].(string); ok && val != "" {
if _, err := time.Parse(time.RFC3339, val); err != nil {
return nil, fmt.Errorf("startTime must be in RFC3339 format (e.g., 2025-12-09T00:00:00Z): %w", err)
}
startTime = val
} else {
startTime = time.Now().AddDate(0, 0, -defaultStartTimeOffsetDays).Format(time.RFC3339)
}
// Parse end time
var endTime string
if val, ok := paramsMap["endTime"].(string); ok && val != "" {
if _, err := time.Parse(time.RFC3339, val); err != nil {
return nil, fmt.Errorf("endTime must be in RFC3339 format (e.g., 2025-12-09T23:59:59Z): %w", err)
}
endTime = val
}
tokenString := ""
if source.UseClientAuthorization() {
tokenString, err = accessToken.ParseBearerToken()
if err != nil {
return nil, fmt.Errorf("failed to parse access token: %w", err)
}
}
queryParams := cla.QueryLogsParams{
Filter: filter,
NewestFirst: newestFirst,
StartTime: startTime,
EndTime: endTime,
Verbose: verbose,
Limit: limit,
}
return source.QueryLogs(ctx, queryParams, tokenString)
}
func (t Tool) ParseParams(data map[string]any, claimsMap map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claimsMap)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return paramValues, nil
}
func (t Tool) Manifest() tools.Manifest {
return t.manifest
}
func (t Tool) McpManifest() tools.McpManifest {
return t.mcpManifest
}
func (t Tool) Authorized(verifiedAuthServices []string) bool {
return tools.IsAuthorized(t.AuthRequired, verifiedAuthServices)
}
func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) {
source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type)
if err != nil {
return false, err
}
return source.UseClientAuthorization(), nil
}
func (t Tool) ToConfig() tools.ToolConfig {
return t.Config
}
func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) {
return "Authorization", nil
}
func (t Tool) GetParameters() parameters.Parameters {
return t.Parameters
}

View File

@@ -1,122 +0,0 @@
// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// 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,
// 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.
package cloudloggingadminquerylogs_test
import (
"context"
"strings"
"testing"
"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/cloudloggingadmin/cloudloggingadminquerylogs"
)
func TestParseFromYaml(t *testing.T) {
tcs := []struct {
desc string
in string
want server.ToolConfigs
}{
{
desc: "basic example",
in: `
kind: tools
name: example_tool
type: cloud-logging-admin-query-logs
source: my-logging-admin-source
description: query logs
authRequired:
- my-google-auth-service
`,
want: server.ToolConfigs{
"example_tool": cloudloggingadminquerylogs.Config{
Name: "example_tool",
Type: "cloud-logging-admin-query-logs",
Source: "my-logging-admin-source",
Description: "query logs",
AuthRequired: []string{"my-google-auth-service"},
},
},
},
}
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 diff := cmp.Diff(tc.want, got); diff != "" {
t.Fatalf("incorrect parse: diff %v", diff)
}
})
}
}
func TestFailParseFromYaml(t *testing.T) {
ctx, err := testutils.ContextWithNewLogger()
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
tcs := []struct {
desc string
in string
err string
}{
{
desc: "Invalid type",
in: `
kind: tools
name: example_tool
type: invalid-type
source: my-instance
description: some description
`,
err: `unknown tool type: "invalid-type"`,
},
{
desc: "missing source",
in: `
kind: tools
name: example_tool
type: cloud-logging-admin-query-logs
description: some description
`,
err: `Key: 'Config.Source' Error:Field validation for 'Source' failed on the 'required' tag`,
},
{
desc: "missing description",
in: `
kind: tools
name: example_tool
type: cloud-logging-admin-query-logs
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) {
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in))
if err == nil {
t.Fatalf("expect parsing to fail")
}
errStr := err.Error()
if !strings.Contains(errStr, tc.err) {
t.Fatalf("unexpected error string: got %q, want substring %q", errStr, tc.err)
}
})
}
}

View File

@@ -111,6 +111,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.RunQuery(projectID, query) return source.RunQuery(projectID, query)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -151,6 +151,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.CloneInstance(ctx, project, sourceInstanceName, destinationInstanceName, pointInTime, preferredZone, preferredSecondaryZone, string(accessToken)) return source.CloneInstance(ctx, project, sourceInstanceName, destinationInstanceName, pointInTime, preferredZone, preferredSecondaryZone, string(accessToken))
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -142,6 +142,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.InsertBackupRun(ctx, project, instance, location, description, string(accessToken)) return source.InsertBackupRun(ctx, project, instance, location, description, string(accessToken))
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -140,6 +140,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.CreateDatabase(ctx, name, project, instance, string(accessToken)) return source.CreateDatabase(ctx, name, project, instance, string(accessToken))
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -145,6 +145,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.CreateUsers(ctx, project, instance, name, password, iamUser, string(accessToken)) return source.CreateUsers(ctx, project, instance, name, password, iamUser, string(accessToken))
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -136,6 +136,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.GetInstance(ctx, projectId, instanceId, string(accessToken)) return source.GetInstance(ctx, projectId, instanceId, string(accessToken))
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -135,6 +135,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.ListDatabase(ctx, project, instance, string(accessToken)) return source.ListDatabase(ctx, project, instance, string(accessToken))
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -130,6 +130,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.ListInstance(ctx, project, string(accessToken)) return source.ListInstance(ctx, project, string(accessToken))
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -145,6 +145,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.RestoreBackup(ctx, targetProject, targetInstance, sourceProject, sourceInstance, backupID, string(accessToken)) return source.RestoreBackup(ctx, targetProject, targetInstance, sourceProject, sourceInstance, backupID, string(accessToken))
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -265,6 +265,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return nil, fmt.Errorf("exceeded max retries waiting for operation") return nil, fmt.Errorf("exceeded max retries waiting for operation")
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -169,6 +169,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.CreateInstance(ctx, project, name, dbVersion, rootPassword, settings, string(accessToken)) return source.CreateInstance(ctx, project, name, dbVersion, rootPassword, settings, string(accessToken))
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -171,6 +171,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.CreateInstance(ctx, project, name, dbVersion, rootPassword, settings, string(accessToken)) return source.CreateInstance(ctx, project, name, dbVersion, rootPassword, settings, string(accessToken))
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -170,6 +170,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.CreateInstance(ctx, project, name, dbVersion, rootPassword, settings, string(accessToken)) return source.CreateInstance(ctx, project, name, dbVersion, rootPassword, settings, string(accessToken))
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -206,6 +206,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return op, nil return op, nil
} }
// ParseParams parses the parameters for the tool.
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -115,6 +115,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.RunSQL(newStatement, newParams) return source.RunSQL(newStatement, newParams)
} }
func (t Tool) ParseParams(data map[string]any, claimsMap map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.AllParams, data, claimsMap)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.AllParams, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -103,6 +103,10 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return strings.TrimSpace(string(output)), nil return strings.TrimSpace(string(output)), nil
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -128,6 +128,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.LookupEntry(ctx, name, view, aspectTypes, entry) return source.LookupEntry(ctx, name, view, aspectTypes, entry)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
// Parse parameters from the provided data
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

View File

@@ -105,6 +105,11 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
return source.SearchAspectTypes(ctx, query, pageSize, orderBy) return source.SearchAspectTypes(ctx, query, pageSize, orderBy)
} }
func (t Tool) ParseParams(data map[string]any, claims map[string]map[string]any) (parameters.ParamValues, error) {
// Parse parameters from the provided data
return parameters.ParseParams(t.Parameters, data, claims)
}
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) { func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil) return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
} }

Some files were not shown because too many files have changed in this diff Show More