mirror of
https://github.com/googleapis/genai-toolbox.git
synced 2026-01-08 15:14:00 -05:00
fix(tools/alloydbainl)!: AlloyDB AI NL execute_sql statement order (#1753)
## Description
The order of parameters in alloydb_ai_nl.execute_nl_query changed, which
broke the alloydbainl tool. This adds named parameters to the statement
in the tool, which fixes this.
This will be a breaking change for existing user that defined their
natural language configuration with the `create_configure` operation.
The `execute_nl_query` input argument parameter and order had been
updated recently, hence, users that are defining their configuration
with the latest instructions will not be able to use Toolbox. This
update is inevitable.
Previously, user will create the configuration with the following:
```
CALL google_ml.create_model(model_id => 'gemini-2_0_flash', ...);
SELECT alloydb_ai_nl.g_manage_configuration(
'create_configuration', -- operation
'my_nl_config', -- configuration_id_in
'gemini-2_0_flash' -- model_id_in
);
SELECT alloydb_ai_nl.g_manage_configuration(
operation => 'register_table_view',
configuration_id_in => 'my_nl_config',
table_views_in=>'{auth_psv}');
```
Currently, user will create the configuration with the following:
```
SELECT alloydb_ai_nl.g_create_configuration(configuration_id =>'my_nl_config');
SELECT alloydb_ai_nl.g_manage_configuration(
operation => 'register_table_view',
configuration_id_in => 'my_nl_config',
table_views_in=>'{auth_psv}'
);
```
This PR also updates the nl_question from "return 1" to "return the
number 1" to provide more context to the model.
A new `ainl_update_testing` database was created with the new NL
configuration in order to not break existing integration tests before
merging this PR. Once this is merged, the existing `test_database`
database will be updated and will update the integration test's database
again.
## PR Checklist
> Thank you for opening a Pull Request! Before submitting your PR, there
are a
> few things you can do to make sure it goes smoothly:
- [X] Make sure you reviewed
[CONTRIBUTING.md](https://github.com/googleapis/genai-toolbox/blob/main/CONTRIBUTING.md)
- [X] Make sure to open an issue as a
[bug/issue](https://github.com/googleapis/genai-toolbox/issues/new/choose)
before writing your code! That way we can discuss the change, evaluate
designs, and agree on the general idea
- [X] Ensure the tests and linter pass
- [X] Code coverage does not decrease (if any source code was changed)
- [X] Appropriate docs were updated (if necessary)
- [X] Make sure to add `!` if this involve a breaking change
🛠️ Fixes #1752
---------
Co-authored-by: Yuan Teoh <yuanteoh@google.com>
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
This commit is contained in:
@@ -118,7 +118,7 @@ steps:
|
||||
- "ALLOYDB_AI_NL_PROJECT=$PROJECT_ID"
|
||||
- "ALLOYDB_AI_NL_CLUSTER=$_ALLOYDB_AI_NL_CLUSTER"
|
||||
- "ALLOYDB_AI_NL_INSTANCE=$_ALLOYDB_AI_NL_INSTANCE"
|
||||
- "ALLOYDB_AI_NL_DATABASE=$_DATABASE_NAME"
|
||||
- "ALLOYDB_AI_NL_DATABASE=$_AI_NL_DATABASE_NAME"
|
||||
- "ALLOYDB_AI_NL_REGION=$_REGION"
|
||||
- "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
|
||||
secretEnv: ["ALLOYDB_AI_NL_USER", "ALLOYDB_AI_NL_PASS", "CLIENT_ID"]
|
||||
@@ -850,6 +850,7 @@ options:
|
||||
|
||||
substitutions:
|
||||
_DATABASE_NAME: test_database
|
||||
_AI_NL_DATABASE_NAME: ainl_update_testing
|
||||
_FIREBIRD_DATABASE_NAME: /firebird/test_database.fdb
|
||||
_REGION: "us-central1"
|
||||
_CLOUD_SQL_POSTGRES_INSTANCE: "cloud-sql-pg-testing"
|
||||
@@ -890,4 +891,4 @@ substitutions:
|
||||
_YUGABYTEDB_DATABASE: "yugabyte"
|
||||
_YUGABYTEDB_PORT: "5433"
|
||||
_YUGABYTEDB_LOADBALANCE: "false"
|
||||
_ORACLE_SERVER_NAME: "FREEPDB1"
|
||||
_ORACLE_SERVER_NAME: "FREEPDB1"
|
||||
|
||||
@@ -42,6 +42,17 @@ the steps listed in the [Generate SQL queries that answer natural language
|
||||
questions][alloydb-ai-gen-nl], including enabling the extension and configuring
|
||||
context for your application.
|
||||
|
||||
{{< notice note >}}
|
||||
As of AlloyDB AI NL v1.0.3+, the signature of `execute_nl_query` has been
|
||||
updated. Run `SELECT extversion FROM pg_extension WHERE extname =
|
||||
'alloydb_ai_nl';` to check which version your instance is using.
|
||||
AlloyDB AI NL v1.0.3+ is required for Toolbox v0.19.0+. Starting with Toolbox v0.19.0, users
|
||||
who previously used the create_configuration operation for the natural language
|
||||
configuration must update it. To do so, please drop the existing configuration
|
||||
and redefine it using the instructions
|
||||
[here](https://docs.cloud.google.com/alloydb/docs/ai/use-natural-language-generate-sql-queries#create-config).
|
||||
{{< /notice >}}
|
||||
|
||||
[alloydb-ai-nl-overview]: https://cloud.google.com/alloydb/docs/ai/natural-language-overview
|
||||
[alloydb-ai-gen-nl]: https://cloud.google.com/alloydb/docs/ai/generate-sql-queries-natural-language
|
||||
|
||||
|
||||
@@ -108,8 +108,8 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
|
||||
// The second parameter is the NLConfig, which is passed as a $2
|
||||
// The following params are the list of PSV values passed to the NLConfig
|
||||
// Example SQL statement being executed:
|
||||
// SELECT alloydb_ai_nl.execute_nl_query('How many tickets do I have?', 'cymbal_air_nl_config', param_names => ARRAY ['user_email'], param_values => ARRAY ['hailongli@google.com']);
|
||||
stmtFormat := "SELECT alloydb_ai_nl.execute_nl_query($1, $2, param_names => %s, param_values => %s);"
|
||||
// SELECT alloydb_ai_nl.execute_nl_query(nl_question => 'How many tickets do I have?', nl_config_id => 'cymbal_air_nl_config', param_names => ARRAY ['user_email'], param_values => ARRAY ['hailongli@google.com']);
|
||||
stmtFormat := "SELECT alloydb_ai_nl.execute_nl_query(nl_question => $1, nl_config_id => $2, param_names => %s, param_values => %s);"
|
||||
stmt := fmt.Sprintf(stmtFormat, paramNamesSQL, paramValuesSQL)
|
||||
|
||||
newQuestionParam := tools.NewStringParameter(
|
||||
@@ -163,7 +163,7 @@ func (t Tool) Invoke(ctx context.Context, params tools.ParamValues, accessToken
|
||||
|
||||
results, err := t.Pool.Query(ctx, t.Statement, allParamValues...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to execute query: %w. Query: %v , Values: %v", err, t.Statement, allParamValues)
|
||||
return nil, fmt.Errorf("unable to execute query: %w. Query: %v , Values: %v. Toolbox v0.19.0+ is only compatible with AlloyDB AI NL v1.0.3+. Please ensure that you are using the latest AlloyDB AI NL extension", err, t.Statement, allParamValues)
|
||||
}
|
||||
|
||||
fields := results.FieldDescriptions()
|
||||
|
||||
@@ -177,7 +177,7 @@ func runAINLToolInvokeTest(t *testing.T) {
|
||||
name: "invoke my-simple-tool",
|
||||
api: "http://127.0.0.1:5000/api/tool/my-simple-tool/invoke",
|
||||
requestHeader: map[string]string{},
|
||||
requestBody: bytes.NewBuffer([]byte(`{"question": "return 1"}`)),
|
||||
requestBody: bytes.NewBuffer([]byte(`{"question": "return the number 1"}`)),
|
||||
want: "[{\"execute_nl_query\":{\"?column?\":1}}]",
|
||||
isErr: false,
|
||||
},
|
||||
@@ -200,21 +200,21 @@ func runAINLToolInvokeTest(t *testing.T) {
|
||||
name: "Invoke my-auth-tool with invalid auth token",
|
||||
api: "http://127.0.0.1:5000/api/tool/my-auth-tool/invoke",
|
||||
requestHeader: map[string]string{"my-google-auth_token": "INVALID_TOKEN"},
|
||||
requestBody: bytes.NewBuffer([]byte(`{"question": "return 1"}`)),
|
||||
requestBody: bytes.NewBuffer([]byte(`{"question": "return the number 1"}`)),
|
||||
isErr: true,
|
||||
},
|
||||
{
|
||||
name: "Invoke my-auth-tool without auth token",
|
||||
api: "http://127.0.0.1:5000/api/tool/my-auth-tool/invoke",
|
||||
requestHeader: map[string]string{},
|
||||
requestBody: bytes.NewBuffer([]byte(`{"question": "return 1"}`)),
|
||||
requestBody: bytes.NewBuffer([]byte(`{"question": "return the number 1"}`)),
|
||||
isErr: true,
|
||||
},
|
||||
{
|
||||
name: "Invoke my-auth-required-tool with auth token",
|
||||
api: "http://127.0.0.1:5000/api/tool/my-auth-required-tool/invoke",
|
||||
requestHeader: map[string]string{"my-google-auth_token": idToken},
|
||||
requestBody: bytes.NewBuffer([]byte(`{"question": "return 1"}`)),
|
||||
requestBody: bytes.NewBuffer([]byte(`{"question": "return the number 1"}`)),
|
||||
isErr: false,
|
||||
want: "[{\"execute_nl_query\":{\"?column?\":1}}]",
|
||||
},
|
||||
@@ -222,14 +222,14 @@ func runAINLToolInvokeTest(t *testing.T) {
|
||||
name: "Invoke my-auth-required-tool with invalid auth token",
|
||||
api: "http://127.0.0.1:5000/api/tool/my-auth-required-tool/invoke",
|
||||
requestHeader: map[string]string{"my-google-auth_token": "INVALID_TOKEN"},
|
||||
requestBody: bytes.NewBuffer([]byte(`{"question": "return 1"}`)),
|
||||
requestBody: bytes.NewBuffer([]byte(`{"question": "return the number 1"}`)),
|
||||
isErr: true,
|
||||
},
|
||||
{
|
||||
name: "Invoke my-auth-required-tool without auth token",
|
||||
api: "http://127.0.0.1:5000/api/tool/my-auth-tool/invoke",
|
||||
requestHeader: map[string]string{},
|
||||
requestBody: bytes.NewBuffer([]byte(`{"question": "return 1"}`)),
|
||||
requestBody: bytes.NewBuffer([]byte(`{"question": "return the number 1"}`)),
|
||||
isErr: true,
|
||||
},
|
||||
}
|
||||
@@ -358,7 +358,7 @@ func runAINLMCPToolCallMethod(t *testing.T) {
|
||||
Params: map[string]any{
|
||||
"name": "my-simple-tool",
|
||||
"arguments": map[string]any{
|
||||
"question": "return 1",
|
||||
"question": "return the number 1",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user