231 Commits

Author SHA1 Message Date
Dr. Strangelove
bc91559cc4 feat(tools/looker): Control over whether hidden objects are surfaced (#1222)
The following config is added to the looker source:

* show_hidden_models
* show_hidden_explores
* show_hidden_fields

## Description
---
> Should include a concise description of the changes (bug or feature),
it's
> impact, along with a summary of the solution

## 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/langchain-google-alloydb-pg-python/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 #1214
2025-08-26 15:39:44 -07:00
Wenxin Du
650e2e26f5 feat(sources/bigquery): add support for user-credential passthrough (#1067)
Support end-user credential passthrough with the BigQuery source and the
`bigquery-sql` tool.
Support for other BQ tools will be added in subsequent PRs.

Issue: https://github.com/googleapis/genai-toolbox/issues/813
2025-08-26 17:52:24 -04:00
Dr. Strangelove
00866bc7fc fix(tools/looker): lookergetdashboards uses proper Authorized helper func (#1255)
looker-getdash-board uses the Authorized helper function.

## 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)
- [ ] Make sure to open an issue as a

[bug/issue](https://github.com/googleapis/langchain-google-alloydb-pg-python/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
2025-08-26 20:32:08 +00:00
Huan Chen
7651357d42 feat(tools/bigquery-ask-data-insights): add bigquery ask-data-insights tool (#932)
1. Add ask-data-insights tool based on conversational analytic API.
2. Add tokenSource for ask-data-insights tool, it uses access token
instead of client or restService.
3. Add a max row count to source, currently fixed to 50 and used only
for ask-data-insights tool. Later we may make it available for user to
make change and apply to bigquery-execute-sql and bigquery-sql to avoid
return too many data by accident.

---------

Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
Co-authored-by: Averi Kitsch <akitsch@google.com>
2025-08-26 20:16:17 +00:00
Wenxin Du
b94a021ca1 feat(server): implement Tool call auth error propagation (#1235)
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.
2025-08-26 15:27:46 -04:00
Dr. Strangelove
81c36354cb fix(tools/looker): Minor fixes and refinements to Looker (#1215)
* fix not null expression 
* exclude dimensions that end in _raw
* Add tags to return from get_dimensions, get_measures, etc.
* Add synonyms to return from get_dimensions, get_measures, etc.
* Instruct Agent to only create pie chart visualizations with one
measure and one dimension.
* Added docs about the return types of
get_dimensions/get_measures/get_filters/get_parameters.

---------

Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
2025-08-26 18:55:23 +00:00
Yuan Teoh
a37cfa841d fix(tools/mysql): fix encoded text for mysql (#1161)
Update the type conversion to according to the types that mysql driver
returns: https://github.com/go-sql-driver/mysql/blob/v1.9.3/fields.go

All `scanTypeBytes` or `scanTypeString` or `scanTypeNullString` will now
be converted into string. Remaining types (numeric types or
`scanTypeUnknown`) are all returned as is.

Separately handle "JSON" to prevent double marshaling.

Fixes #840
2025-08-25 21:24:00 -07:00
Wenxin Du
b1abbeb380 refactor: Add Tool method to check client authorization (#1217)
Add `RequiresClientAuthorization()` method to the `Tool` interface.
Currently returning false for all tools.
Supports: https://github.com/googleapis/genai-toolbox/pull/1067
2025-08-22 20:53:14 +00:00
Paulo Mota
4f6b806de9 feat(firebird): Add Firebird SQL 2.5+ source and tool support (#1011)
## Description
This Pull Request introduces support for the Firebird database as a new
`source` and adds the `firebird-sql` and `firebird-execute-sql` tools.
The implementation follows the architectural pattern established by the
existing PostgreSQL and MySQL tools.

Comprehensive integration tests have been added in the `tests/firebird`
directory, covering table creation, data insertion, and the invocation
of all related tools. Corresponding user and developer documentation has
also been included.

## Test Results
The core functionality is working as demonstrated by the vast majority
of tests passing. However, a few tests fail due to limitations and
inflexibilities in the generic test harness (`tests/tool.go`), which is
not fully compatible with Firebird's specific syntax and behavior.

### Known and Justified Failures:

* **`invoke_my-tool` / `invoke_my-array-tool`:** The `RunToolInvokeTest`
function reuses the same `want` variable for both sub-tests, which have
different inputs and expected outputs. The test is configured for
`my-tool` to pass, which consequently causes the `my-array-tool` test to
fail its assertion. The `got` log for the array test confirms that the
tool returns the correct response for the given input.
* **`invoke_my-exec-sql-tool`:** This test fails because the harness
sends the query `SELECT 1`, which is invalid syntax in Firebird.
Subsequent tests for this tool using DDL and DML (`create`, `select`,
`drop`) all pass, confirming its core functionality.
* **`invoke_select-fields-templateParams-tool`:** This test fails due to
a case-sensitivity mismatch in column names (`NAME` vs. `name`). The
expected output in the test harness is hardcoded with a lowercase name.
* **Authentication Tests:** All authentication-related tests are
failing. This appears to be a general issue with the local test
environment setup and is not specific to the Firebird implementation.

## Next Steps
I believe the implementation is ready for review. I am available to make
any requested changes.
Feat #935

---------

Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
Co-authored-by: Yuan Teoh <yuanteoh@google.com>
2025-08-22 11:01:14 -07:00
trehanshakuntG
00101232a3 feat(tools/firestore-update-document): Add firestore-update-document tool (#1191)
## Add firestore-update-document tool

Adds a new tool for updating existing documents in Firestore
collections.

__What it does:__

- Updates documents at any path in Firestore
- Supports partial updates with field masks for selective field
modification
- Handles all Firestore data types (strings, numbers, booleans,
timestamps, geopoints, arrays, maps, etc.)
- Supports field deletion using updateMask
- Uses Firestore's native JSON format for type safety
- Can update nested fields within maps using dot notation

__Key parameters:__

- `documentPath`: The path of the document to update
- `documentData`: The document content in Firestore JSON format
- `updateMask`: Optional array of field paths for selective updates
- `returnData`: Optional flag to include updated document in response

__Special features:__

- When `updateMask` is provided, only specified fields are updated
- Can access nested fields with dot notation (e.g., 'address.city',
'user.profile.name')
- Without updateMask, performs a merge operation updating all provided
fields
2025-08-22 06:56:23 +00:00
Abhinav Misra
7dd123b3d7 feat(trino): Add Trino source and tools (#948)
Add support for Trino distributed SQL query engine with complete
implementation including sources, tools, documentation, and tests.

## Summary

- Add Trino source implementation with multiple authentication methods
- Create trino-execute-sql tool for arbitrary SQL execution
- Create trino-sql tool for parameterized queries
- Add comprehensive documentation ~~and prebuilt configurations~~
- Include unit tests for all components

## Features

### Authentication Support
- Basic authentication (username/password)
- JWT token authentication
- Kerberos authentication
- SSL/TLS connections

### Tools
- **trino-execute-sql**: Execute arbitrary SQL queries
- **trino-sql**: Execute parameterized SQL with prepared statements
- Prebuilt tools for common operations (list catalogs, schemas, tables,
etc.)

### Cross-Catalog Queries
- Support for federated queries across multiple data sources
- Query Hive, PostgreSQL, MySQL, and other connectors in single queries
- Leverage Trino's distributed query engine capabilities

## Test Plan
- [x] Unit tests pass for source DSN generation
- [x] Unit tests pass for tool parameter validation
- [x] Project builds successfully with new dependencies
- [x] Documentation includes comprehensive examples

Ref #880

---------

Co-authored-by: Yuan Teoh <yuanteoh@google.com>
Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
2025-08-22 00:03:04 +00:00
dishaprakash
7f553a865b chore(prebuilt): dynamically generate --prebuilt flag options (#1205)
## Description
---
This PR changes the help description in the prebuilt flag from hardcoded
source options to dynamically fetching it from the prebuilt configs.

## 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)
- [ ] Make sure to open an issue as a

[bug/issue](https://github.com/googleapis/langchain-google-alloydb-pg-python/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)
- [ ] Make sure to add `!` if this involve a breaking change

🛠️ Fixes #<issue_number_goes_here>
2025-08-22 04:38:11 +05:30
Wenxin Du
bffe7b0661 refactor: Pass Authorization header token to Tool call functions (#1200)
Pass in authorization token to the Tool invocation functions.
Support: https://github.com/googleapis/genai-toolbox/pull/1067
2025-08-21 18:20:42 -04:00
Averi Kitsch
8ea6a98bd9 fix(tools/mongodb-find-one): ProjectPayload unmarshaling (#1167)
## Description
---
Update mongodb find one to unmarshal projectpayload

## 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:
- [ ] Make sure you reviewed

[CONTRIBUTING.md](https://github.com/googleapis/genai-toolbox/blob/main/CONTRIBUTING.md)
- [ ] Make sure to open an issue as a

[bug/issue](https://github.com/googleapis/langchain-google-alloydb-pg-python/issues/new/choose)
before writing your code! That way we can discuss the change, evaluate
  designs, and agree on the general idea
- [ ] Ensure the tests and linter pass
- [ ] Code coverage does not decrease (if any source code was changed)
- [ ] Appropriate docs were updated (if necessary)
- [ ] Make sure to add `!` if this involve a breaking change

🛠️ Fixes #1153
2025-08-21 11:01:35 -07:00
prernakakkar-google
f8f09818c7 feat(prebuilt/alloydb)!: Add bearer token support for alloydb-wait-for-operation (#1183)
## Description
---
The *alloydb-wait-for-operation* tool now automatically obtains a Google
Cloud Platform OAuth2 token and uses it as a bearer token to
authenticate requests to the AlloyDB Admin API. This ensures secure and
proper communication with the API.
<img width="3840" height="2084" alt="image"
src="https://github.com/user-attachments/assets/e756255f-83f9-4719-8d8b-596a628ca1e3"
/>
## 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/langchain-google-alloydb-pg-python/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
https://github.com/googleapis/langchain-google-alloydb-pg-python/issues/456
2025-08-21 11:58:17 +05:30
Dr. Strangelove
97f0dd2acf feat(tool/looker): add support for "description" field in looker tool (#1199)
## Description
---
Adds support for fetching description for looker dimensions and
measures.
Descriptions give important context to any agent about how to filter and
aggregate.

Adds the `description` DimensionFields and MeasureFields
Handles cases when description is not available.
Adds tests.

## PR Checklist
---
- [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/langchain-google-alloydb-pg-python/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 #1197

---------

Co-authored-by: Magnus Benediktsson <magnus.benediktsson@nordnet.se>
2025-08-20 12:41:18 -07:00
Wenxin Du
5dcc66c84f feat(server/mcp): Support ping mechanism (#1178)
Send back an empty result with a `ping` request following the [MCP ping
spec](https://modelcontextprotocol.io/specification/2025-06-18/basic/utilities/ping).

<img width="577" height="481" alt="Screenshot 2025-08-18 at 4 20 09 PM"
src="https://github.com/user-attachments/assets/fd48725e-298e-4938-9368-d704bea0a546"
/>
2025-08-20 15:04:47 -04:00
trehanshakuntG
ee4a70a0e8 feat(tools/firestore-add-documents): Add firestore-add-documents tool (#1107)
## Add firestore-add-documents tool

Adds a new tool for creating documents in Firestore collections.

__What it does:__

- Adds documents to any Firestore collection
- Auto-generates unique document IDs
- Supports all Firestore data types (strings, numbers, booleans,
timestamps, geopoints, arrays, maps, etc.)
- Uses Firestore's native JSON format for type safety

__Key parameters:__

- `collectionPath`: Where to add the document
- `documentData`: The document content in Firestore JSON format
- `returnData`: Optional flag to include created document in response

---------

Co-authored-by: Averi Kitsch <akitsch@google.com>
2025-08-19 11:24:21 +05:30
Haoming Chen
2ad0ccf83d feat(tools/bigquery-forecast): Add bigqueryforecast tool (#1148)
This tool wraps the BigQuery's AI.FORECAST function to do the time
series forecasting.

Co-authored-by: Averi Kitsch <akitsch@google.com>
2025-08-18 13:45:54 -07:00
zhouyh
6fc49826d4 feat(tools/oceanbase): Add oceanbase Source and Tool (#895)
1.Added oceanbase Source and Tool
2.Add tests related to OceanBase
3.Add the documentation for Oceanbase
Close #894

---------

Co-authored-by: Wenxin Du <117315983+duwenxin99@users.noreply.github.com>
Co-authored-by: duwenxin <duwenxin@google.com>
2025-08-18 11:40:10 -04:00
Anuj Jhunjhunwala
d940187c85 feat(tools/dataplex-search-aspect-types): Add support for dataplex-search-aspect-types tool (#1061)
Added support for search aspect types tool in Dataplex.
Fixes #1056

---------

Co-authored-by: Averi Kitsch <akitsch@google.com>
2025-08-14 13:34:00 -07:00
Yuan Teoh
31ed87861d chore: refactor process parameters function (#1145)
Added check to `ProcessParameters()` to check for parameter name
duplication and simplify the function.

ref: #1135
2025-08-14 19:27:09 +00:00
Wenxin Du
0b0457c8e6 fix: Correct the capitalization of map manifests (#1139)
Manifests field keys should start with lower case
2025-08-13 22:37:41 +00:00
prernakakkar-google
f5bcb9c755 feat(prebuiltconfig/alloydb-postgres): add tool to create user via Built in user type or IAM (#1130)
…ilt in or IAM

Co-authored-by: Averi Kitsch <akitsch@google.com>
2025-08-13 13:05:06 -07:00
prernakakkar-google
b42c139158 feat(prebuiltconfig/alloydb-admin): Add list cluster, instance and users (#1126)
…er tool

---------

Co-authored-by: Averi Kitsch <akitsch@google.com>
2025-08-13 12:28:20 -07:00
Wenxin Du
fbe8c1a9c0 fix: Remove unnecessary fields from map parameter manifests (#1138)
Previously the `additionalProperties` field manifests returns name,
descriptions, authSources etc. that are not needed.
These fields are removed for clarity.
2025-08-13 18:12:27 +00:00
Sri Varshitha
497d3b126d feat: Introduce additional parameter to limit context in list_tables (#1151)
Co-authored-by: Averi Kitsch <akitsch@google.com>
2025-08-13 11:02:55 -07:00
Yuan Teoh
7b57251402 feat(sources/postgres): add support for queryParams (#1047)
Add support for `queryParams` for users that would like to connect with
additional query parameters.

```
sources:
    my-pg-source:
        kind: postgres
        host: 127.0.0.1
        port: 5432
        database: my_db
        user: ${USER_NAME}
        password: ${PASSWORD}
        queryParams:
            sslmode: verify-full
            sslrootcert: /tmp/ca.crt
```

`queryParams` will be added as raw query of the database connection url.

Fixes #963
2025-08-12 22:34:56 +00:00
Wenxin Du
e8006d31eb chore(tools/http): Refactor HTTP manifest creation (#1135)
Simplify manifest creation and replace duplication checking with common
helper.
2025-08-12 18:22:41 +00:00
Dr. Strangelove
42be3f550c feat(tools/looker): New Looker tools for dashboards (#1118)
* get_dashboards
* make_dashboard
* add_dashboard_element
2025-08-11 17:13:08 -04:00
prernakakkar-google
6f55b78e96 feat(source/http): Add User Agent to calls (#1102)
This change adds a User Agent for all http calls as part of source. This
will append the user agent being passed as part of prebuilt tools
context to default headers.
2025-08-11 18:43:28 +00:00
AlexTalreja
0820ae6881 chore(ui): logo redirects to homepage for Toolbox UI (#1112)
Clicking on the MCP Toolbox Logo will redirect to the Toolbox UI
Homepage.
2025-08-07 15:50:22 -07:00
AlexTalreja
37ae55648d feat: add instructions and links to docs in UI (#1100)
Add instructions on basic usage + links to the public documentation on
the main content area of the Homepage, Tools page, and Toolsets page.
2025-08-07 11:33:09 -07:00
Dr. Strangelove
61d9489344 feat(tools/looker): add looker-make-look tool to create Looks (#1099) 2025-08-07 12:48:40 -04:00
Dr. Strangelove
5bf275846a feat: add visualizations to query-url tool (#1090)
Co-authored-by: Wenxin Du <117315983+duwenxin99@users.noreply.github.com>
2025-08-06 18:17:02 -04:00
Wenxin Du
4fd19bf9af chore: Access params by maps for execute-sql tools (#1097)
It's safer and also more readable to access params by map.
2025-08-06 16:42:02 -04:00
Wenxin Du
5fda4d4ed1 Revert "chore: Access params by maps for execute-sql tools" (#1095)
This reverts commit 6455ba964b.
2025-08-06 16:13:36 -04:00
duwenxin99
6455ba964b chore: Access params by maps for execute-sql tools 2025-08-06 15:24:00 -04:00
Dr. Strangelove
3b1cce72e7 fix(tools/looker): add isAuthorized call to all Looker tools (#1091) 2025-08-06 16:15:05 +00:00
Huan Chen
1cac9b5b37 feat(bigquery-execute-sql): add dry run support (#1057)
Add optional `dry_run` parameter to bigquery-execute-sql, which defaults
to `false`.

When the `dry_run` parameter is set to `true`, the tool returns the
metadata from the dry run instead of executing the query.

Fixes #703

---------

Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
2025-08-05 23:56:28 +00:00
AlexTalreja
d91bdfcbdc feat: add login with google button for automatic id token retrieval (#1044)
Add `Sign in with Google` button within Toolbox UI's `Edit Header` modal
that automatically retrieves a valid ID token for users based on an
input clientID.

This should make it significantly easier/faster for users to format
request headers properly and test tools that use auth.
2025-08-05 15:55:28 -07:00
Averi Kitsch
f79cdd6144 revert: 'feat: add support for DuckDB' (#1079)
DuckDB requires an overhaul of the build system, see
https://github.com/marcboeker/go-duckdb/issues/94
2025-08-05 11:44:52 -07:00
prernakakkar-google
c3a58e1d16 feat(prebuiltconfigs/cloud-sql-postgres): Introduce additional parameter to limit context in list tables (#1062) 2025-08-05 17:13:03 +00:00
Wenxin Du
0527532bd7 feat(tools/bigquery,mssql,mysql,postgres,spanner,tidb): Add query logging to execute-sql tools (#1069)
fix: https://github.com/googleapis/genai-toolbox/issues/1052
2025-08-05 03:01:19 +00:00
Dr. Strangelove
8da5a8f68d refactor(tools/looker): dedup code into helper functions (#1053)
Refactoring code in the Looker tools as suggested by Gemini

---------

Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
2025-08-04 16:51:31 -07:00
AlexTalreja
8749b03003 feat: interactive web UI for Toolbox (#1065)
Introduce Toolbox UI, which can be launched with the `--ui` flag. 

This initial version of Toolbox UI allows users to test Toolbox by
inspecting tools/toolsets, modifying parameters, managing headers, and
executing API calls.
2025-08-04 11:47:38 -07:00
Yuan Teoh
e843f73079 chore(server/mcp): update to accept other json content type request (#1049)
Toolbox MCP endpoint to accept request of multiple content type
according to the json schema
(https://www.jsonrpc.org/historical/json-rpc-over-http.html#http-header)

Toolbox endpoints only accept `Content-Type: application/json`. Update
to accept `Content-Type: application/json-rpc` and
`Content-Type:application/jsonrequest` as well.

Fixes #1004
2025-08-02 08:04:46 +00:00
Cheese
6eaf36ac85 feat: support tidb in data source, sql tool, and execute sql tool (#829)
This PR supports TiDB in:

1. sources - tidb: As a data source;
2. tools - tidb - tidbsql: As a prepared SQL running tool;
3. tools - tidb - tidbexecutesql: As an arbitrary SQL running tool (for
development purposes).

And its corresponding docs.

---------

Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
Co-authored-by: Yuan Teoh <yuanteoh@google.com>
2025-08-02 00:54:22 -07:00
Huan Chen
051e686476 fix(tools/bigquery-execute-sql): update the return messages (#1034)
Updated return message to make sure all cases are covered.
2025-08-01 14:39:16 -07:00
Huan Chen
9af55b651d fix(tools/bigquery-sql): ensure invoke always returns a non-null value (#1020)
This is to make bigquery-sql consistent with bigquery-execute-sql. May
not be necessary to have.

- Added a dry run step to identify the query type (e.g., SELECT, DML),
which allows the tool to correctly handle the query's output.
- The recommended high-level client, cloud.google.com/go/bigquery, does
not expose the statement type from a dry run. To circumvent this
limitation, the low-level BigQuery REST API client
(google.golang.org/api/bigquery/v2) was added to gain access to these
necessary details.

---------

Co-authored-by: Averi Kitsch <akitsch@google.com>
2025-08-01 14:16:57 -07:00