Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/internal/imports.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ import (
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetdimensions"
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetexplores"
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetfilters"
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetlookmltests"
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetlooks"
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetmeasures"
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetmodels"
Expand Down
2 changes: 1 addition & 1 deletion cmd/internal/tools_file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1778,7 +1778,7 @@ func TestPrebuiltTools(t *testing.T) {
wantToolset: server.ToolsetConfigs{
"looker_tools": tools.ToolsetConfig{
Name: "looker_tools",
ToolNames: []string{"get_models", "get_explores", "get_dimensions", "get_measures", "get_filters", "get_parameters", "query", "query_sql", "query_url", "get_looks", "run_look", "make_look", "get_dashboards", "run_dashboard", "make_dashboard", "add_dashboard_element", "add_dashboard_filter", "generate_embed_url", "health_pulse", "health_analyze", "health_vacuum", "dev_mode", "get_projects", "get_project_files", "get_project_file", "create_project_file", "update_project_file", "delete_project_file", "get_project_directories", "create_project_directory", "delete_project_directory", "validate_project", "get_connections", "get_connection_schemas", "get_connection_databases", "get_connection_tables", "get_connection_table_columns"},
ToolNames: []string{"get_models", "get_explores", "get_dimensions", "get_measures", "get_filters", "get_parameters", "query", "query_sql", "query_url", "get_looks", "run_look", "make_look", "get_dashboards", "run_dashboard", "make_dashboard", "add_dashboard_element", "add_dashboard_filter", "generate_embed_url", "health_pulse", "health_analyze", "health_vacuum", "dev_mode", "get_projects", "get_project_files", "get_project_file", "create_project_file", "update_project_file", "delete_project_file", "get_project_directories", "create_project_directory", "delete_project_directory", "validate_project", "get_connections", "get_connection_schemas", "get_connection_databases", "get_connection_tables", "get_connection_table_columns", "get_lookml_tests"},
},
},
},
Expand Down
65 changes: 65 additions & 0 deletions internal/prebuiltconfigs/tools/looker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,68 @@ tools:
A JSON array of objects, where each object represents a column and contains details
such as `table_name`, `column_name`, `data_type`, and `is_nullable`.

get_lookml_tests:
kind: looker-get-lookml-tests
source: looker-source
description: |
Returns a list of tests which can be run to validate a project's LookML code and/or the underlying data, optionally filtered by the file id.

Prerequisite: The Looker session must be in Development Mode. Use `dev_mode: true` first.

Parameters:
- project_id (required): The unique ID of the LookML project.
- file_id (optional): The ID of the file to filter tests by. This must be the complete file path from the project root (e.g., `models/my_model.model.lkml` or `views/my_view.view.lkml`).

Output:
A JSON array of LookML test objects, each containing:
- model_name: The name of the model.
- name: The name of the test.
- explore_name: The name of the explore being tested.
- query_url_params: The query parameters used for the test.
- file: The file path where the test is defined.
- line: The line number where the test is defined.

run_lookml_tests:
kind: looker-run-lookml-tests
source: looker-source
description: |
This tool runs LookML tests in the project, filtered by file, test, and/or model. These filters work in conjunction (logical AND).

Prerequisite: The Looker session must be in Development Mode. Use `dev_mode: true` first.

Parameters:
- project_id (required): The unique ID of the project to run LookML tests for.
- file_id (optional): The ID of the file to run tests for. This must be the complete file path from the project root (e.g., `models/my_model.model.lkml` or `views/my_view.view.lkml`).
- test (optional): The name of the test to run.
- model (optional): The name of the model to run tests for.

Output:
A JSON array containing the results of the executed tests, where each object includes:
- model_name: Name of the model tested.
- test_name: Name of the test.
- assertions_count: Total number of assertions in the test.
- assertions_failed: Number of assertions that failed.
- success: Boolean indicating if the test passed.
- errors: Array of error objects (if any), containing details like `message`, `file_path`, `line_number`, and `severity`.
- warnings: Array of warning messages (if any).

create_view_from_table:
kind: looker-create-view-from-table
source: looker-source
description: |
This tool generates boilerplate LookML views directly from the database schema.
It does not create model or explore files, only view files in the specified folder.

Prerequisite: The Looker session must be in Development Mode. Use `dev_mode: true` first.

Parameters:
- project_id (required): The unique ID of the LookML project.
- connection (required): The database connection name.
- tables (required): A list of objects to generate views for. Each object must contain `schema` and `table_name` (note: table names are case-sensitive). Optional fields include `primary_key`, `base_view`, and `columns` (array of objects with `column_name`).
- folder_name (optional): The folder to place the view files in (defaults to 'views/').

Output:
A confirmation message upon successful view generation, or an error message if the operation fails.

toolsets:
looker_tools:
Expand Down Expand Up @@ -1138,3 +1200,6 @@ toolsets:
- get_connection_databases
- get_connection_tables
- get_connection_table_columns
- get_lookml_tests
- run_lookml_tests
- create_view_from_table
42 changes: 42 additions & 0 deletions internal/tools/looker/lookercommon/lookercommon.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,3 +330,45 @@ func DeleteProjectDirectory(l *v4.LookerSDK, projectId string, directoryPath str
path := fmt.Sprintf("/projects/%s/directories", url.PathEscape(projectId))
return l.AuthSession.Do(&result, "DELETE", "/4.0", path, query, nil, options)
}

type ProjectGeneratorColumn struct {
ColumnName string `json:"column_name"`
}

type ProjectGeneratorTable struct {
Schema string `json:"schema"`
TableName string `json:"table_name"`
PrimaryKey *string `json:"primary_key,omitempty"`
BaseView *bool `json:"base_view,omitempty"`
Columns []ProjectGeneratorColumn `json:"columns,omitempty"`
}

type ProjectGeneratorRequestBody struct {
Tables []ProjectGeneratorTable `json:"tables"`
}

type ProjectGeneratorQueryParams struct {
Connection string `json:"connection"`
FileTypeForExplores string `json:"file_type_for_explores"`
FolderName string `json:"folder_name,omitempty"`
}

func CreateViewsFromTables(ctx context.Context, l *v4.LookerSDK, projectId string, queryParams ProjectGeneratorQueryParams, reqBody ProjectGeneratorRequestBody, options *rtl.ApiSettings) error {
path := fmt.Sprintf("/projects/%s/generate", url.PathEscape(projectId))

// Construct query parameter map
query := map[string]any{
"connection": queryParams.Connection,
"file_type_for_explores": queryParams.FileTypeForExplores,
"folder_name": queryParams.FolderName,
}

// Pass the Tables slice directly as the body, not the wrapped struct.
// The API spec defines `tables` as `body_param ... array: true`,
// which means the body itself should be the array.
err := l.AuthSession.Do(nil, "POST", "/4.0", path, query, reqBody.Tables, options)

logger, _ := util.LoggerFromContext(ctx)
logger.DebugContext(ctx, fmt.Sprintf("generating views with request: query=%v body=%v error=%v", query, reqBody.Tables, err))
return err
}
Loading
Loading