For Toolbox protocol:
Before - return 400 error for all tool invocation errors.
After - Propagate auth-related errors (401 & 403) to the client if using
client credentials. If using ADC, raise 500 error instead.
For MCP protocol:
Before - return 200 with error message in the response body.
After - Propagate auth-related errors (401 & 403) to the client if using
client credentials. If using ADC, raise 500 error instead.
Allow Toolbox server to automatically update when users modify their
tool configuration file(s), instead of requiring a restart.
This feature is automatically enabled, but can be turned off with the
flag `--disable-reload`.
This feature includes the following:
* Implement initialize lifecycle (including version negotiation)
* Add the v20250326 schema
* Supporting the `DELETE` and `GET` endpoint for MCP.
* Supporting streamable HTTP (without SSE).
* Terminating sessions after timeout (default = 10 minutes from last
active).
* Toolbox do not support batch request. Will response with `Invalid
requests` if batch requests is received.
gosimple had been deprecated in favor of staticcheck:
https://github.com/golangci/golangci-lint/issues/357
Other requirements are all migrated.
`std-error-handling` exclusions is included because without that, it
will ask to check all error returns from (`Close()`, or `os.Setenv`s, or
`fmt.Fprint`s...
Rename existing `authSource` to `authService` through deprecation.
`AuthService` more clearly distinguishes it from `Sources` objects.
`authSources` will be converted into `authServices` after the
unmarshalling process. A warning log is shown if `authSources` are used
(for both within tools parameters and defining auth services):
```
2025-02-20T13:57:51.156025-08:00 WARN "`authSources` is deprecated, use `authServices` for parameters instead"
2025-02-20T13:57:51.156569-08:00 WARN "`authSources` is deprecated, use `authServices` instead"
2025-02-20T13:57:52.047584-08:00 INFO "Initialized 1 sources."
...
```
The manifest generated will continue to use `authSources` to keep
compatibility with the sdks:
```
{
"serverVersion":"0.1.0",
"tools":{
"test_tool2":{
"description":"Use this tool to test\n",
"parameters":[{
"name":"user_id",
"type":"string",
"description":"Auto-populated from Google login",
"authSources":["my-google-auth"]
}]
}
}
}
```
Test cases with `authSources` are kept for compatibility. Will be
removed when `authSources` are no longer supported.
Currently, we are throwing 401 error immediately after auth token
verification failure. This is not expected in the following situations:
1. Non-auth tool invocation with auth token that is invalid.
2. Auth tool invocation with all the required auth token, but the header
contains extra non-required token that is invalid
These requests should pass the authorization check but fail under the
current implementation.
Change made in this PR:
1. Do not throw error immediately after auth token verification failure.
Instead only log it and continue to the next header iteration.
2. In the parseParams() method, if an auth parameter is missing, we
should error with the message telling the user that either the auth
header is missing or is invalid.
Add debug logs to Toolbox.
For example when a http fail, it will just show Error at the http level,
but not log with actual error message. err message are returned to the
api as following `{"status":"Internal Server Error","error":"error while
invoking tool: unable to execute client: spanner: code =
\"InvalidArgument\", desc = \"invalid session pool\""}`.
After adding this, if user/dev run toolbox with `--log-level=debug`, it
will output the following (debug log in addition to the error for http
request):
```
2025-01-08T14:16:25.040824-08:00 DEBUG "error while invoking tool: unable to execute client: spanner: code = \"InvalidArgument\", desc = \"invalid session pool\""
2025-01-08T14:16:25.040968-08:00 ERROR Response: 500 Server Error service: "httplog" httpRequest: {url: "http://127.0.0.1:5000/api/tool/test_tool_two/invoke" method: "POST" path: "/api/tool/test_tool_two/invoke" remoteIP: "127.0.0.1:51708" proto: "HTTP/1.1" requestID: "yuanteoh-macbookpro.roam.internal/N7LNMcLIUH-000001" scheme: "http" header: {user-agent: "curl/8.7.1" accept: "*/*" content-type: "application/json" content-length: "2"}} httpResponse: {status: 500 bytes: 167 elapsed: 0.301917}
```
Corrects an issue caused by Go defaulting to parsing JSON Numbers as
float64s. This caused some numbers to be incorrectly parsed as floats
when they were integers. This defaults to parsing using json.Number,
which allows us to parse between Int/Float more accurately.
Adds logic to make the server shutdown gracefully, including better
respecting cancelled contexts and providing up to 10 seconds to finish
current connections.
1. Add []ParamAuthSource to every Parameter type implementation to
support authenticated configs. Create new constructors for types with
auth.
2. Tool invocation API changes to parse auth header and authentecated
parameters.
3. Add authSources to Tool manifest.
Logging support 4 different types of logging (debug, info, warn, error).
The default logging level is Info.
User will be able to set flag for log level (allowed values: "debug",
"info", "warn", "error"), example:
`go run . --log-level debug`
User will be able to set flag for logging format (allowed values:
"standard", "JSON"), example:
`go run . --logging-format json`
**sample http request log - std:**
server
```
2024-11-12T15:08:11.451377-08:00 INFO "Initalized 0 sources.\n"
```
httplog
```
2024-11-26T15:15:53.947287-08:00 INFO Response: 200 OK service: "httplog" httpRequest: {url: "http://127.0.0.1:5000/" method: "GET" path: "/" remoteIP: "127.0.0.1:64216" proto: "HTTP/1.1" requestID: "macbookpro.roam.interna/..." scheme: "http" header: {user-agent: "curl/8.7.1" accept: "*/*"}} httpResponse: {status: 200 bytes: 22 elapsed: 0.012417}
```
**sample http request log - structured:**
server
```
{
"timestamp":"2024-11-04T16:45:11.987299-08:00",
"severity":"ERROR",
"logging.googleapis.com/sourceLocation":{
"function":"github.com/googleapis/genai-toolbox/internal/log.(*StructuredLogger).Errorf",
"file":"/Users/yuanteoh/github/genai-toolbox/internal/log/log.go","line":157
},
"message":"unable to parse tool file at \"tools.yaml\": \"cloud-sql-postgres1\" is not a valid kind of data source"
}
```
httplog
```
{
"timestamp":"2024-11-26T15:12:49.290974-08:00",
"severity":"INFO",
"logging.googleapis.com/sourceLocation":{
"function":"github.com/go-chi/httplog/v2.(*RequestLoggerEntry).Write",
"file":"/Users/yuanteoh/go/pkg/mod/github.com/go-chi/httplog/v2@v2.1.1/httplog.go","line":173
},
"message":"Response: 200 OK",
"service":"httplog",
"httpRequest":{
"url":"http://127.0.0.1:5000/",
"method":"GET",
"path":"/",
"remoteIP":"127.0.0.1:64140",
"proto":"HTTP/1.1",
"requestID":"yuanteoh-macbookpro.roam.internal/NBrtYBu3q9-000001",
"scheme":"http",
"header":{"user-agent":"curl/8.7.1","accept":"*/*"}
},
"httpResponse":{"status":200,"bytes":22,"elapsed":0.0115}
}
```
Adds support for "array" type parameters. Uses a subet of JSONSchema for
specification, in that arrays can be specified in the following way:
```yaml
parameters:
name: "my_array"
type: "array"
description: "some description"
items:
type: "integer"
```
1. Calculate tool manifests when server starts.
2. Add toolset manifest endpoints.
---------
Co-authored-by: Kurtis Van Gent <31518063+kurtisvg@users.noreply.github.com>
Makes the following changes:
- Fills in previously stubbed "Invoke()" function for the Cloud SQL
Generic Tool
- Updates API to /{tool_name}/invoke to for invocation of said tool
- Updates response to use JSON
- Correctly returns error messages for invalid http codes
This PR adds preliminary parsing of parameters. Currently it only
supports 4 types: string, int, float32, and bool. Almost certainly we
will need to introduce more complicated parsing configuration (to handle
objects and arrays), but my initial attempts got quickly complicated, so
I simplified in the short term.
This also makes 2 breaking changes to config.yaml:
- changes "parameters" to be a list over object -- this is because
parameter ordering is important, and needs to be preserved
- removed the "required" field from parameter objects -- we need to
determine how to handle optional parameters in SQL queries