Compare commits

...

4 Commits

4 changed files with 37 additions and 14 deletions

View File

@@ -41,13 +41,13 @@ tools:
### Usage Flow
When using this tool, a `prompt` parameter containing a natural language query is provided to the tool (typically by an agent). The tool then interacts with the Gemini Data Analytics API using the context defined in your configuration.
When using this tool, a `query` parameter containing a natural language query is provided to the tool (typically by an agent). The tool then interacts with the Gemini Data Analytics API using the context defined in your configuration.
The structure of the response depends on the `generationOptions` configured in your tool definition (e.g., enabling `generateQueryResult` will include the SQL query results).
See [Data Analytics API REST documentation](https://clouddocs.devsite.corp.google.com/gemini/docs/conversational-analytics-api/reference/rest/v1alpha/projects.locations/queryData?rep_location=global) for details.
**Example Input Prompt:**
**Example Input Query:**
```text
How many accounts who have region in Prague are eligible for loans? A3 contains the data of region.

View File

@@ -28,6 +28,22 @@ import (
const kind string = "cloud-gemini-data-analytics-query"
// Guidance is the tool guidance string.
const Guidance = `Tool guidance:
Inputs:
1. query: A natural language formulation of a database query.
Outputs: (all optional)
1. disambiguation_question: Clarification questions or comments where the tool needs the users' input.
2. generated_query: The generated query for the user query.
3. intent_explanation: An explanation for why the tool produced ` + "`generated_query`" + `.
4. query_result: The result of executing ` + "`generated_query`" + `.
5. natural_language_answer: The natural language answer that summarizes the ` + "`query`" + ` and ` + "`query_result`" + `.
Usage guidance:
1. If ` + "`disambiguation_question`" + ` is produced, then solicit the needed inputs from the user and try the tool with a new ` + "`query`" + ` that has the needed clarification.
2. If ` + "`natural_language_answer`" + ` is produced, use ` + "`intent_explanation`" + ` and ` + "`generated_query`" + ` to see if you need to clarify any assumptions for the user.
3. If the tool output indicates failure or empty results, explain that clearly using the provided reasoning.`
func init() {
if !tools.Register(kind, newConfig) {
panic(fmt.Sprintf("tool kind %q already registered", kind))
@@ -68,11 +84,18 @@ func (cfg Config) ToolConfigKind() string {
func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) {
// Define the parameters for the Gemini Data Analytics Query API
// The prompt is the only input parameter.
// The query is the only input parameter.
allParameters := parameters.Parameters{
parameters.NewStringParameterWithRequired("prompt", "The natural language question to ask.", true),
parameters.NewStringParameterWithRequired("query", "A natural language formulation of a database query.", true),
}
// The input and outputs are for tool guidance, usage guidance is for multi-turn interaction.
guidance := Guidance
if cfg.Description != "" {
cfg.Description += "\n\n" + guidance
} else {
cfg.Description = guidance
}
mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, allParameters, nil)
return Tool{
@@ -105,9 +128,9 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
}
paramsMap := params.AsMap()
prompt, ok := paramsMap["prompt"].(string)
query, ok := paramsMap["query"].(string)
if !ok {
return nil, fmt.Errorf("prompt parameter not found or not a string")
return nil, fmt.Errorf("query parameter not found or not a string")
}
// Parse the access token if provided
@@ -125,7 +148,7 @@ func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, para
payload := &QueryDataRequest{
Parent: payloadParent,
Prompt: prompt,
Prompt: query,
Context: t.Context,
GenerationOptions: t.GenerationOptions,
}

View File

@@ -328,9 +328,9 @@ func TestInvoke(t *testing.T) {
t.Fatalf("failed to initialize tool: %v", err)
}
// Prepare parameters for invocation - ONLY prompt
// Prepare parameters for invocation - ONLY query
params := parameters.ParamValues{
{Name: "prompt", Value: "How many accounts who have region in Prague are eligible for loans?"},
{Name: "query", Value: "How many accounts who have region in Prague are eligible for loans?"},
}
resourceMgr := resources.NewResourceManager(srcs, nil, nil, nil, nil, nil, nil)

View File

@@ -139,12 +139,12 @@ func TestCloudGdaToolEndpoints(t *testing.T) {
// 1. RunToolGetTestByName
expectedManifest := map[string]any{
toolName: map[string]any{
"description": "Test GDA Tool",
"description": "Test GDA Tool\n\n" + cloudgda.Guidance,
"parameters": []any{
map[string]any{
"name": "prompt",
"name": "query",
"type": "string",
"description": "The natural language question to ask.",
"description": "A natural language formulation of a database query.",
"required": true,
"authSources": []any{},
},
@@ -155,7 +155,7 @@ func TestCloudGdaToolEndpoints(t *testing.T) {
tests.RunToolGetTestByName(t, toolName, expectedManifest)
// 2. RunToolInvokeParametersTest
params := []byte(`{"prompt": "test question"}`)
params := []byte(`{"query": "test question"}`)
tests.RunToolInvokeParametersTest(t, toolName, params, "\"queryResult\":\"SELECT * FROM table;\"")
// 3. Manual MCP Tool Call Test
@@ -172,7 +172,7 @@ func TestCloudGdaToolEndpoints(t *testing.T) {
Params: map[string]any{
"name": toolName,
"arguments": map[string]any{
"prompt": "test question",
"query": "test question",
},
},
}