Skip to content

fix(tools/looker): support instructions, sources, and code interpreter for agent tool#2864

Merged
drstrangelooker merged 4 commits into
googleapis:looker-agentfrom
hiracky16:fix/looker-agent-upstream
Mar 26, 2026
Merged

fix(tools/looker): support instructions, sources, and code interpreter for agent tool#2864
drstrangelooker merged 4 commits into
googleapis:looker-agentfrom
hiracky16:fix/looker-agent-upstream

Conversation

@hiracky16

Copy link
Copy Markdown
Contributor

Description

This PR significantly enhances the looker-agent tool by adding missing parameters required for effective agent management.

In the initial implementation, only name and description (internal) were supported. However, crucial fields for Looker AI Agents such as instructions (system prompt), sources (data models/explores), and code_interpreter were missing. This update fills those gaps and also introduces an update operation.

Changes

  • New Parameters: Added instructions, sources (JSON-encoded array), and code_interpreter (boolean) to both create and update operations.
  • Update Operation: Implemented the update operation to allow modification of existing agents.
  • Robustness:
    - Updated error handling to use http.StatusBadRequest for client-side validation errors.
    - Added safety checks for parameter access to prevent runtime panics.
  • Enhanced Testing: Rewrote and expanded unit tests to cover all new parameters, operations, and validation logic (including MCP manifest verification).
  • Documentation: Updated the tool's documentation with detailed LLM instructions and usage examples for all new fields.

Impact

The looker-agent tool is now fully capable of managing the complete lifecycle and configuration of Looker AI Agents, enabling sophisticated analytical workflows.

Verification

  • Comprehensive unit tests added and passed: go test -v ./internal/tools/looker/lookeragent/...
  • Verified MCP manifest generation and schema correctness.

@hiracky16 hiracky16 requested review from a team as code owners March 26, 2026 22:27
@drstrangelooker drstrangelooker merged commit 900e7c3 into googleapis:looker-agent Mar 26, 2026
10 of 11 checks passed

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request expands the looker-agent tool by adding support for the update operation and introducing new optional parameters: instructions, sources, and code_interpreter. The documentation and unit tests have been updated accordingly. Feedback focuses on a critical bug where default values for optional parameters would incorrectly overwrite existing agent data during updates, a request to maintain consistency with the project's direct type assertion pattern for parameters, and a suggestion to refactor duplicated request body construction logic.

Comment on lines +76 to +78
instructionsParameter := parameters.NewStringParameterWithDefault("instructions", "", "The instructions (system prompt) for the agent. Used for `create` and `update` operations.")
sourcesParameter := parameters.NewArrayParameterWithDefault("sources", []any{}, "Optional. A list of JSON-encoded data sources for the agent (e.g., ['{\"model\": \"my_model\", \"explore\": \"my_explore\"}']).", parameters.NewStringParameter("source", "A JSON-encoded source object with 'model' and 'explore' keys."))
codeInterpreterParameter := parameters.NewBooleanParameterWithDefault("code_interpreter", false, "Optional. Enables Code Interpreter for this Agent. Used for `create` and `update` operations.")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

There's a bug in the update operation logic caused by initializing optional parameters with default values. Because instructions, sources, and code_interpreter have defaults, they are always present in the mapParams. The update logic then always includes them in the request body, incorrectly overwriting existing agent properties with default values if the user doesn't specify them.

To fix this, you should:

  1. Define optional parameters without default values and mark them as not required. This will ensure they are only present if explicitly provided by the user.
  2. With that change, the update logic will work as intended, as it will only process parameters that are actually present in the request.
Suggested change
instructionsParameter := parameters.NewStringParameterWithDefault("instructions", "", "The instructions (system prompt) for the agent. Used for `create` and `update` operations.")
sourcesParameter := parameters.NewArrayParameterWithDefault("sources", []any{}, "Optional. A list of JSON-encoded data sources for the agent (e.g., ['{\"model\": \"my_model\", \"explore\": \"my_explore\"}']).", parameters.NewStringParameter("source", "A JSON-encoded source object with 'model' and 'explore' keys."))
codeInterpreterParameter := parameters.NewBooleanParameterWithDefault("code_interpreter", false, "Optional. Enables Code Interpreter for this Agent. Used for `create` and `update` operations.")
instructionsParameter := parameters.NewStringParameterWithRequired("instructions", "The instructions (system prompt) for the agent. Used for create and update operations.", false)
sourcesParameter := parameters.NewArrayParameterWithRequired("sources", "Optional. A list of JSON-encoded data sources for the agent (e.g., ['{\"model\": \"my_model\", \"explore\": \"my_explore\"}']).", false, parameters.NewStringParameter("source", "A JSON-encoded source object with 'model' and 'explore' keys."))
codeInterpreterParameter := parameters.NewBooleanParameterWithRequired("code_interpreter", "Optional. Enables Code Interpreter for this Agent. Used for create and update operations.", false)

Comment on lines +130 to +142
var operation, agentId, name, instructions string
if v, ok := mapParams["operation"].(string); ok {
operation = v
}
if v, ok := mapParams["agent_id"].(string); ok {
agentId = v
}
if v, ok := mapParams["name"].(string); ok {
name = v
}
if v, ok := mapParams["instructions"].(string); ok {
instructions = v
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The use of the comma-ok idiom for parameter access contradicts the project's established pattern. Direct type assertions are preferred for consistency as the parameter parsing framework's typed constructors guarantee safety. Please revert to direct type assertions for parameters that are guaranteed to be present.

References
  1. Within this project's parameter parsing framework, direct type assertions on parameter values are acceptable without a comma-ok check. The framework's typed constructors already guarantee type safety, and this is an established pattern for consistency.

Comment on lines +204 to +218
body := v4.WriteAgent{}
if name != "" {
body.Name = &name
}
if instructions != "" {
body.Context = &v4.Context{
Instructions: &instructions,
}
}
if len(agentSources) > 0 {
body.Sources = &agentSources
}
if hasCodeInterpreter {
body.CodeInterpreter = &codeInterpreter
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The logic for populating the v4.WriteAgent body is duplicated between the create and update cases. This should be refactored into a helper function to improve code clarity and maintainability. Note that while server lifecycle logic duplication is permitted in this repo, business logic like request body construction should remain DRY.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants