mirror of
https://github.com/googleapis/genai-toolbox.git
synced 2026-02-18 19:05:19 -05:00
Compare commits
208 Commits
pgtriggers
...
skip-lint-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15bae11365 | ||
|
|
d75c5cdf4d | ||
|
|
165d8f31dc | ||
|
|
2c6c34b735 | ||
|
|
857efd1509 | ||
|
|
3e7d9b243d | ||
|
|
5a1559e1c8 | ||
|
|
5b107c53f3 | ||
|
|
4d51c2a61e | ||
|
|
3ceec96f8a | ||
|
|
06e01aecd1 | ||
|
|
af146cfb8a | ||
|
|
417806d84d | ||
|
|
5efd435c23 | ||
|
|
8a96fb1a88 | ||
|
|
d4ff6bebe9 | ||
|
|
41afeafaae | ||
|
|
598b56f478 | ||
|
|
a678886ee3 | ||
|
|
6602abd059 | ||
|
|
62b830987d | ||
|
|
195767bdcd | ||
|
|
c5524d32f5 | ||
|
|
e1739abd81 | ||
|
|
478a0bdb59 | ||
|
|
2d341acaa6 | ||
|
|
f032389a07 | ||
|
|
32610d71a3 | ||
|
|
32cb4db712 | ||
|
|
1fdd99a9b6 | ||
|
|
1f8019c50a | ||
|
|
6e8255476a | ||
|
|
4fb5b34a5a | ||
|
|
1664a69dfd | ||
|
|
7f88caa985 | ||
|
|
3c9365dfd9 | ||
|
|
7767e1e019 | ||
|
|
bb40cdf78c | ||
|
|
a15a12873f | ||
|
|
5e4f2a131f | ||
|
|
80ef346214 | ||
|
|
732eaed41d | ||
|
|
a2097ba8eb | ||
|
|
3f1908a822 | ||
|
|
eef7a94977 | ||
|
|
4c96bb5c81 | ||
|
|
e0245946ea | ||
|
|
6e49ba436e | ||
|
|
4cff979491 | ||
|
|
e995349ea0 | ||
|
|
4c9765f1fb | ||
|
|
d1358916d8 | ||
|
|
2d5d33388c | ||
|
|
252fc3091a | ||
|
|
10c445b05c | ||
|
|
341316bb63 | ||
|
|
44da09300c | ||
|
|
362ed8df41 | ||
|
|
293c1d6889 | ||
|
|
cf477b529a | ||
|
|
cdc4d0d304 | ||
|
|
3aa1b79c13 | ||
|
|
941ed689b4 | ||
|
|
f298c8f444 | ||
|
|
f6474739e3 | ||
|
|
1d7c498116 | ||
|
|
9294ce39c8 | ||
|
|
86bf7bf8d0 | ||
|
|
ad2893d809 | ||
|
|
e535b372ea | ||
|
|
5054212fa4 | ||
|
|
93ca4578da | ||
|
|
ec936aed03 | ||
|
|
fe69272c84 | ||
|
|
15101b1edb | ||
|
|
e4f60e5633 | ||
|
|
d7af21bdde | ||
|
|
adc9589766 | ||
|
|
c25a2330fe | ||
|
|
6e09b08c6a | ||
|
|
1f15a111f1 | ||
|
|
dfddeb528d | ||
|
|
00c3e6d8cb | ||
|
|
d00b6fdf18 | ||
|
|
4d23a3bbf2 | ||
|
|
5e0999ebf5 | ||
|
|
6b02591703 | ||
|
|
8e0fb03483 | ||
|
|
2817dd1e5d | ||
|
|
68a218407e | ||
|
|
d69792d843 | ||
|
|
647b04d3a7 | ||
|
|
030df9766f | ||
|
|
5dbf207162 | ||
|
|
9c3720e31d | ||
|
|
3cd3c39d66 | ||
|
|
0691a6f715 | ||
|
|
467b96a23b | ||
|
|
4abf0c39e7 | ||
|
|
dd7b9de623 | ||
|
|
41b518b955 | ||
|
|
6e8a9eb8ec | ||
|
|
ef8f3b02f2 | ||
|
|
351b007fe3 | ||
|
|
9d1feca108 | ||
|
|
17b41f6453 | ||
|
|
a7799757c9 | ||
|
|
d961e373e1 | ||
|
|
bcb40a720d | ||
|
|
4a4cf1e712 | ||
|
|
b706b5bc68 | ||
|
|
4d3332d37d | ||
|
|
1203b7370a | ||
|
|
4a26ce3c1b | ||
|
|
306b5becda | ||
|
|
a4506009b9 | ||
|
|
17b70ccaa7 | ||
|
|
001d634de1 | ||
|
|
268700bdbf | ||
|
|
eb793398cd | ||
|
|
cf0fc515b5 | ||
|
|
9c62f313ff | ||
|
|
731a32e536 | ||
|
|
53885e6c0d | ||
|
|
b4346dcb8f | ||
|
|
0f27f956c7 | ||
|
|
f9df2635c6 | ||
|
|
c1b87e209f | ||
|
|
55eb958c2a | ||
|
|
20447746e1 | ||
|
|
83670dbe34 | ||
|
|
df2f6a9f0b | ||
|
|
2fa9cdb522 | ||
|
|
285cdcd69a | ||
|
|
38d127a354 | ||
|
|
3d140a657e | ||
|
|
0714d3e126 | ||
|
|
0baffff3b5 | ||
|
|
f87ed05aac | ||
|
|
a35f64ef7d | ||
|
|
980600f31b | ||
|
|
f4c22b3e27 | ||
|
|
c2df6223e6 | ||
|
|
4d6f70b55e | ||
|
|
c088d4ed42 | ||
|
|
0202709efc | ||
|
|
9695fc5eeb | ||
|
|
5447c94ca8 | ||
|
|
7053fbb195 | ||
|
|
5a09d38056 | ||
|
|
967a72da11 | ||
|
|
7daa4111f4 | ||
|
|
18885f6433 | ||
|
|
21d676ed58 | ||
|
|
1c353a3c8e | ||
|
|
a02ca45ba3 | ||
|
|
8217d1424d | ||
|
|
f520b4ed8a | ||
|
|
80315a0ebd | ||
|
|
5788605818 | ||
|
|
0641da0353 | ||
|
|
c9b775d38e | ||
|
|
8ea39ec32f | ||
|
|
aa270b2630 | ||
|
|
e1bd98ef5b | ||
|
|
fa148c60a7 | ||
|
|
6e87349431 | ||
|
|
3fe4e2b671 | ||
|
|
271f39d4b9 | ||
|
|
97b0e7d3ac | ||
|
|
914b3eefda | ||
|
|
776a5ca438 | ||
|
|
d08dd144ad | ||
|
|
fbd92c68ba | ||
|
|
af3d3c5204 | ||
|
|
466aef024f | ||
|
|
a6830744fc | ||
|
|
615b5f0130 | ||
|
|
2b45266598 | ||
|
|
26ead2ed78 | ||
|
|
1f31c2c9b2 | ||
|
|
78e015d7df | ||
|
|
c6ccf4bd87 | ||
|
|
5605eabd69 | ||
|
|
e29c0616d6 | ||
|
|
285aa46b88 | ||
|
|
c5a6daa768 | ||
|
|
78b02f08c3 | ||
|
|
18d0440f4e | ||
|
|
7a135ce078 | ||
|
|
ea9e2d12bd | ||
|
|
bea9705450 | ||
|
|
489117d747 | ||
|
|
32367a472f | ||
|
|
3b40fea25e | ||
|
|
f6b6a9fb5d | ||
|
|
1dd971b8d5 | ||
|
|
cb4529cbaa | ||
|
|
ac375114fd | ||
|
|
8a0eba9d62 | ||
|
|
5ad7c6127b | ||
|
|
f4b1f0a680 | ||
|
|
17a979207d | ||
|
|
3bf3fe8fa7 | ||
|
|
1bf0b51f03 | ||
|
|
744214e04c | ||
|
|
155bff80c1 | ||
|
|
e84252feb4 |
@@ -305,4 +305,4 @@ substitutions:
|
|||||||
_AR_HOSTNAME: ${_REGION}-docker.pkg.dev
|
_AR_HOSTNAME: ${_REGION}-docker.pkg.dev
|
||||||
_AR_REPO_NAME: toolbox-dev
|
_AR_REPO_NAME: toolbox-dev
|
||||||
_BUCKET_NAME: genai-toolbox-dev
|
_BUCKET_NAME: genai-toolbox-dev
|
||||||
_DOCKER_URI: ${_AR_HOSTNAME}/${PROJECT_ID}/${_AR_REPO_NAME}/toolbox
|
_DOCKER_URI: ${_AR_HOSTNAME}/${PROJECT_ID}/${_AR_REPO_NAME}/toolbox
|
||||||
@@ -87,7 +87,7 @@ steps:
|
|||||||
- "CLOUD_SQL_POSTGRES_REGION=$_REGION"
|
- "CLOUD_SQL_POSTGRES_REGION=$_REGION"
|
||||||
- "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
|
- "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
|
||||||
secretEnv:
|
secretEnv:
|
||||||
["CLOUD_SQL_POSTGRES_USER", "CLOUD_SQL_POSTGRES_PASS", "CLIENT_ID"]
|
["CLOUD_SQL_POSTGRES_USER", "CLOUD_SQL_POSTGRES_PASS", "CLIENT_ID", "API_KEY"]
|
||||||
volumes:
|
volumes:
|
||||||
- name: "go"
|
- name: "go"
|
||||||
path: "/gopath"
|
path: "/gopath"
|
||||||
@@ -134,7 +134,7 @@ steps:
|
|||||||
- "ALLOYDB_POSTGRES_DATABASE=$_DATABASE_NAME"
|
- "ALLOYDB_POSTGRES_DATABASE=$_DATABASE_NAME"
|
||||||
- "ALLOYDB_POSTGRES_REGION=$_REGION"
|
- "ALLOYDB_POSTGRES_REGION=$_REGION"
|
||||||
- "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
|
- "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
|
||||||
secretEnv: ["ALLOYDB_POSTGRES_USER", "ALLOYDB_POSTGRES_PASS", "CLIENT_ID"]
|
secretEnv: ["ALLOYDB_POSTGRES_USER", "ALLOYDB_POSTGRES_PASS", "CLIENT_ID", "API_KEY"]
|
||||||
volumes:
|
volumes:
|
||||||
- name: "go"
|
- name: "go"
|
||||||
path: "/gopath"
|
path: "/gopath"
|
||||||
@@ -171,6 +171,23 @@ steps:
|
|||||||
alloydbainl \
|
alloydbainl \
|
||||||
alloydbainl
|
alloydbainl
|
||||||
|
|
||||||
|
- id: "alloydb-omni"
|
||||||
|
name: golang:1
|
||||||
|
waitFor: ["compile-test-binary"]
|
||||||
|
entrypoint: /bin/bash
|
||||||
|
env:
|
||||||
|
- "GOPATH=/gopath"
|
||||||
|
volumes:
|
||||||
|
- name: "go"
|
||||||
|
path: "/gopath"
|
||||||
|
args:
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
.ci/test_with_coverage.sh \
|
||||||
|
"AlloyDB Omni" \
|
||||||
|
alloydbomni \
|
||||||
|
postgres
|
||||||
|
|
||||||
- id: "bigtable"
|
- id: "bigtable"
|
||||||
name: golang:1
|
name: golang:1
|
||||||
waitFor: ["compile-test-binary"]
|
waitFor: ["compile-test-binary"]
|
||||||
@@ -212,6 +229,26 @@ steps:
|
|||||||
bigquery \
|
bigquery \
|
||||||
bigquery
|
bigquery
|
||||||
|
|
||||||
|
- id: "cloud-gda"
|
||||||
|
name: golang:1
|
||||||
|
waitFor: ["compile-test-binary"]
|
||||||
|
entrypoint: /bin/bash
|
||||||
|
env:
|
||||||
|
- "GOPATH=/gopath"
|
||||||
|
- "CLOUD_GDA_PROJECT=$PROJECT_ID"
|
||||||
|
- "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
|
||||||
|
secretEnv: ["CLIENT_ID"]
|
||||||
|
volumes:
|
||||||
|
- name: "go"
|
||||||
|
path: "/gopath"
|
||||||
|
args:
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
.ci/test_with_coverage.sh \
|
||||||
|
"Cloud Gemini Data Analytics" \
|
||||||
|
cloudgda \
|
||||||
|
cloudgda
|
||||||
|
|
||||||
- id: "dataplex"
|
- id: "dataplex"
|
||||||
name: golang:1
|
name: golang:1
|
||||||
waitFor: ["compile-test-binary"]
|
waitFor: ["compile-test-binary"]
|
||||||
@@ -273,7 +310,26 @@ steps:
|
|||||||
.ci/test_with_coverage.sh \
|
.ci/test_with_coverage.sh \
|
||||||
"Cloud Healthcare API" \
|
"Cloud Healthcare API" \
|
||||||
cloudhealthcare \
|
cloudhealthcare \
|
||||||
cloudhealthcare || echo "Integration tests failed."
|
cloudhealthcare
|
||||||
|
|
||||||
|
- id: "cloud-logging-admin"
|
||||||
|
name: golang:1
|
||||||
|
waitFor: ["compile-test-binary"]
|
||||||
|
entrypoint: /bin/bash
|
||||||
|
env:
|
||||||
|
- "GOPATH=/gopath"
|
||||||
|
- "LOGADMIN_PROJECT=$PROJECT_ID"
|
||||||
|
secretEnv: ["CLIENT_ID"]
|
||||||
|
volumes:
|
||||||
|
- name: "go"
|
||||||
|
path: "/gopath"
|
||||||
|
args:
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
.ci/test_with_coverage.sh \
|
||||||
|
"Cloud Logging Admin" \
|
||||||
|
cloudloggingadmin \
|
||||||
|
cloudloggingadmin
|
||||||
|
|
||||||
- id: "postgres"
|
- id: "postgres"
|
||||||
name: golang:1
|
name: golang:1
|
||||||
@@ -285,7 +341,7 @@ steps:
|
|||||||
- "POSTGRES_HOST=$_POSTGRES_HOST"
|
- "POSTGRES_HOST=$_POSTGRES_HOST"
|
||||||
- "POSTGRES_PORT=$_POSTGRES_PORT"
|
- "POSTGRES_PORT=$_POSTGRES_PORT"
|
||||||
- "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
|
- "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
|
||||||
secretEnv: ["POSTGRES_USER", "POSTGRES_PASS", "CLIENT_ID"]
|
secretEnv: ["POSTGRES_USER", "POSTGRES_PASS", "CLIENT_ID", "API_KEY"]
|
||||||
volumes:
|
volumes:
|
||||||
- name: "go"
|
- name: "go"
|
||||||
path: "/gopath"
|
path: "/gopath"
|
||||||
@@ -298,6 +354,30 @@ steps:
|
|||||||
postgressql \
|
postgressql \
|
||||||
postgresexecutesql
|
postgresexecutesql
|
||||||
|
|
||||||
|
- id: "cockroachdb"
|
||||||
|
name: golang:1
|
||||||
|
waitFor: ["compile-test-binary"]
|
||||||
|
entrypoint: /bin/bash
|
||||||
|
env:
|
||||||
|
- "GOPATH=/gopath"
|
||||||
|
- "COCKROACHDB_DATABASE=$_DATABASE_NAME"
|
||||||
|
- "COCKROACHDB_PORT=$_COCKROACHDB_PORT"
|
||||||
|
- "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
|
||||||
|
secretEnv: ["COCKROACHDB_USER", "COCKROACHDB_HOST","CLIENT_ID"]
|
||||||
|
volumes:
|
||||||
|
- name: "go"
|
||||||
|
path: "/gopath"
|
||||||
|
args:
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
.ci/test_with_coverage.sh \
|
||||||
|
"CockroachDB" \
|
||||||
|
cockroachdb \
|
||||||
|
cockroachdbsql \
|
||||||
|
cockroachdbexecutesql \
|
||||||
|
cockroachdblisttables \
|
||||||
|
cockroachdblistschemas
|
||||||
|
|
||||||
- id: "spanner"
|
- id: "spanner"
|
||||||
name: golang:1
|
name: golang:1
|
||||||
waitFor: ["compile-test-binary"]
|
waitFor: ["compile-test-binary"]
|
||||||
@@ -318,7 +398,7 @@ steps:
|
|||||||
.ci/test_with_coverage.sh \
|
.ci/test_with_coverage.sh \
|
||||||
"Spanner" \
|
"Spanner" \
|
||||||
spanner \
|
spanner \
|
||||||
spanner
|
spanner || echo "Integration tests failed." # ignore test failures
|
||||||
|
|
||||||
- id: "neo4j"
|
- id: "neo4j"
|
||||||
name: golang:1
|
name: golang:1
|
||||||
@@ -589,6 +669,26 @@ steps:
|
|||||||
firestore \
|
firestore \
|
||||||
firestore
|
firestore
|
||||||
|
|
||||||
|
- id: "mongodb"
|
||||||
|
name: golang:1
|
||||||
|
waitFor: ["compile-test-binary"]
|
||||||
|
entrypoint: /bin/bash
|
||||||
|
env:
|
||||||
|
- "GOPATH=/gopath"
|
||||||
|
- "MONGODB_DATABASE=$_DATABASE_NAME"
|
||||||
|
- "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
|
||||||
|
secretEnv: ["MONGODB_URI", "CLIENT_ID"]
|
||||||
|
volumes:
|
||||||
|
- name: "go"
|
||||||
|
path: "/gopath"
|
||||||
|
args:
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
.ci/test_with_coverage.sh \
|
||||||
|
"MongoDB" \
|
||||||
|
mongodb \
|
||||||
|
mongodb
|
||||||
|
|
||||||
- id: "looker"
|
- id: "looker"
|
||||||
name: golang:1
|
name: golang:1
|
||||||
waitFor: ["compile-test-binary"]
|
waitFor: ["compile-test-binary"]
|
||||||
@@ -617,7 +717,7 @@ steps:
|
|||||||
"Looker" \
|
"Looker" \
|
||||||
looker \
|
looker \
|
||||||
looker
|
looker
|
||||||
|
|
||||||
- id: "mindsdb"
|
- id: "mindsdb"
|
||||||
name: golang:1
|
name: golang:1
|
||||||
waitFor: ["compile-test-binary"]
|
waitFor: ["compile-test-binary"]
|
||||||
@@ -785,6 +885,26 @@ steps:
|
|||||||
elasticsearch \
|
elasticsearch \
|
||||||
elasticsearch
|
elasticsearch
|
||||||
|
|
||||||
|
- id: "snowflake"
|
||||||
|
name: golang:1
|
||||||
|
waitFor: ["compile-test-binary"]
|
||||||
|
entrypoint: /bin/bash
|
||||||
|
env:
|
||||||
|
- "GOPATH=/gopath"
|
||||||
|
- "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
|
||||||
|
- "SNOWFLAKE_DATABASE=$_SNOWFLAKE_DATABASE"
|
||||||
|
- "SNOWFLAKE_SCHEMA=$_SNOWFLAKE_SCHEMA"
|
||||||
|
secretEnv: ["CLIENT_ID", "SNOWFLAKE_USER", "SNOWFLAKE_PASS", "SNOWFLAKE_ACCOUNT"]
|
||||||
|
volumes:
|
||||||
|
- name: "go"
|
||||||
|
path: "/gopath"
|
||||||
|
args:
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
.ci/test_with_coverage.sh \
|
||||||
|
"Snowflake" \
|
||||||
|
snowflake \
|
||||||
|
snowflake
|
||||||
|
|
||||||
- id: "cassandra"
|
- id: "cassandra"
|
||||||
name: golang:1
|
name: golang:1
|
||||||
@@ -806,8 +926,8 @@ steps:
|
|||||||
cassandra
|
cassandra
|
||||||
|
|
||||||
- id: "oracle"
|
- id: "oracle"
|
||||||
name: golang:1
|
name: ghcr.io/oracle/oraclelinux9-instantclient:23
|
||||||
waitFor: ["compile-test-binary"]
|
waitFor: ["install-dependencies"]
|
||||||
entrypoint: /bin/bash
|
entrypoint: /bin/bash
|
||||||
env:
|
env:
|
||||||
- "GOPATH=/gopath"
|
- "GOPATH=/gopath"
|
||||||
@@ -820,10 +940,25 @@ steps:
|
|||||||
args:
|
args:
|
||||||
- -c
|
- -c
|
||||||
- |
|
- |
|
||||||
.ci/test_with_coverage.sh \
|
# Install the C compiler and Oracle SDK headers needed for cgo
|
||||||
"Oracle" \
|
dnf install -y gcc oracle-instantclient-devel
|
||||||
oracle \
|
# Install Go
|
||||||
oracle
|
curl -L -o go.tar.gz "https://go.dev/dl/go1.25.1.linux-amd64.tar.gz"
|
||||||
|
tar -C /usr/local -xzf go.tar.gz
|
||||||
|
export PATH="/usr/local/go/bin:$$PATH"
|
||||||
|
|
||||||
|
go test -v ./tests/oracle/... \
|
||||||
|
-coverprofile=oracle_coverage.out \
|
||||||
|
-coverpkg=./internal/sources/oracle/...,./internal/tools/oracle/...
|
||||||
|
|
||||||
|
# Coverage check
|
||||||
|
total_coverage=$(go tool cover -func=oracle_coverage.out | grep "total:" | awk '{print $3}')
|
||||||
|
echo "Oracle total coverage: $total_coverage"
|
||||||
|
coverage_numeric=$(echo "$total_coverage" | sed 's/%//')
|
||||||
|
if awk -v cov="$coverage_numeric" 'BEGIN {exit !(cov < 60)}'; then
|
||||||
|
echo "Coverage failure: $total_coverage is below 60%."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
- id: "serverless-spark"
|
- id: "serverless-spark"
|
||||||
name: golang:1
|
name: golang:1
|
||||||
@@ -867,8 +1002,35 @@ steps:
|
|||||||
singlestore \
|
singlestore \
|
||||||
singlestore
|
singlestore
|
||||||
|
|
||||||
|
- id: "mariadb"
|
||||||
|
name: golang:1
|
||||||
|
waitFor: ["compile-test-binary"]
|
||||||
|
entrypoint: /bin/bash
|
||||||
|
env:
|
||||||
|
- "GOPATH=/gopath"
|
||||||
|
- "MARIADB_DATABASE=$_MARIADB_DATABASE"
|
||||||
|
- "MARIADB_PORT=$_MARIADB_PORT"
|
||||||
|
- "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
|
||||||
|
secretEnv: ["MARIADB_USER", "MARIADB_PASS", "MARIADB_HOST", "CLIENT_ID"]
|
||||||
|
volumes:
|
||||||
|
- name: "go"
|
||||||
|
path: "/gopath"
|
||||||
|
args:
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
# skip coverage check as it re-uses current MySQL implementation
|
||||||
|
go test ./tests/mariadb
|
||||||
|
|
||||||
|
|
||||||
availableSecrets:
|
availableSecrets:
|
||||||
secretManager:
|
secretManager:
|
||||||
|
# Common secrets
|
||||||
|
- versionName: projects/$PROJECT_ID/secrets/client_id/versions/latest
|
||||||
|
env: CLIENT_ID
|
||||||
|
- versionName: projects/$PROJECT_ID/secrets/api_key/versions/latest
|
||||||
|
env: API_KEY
|
||||||
|
|
||||||
|
# Resource-specific secrets
|
||||||
- versionName: projects/$PROJECT_ID/secrets/cloud_sql_pg_user/versions/latest
|
- versionName: projects/$PROJECT_ID/secrets/cloud_sql_pg_user/versions/latest
|
||||||
env: CLOUD_SQL_POSTGRES_USER
|
env: CLOUD_SQL_POSTGRES_USER
|
||||||
- versionName: projects/$PROJECT_ID/secrets/cloud_sql_pg_pass/versions/latest
|
- versionName: projects/$PROJECT_ID/secrets/cloud_sql_pg_pass/versions/latest
|
||||||
@@ -885,8 +1047,6 @@ availableSecrets:
|
|||||||
env: POSTGRES_USER
|
env: POSTGRES_USER
|
||||||
- versionName: projects/$PROJECT_ID/secrets/postgres_pass/versions/latest
|
- versionName: projects/$PROJECT_ID/secrets/postgres_pass/versions/latest
|
||||||
env: POSTGRES_PASS
|
env: POSTGRES_PASS
|
||||||
- versionName: projects/$PROJECT_ID/secrets/client_id/versions/latest
|
|
||||||
env: CLIENT_ID
|
|
||||||
- versionName: projects/$PROJECT_ID/secrets/neo4j_user/versions/latest
|
- versionName: projects/$PROJECT_ID/secrets/neo4j_user/versions/latest
|
||||||
env: NEO4J_USER
|
env: NEO4J_USER
|
||||||
- versionName: projects/$PROJECT_ID/secrets/neo4j_pass/versions/latest
|
- versionName: projects/$PROJECT_ID/secrets/neo4j_pass/versions/latest
|
||||||
@@ -963,6 +1123,12 @@ availableSecrets:
|
|||||||
env: ELASTICSEARCH_USER
|
env: ELASTICSEARCH_USER
|
||||||
- versionName: projects/$PROJECT_ID/secrets/elastic_search_pass/versions/latest
|
- versionName: projects/$PROJECT_ID/secrets/elastic_search_pass/versions/latest
|
||||||
env: ELASTICSEARCH_PASS
|
env: ELASTICSEARCH_PASS
|
||||||
|
- versionName: projects/$PROJECT_ID/secrets/snowflake_account/versions/latest
|
||||||
|
env: SNOWFLAKE_ACCOUNT
|
||||||
|
- versionName: projects/$PROJECT_ID/secrets/snowflake_user/versions/latest
|
||||||
|
env: SNOWFLAKE_USER
|
||||||
|
- versionName: projects/$PROJECT_ID/secrets/snowflake_pass/versions/latest
|
||||||
|
env: SNOWFLAKE_PASS
|
||||||
- versionName: projects/$PROJECT_ID/secrets/cassandra_user/versions/latest
|
- versionName: projects/$PROJECT_ID/secrets/cassandra_user/versions/latest
|
||||||
env: CASSANDRA_USER
|
env: CASSANDRA_USER
|
||||||
- versionName: projects/$PROJECT_ID/secrets/cassandra_pass/versions/latest
|
- versionName: projects/$PROJECT_ID/secrets/cassandra_pass/versions/latest
|
||||||
@@ -979,6 +1145,19 @@ availableSecrets:
|
|||||||
env: SINGLESTORE_PASSWORD
|
env: SINGLESTORE_PASSWORD
|
||||||
- versionName: projects/$PROJECT_ID/secrets/singlestore_host/versions/latest
|
- versionName: projects/$PROJECT_ID/secrets/singlestore_host/versions/latest
|
||||||
env: SINGLESTORE_HOST
|
env: SINGLESTORE_HOST
|
||||||
|
- versionName: projects/$PROJECT_ID/secrets/mariadb_user/versions/latest
|
||||||
|
env: MARIADB_USER
|
||||||
|
- versionName: projects/$PROJECT_ID/secrets/mariadb_pass/versions/latest
|
||||||
|
env: MARIADB_PASS
|
||||||
|
- versionName: projects/$PROJECT_ID/secrets/mariadb_host/versions/latest
|
||||||
|
env: MARIADB_HOST
|
||||||
|
- versionName: projects/$PROJECT_ID/secrets/mongodb_uri/versions/latest
|
||||||
|
env: MONGODB_URI
|
||||||
|
- versionName: projects/$PROJECT_ID/secrets/cockroachdb_user/versions/latest
|
||||||
|
env: COCKROACHDB_USER
|
||||||
|
- versionName: projects/$PROJECT_ID/secrets/cockroachdb_host/versions/latest
|
||||||
|
env: COCKROACHDB_HOST
|
||||||
|
|
||||||
|
|
||||||
options:
|
options:
|
||||||
logging: CLOUD_LOGGING_ONLY
|
logging: CLOUD_LOGGING_ONLY
|
||||||
@@ -1039,3 +1218,10 @@ substitutions:
|
|||||||
_SINGLESTORE_PORT: "3308"
|
_SINGLESTORE_PORT: "3308"
|
||||||
_SINGLESTORE_DATABASE: "singlestore"
|
_SINGLESTORE_DATABASE: "singlestore"
|
||||||
_SINGLESTORE_USER: "root"
|
_SINGLESTORE_USER: "root"
|
||||||
|
_COCKROACHDB_HOST: 127.0.0.1
|
||||||
|
_COCKROACHDB_PORT: "26257"
|
||||||
|
_COCKROACHDB_USER: "root"
|
||||||
|
_MARIADB_PORT: "3307"
|
||||||
|
_MARIADB_DATABASE: test_database
|
||||||
|
_SNOWFLAKE_DATABASE: "test"
|
||||||
|
_SNOWFLAKE_SCHEMA: "PUBLIC"
|
||||||
|
|||||||
@@ -1,125 +0,0 @@
|
|||||||
# Copyright 2025 Google LLC
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
TABLE_NAME="hotels_go"
|
|
||||||
QUICKSTART_GO_DIR="docs/en/getting-started/quickstart/go"
|
|
||||||
SQL_FILE=".ci/quickstart_test/setup_hotels_sample.sql"
|
|
||||||
|
|
||||||
PROXY_PID=""
|
|
||||||
TOOLBOX_PID=""
|
|
||||||
|
|
||||||
install_system_packages() {
|
|
||||||
apt-get update && apt-get install -y \
|
|
||||||
postgresql-client \
|
|
||||||
wget \
|
|
||||||
gettext-base \
|
|
||||||
netcat-openbsd
|
|
||||||
}
|
|
||||||
|
|
||||||
start_cloud_sql_proxy() {
|
|
||||||
wget "https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.10.0/cloud-sql-proxy.linux.amd64" -O /usr/local/bin/cloud-sql-proxy
|
|
||||||
chmod +x /usr/local/bin/cloud-sql-proxy
|
|
||||||
cloud-sql-proxy "${CLOUD_SQL_INSTANCE}" &
|
|
||||||
PROXY_PID=$!
|
|
||||||
|
|
||||||
for i in {1..30}; do
|
|
||||||
if nc -z 127.0.0.1 5432; then
|
|
||||||
echo "Cloud SQL Proxy is up and running."
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Cloud SQL Proxy failed to start within the timeout period."
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_toolbox() {
|
|
||||||
TOOLBOX_YAML="/tools.yaml"
|
|
||||||
echo "${TOOLS_YAML_CONTENT}" > "$TOOLBOX_YAML"
|
|
||||||
if [ ! -f "$TOOLBOX_YAML" ]; then echo "Failed to create tools.yaml"; exit 1; fi
|
|
||||||
wget "https://storage.googleapis.com/genai-toolbox/v${VERSION}/linux/amd64/toolbox" -O "/toolbox"
|
|
||||||
chmod +x "/toolbox"
|
|
||||||
/toolbox --tools-file "$TOOLBOX_YAML" &
|
|
||||||
TOOLBOX_PID=$!
|
|
||||||
sleep 2
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_orch_table() {
|
|
||||||
export TABLE_NAME
|
|
||||||
envsubst < "$SQL_FILE" | psql -h "$PGHOST" -p "$PGPORT" -U "$DB_USER" -d "$DATABASE_NAME"
|
|
||||||
}
|
|
||||||
|
|
||||||
run_orch_test() {
|
|
||||||
local orch_dir="$1"
|
|
||||||
local orch_name
|
|
||||||
orch_name=$(basename "$orch_dir")
|
|
||||||
|
|
||||||
if [ "$orch_name" == "openAI" ]; then
|
|
||||||
echo -e "\nSkipping framework '${orch_name}': Temporarily excluded."
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
(
|
|
||||||
set -e
|
|
||||||
setup_orch_table
|
|
||||||
|
|
||||||
echo "--- Preparing module for $orch_name ---"
|
|
||||||
cd "$orch_dir"
|
|
||||||
|
|
||||||
if [ -f "go.mod" ]; then
|
|
||||||
go mod tidy
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
export ORCH_NAME="$orch_name"
|
|
||||||
|
|
||||||
echo "--- Running tests for $orch_name ---"
|
|
||||||
go test -v ./...
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup_all() {
|
|
||||||
echo "--- Final cleanup: Shutting down processes and dropping table ---"
|
|
||||||
if [ -n "$TOOLBOX_PID" ]; then
|
|
||||||
kill $TOOLBOX_PID || true
|
|
||||||
fi
|
|
||||||
if [ -n "$PROXY_PID" ]; then
|
|
||||||
kill $PROXY_PID || true
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
trap cleanup_all EXIT
|
|
||||||
|
|
||||||
# Main script execution
|
|
||||||
install_system_packages
|
|
||||||
start_cloud_sql_proxy
|
|
||||||
|
|
||||||
export PGHOST=127.0.0.1
|
|
||||||
export PGPORT=5432
|
|
||||||
export PGPASSWORD="$DB_PASSWORD"
|
|
||||||
export GOOGLE_API_KEY="$GOOGLE_API_KEY"
|
|
||||||
|
|
||||||
setup_toolbox
|
|
||||||
|
|
||||||
for ORCH_DIR in "$QUICKSTART_GO_DIR"/*/; do
|
|
||||||
if [ ! -d "$ORCH_DIR" ]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
run_orch_test "$ORCH_DIR"
|
|
||||||
done
|
|
||||||
@@ -1,125 +0,0 @@
|
|||||||
# Copyright 2025 Google LLC
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
TABLE_NAME="hotels_js"
|
|
||||||
QUICKSTART_JS_DIR="docs/en/getting-started/quickstart/js"
|
|
||||||
SQL_FILE=".ci/quickstart_test/setup_hotels_sample.sql"
|
|
||||||
|
|
||||||
# Initialize process IDs to empty at the top of the script
|
|
||||||
PROXY_PID=""
|
|
||||||
TOOLBOX_PID=""
|
|
||||||
|
|
||||||
install_system_packages() {
|
|
||||||
apt-get update && apt-get install -y \
|
|
||||||
postgresql-client \
|
|
||||||
wget \
|
|
||||||
gettext-base \
|
|
||||||
netcat-openbsd
|
|
||||||
}
|
|
||||||
|
|
||||||
start_cloud_sql_proxy() {
|
|
||||||
wget "https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.10.0/cloud-sql-proxy.linux.amd64" -O /usr/local/bin/cloud-sql-proxy
|
|
||||||
chmod +x /usr/local/bin/cloud-sql-proxy
|
|
||||||
cloud-sql-proxy "${CLOUD_SQL_INSTANCE}" &
|
|
||||||
PROXY_PID=$!
|
|
||||||
|
|
||||||
for i in {1..30}; do
|
|
||||||
if nc -z 127.0.0.1 5432; then
|
|
||||||
echo "Cloud SQL Proxy is up and running."
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Cloud SQL Proxy failed to start within the timeout period."
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_toolbox() {
|
|
||||||
TOOLBOX_YAML="/tools.yaml"
|
|
||||||
echo "${TOOLS_YAML_CONTENT}" > "$TOOLBOX_YAML"
|
|
||||||
if [ ! -f "$TOOLBOX_YAML" ]; then echo "Failed to create tools.yaml"; exit 1; fi
|
|
||||||
wget "https://storage.googleapis.com/genai-toolbox/v${VERSION}/linux/amd64/toolbox" -O "/toolbox"
|
|
||||||
chmod +x "/toolbox"
|
|
||||||
/toolbox --tools-file "$TOOLBOX_YAML" &
|
|
||||||
TOOLBOX_PID=$!
|
|
||||||
sleep 2
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_orch_table() {
|
|
||||||
export TABLE_NAME
|
|
||||||
envsubst < "$SQL_FILE" | psql -h "$PGHOST" -p "$PGPORT" -U "$DB_USER" -d "$DATABASE_NAME"
|
|
||||||
}
|
|
||||||
|
|
||||||
run_orch_test() {
|
|
||||||
local orch_dir="$1"
|
|
||||||
local orch_name
|
|
||||||
orch_name=$(basename "$orch_dir")
|
|
||||||
|
|
||||||
(
|
|
||||||
set -e
|
|
||||||
echo "--- Preparing environment for $orch_name ---"
|
|
||||||
setup_orch_table
|
|
||||||
|
|
||||||
cd "$orch_dir"
|
|
||||||
echo "Installing dependencies for $orch_name..."
|
|
||||||
if [ -f "package-lock.json" ]; then
|
|
||||||
npm ci
|
|
||||||
else
|
|
||||||
npm install
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
echo "--- Running tests for $orch_name ---"
|
|
||||||
export ORCH_NAME="$orch_name"
|
|
||||||
node --test quickstart.test.js
|
|
||||||
|
|
||||||
echo "--- Cleaning environment for $orch_name ---"
|
|
||||||
rm -rf "${orch_name}/node_modules"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup_all() {
|
|
||||||
echo "--- Final cleanup: Shutting down processes and dropping table ---"
|
|
||||||
if [ -n "$TOOLBOX_PID" ]; then
|
|
||||||
kill $TOOLBOX_PID || true
|
|
||||||
fi
|
|
||||||
if [ -n "$PROXY_PID" ]; then
|
|
||||||
kill $PROXY_PID || true
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
trap cleanup_all EXIT
|
|
||||||
|
|
||||||
# Main script execution
|
|
||||||
install_system_packages
|
|
||||||
start_cloud_sql_proxy
|
|
||||||
|
|
||||||
export PGHOST=127.0.0.1
|
|
||||||
export PGPORT=5432
|
|
||||||
export PGPASSWORD="$DB_PASSWORD"
|
|
||||||
export GOOGLE_API_KEY="$GOOGLE_API_KEY"
|
|
||||||
|
|
||||||
setup_toolbox
|
|
||||||
|
|
||||||
for ORCH_DIR in "$QUICKSTART_JS_DIR"/*/; do
|
|
||||||
if [ ! -d "$ORCH_DIR" ]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
run_orch_test "$ORCH_DIR"
|
|
||||||
done
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
# Copyright 2025 Google LLC
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
TABLE_NAME="hotels_python"
|
|
||||||
QUICKSTART_PYTHON_DIR="docs/en/getting-started/quickstart/python"
|
|
||||||
SQL_FILE=".ci/quickstart_test/setup_hotels_sample.sql"
|
|
||||||
|
|
||||||
PROXY_PID=""
|
|
||||||
TOOLBOX_PID=""
|
|
||||||
|
|
||||||
install_system_packages() {
|
|
||||||
apt-get update && apt-get install -y \
|
|
||||||
postgresql-client \
|
|
||||||
python3-venv \
|
|
||||||
wget \
|
|
||||||
gettext-base \
|
|
||||||
netcat-openbsd
|
|
||||||
}
|
|
||||||
|
|
||||||
start_cloud_sql_proxy() {
|
|
||||||
wget "https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.10.0/cloud-sql-proxy.linux.amd64" -O /usr/local/bin/cloud-sql-proxy
|
|
||||||
chmod +x /usr/local/bin/cloud-sql-proxy
|
|
||||||
cloud-sql-proxy "${CLOUD_SQL_INSTANCE}" &
|
|
||||||
PROXY_PID=$!
|
|
||||||
|
|
||||||
for i in {1..30}; do
|
|
||||||
if nc -z 127.0.0.1 5432; then
|
|
||||||
echo "Cloud SQL Proxy is up and running."
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Cloud SQL Proxy failed to start within the timeout period."
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_toolbox() {
|
|
||||||
TOOLBOX_YAML="/tools.yaml"
|
|
||||||
echo "${TOOLS_YAML_CONTENT}" > "$TOOLBOX_YAML"
|
|
||||||
if [ ! -f "$TOOLBOX_YAML" ]; then echo "Failed to create tools.yaml"; exit 1; fi
|
|
||||||
wget "https://storage.googleapis.com/genai-toolbox/v${VERSION}/linux/amd64/toolbox" -O "/toolbox"
|
|
||||||
chmod +x "/toolbox"
|
|
||||||
/toolbox --tools-file "$TOOLBOX_YAML" &
|
|
||||||
TOOLBOX_PID=$!
|
|
||||||
sleep 2
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_orch_table() {
|
|
||||||
export TABLE_NAME
|
|
||||||
envsubst < "$SQL_FILE" | psql -h "$PGHOST" -p "$PGPORT" -U "$DB_USER" -d "$DATABASE_NAME"
|
|
||||||
}
|
|
||||||
|
|
||||||
run_orch_test() {
|
|
||||||
local orch_dir="$1"
|
|
||||||
local orch_name
|
|
||||||
orch_name=$(basename "$orch_dir")
|
|
||||||
(
|
|
||||||
set -e
|
|
||||||
setup_orch_table
|
|
||||||
cd "$orch_dir"
|
|
||||||
local VENV_DIR=".venv"
|
|
||||||
python3 -m venv "$VENV_DIR"
|
|
||||||
source "$VENV_DIR/bin/activate"
|
|
||||||
pip install -r requirements.txt
|
|
||||||
echo "--- Running tests for $orch_name ---"
|
|
||||||
cd ..
|
|
||||||
ORCH_NAME="$orch_name" pytest
|
|
||||||
rm -rf "$VENV_DIR"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup_all() {
|
|
||||||
echo "--- Final cleanup: Shutting down processes and dropping table ---"
|
|
||||||
if [ -n "$TOOLBOX_PID" ]; then
|
|
||||||
kill $TOOLBOX_PID || true
|
|
||||||
fi
|
|
||||||
if [ -n "$PROXY_PID" ]; then
|
|
||||||
kill $PROXY_PID || true
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
trap cleanup_all EXIT
|
|
||||||
|
|
||||||
# Main script execution
|
|
||||||
install_system_packages
|
|
||||||
start_cloud_sql_proxy
|
|
||||||
|
|
||||||
export PGHOST=127.0.0.1
|
|
||||||
export PGPORT=5432
|
|
||||||
export PGPASSWORD="$DB_PASSWORD"
|
|
||||||
export GOOGLE_API_KEY="$GOOGLE_API_KEY"
|
|
||||||
|
|
||||||
setup_toolbox
|
|
||||||
|
|
||||||
for ORCH_DIR in "$QUICKSTART_PYTHON_DIR"/*/; do
|
|
||||||
if [ ! -d "$ORCH_DIR" ]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
run_orch_test "$ORCH_DIR"
|
|
||||||
done
|
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
# Copyright 2026 Google LLC
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: "${_IMAGE}"
|
||||||
|
id: "go-pre-post-processing-test"
|
||||||
|
entrypoint: "bash"
|
||||||
|
args:
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
set -ex
|
||||||
|
chmod +x .ci/sample_tests/run_tests.sh
|
||||||
|
.ci/sample_tests/run_tests.sh
|
||||||
|
env:
|
||||||
|
- "CLOUD_SQL_INSTANCE=${_CLOUD_SQL_INSTANCE}"
|
||||||
|
- "GCP_PROJECT=${_GCP_PROJECT}"
|
||||||
|
- "DATABASE_NAME=${_DATABASE_NAME}"
|
||||||
|
- "DB_USER=${_DB_USER}"
|
||||||
|
- "TARGET_ROOT=${_TARGET_ROOT}"
|
||||||
|
- "TARGET_LANG=${_TARGET_LANG}"
|
||||||
|
- "TABLE_NAME=${_TABLE_NAME}"
|
||||||
|
- "SQL_FILE=${_SQL_FILE}"
|
||||||
|
- "AGENT_FILE_PATTERN=${_AGENT_FILE_PATTERN}"
|
||||||
|
secretEnv: ["TOOLS_YAML_CONTENT", "GOOGLE_API_KEY", "DB_PASSWORD"]
|
||||||
|
|
||||||
|
availableSecrets:
|
||||||
|
secretManager:
|
||||||
|
- versionName: projects/${_GCP_PROJECT}/secrets/${_TOOLS_YAML_SECRET}/versions/5
|
||||||
|
env: "TOOLS_YAML_CONTENT"
|
||||||
|
- versionName: projects/${_GCP_PROJECT_NUMBER}/secrets/${_API_KEY_SECRET}/versions/latest
|
||||||
|
env: "GOOGLE_API_KEY"
|
||||||
|
- versionName: projects/${_GCP_PROJECT}/secrets/${_DB_PASS_SECRET}/versions/latest
|
||||||
|
env: "DB_PASSWORD"
|
||||||
|
|
||||||
|
timeout: 1200s
|
||||||
|
|
||||||
|
substitutions:
|
||||||
|
_TARGET_LANG: "go"
|
||||||
|
_IMAGE: "golang:1.25.1"
|
||||||
|
_TARGET_ROOT: "docs/en/samples/pre_post_processing/go"
|
||||||
|
_TABLE_NAME: "hotels_go_pre_post_processing"
|
||||||
|
_SQL_FILE: ".ci/sample_tests/setup_hotels.sql"
|
||||||
|
_AGENT_FILE_PATTERN: "agent.go"
|
||||||
|
|
||||||
|
options:
|
||||||
|
logging: CLOUD_LOGGING_ONLY
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
# Copyright 2026 Google LLC
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: "${_IMAGE}"
|
||||||
|
id: "py-pre-post-processing-test"
|
||||||
|
entrypoint: "bash"
|
||||||
|
args:
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
set -ex
|
||||||
|
chmod +x .ci/sample_tests/run_tests.sh
|
||||||
|
.ci/sample_tests/run_tests.sh
|
||||||
|
env:
|
||||||
|
- "CLOUD_SQL_INSTANCE=${_CLOUD_SQL_INSTANCE}"
|
||||||
|
- "GCP_PROJECT=${_GCP_PROJECT}"
|
||||||
|
- "DATABASE_NAME=${_DATABASE_NAME}"
|
||||||
|
- "DB_USER=${_DB_USER}"
|
||||||
|
- "TARGET_ROOT=${_TARGET_ROOT}"
|
||||||
|
- "TARGET_LANG=${_TARGET_LANG}"
|
||||||
|
- "TABLE_NAME=${_TABLE_NAME}"
|
||||||
|
- "SQL_FILE=${_SQL_FILE}"
|
||||||
|
- "AGENT_FILE_PATTERN=${_AGENT_FILE_PATTERN}"
|
||||||
|
secretEnv: ["TOOLS_YAML_CONTENT", "GOOGLE_API_KEY", "DB_PASSWORD"]
|
||||||
|
|
||||||
|
availableSecrets:
|
||||||
|
secretManager:
|
||||||
|
- versionName: projects/${_GCP_PROJECT}/secrets/${_TOOLS_YAML_SECRET}/versions/5
|
||||||
|
env: "TOOLS_YAML_CONTENT"
|
||||||
|
- versionName: projects/${_GCP_PROJECT_NUMBER}/secrets/${_API_KEY_SECRET}/versions/latest
|
||||||
|
env: "GOOGLE_API_KEY"
|
||||||
|
- versionName: projects/${_GCP_PROJECT}/secrets/${_DB_PASS_SECRET}/versions/latest
|
||||||
|
env: "DB_PASSWORD"
|
||||||
|
|
||||||
|
timeout: 1200s
|
||||||
|
|
||||||
|
substitutions:
|
||||||
|
_TARGET_LANG: "python"
|
||||||
|
_IMAGE: "gcr.io/google.com/cloudsdktool/cloud-sdk:537.0.0"
|
||||||
|
_TARGET_ROOT: "docs/en/samples/pre_post_processing/python"
|
||||||
|
_TABLE_NAME: "hotels_py_pre_post_processing"
|
||||||
|
_SQL_FILE: ".ci/sample_tests/setup_hotels.sql"
|
||||||
|
_AGENT_FILE_PATTERN: "agent.py"
|
||||||
|
|
||||||
|
options:
|
||||||
|
logging: CLOUD_LOGGING_ONLY
|
||||||
@@ -23,13 +23,18 @@ steps:
|
|||||||
- |
|
- |
|
||||||
set -ex
|
set -ex
|
||||||
export VERSION=$(cat ./cmd/version.txt)
|
export VERSION=$(cat ./cmd/version.txt)
|
||||||
chmod +x .ci/quickstart_test/run_go_tests.sh
|
chmod +x .ci/sample_tests/run_tests.sh
|
||||||
.ci/quickstart_test/run_go_tests.sh
|
.ci/sample_tests/run_tests.sh
|
||||||
env:
|
env:
|
||||||
- 'CLOUD_SQL_INSTANCE=${_CLOUD_SQL_INSTANCE}'
|
- 'CLOUD_SQL_INSTANCE=${_CLOUD_SQL_INSTANCE}'
|
||||||
- 'GCP_PROJECT=${_GCP_PROJECT}'
|
- 'GCP_PROJECT=${_GCP_PROJECT}'
|
||||||
- 'DATABASE_NAME=${_DATABASE_NAME}'
|
- 'DATABASE_NAME=${_DATABASE_NAME}'
|
||||||
- 'DB_USER=${_DB_USER}'
|
- 'DB_USER=${_DB_USER}'
|
||||||
|
- 'TARGET_ROOT=docs/en/getting-started/quickstart/go'
|
||||||
|
- 'TARGET_LANG=go'
|
||||||
|
- 'TABLE_NAME=hotels_go'
|
||||||
|
- 'SQL_FILE=.ci/sample_tests/setup_hotels.sql'
|
||||||
|
- 'AGENT_FILE_PATTERN=quickstart.go'
|
||||||
secretEnv: ['TOOLS_YAML_CONTENT', 'GOOGLE_API_KEY', 'DB_PASSWORD']
|
secretEnv: ['TOOLS_YAML_CONTENT', 'GOOGLE_API_KEY', 'DB_PASSWORD']
|
||||||
|
|
||||||
availableSecrets:
|
availableSecrets:
|
||||||
@@ -23,13 +23,18 @@ steps:
|
|||||||
- |
|
- |
|
||||||
set -ex
|
set -ex
|
||||||
export VERSION=$(cat ./cmd/version.txt)
|
export VERSION=$(cat ./cmd/version.txt)
|
||||||
chmod +x .ci/quickstart_test/run_js_tests.sh
|
chmod +x .ci/sample_tests/run_tests.sh
|
||||||
.ci/quickstart_test/run_js_tests.sh
|
.ci/sample_tests/run_tests.sh
|
||||||
env:
|
env:
|
||||||
- 'CLOUD_SQL_INSTANCE=${_CLOUD_SQL_INSTANCE}'
|
- 'CLOUD_SQL_INSTANCE=${_CLOUD_SQL_INSTANCE}'
|
||||||
- 'GCP_PROJECT=${_GCP_PROJECT}'
|
- 'GCP_PROJECT=${_GCP_PROJECT}'
|
||||||
- 'DATABASE_NAME=${_DATABASE_NAME}'
|
- 'DATABASE_NAME=${_DATABASE_NAME}'
|
||||||
- 'DB_USER=${_DB_USER}'
|
- 'DB_USER=${_DB_USER}'
|
||||||
|
- 'TARGET_ROOT=docs/en/getting-started/quickstart/js'
|
||||||
|
- 'TARGET_LANG=js'
|
||||||
|
- 'TABLE_NAME=hotels_js'
|
||||||
|
- 'SQL_FILE=.ci/sample_tests/setup_hotels.sql'
|
||||||
|
- 'AGENT_FILE_PATTERN=quickstart.js'
|
||||||
secretEnv: ['TOOLS_YAML_CONTENT', 'GOOGLE_API_KEY', 'DB_PASSWORD']
|
secretEnv: ['TOOLS_YAML_CONTENT', 'GOOGLE_API_KEY', 'DB_PASSWORD']
|
||||||
|
|
||||||
availableSecrets:
|
availableSecrets:
|
||||||
@@ -23,13 +23,18 @@ steps:
|
|||||||
- |
|
- |
|
||||||
set -ex
|
set -ex
|
||||||
export VERSION=$(cat ./cmd/version.txt)
|
export VERSION=$(cat ./cmd/version.txt)
|
||||||
chmod +x .ci/quickstart_test/run_py_tests.sh
|
chmod +x .ci/sample_tests/run_tests.sh
|
||||||
.ci/quickstart_test/run_py_tests.sh
|
.ci/sample_tests/run_tests.sh
|
||||||
env:
|
env:
|
||||||
- 'CLOUD_SQL_INSTANCE=${_CLOUD_SQL_INSTANCE}'
|
- 'CLOUD_SQL_INSTANCE=${_CLOUD_SQL_INSTANCE}'
|
||||||
- 'GCP_PROJECT=${_GCP_PROJECT}'
|
- 'GCP_PROJECT=${_GCP_PROJECT}'
|
||||||
- 'DATABASE_NAME=${_DATABASE_NAME}'
|
- 'DATABASE_NAME=${_DATABASE_NAME}'
|
||||||
- 'DB_USER=${_DB_USER}'
|
- 'DB_USER=${_DB_USER}'
|
||||||
|
- 'TARGET_ROOT=docs/en/getting-started/quickstart/python'
|
||||||
|
- 'TARGET_LANG=python'
|
||||||
|
- 'TABLE_NAME=hotels_python'
|
||||||
|
- 'SQL_FILE=.ci/sample_tests/setup_hotels.sql'
|
||||||
|
- 'AGENT_FILE_PATTERN=quickstart.py'
|
||||||
secretEnv: ['TOOLS_YAML_CONTENT', 'GOOGLE_API_KEY', 'DB_PASSWORD']
|
secretEnv: ['TOOLS_YAML_CONTENT', 'GOOGLE_API_KEY', 'DB_PASSWORD']
|
||||||
|
|
||||||
availableSecrets:
|
availableSecrets:
|
||||||
202
.ci/sample_tests/run_tests.sh
Normal file
202
.ci/sample_tests/run_tests.sh
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
# Copyright 2026 Google LLC
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# --- Configuration (from Environment Variables) ---
|
||||||
|
# TARGET_ROOT: The directory to search for tests (e.g., docs/en/getting-started/quickstart/js)
|
||||||
|
# TARGET_LANG: python, js, go
|
||||||
|
# TABLE_NAME: Database table name to use
|
||||||
|
# SQL_FILE: Path to the SQL setup file
|
||||||
|
# AGENT_FILE_PATTERN: Filename to look for (e.g., quickstart.js or agent.py)
|
||||||
|
|
||||||
|
VERSION=$(cat ./cmd/version.txt)
|
||||||
|
|
||||||
|
# Process IDs & Logs
|
||||||
|
PROXY_PID=""
|
||||||
|
TOOLBOX_PID=""
|
||||||
|
PROXY_LOG="cloud_sql_proxy.log"
|
||||||
|
TOOLBOX_LOG="toolbox_server.log"
|
||||||
|
|
||||||
|
install_system_packages() {
|
||||||
|
echo "Installing system packages..."
|
||||||
|
apt-get update && apt-get install -y \
|
||||||
|
postgresql-client \
|
||||||
|
wget \
|
||||||
|
gettext-base \
|
||||||
|
netcat-openbsd
|
||||||
|
|
||||||
|
if [[ "$TARGET_LANG" == "python" ]]; then
|
||||||
|
apt-get install -y python3-venv
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
start_cloud_sql_proxy() {
|
||||||
|
echo "Starting Cloud SQL Proxy..."
|
||||||
|
wget -q "https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.10.0/cloud-sql-proxy.linux.amd64" -O /usr/local/bin/cloud-sql-proxy
|
||||||
|
chmod +x /usr/local/bin/cloud-sql-proxy
|
||||||
|
cloud-sql-proxy "${CLOUD_SQL_INSTANCE}" > "$PROXY_LOG" 2>&1 &
|
||||||
|
PROXY_PID=$!
|
||||||
|
|
||||||
|
# Health Check
|
||||||
|
for i in {1..30}; do
|
||||||
|
if nc -z 127.0.0.1 5432; then
|
||||||
|
echo "Cloud SQL Proxy is up and running."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
echo "ERROR: Cloud SQL Proxy failed to start. Logs:"
|
||||||
|
cat "$PROXY_LOG"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_toolbox() {
|
||||||
|
echo "Setting up Toolbox server..."
|
||||||
|
TOOLBOX_YAML="/tools.yaml"
|
||||||
|
echo "${TOOLS_YAML_CONTENT}" > "$TOOLBOX_YAML"
|
||||||
|
wget -q "https://storage.googleapis.com/genai-toolbox/v${VERSION}/linux/amd64/toolbox" -O "/toolbox"
|
||||||
|
chmod +x "/toolbox"
|
||||||
|
/toolbox --tools-file "$TOOLBOX_YAML" > "$TOOLBOX_LOG" 2>&1 &
|
||||||
|
TOOLBOX_PID=$!
|
||||||
|
|
||||||
|
# Health Check
|
||||||
|
for i in {1..15}; do
|
||||||
|
if nc -z 127.0.0.1 5000; then
|
||||||
|
echo "Toolbox server is up and running."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
echo "ERROR: Toolbox server failed to start. Logs:"
|
||||||
|
cat "$TOOLBOX_LOG"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_db_table() {
|
||||||
|
echo "Setting up database table $TABLE_NAME using $SQL_FILE..."
|
||||||
|
export TABLE_NAME
|
||||||
|
envsubst < "$SQL_FILE" | psql -h 127.0.0.1 -p 5432 -U "$DB_USER" -d "$DATABASE_NAME"
|
||||||
|
}
|
||||||
|
|
||||||
|
run_python_test() {
|
||||||
|
local dir=$1
|
||||||
|
local name=$(basename "$dir")
|
||||||
|
echo "--- Running Python Test: $name ---"
|
||||||
|
(
|
||||||
|
cd "$dir"
|
||||||
|
python3 -m venv .venv
|
||||||
|
source .venv/bin/activate
|
||||||
|
pip install -q -r requirements.txt pytest
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
local test_file=$(find . -maxdepth 1 -name "*test.py" | head -n 1)
|
||||||
|
if [ -n "$test_file" ]; then
|
||||||
|
echo "Found native test: $test_file. Running pytest..."
|
||||||
|
export ORCH_NAME="$name"
|
||||||
|
export PYTHONPATH="../"
|
||||||
|
pytest "$test_file"
|
||||||
|
else
|
||||||
|
echo "No native test found. running agent directly..."
|
||||||
|
export PYTHONPATH="../"
|
||||||
|
python3 "${name}/${AGENT_FILE_PATTERN}"
|
||||||
|
fi
|
||||||
|
rm -rf "${name}/.venv"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
run_js_test() {
|
||||||
|
local dir=$1
|
||||||
|
local name=$(basename "$dir")
|
||||||
|
echo "--- Running JS Test: $name ---"
|
||||||
|
(
|
||||||
|
cd "$dir"
|
||||||
|
if [ -f "package-lock.json" ]; then npm ci -q; else npm install -q; fi
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
# Looking for a JS test file in the parent directory
|
||||||
|
local test_file=$(find . -maxdepth 1 -name "*test.js" | head -n 1)
|
||||||
|
if [ -n "$test_file" ]; then
|
||||||
|
echo "Found native test: $test_file. Running node --test..."
|
||||||
|
export ORCH_NAME="$name"
|
||||||
|
node --test "$test_file"
|
||||||
|
else
|
||||||
|
echo "No native test found. running agent directly..."
|
||||||
|
node "${name}/${AGENT_FILE_PATTERN}"
|
||||||
|
fi
|
||||||
|
rm -rf "${name}/node_modules"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
run_go_test() {
|
||||||
|
local dir=$1
|
||||||
|
local name=$(basename "$dir")
|
||||||
|
|
||||||
|
if [ "$name" == "openAI" ]; then
|
||||||
|
echo -e "\nSkipping framework '${name}': Temporarily excluded."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "--- Running Go Test: $name ---"
|
||||||
|
(
|
||||||
|
cd "$dir"
|
||||||
|
if [ -f "go.mod" ]; then
|
||||||
|
go mod tidy
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
local test_file=$(find . -maxdepth 1 -name "*test.go" | head -n 1)
|
||||||
|
if [ -n "$test_file" ]; then
|
||||||
|
echo "Found native test: $test_file. Running go test..."
|
||||||
|
export ORCH_NAME="$name"
|
||||||
|
go test -v ./...
|
||||||
|
else
|
||||||
|
echo "No native test found. running agent directly..."
|
||||||
|
cd "$name"
|
||||||
|
go run "."
|
||||||
|
fi
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
echo "Cleaning up background processes..."
|
||||||
|
[ -n "$TOOLBOX_PID" ] && kill "$TOOLBOX_PID" || true
|
||||||
|
[ -n "$PROXY_PID" ] && kill "$PROXY_PID" || true
|
||||||
|
}
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
# --- Execution ---
|
||||||
|
install_system_packages
|
||||||
|
start_cloud_sql_proxy
|
||||||
|
|
||||||
|
export PGHOST=127.0.0.1
|
||||||
|
export PGPORT=5432
|
||||||
|
export PGPASSWORD="$DB_PASSWORD"
|
||||||
|
export GOOGLE_API_KEY="$GOOGLE_API_KEY"
|
||||||
|
|
||||||
|
setup_toolbox
|
||||||
|
setup_db_table
|
||||||
|
|
||||||
|
echo "Scanning $TARGET_ROOT for tests with pattern $AGENT_FILE_PATTERN..."
|
||||||
|
|
||||||
|
find "$TARGET_ROOT" -name "$AGENT_FILE_PATTERN" | while read -r agent_file; do
|
||||||
|
sample_dir=$(dirname "$agent_file")
|
||||||
|
if [[ "$TARGET_LANG" == "python" ]]; then
|
||||||
|
run_python_test "$sample_dir"
|
||||||
|
elif [[ "$TARGET_LANG" == "js" ]]; then
|
||||||
|
run_js_test "$sample_dir"
|
||||||
|
elif [[ "$TARGET_LANG" == "go" ]]; then
|
||||||
|
run_go_test "$sample_dir"
|
||||||
|
fi
|
||||||
|
done
|
||||||
18
.github/renovate.json5
vendored
18
.github/renovate.json5
vendored
@@ -24,5 +24,23 @@
|
|||||||
],
|
],
|
||||||
pinDigests: true,
|
pinDigests: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
groupName: 'Go',
|
||||||
|
matchManagers: [
|
||||||
|
'gomod',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
groupName: 'Node',
|
||||||
|
matchManagers: [
|
||||||
|
'npm',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
groupName: 'Pip',
|
||||||
|
matchManagers: [
|
||||||
|
'pip_requirements',
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|||||||
6
.github/workflows/deploy_dev_docs.yaml
vendored
6
.github/workflows/deploy_dev_docs.yaml
vendored
@@ -40,7 +40,7 @@ jobs:
|
|||||||
group: docs-deployment
|
group: docs-deployment
|
||||||
cancel-in-progress: false
|
cancel-in-progress: false
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
|
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
|
||||||
|
|
||||||
@@ -51,12 +51,12 @@ jobs:
|
|||||||
extended: true
|
extended: true
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
|
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
|
||||||
with:
|
with:
|
||||||
node-version: "22"
|
node-version: "22"
|
||||||
|
|
||||||
- name: Cache dependencies
|
- name: Cache dependencies
|
||||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
|
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
|
||||||
with:
|
with:
|
||||||
path: ~/.npm
|
path: ~/.npm
|
||||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||||
|
|||||||
@@ -30,14 +30,14 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout main branch (for latest templates and theme)
|
- name: Checkout main branch (for latest templates and theme)
|
||||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
with:
|
with:
|
||||||
ref: 'main'
|
ref: 'main'
|
||||||
submodules: 'recursive'
|
submodules: 'recursive'
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Checkout old content from tag into a temporary directory
|
- name: Checkout old content from tag into a temporary directory
|
||||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.inputs.version_tag }}
|
ref: ${{ github.event.inputs.version_tag }}
|
||||||
path: 'old_version_source' # Checkout into a temp subdir
|
path: 'old_version_source' # Checkout into a temp subdir
|
||||||
@@ -57,7 +57,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
hugo-version: "0.145.0"
|
hugo-version: "0.145.0"
|
||||||
extended: true
|
extended: true
|
||||||
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
|
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
|
||||||
with:
|
with:
|
||||||
node-version: "22"
|
node-version: "22"
|
||||||
|
|
||||||
|
|||||||
8
.github/workflows/deploy_versioned_docs.yaml
vendored
8
.github/workflows/deploy_versioned_docs.yaml
vendored
@@ -30,12 +30,14 @@ jobs:
|
|||||||
cancel-in-progress: false
|
cancel-in-progress: false
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Code at Tag
|
- name: Checkout Code at Tag
|
||||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.release.tag_name }}
|
ref: ${{ github.event.release.tag_name }}
|
||||||
|
|
||||||
- name: Get Version from Release Tag
|
- name: Get Version from Release Tag
|
||||||
run: echo "VERSION=${{ github.event.release.tag_name }}" >> $GITHUB_ENV
|
run: echo "VERSION=${GITHUB_EVENT_RELEASE_TAG_NAME}" >> $GITHUB_ENV
|
||||||
|
env:
|
||||||
|
GITHUB_EVENT_RELEASE_TAG_NAME: ${{ github.event.release.tag_name }}
|
||||||
|
|
||||||
- name: Setup Hugo
|
- name: Setup Hugo
|
||||||
uses: peaceiris/actions-hugo@75d2e84710de30f6ff7268e08f310b60ef14033f # v3
|
uses: peaceiris/actions-hugo@75d2e84710de30f6ff7268e08f310b60ef14033f # v3
|
||||||
@@ -44,7 +46,7 @@ jobs:
|
|||||||
extended: true
|
extended: true
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
|
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
|
||||||
with:
|
with:
|
||||||
node-version: "22"
|
node-version: "22"
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/docs_preview_clean.yaml
vendored
2
.github/workflows/docs_preview_clean.yaml
vendored
@@ -34,7 +34,7 @@ jobs:
|
|||||||
group: "preview-${{ github.event.number }}"
|
group: "preview-${{ github.event.number }}"
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
with:
|
with:
|
||||||
ref: versioned-gh-pages
|
ref: versioned-gh-pages
|
||||||
|
|
||||||
|
|||||||
6
.github/workflows/docs_preview_deploy.yaml
vendored
6
.github/workflows/docs_preview_deploy.yaml
vendored
@@ -49,7 +49,7 @@ jobs:
|
|||||||
group: "preview-${{ github.event.number }}"
|
group: "preview-${{ github.event.number }}"
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
with:
|
with:
|
||||||
# Checkout the PR's HEAD commit (supports forks).
|
# Checkout the PR's HEAD commit (supports forks).
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
@@ -62,12 +62,12 @@ jobs:
|
|||||||
extended: true
|
extended: true
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6
|
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
|
||||||
with:
|
with:
|
||||||
node-version: "22"
|
node-version: "22"
|
||||||
|
|
||||||
- name: Cache dependencies
|
- name: Cache dependencies
|
||||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
|
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
|
||||||
with:
|
with:
|
||||||
path: ~/.npm
|
path: ~/.npm
|
||||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||||
|
|||||||
132
.github/workflows/link_checker.yaml
vendored
Normal file
132
.github/workflows/link_checker.yaml
vendored
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
# Copyright 2025 Google LLC
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
name: Link Checker
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: write
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
link-check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout Repository
|
||||||
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Identify Changed Files
|
||||||
|
id: changed-files
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
git fetch origin main
|
||||||
|
CHANGED_FILES=$(git diff --name-only --diff-filter=ACMRT origin/main...HEAD -- '*.md')
|
||||||
|
|
||||||
|
if [ -z "$CHANGED_FILES" ]; then
|
||||||
|
echo "No markdown files changed. Skipping checks."
|
||||||
|
echo "HAS_CHANGES=false" >> $GITHUB_ENV
|
||||||
|
else
|
||||||
|
echo "--- Changed Files to Scan ---"
|
||||||
|
echo "$CHANGED_FILES"
|
||||||
|
echo "-----------------------------"
|
||||||
|
|
||||||
|
# FIX: Wrap filenames in quotes to handle spaces
|
||||||
|
FILES_QUOTED=$(echo "$CHANGED_FILES" | sed 's/^/"/;s/$/"/' | tr '\n' ' ')
|
||||||
|
|
||||||
|
# Write to env using EOF pattern
|
||||||
|
echo "CHECK_FILES<<EOF" >> $GITHUB_ENV
|
||||||
|
echo "$FILES_QUOTED" >> $GITHUB_ENV
|
||||||
|
echo "EOF" >> $GITHUB_ENV
|
||||||
|
echo "HAS_CHANGES=true" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
- name: Restore lychee cache
|
||||||
|
if: env.HAS_CHANGES == 'true'
|
||||||
|
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
|
||||||
|
with:
|
||||||
|
path: .lycheecache
|
||||||
|
key: cache-lychee-${{ github.sha }}
|
||||||
|
restore-keys: cache-lychee-
|
||||||
|
|
||||||
|
- name: Link Checker
|
||||||
|
id: lychee-check
|
||||||
|
if: env.HAS_CHANGES == 'true'
|
||||||
|
uses: lycheeverse/lychee-action@a8c4c7cb88f0c7386610c35eb25108e448569cb0 # v2
|
||||||
|
continue-on-error: true
|
||||||
|
with:
|
||||||
|
args: >
|
||||||
|
--quiet
|
||||||
|
--no-progress
|
||||||
|
--cache
|
||||||
|
--max-cache-age 1d
|
||||||
|
--exclude '^neo4j\+.*' --exclude '^bolt://.*'
|
||||||
|
${{ env.CHECK_FILES }}
|
||||||
|
output: lychee-report.md
|
||||||
|
format: markdown
|
||||||
|
fail: true
|
||||||
|
jobSummary: false
|
||||||
|
debug: false
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
- name: Find comment
|
||||||
|
uses: peter-evans/find-comment@b30e6a3c0ed37e7c023ccd3f1db5c6c0b0c23aad # v4
|
||||||
|
id: find-comment
|
||||||
|
with:
|
||||||
|
issue-number: ${{ github.event.pull_request.number }}
|
||||||
|
comment-author: 'github-actions[bot]'
|
||||||
|
body-includes: "## Link Resolution Note"
|
||||||
|
|
||||||
|
- name: Delete comment on success
|
||||||
|
if: steps.lychee-check.outcome == 'success' && steps.find-comment.outputs.comment-id != ''
|
||||||
|
run: |
|
||||||
|
gh api \
|
||||||
|
--method DELETE \
|
||||||
|
-H "Accept: application/vnd.github+json" \
|
||||||
|
/repos/${{ github.repository }}/issues/comments/${{ steps.find-comment.outputs.comment-id }}
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Prepare Report
|
||||||
|
if: env.HAS_CHANGES == 'true' && steps.lychee-check.outcome == 'failure'
|
||||||
|
run: |
|
||||||
|
echo "## Link Resolution Note" > full-report.md
|
||||||
|
|
||||||
|
|
||||||
|
echo "Local links and directory changes work differently on GitHub than on the docsite.You must ensure fixes pass the **GitHub check** and also work with **\`hugo server\`**." >> full-report.md
|
||||||
|
echo "See [Link Checking and Fixing with Lychee](https://github.com/googleapis/genai-toolbox/blob/main/DEVELOPER.md#link-checking-and-fixing-with-lychee) for more details." >> full-report.md
|
||||||
|
echo "" >> full-report.md
|
||||||
|
sed -E '/(Redirect|Redirects per input)/d' lychee-report.md >> full-report.md
|
||||||
|
|
||||||
|
- name: Create PR Comment
|
||||||
|
if: env.HAS_CHANGES == 'true' && steps.lychee-check.outcome == 'failure'
|
||||||
|
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4
|
||||||
|
with:
|
||||||
|
comment-id: ${{ steps.find-comment.outputs.comment-id }}
|
||||||
|
issue-number: ${{ github.event.pull_request.number }}
|
||||||
|
body-path: full-report.md
|
||||||
|
edit-mode: replace
|
||||||
|
|
||||||
|
- name: Display Failure Report
|
||||||
|
# Run this ONLY if the link checker failed
|
||||||
|
if: steps.lychee-check.outcome == 'failure'
|
||||||
|
run: |
|
||||||
|
# We can now simply output the prepared file to the job summary
|
||||||
|
cat full-report.md >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
# Fail the job
|
||||||
|
exit 1
|
||||||
11
.github/workflows/lint.yaml
vendored
11
.github/workflows/lint.yaml
vendored
@@ -15,6 +15,11 @@
|
|||||||
name: lint
|
name: lint
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- "docs/**"
|
||||||
|
- "**.md"
|
||||||
|
- ".github/**"
|
||||||
|
- "!.github/workflows/lint.yaml"
|
||||||
pull_request_target:
|
pull_request_target:
|
||||||
types: [labeled]
|
types: [labeled]
|
||||||
|
|
||||||
@@ -51,11 +56,11 @@ jobs:
|
|||||||
console.log('Failed to remove label. Another job may have already removed it!');
|
console.log('Failed to remove label. Another job may have already removed it!');
|
||||||
}
|
}
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
|
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||||
with:
|
with:
|
||||||
go-version: "1.25"
|
go-version: "1.25"
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
||||||
@@ -66,7 +71,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
go mod tidy && git diff --exit-code
|
go mod tidy && git diff --exit-code
|
||||||
- name: golangci-lint
|
- name: golangci-lint
|
||||||
uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0
|
uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
|
||||||
with:
|
with:
|
||||||
version: latest
|
version: latest
|
||||||
args: --timeout 10m
|
args: --timeout 10m
|
||||||
|
|||||||
35
.github/workflows/lint_fallback.yaml
vendored
Normal file
35
.github/workflows/lint_fallback.yaml
vendored
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# Copyright 2026 Google LLC
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
name: lint
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- "docs/**"
|
||||||
|
- "**.md"
|
||||||
|
- ".github/**"
|
||||||
|
- "!.github/workflows/lint.yaml"
|
||||||
|
|
||||||
|
permissions: read-all
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
name: lint
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Skip Lint
|
||||||
|
run: |
|
||||||
|
echo "Skipping lint for documentation/config-only changes."
|
||||||
|
echo "This job exists to satisfy the required status check."
|
||||||
2
.github/workflows/publish-mcp.yml
vendored
2
.github/workflows/publish-mcp.yml
vendored
@@ -29,7 +29,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
|
|
||||||
- name: Wait for image in Artifact Registry
|
- name: Wait for image in Artifact Registry
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
2
.github/workflows/sync-labels.yaml
vendored
2
.github/workflows/sync-labels.yaml
vendored
@@ -29,7 +29,7 @@ jobs:
|
|||||||
issues: 'write'
|
issues: 'write'
|
||||||
pull-requests: 'write'
|
pull-requests: 'write'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
- uses: micnncim/action-label-syncer@3abd5ab72fda571e69fffd97bd4e0033dd5f495c # v1.3.0
|
- uses: micnncim/action-label-syncer@3abd5ab72fda571e69fffd97bd4e0033dd5f495c # v1.3.0
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|||||||
14
.github/workflows/tests.yaml
vendored
14
.github/workflows/tests.yaml
vendored
@@ -17,7 +17,17 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- "main"
|
- "main"
|
||||||
|
paths-ignore:
|
||||||
|
- "docs/**"
|
||||||
|
- "**.md"
|
||||||
|
- ".github/**"
|
||||||
|
- "!.github/workflows/tests.yaml"
|
||||||
pull_request:
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- "docs/**"
|
||||||
|
- "**.md"
|
||||||
|
- ".github/**"
|
||||||
|
- "!.github/workflows/tests.yaml"
|
||||||
pull_request_target:
|
pull_request_target:
|
||||||
types: [labeled]
|
types: [labeled]
|
||||||
|
|
||||||
@@ -57,12 +67,12 @@ jobs:
|
|||||||
}
|
}
|
||||||
|
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
|
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||||
with:
|
with:
|
||||||
go-version: "1.24"
|
go-version: "1.24"
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
||||||
|
|||||||
46
.github/workflows/tests_fallback.yaml
vendored
Normal file
46
.github/workflows/tests_fallback.yaml
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# Copyright 2025 Google LLC
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
name: tests
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "main"
|
||||||
|
paths:
|
||||||
|
- "docs/**"
|
||||||
|
- "**.md"
|
||||||
|
- ".github/**"
|
||||||
|
- "!.github/workflows/tests.yaml"
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- "docs/**"
|
||||||
|
- "**.md"
|
||||||
|
- ".github/**"
|
||||||
|
- "!.github/workflows/tests.yaml"
|
||||||
|
|
||||||
|
permissions: read-all
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
integration:
|
||||||
|
name: unit tests
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||||
|
steps:
|
||||||
|
- name: Skip Tests
|
||||||
|
run: |
|
||||||
|
echo "Skipping unit tests for documentation/config-only changes."
|
||||||
|
echo "This job exists to satisfy the required status check."
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -20,4 +20,4 @@ node_modules
|
|||||||
|
|
||||||
# executable
|
# executable
|
||||||
genai-toolbox
|
genai-toolbox
|
||||||
toolbox
|
toolbox
|
||||||
@@ -1 +1,9 @@
|
|||||||
@import 'td/code-dark';
|
@import 'td/code-dark';
|
||||||
|
|
||||||
|
// Make tabs scrollable horizontally instead of wrapping
|
||||||
|
.nav-tabs {
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
@@ -51,6 +51,30 @@ ignoreFiles = ["quickstart/shared", "quickstart/python", "quickstart/js", "quick
|
|||||||
# Add a new version block here before every release
|
# Add a new version block here before every release
|
||||||
# The order of versions in this file is mirrored into the dropdown
|
# The order of versions in this file is mirrored into the dropdown
|
||||||
|
|
||||||
|
[[params.versions]]
|
||||||
|
version = "v0.27.0"
|
||||||
|
url = "https://googleapis.github.io/genai-toolbox/v0.27.0/"
|
||||||
|
|
||||||
|
[[params.versions]]
|
||||||
|
version = "v0.26.0"
|
||||||
|
url = "https://googleapis.github.io/genai-toolbox/v0.26.0/"
|
||||||
|
|
||||||
|
[[params.versions]]
|
||||||
|
version = "v0.25.0"
|
||||||
|
url = "https://googleapis.github.io/genai-toolbox/v0.25.0/"
|
||||||
|
|
||||||
|
[[params.versions]]
|
||||||
|
version = "v0.24.0"
|
||||||
|
url = "https://googleapis.github.io/genai-toolbox/v0.24.0/"
|
||||||
|
|
||||||
|
[[params.versions]]
|
||||||
|
version = "v0.23.0"
|
||||||
|
url = "https://googleapis.github.io/genai-toolbox/v0.23.0/"
|
||||||
|
|
||||||
|
[[params.versions]]
|
||||||
|
version = "v0.22.0"
|
||||||
|
url = "https://googleapis.github.io/genai-toolbox/v0.22.0/"
|
||||||
|
|
||||||
[[params.versions]]
|
[[params.versions]]
|
||||||
version = "v0.21.0"
|
version = "v0.21.0"
|
||||||
url = "https://googleapis.github.io/genai-toolbox/v0.21.0/"
|
url = "https://googleapis.github.io/genai-toolbox/v0.21.0/"
|
||||||
|
|||||||
44
.lycheeignore
Normal file
44
.lycheeignore
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# Ignore documentation placeholders and generic example domains
|
||||||
|
^https?://([a-zA-Z0-9-]+\.)?example\.com(:\d+)?(/.*)?$
|
||||||
|
^http://example\.net
|
||||||
|
|
||||||
|
# Shields.io badges often trigger rate limits or intermittent 503s
|
||||||
|
^https://img\.shields\.io/.*
|
||||||
|
|
||||||
|
# PDF files are ignored as lychee cannot reliably parse internal PDF links
|
||||||
|
\.pdf$
|
||||||
|
|
||||||
|
# Standard mailto: protocol is not a web URL
|
||||||
|
^mailto:
|
||||||
|
|
||||||
|
# Ignore local development endpoints that won't resolve in CI/CD environments
|
||||||
|
^https?://(127\.0\.0\.1|localhost)(:\d+)?(/.*)?$
|
||||||
|
|
||||||
|
# Placeholder for Google Cloud Run service discovery
|
||||||
|
https://cloud-run-url.app/
|
||||||
|
|
||||||
|
# DGraph Cloud and private instance endpoints
|
||||||
|
https://xxx.cloud.dgraph.io/
|
||||||
|
https://cloud.dgraph.io/login
|
||||||
|
https://dgraph.io/docs
|
||||||
|
|
||||||
|
# MySQL Community downloads and main site (often protected by bot mitigation)
|
||||||
|
^https?://(.*\.)?mysql\.com/.*
|
||||||
|
|
||||||
|
# Claude desktop download link
|
||||||
|
https://claude.ai/download
|
||||||
|
|
||||||
|
# Google Cloud Run product page
|
||||||
|
https://cloud.google.com/run
|
||||||
|
|
||||||
|
# These specific deep links are known to cause redirect loops or 403s in automated scrapers
|
||||||
|
https://dev.mysql.com/doc/refman/8.4/en/sql-prepared-statements.html
|
||||||
|
https://dev.mysql.com/doc/refman/8.4/en/user-names.html
|
||||||
|
|
||||||
|
# npmjs links can occasionally trigger rate limiting during high-frequency CI builds
|
||||||
|
^https?://(www\.)?npmjs\.com/.*
|
||||||
|
|
||||||
|
https://www.oceanbase.com/
|
||||||
|
|
||||||
|
# Ignore social media and blog profiles to reduce external request overhead
|
||||||
|
https://medium.com/@mcp_toolbox
|
||||||
155
CHANGELOG.md
155
CHANGELOG.md
@@ -1,5 +1,160 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [0.27.0](https://github.com/googleapis/genai-toolbox/compare/v0.26.0...v0.27.0) (2026-02-12)
|
||||||
|
|
||||||
|
|
||||||
|
### ⚠ BREAKING CHANGES
|
||||||
|
|
||||||
|
* Update configuration file v2 ([#2369](https://github.com/googleapis/genai-toolbox/issues/2369))([293c1d6](https://github.com/googleapis/genai-toolbox/commit/293c1d6889c39807855ba5e01d4c13ba2a4c50ce))
|
||||||
|
* Update/add detailed telemetry for mcp endpoint compliant with OTEL semantic convention ([#1987](https://github.com/googleapis/genai-toolbox/issues/1987)) ([478a0bd](https://github.com/googleapis/genai-toolbox/commit/478a0bdb59288c1213f83862f95a698b4c2c0aab))
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **cli/invoke:** Add support for direct tool invocation from CLI ([#2353](https://github.com/googleapis/genai-toolbox/issues/2353)) ([6e49ba4](https://github.com/googleapis/genai-toolbox/commit/6e49ba436ef2390c13feaf902b29f5907acffb57))
|
||||||
|
* **cli/skills:** Add support for generating agent skills from toolset ([#2392](https://github.com/googleapis/genai-toolbox/issues/2392)) ([80ef346](https://github.com/googleapis/genai-toolbox/commit/80ef34621453b77bdf6a6016c354f102a17ada04))
|
||||||
|
* **cloud-logging-admin:** Add source, tools, integration test and docs ([#2137](https://github.com/googleapis/genai-toolbox/issues/2137)) ([252fc30](https://github.com/googleapis/genai-toolbox/commit/252fc3091af10d25d8d7af7e047b5ac87a5dd041))
|
||||||
|
* **cockroachdb:** Add CockroachDB integration with cockroach-go ([#2006](https://github.com/googleapis/genai-toolbox/issues/2006)) ([1fdd99a](https://github.com/googleapis/genai-toolbox/commit/1fdd99a9b609a5e906acce414226ff44d75d5975))
|
||||||
|
* **prebuiltconfigs/alloydb-omni:** Implement Alloydb omni dataplane tools ([#2340](https://github.com/googleapis/genai-toolbox/issues/2340)) ([e995349](https://github.com/googleapis/genai-toolbox/commit/e995349ea0756c700d188b8f04e9459121219f0c))
|
||||||
|
* **server:** Add Tool call error categories ([#2387](https://github.com/googleapis/genai-toolbox/issues/2387)) ([32cb4db](https://github.com/googleapis/genai-toolbox/commit/32cb4db712d27579c1bf29e61cbd0bed02286c28))
|
||||||
|
* **tools/looker:** support `looker-validate-project` tool ([#2430](https://github.com/googleapis/genai-toolbox/issues/2430)) ([a15a128](https://github.com/googleapis/genai-toolbox/commit/a15a12873f936b0102aeb9500cc3bcd71bb38c34))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **dataplex:** Capture GCP HTTP errors in MCP Toolbox ([#2347](https://github.com/googleapis/genai-toolbox/issues/2347)) ([1d7c498](https://github.com/googleapis/genai-toolbox/commit/1d7c4981164c34b4d7bc8edecfd449f57ad11e15))
|
||||||
|
* **sources/cockroachdb:** Update kind to type ([#2465](https://github.com/googleapis/genai-toolbox/issues/2465)) ([2d341ac](https://github.com/googleapis/genai-toolbox/commit/2d341acaa61c3c1fe908fceee8afbd90fb646d3a))
|
||||||
|
* Surface Dataplex API errors in MCP results ([#2347](https://github.com/googleapis/genai-toolbox/pull/2347))([1d7c498](https://github.com/googleapis/genai-toolbox/commit/1d7c4981164c34b4d7bc8edecfd449f57ad11e15))
|
||||||
|
|
||||||
|
## [0.26.0](https://github.com/googleapis/genai-toolbox/compare/v0.25.0...v0.26.0) (2026-01-22)
|
||||||
|
|
||||||
|
|
||||||
|
### ⚠ BREAKING CHANGES
|
||||||
|
|
||||||
|
* Validate tool naming ([#2305](https://github.com/googleapis/genai-toolbox/issues/2305)) ([5054212](https://github.com/googleapis/genai-toolbox/commit/5054212fa43017207fe83275d27b9fbab96e8ab5))
|
||||||
|
* **tools/cloudgda:** Update description and parameter name for cloudgda tool ([#2288](https://github.com/googleapis/genai-toolbox/issues/2288)) ([6b02591](https://github.com/googleapis/genai-toolbox/commit/6b025917032394a66840488259db8ff2c3063016))
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add new `user-agent-metadata` flag ([#2302](https://github.com/googleapis/genai-toolbox/issues/2302)) ([adc9589](https://github.com/googleapis/genai-toolbox/commit/adc9589766904d9e3cbe0a6399222f8d4bb9d0cc))
|
||||||
|
* Add remaining flag to Toolbox server in MCP registry ([#2272](https://github.com/googleapis/genai-toolbox/issues/2272)) ([5e0999e](https://github.com/googleapis/genai-toolbox/commit/5e0999ebf5cdd9046e96857738254b2e0561b6d2))
|
||||||
|
* **embeddingModel:** Add embedding model to MCP handler ([#2310](https://github.com/googleapis/genai-toolbox/issues/2310)) ([e4f60e5](https://github.com/googleapis/genai-toolbox/commit/e4f60e56335b755ef55b9553d3f40b31858ec8d9))
|
||||||
|
* **sources/bigquery:** Make maximum rows returned from queries configurable ([#2262](https://github.com/googleapis/genai-toolbox/issues/2262)) ([4abf0c3](https://github.com/googleapis/genai-toolbox/commit/4abf0c39e717d53b22cc61efb65e09928c598236))
|
||||||
|
* **prebuilt/cloud-sql:** Add create backup tool for Cloud SQL ([#2141](https://github.com/googleapis/genai-toolbox/issues/2141)) ([8e0fb03](https://github.com/googleapis/genai-toolbox/commit/8e0fb0348315a80f63cb47b3c7204869482448f4))
|
||||||
|
* **prebuilt/cloud-sql:** Add restore backup tool for Cloud SQL ([#2171](https://github.com/googleapis/genai-toolbox/issues/2171)) ([00c3e6d](https://github.com/googleapis/genai-toolbox/commit/00c3e6d8cba54e2ab6cb271c7e6b378895df53e1))
|
||||||
|
* Support combining multiple prebuilt configurations ([#2295](https://github.com/googleapis/genai-toolbox/issues/2295)) ([e535b37](https://github.com/googleapis/genai-toolbox/commit/e535b372ea81864d644a67135a1b07e4e519b4b4))
|
||||||
|
* Support MCP specs version 2025-11-25 ([#2303](https://github.com/googleapis/genai-toolbox/issues/2303)) ([4d23a3b](https://github.com/googleapis/genai-toolbox/commit/4d23a3bbf2797b1f7fe328aeb5789e778121da23))
|
||||||
|
* **tools:** Add `valueFromParam` support to Tool config ([#2333](https://github.com/googleapis/genai-toolbox/issues/2333)) ([15101b1](https://github.com/googleapis/genai-toolbox/commit/15101b1edbe2b85a4a5f9f819c23cf83138f4ee1))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **tools/cloudhealthcare:** Add check for client authorization before retrieving token string ([#2327](https://github.com/googleapis/genai-toolbox/issues/2327)) ([c25a233](https://github.com/googleapis/genai-toolbox/commit/c25a2330fea2ac382a398842c9e572e4e19bcb08))
|
||||||
|
|
||||||
|
## [0.25.0](https://github.com/googleapis/genai-toolbox/compare/v0.24.0...v0.25.0) (2026-01-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add `embeddingModel` support ([#2121](https://github.com/googleapis/genai-toolbox/issues/2121)) ([9c62f31](https://github.com/googleapis/genai-toolbox/commit/9c62f313ff5edf0a3b5b8a3e996eba078fba4095))
|
||||||
|
* Add `allowed-hosts` flag ([#2254](https://github.com/googleapis/genai-toolbox/issues/2254)) ([17b41f6](https://github.com/googleapis/genai-toolbox/commit/17b41f64531b8fe417c28ada45d1992ba430dc1b))
|
||||||
|
* Add parameter default value to manifest ([#2264](https://github.com/googleapis/genai-toolbox/issues/2264)) ([9d1feca](https://github.com/googleapis/genai-toolbox/commit/9d1feca10810fa42cb4c94a409252f1bd373ee36))
|
||||||
|
* **snowflake:** Add Snowflake Source and Tools ([#858](https://github.com/googleapis/genai-toolbox/issues/858)) ([b706b5b](https://github.com/googleapis/genai-toolbox/commit/b706b5bc685aeda277f277868bae77d38d5fd7b6))
|
||||||
|
* **prebuilt/cloud-sql-mysql:** Update CSQL MySQL prebuilt tools to use IAM ([#2202](https://github.com/googleapis/genai-toolbox/issues/2202)) ([731a32e](https://github.com/googleapis/genai-toolbox/commit/731a32e5360b4d6862d81fcb27d7127c655679a8))
|
||||||
|
* **sources/bigquery:** Make credentials scope configurable ([#2210](https://github.com/googleapis/genai-toolbox/issues/2210)) ([a450600](https://github.com/googleapis/genai-toolbox/commit/a4506009b93771b77fb05ae97044f914967e67ed))
|
||||||
|
* **sources/trino:** Add ssl verification options and fix docs example ([#2155](https://github.com/googleapis/genai-toolbox/issues/2155)) ([4a4cf1e](https://github.com/googleapis/genai-toolbox/commit/4a4cf1e712b671853678dba99c4dc49dd4fc16a2))
|
||||||
|
* **tools/looker:** Add ability to set destination folder with `make_look` and `make_dashboard`. ([#2245](https://github.com/googleapis/genai-toolbox/issues/2245)) ([eb79339](https://github.com/googleapis/genai-toolbox/commit/eb793398cd1cc4006d9808ccda5dc7aea5e92bd5))
|
||||||
|
* **tools/postgressql:** Add tool to list store procedure ([#2156](https://github.com/googleapis/genai-toolbox/issues/2156)) ([cf0fc51](https://github.com/googleapis/genai-toolbox/commit/cf0fc515b57d9b84770076f3c0c5597c4597ef62))
|
||||||
|
* **tools/postgressql:** Add Parameter `embeddedBy` config support ([#2151](https://github.com/googleapis/genai-toolbox/issues/2151)) ([17b70cc](https://github.com/googleapis/genai-toolbox/commit/17b70ccaa754d15bcc33a1a3ecb7e652520fa600))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **server:** Add `embeddingModel` config initialization ([#2281](https://github.com/googleapis/genai-toolbox/issues/2281)) ([a779975](https://github.com/googleapis/genai-toolbox/commit/a7799757c9345f99b6d2717841fbf792d364e1a2))
|
||||||
|
* **sources/cloudgda:** Add import for cloudgda source ([#2217](https://github.com/googleapis/genai-toolbox/issues/2217)) ([7daa411](https://github.com/googleapis/genai-toolbox/commit/7daa4111f4ebfb0a35319fd67a8f7b9f0f99efcf))
|
||||||
|
* **tools/alloydb-wait-for-operation:** Fix connection message generation ([#2228](https://github.com/googleapis/genai-toolbox/issues/2228)) ([7053fbb](https://github.com/googleapis/genai-toolbox/commit/7053fbb1953653143d39a8510916ea97a91022a6))
|
||||||
|
* **tools/alloydbainl:** Only add psv when NL Config Param is defined ([#2265](https://github.com/googleapis/genai-toolbox/issues/2265)) ([ef8f3b0](https://github.com/googleapis/genai-toolbox/commit/ef8f3b02f2f38ce94a6ba9acf35d08b9469bef4e))
|
||||||
|
* **tools/looker:** Looker client OAuth nil pointer error ([#2231](https://github.com/googleapis/genai-toolbox/issues/2231)) ([268700b](https://github.com/googleapis/genai-toolbox/commit/268700bdbf8281de0318d60ca613ed3672990b20))
|
||||||
|
|
||||||
|
## [0.24.0](https://github.com/googleapis/genai-toolbox/compare/v0.23.0...v0.24.0) (2025-12-19)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **sources/cloud-gemini-data-analytics:** Add the Gemini Data Analytics (GDA) integration for DB NL2SQL conversion to Toolbox ([#2181](https://github.com/googleapis/genai-toolbox/issues/2181)) ([aa270b2](https://github.com/googleapis/genai-toolbox/commit/aa270b2630da2e3d618db804ca95550445367dbc))
|
||||||
|
* **source/cloudsqlmysql:** Add support for IAM authentication in Cloud SQL MySQL source ([#2050](https://github.com/googleapis/genai-toolbox/issues/2050)) ([af3d3c5](https://github.com/googleapis/genai-toolbox/commit/af3d3c52044bea17781b89ce4ab71ff0f874ac20))
|
||||||
|
* **sources/oracle:** Add Oracle OCI and Wallet support ([#1945](https://github.com/googleapis/genai-toolbox/issues/1945)) ([8ea39ec](https://github.com/googleapis/genai-toolbox/commit/8ea39ec32fbbaa97939c626fec8c5d86040ed464))
|
||||||
|
* Support combining prebuilt and custom tool configurations ([#2188](https://github.com/googleapis/genai-toolbox/issues/2188)) ([5788605](https://github.com/googleapis/genai-toolbox/commit/57886058188aa5d2a51d5846a98bc6d8a650edd1))
|
||||||
|
* **tools/mysql-get-query-plan:** Add new `mysql-get-query-plan` tool for MySQL source ([#2123](https://github.com/googleapis/genai-toolbox/issues/2123)) ([0641da0](https://github.com/googleapis/genai-toolbox/commit/0641da0353857317113b2169e547ca69603ddfde))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **spanner:** Move list graphs validation to runtime ([#2154](https://github.com/googleapis/genai-toolbox/issues/2154)) ([914b3ee](https://github.com/googleapis/genai-toolbox/commit/914b3eefda40a650efe552d245369e007277dab5))
|
||||||
|
|
||||||
|
|
||||||
|
## [0.23.0](https://github.com/googleapis/genai-toolbox/compare/v0.22.0...v0.23.0) (2025-12-11)
|
||||||
|
|
||||||
|
|
||||||
|
### ⚠ BREAKING CHANGES
|
||||||
|
|
||||||
|
* **serverless-spark:** add URLs to create batch tool outputs
|
||||||
|
* **serverless-spark:** add URLs to list_batches output
|
||||||
|
* **serverless-spark:** add Cloud Console and Logging URLs to get_batch
|
||||||
|
* **tools/postgres:** Add additional filter params for existing postgres tools ([#2033](https://github.com/googleapis/genai-toolbox/issues/2033))
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **tools/postgres:** Add list-table-stats-tool to list table statistics. ([#2055](https://github.com/googleapis/genai-toolbox/issues/2055)) ([78b02f0](https://github.com/googleapis/genai-toolbox/commit/78b02f08c3cc3062943bb2f91cf60d5149c8d28d))
|
||||||
|
* **looker/tools:** Enhance dashboard creation with dashboard filters ([#2133](https://github.com/googleapis/genai-toolbox/issues/2133)) ([285aa46](https://github.com/googleapis/genai-toolbox/commit/285aa46b887d9acb2da8766e107bbf1ab75b8812))
|
||||||
|
* **serverless-spark:** Add Cloud Console and Logging URLs to get_batch ([e29c061](https://github.com/googleapis/genai-toolbox/commit/e29c0616d6b9ecda2badcaf7b69614e511ac031b))
|
||||||
|
* **serverless-spark:** Add URLs to create batch tool outputs ([c6ccf4b](https://github.com/googleapis/genai-toolbox/commit/c6ccf4bd87026484143a2d0f5527b2edab03b54a))
|
||||||
|
* **serverless-spark:** Add URLs to list_batches output ([5605eab](https://github.com/googleapis/genai-toolbox/commit/5605eabd696696ade07f52431a28ef65c0fb1f77))
|
||||||
|
* **sources/mariadb:** Add MariaDB source and MySQL tools integration ([#1908](https://github.com/googleapis/genai-toolbox/issues/1908)) ([3b40fea](https://github.com/googleapis/genai-toolbox/commit/3b40fea25edae607e02c1e8fc2b0c957fa2c8e9a))
|
||||||
|
* **tools/postgres:** Add additional filter params for existing postgres tools ([#2033](https://github.com/googleapis/genai-toolbox/issues/2033)) ([489117d](https://github.com/googleapis/genai-toolbox/commit/489117d74711ac9260e7547163ca463eb45eeaa2))
|
||||||
|
* **tools/postgres:** Add list_pg_settings, list_database_stats tools for postgres ([#2030](https://github.com/googleapis/genai-toolbox/issues/2030)) ([32367a4](https://github.com/googleapis/genai-toolbox/commit/32367a472fae9653fed7f126428eba0252978bd5))
|
||||||
|
* **tools/postgres:** Add new postgres-list-roles tool ([#2038](https://github.com/googleapis/genai-toolbox/issues/2038)) ([bea9705](https://github.com/googleapis/genai-toolbox/commit/bea97054502cfa236aa10e2ebc8ff58eb00ad035))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* List tables tools null fix ([#2107](https://github.com/googleapis/genai-toolbox/issues/2107)) ([2b45266](https://github.com/googleapis/genai-toolbox/commit/2b452665983154041d4cd0ed7d82532e4af682eb))
|
||||||
|
* **tools/mongodb:** Removed sortPayload and sortParams ([#1238](https://github.com/googleapis/genai-toolbox/issues/1238)) ([c5a6daa](https://github.com/googleapis/genai-toolbox/commit/c5a6daa7683d2f9be654300d977692c368e55e31))
|
||||||
|
|
||||||
|
|
||||||
|
### Miscellaneous Chores
|
||||||
|
* **looker:** Upgrade to latest go sdk ([#2159](https://github.com/googleapis/genai-toolbox/issues/2159)) ([78e015d](https://github.com/googleapis/genai-toolbox/commit/78e015d7dfd9cce7e2b444ed934da17eb355bc86))
|
||||||
|
|
||||||
|
## [0.22.0](https://github.com/googleapis/genai-toolbox/compare/v0.21.0...v0.22.0) (2025-12-04)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **tools/postgres:** Add allowed-origins flag ([#1984](https://github.com/googleapis/genai-toolbox/issues/1984)) ([862868f](https://github.com/googleapis/genai-toolbox/commit/862868f28476ea981575ce412faa7d6a03138f31))
|
||||||
|
* **tools/postgres:** Add list-query-stats and get-column-cardinality functions ([#1976](https://github.com/googleapis/genai-toolbox/issues/1976)) ([9f76026](https://github.com/googleapis/genai-toolbox/commit/9f760269253a8cc92a357e995c6993ccc4a0fb7b))
|
||||||
|
* **tools/spanner:** Add spanner list graphs to prebuiltconfigs ([#2056](https://github.com/googleapis/genai-toolbox/issues/2056)) ([0e7fbf4](https://github.com/googleapis/genai-toolbox/commit/0e7fbf465c488397aa9d8cab2e55165fff4eb53c))
|
||||||
|
* **prebuilt/cloud-sql:** Add clone instance tool for cloud sql ([#1845](https://github.com/googleapis/genai-toolbox/issues/1845)) ([5e43630](https://github.com/googleapis/genai-toolbox/commit/5e43630907aa2d7bc6818142483a33272eab060b))
|
||||||
|
* **serverless-spark:** Add create_pyspark_batch tool ([1bf0b51](https://github.com/googleapis/genai-toolbox/commit/1bf0b51f033c956790be1577bf5310d0b17e9c12))
|
||||||
|
* **serverless-spark:** Add create_spark_batch tool ([17a9792](https://github.com/googleapis/genai-toolbox/commit/17a979207dbc4fe70acd0ebda164d1a8d34c1ed3))
|
||||||
|
* Support alternate accessToken header name ([#1968](https://github.com/googleapis/genai-toolbox/issues/1968)) ([18017d6](https://github.com/googleapis/genai-toolbox/commit/18017d6545335a6fc1c472617101c35254d9a597))
|
||||||
|
* Support for annotations ([#2007](https://github.com/googleapis/genai-toolbox/issues/2007)) ([ac21335](https://github.com/googleapis/genai-toolbox/commit/ac21335f4e88ca52d954d7f8143a551a35661b94))
|
||||||
|
* **tool/mssql:** Set default host and port for MSSQL source ([#1943](https://github.com/googleapis/genai-toolbox/issues/1943)) ([7a9cc63](https://github.com/googleapis/genai-toolbox/commit/7a9cc633768d9ae9a7ff8230002da69d6a36ca86))
|
||||||
|
* **tools/cloudsqlpg:** Add CloudSQL PostgreSQL pre-check tool ([#1722](https://github.com/googleapis/genai-toolbox/issues/1722)) ([8752e05](https://github.com/googleapis/genai-toolbox/commit/8752e05ab6e98812d95673a6f1ff67e9a6ae48d2))
|
||||||
|
* **tools/postgres-list-publication-tables:** Add new postgres-list-publication-tables tool ([#1919](https://github.com/googleapis/genai-toolbox/issues/1919)) ([f4b1f0a](https://github.com/googleapis/genai-toolbox/commit/f4b1f0a68000ca2fc0325f55a1905705417c38a2))
|
||||||
|
* **tools/postgres-list-tablespaces:** Add new postgres-list-tablespaces tool ([#1934](https://github.com/googleapis/genai-toolbox/issues/1934)) ([5ad7c61](https://github.com/googleapis/genai-toolbox/commit/5ad7c6127b3e47504fc4afda0b7f3de1dff78b8b))
|
||||||
|
* **tools/spanner-list-graph:** Tool impl + docs + tests ([#1923](https://github.com/googleapis/genai-toolbox/issues/1923)) ([a0f44d3](https://github.com/googleapis/genai-toolbox/commit/a0f44d34ea3f044dd08501be616f70ddfd63ab45))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Add import for firebirdsql ([#2045](https://github.com/googleapis/genai-toolbox/issues/2045)) ([fb7aae9](https://github.com/googleapis/genai-toolbox/commit/fb7aae9d35b760d3471d8379642f835a0d84ec41))
|
||||||
|
* Correct FAQ to mention HTTP tools ([#2036](https://github.com/googleapis/genai-toolbox/issues/2036)) ([7b44237](https://github.com/googleapis/genai-toolbox/commit/7b44237d4a21bfbf8d3cebe4d32a15affa29584d))
|
||||||
|
* Format BigQuery numeric output as decimal strings ([#2084](https://github.com/googleapis/genai-toolbox/issues/2084)) ([155bff8](https://github.com/googleapis/genai-toolbox/commit/155bff80c1da4fae1e169e425fd82e1dc3373041))
|
||||||
|
* Set default annotations for tools in code if annotation not provided in yaml ([#2049](https://github.com/googleapis/genai-toolbox/issues/2049)) ([565460c](https://github.com/googleapis/genai-toolbox/commit/565460c4ea8953dbe80070a8e469f957c0f7a70c))
|
||||||
|
* **tools/alloydb-postgres-list-tables:** Exclude google_ml schema from list_tables ([#2046](https://github.com/googleapis/genai-toolbox/issues/2046)) ([a03984c](https://github.com/googleapis/genai-toolbox/commit/a03984cc15254c928f30085f8fa509ded6a79a0c))
|
||||||
|
* **tools/alloydbcreateuser:** Remove duplication of project praram ([#2028](https://github.com/googleapis/genai-toolbox/issues/2028)) ([730ac6d](https://github.com/googleapis/genai-toolbox/commit/730ac6d22805fd50b4a675b74c1865f4e7689e7c))
|
||||||
|
* **tools/mongodb:** Remove `required` tag from the `canonical` field ([#2099](https://github.com/googleapis/genai-toolbox/issues/2099)) ([744214e](https://github.com/googleapis/genai-toolbox/commit/744214e04cd12b11d166e6eb7da8ce4714904abc))
|
||||||
|
|
||||||
## [0.21.0](https://github.com/googleapis/genai-toolbox/compare/v0.20.0...v0.21.0) (2025-11-19)
|
## [0.21.0](https://github.com/googleapis/genai-toolbox/compare/v0.20.0...v0.21.0) (2025-11-19)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,13 @@ You can manually trigger the bot by commenting on your Pull Request:
|
|||||||
* `/gemini summary`: Posts a summary of the changes in the pull request.
|
* `/gemini summary`: Posts a summary of the changes in the pull request.
|
||||||
* `/gemini help`: Overview of the available commands
|
* `/gemini help`: Overview of the available commands
|
||||||
|
|
||||||
|
## Guidelines for Pull Requests
|
||||||
|
|
||||||
|
1. Please keep your PR small for more thorough review and easier updates. In case of regression, it also allows us to roll back a single feature instead of multiple ones.
|
||||||
|
1. For non-trivial changes, consider opening an issue and discussing it with the code owners first.
|
||||||
|
1. Provide a good PR description as a record of what change is being made and why it was made. Link to a GitHub issue if it exists.
|
||||||
|
1. Make sure your code is thoroughly tested with unit tests and integration tests. Remember to clean up the test instances properly in your code to avoid memory leaks.
|
||||||
|
|
||||||
## Adding a New Database Source or Tool
|
## Adding a New Database Source or Tool
|
||||||
|
|
||||||
Please create an
|
Please create an
|
||||||
@@ -85,11 +92,11 @@ implementation](https://github.com/googleapis/genai-toolbox/blob/main/internal/s
|
|||||||
`newdb.go`. Create a `Config` struct to include all the necessary parameters
|
`newdb.go`. Create a `Config` struct to include all the necessary parameters
|
||||||
for connecting to the database (e.g., host, port, username, password, database
|
for connecting to the database (e.g., host, port, username, password, database
|
||||||
name) and a `Source` struct to store necessary parameters for tools (e.g.,
|
name) and a `Source` struct to store necessary parameters for tools (e.g.,
|
||||||
Name, Kind, connection object, additional config).
|
Name, Type, connection object, additional config).
|
||||||
* **Implement the
|
* **Implement the
|
||||||
[`SourceConfig`](https://github.com/googleapis/genai-toolbox/blob/fd300dc606d88bf9f7bba689e2cee4e3565537dd/internal/sources/sources.go#L57)
|
[`SourceConfig`](https://github.com/googleapis/genai-toolbox/blob/fd300dc606d88bf9f7bba689e2cee4e3565537dd/internal/sources/sources.go#L57)
|
||||||
interface**. This interface requires two methods:
|
interface**. This interface requires two methods:
|
||||||
* `SourceConfigKind() string`: Returns a unique string identifier for your
|
* `SourceConfigType() string`: Returns a unique string identifier for your
|
||||||
data source (e.g., `"newdb"`).
|
data source (e.g., `"newdb"`).
|
||||||
* `Initialize(ctx context.Context, tracer trace.Tracer) (Source, error)`:
|
* `Initialize(ctx context.Context, tracer trace.Tracer) (Source, error)`:
|
||||||
Creates a new instance of your data source and establishes a connection to
|
Creates a new instance of your data source and establishes a connection to
|
||||||
@@ -97,7 +104,7 @@ implementation](https://github.com/googleapis/genai-toolbox/blob/main/internal/s
|
|||||||
* **Implement the
|
* **Implement the
|
||||||
[`Source`](https://github.com/googleapis/genai-toolbox/blob/fd300dc606d88bf9f7bba689e2cee4e3565537dd/internal/sources/sources.go#L63)
|
[`Source`](https://github.com/googleapis/genai-toolbox/blob/fd300dc606d88bf9f7bba689e2cee4e3565537dd/internal/sources/sources.go#L63)
|
||||||
interface**. This interface requires one method:
|
interface**. This interface requires one method:
|
||||||
* `SourceKind() string`: Returns the same string identifier as `SourceConfigKind()`.
|
* `SourceType() string`: Returns the same string identifier as `SourceConfigType()`.
|
||||||
* **Implement `init()`** to register the new Source.
|
* **Implement `init()`** to register the new Source.
|
||||||
* **Implement Unit Tests** in a file named `newdb_test.go`.
|
* **Implement Unit Tests** in a file named `newdb_test.go`.
|
||||||
|
|
||||||
@@ -110,6 +117,8 @@ implementation](https://github.com/googleapis/genai-toolbox/blob/main/internal/s
|
|||||||
We recommend looking at an [example tool
|
We recommend looking at an [example tool
|
||||||
implementation](https://github.com/googleapis/genai-toolbox/tree/main/internal/tools/postgres/postgressql).
|
implementation](https://github.com/googleapis/genai-toolbox/tree/main/internal/tools/postgres/postgressql).
|
||||||
|
|
||||||
|
Remember to keep your PRs small. For example, if you are contributing a new Source, only include one or two core Tools within the same PR, the rest of the Tools can come in subsequent PRs.
|
||||||
|
|
||||||
* **Create a new directory** under `internal/tools` for your tool type (e.g., `internal/tools/newdb/newdbtool`).
|
* **Create a new directory** under `internal/tools` for your tool type (e.g., `internal/tools/newdb/newdbtool`).
|
||||||
* **Define a configuration struct** for your tool in a file named `newdbtool.go`.
|
* **Define a configuration struct** for your tool in a file named `newdbtool.go`.
|
||||||
Create a `Config` struct and a `Tool` struct to store necessary parameters for
|
Create a `Config` struct and a `Tool` struct to store necessary parameters for
|
||||||
@@ -117,7 +126,7 @@ tools.
|
|||||||
* **Implement the
|
* **Implement the
|
||||||
[`ToolConfig`](https://github.com/googleapis/genai-toolbox/blob/fd300dc606d88bf9f7bba689e2cee4e3565537dd/internal/tools/tools.go#L61)
|
[`ToolConfig`](https://github.com/googleapis/genai-toolbox/blob/fd300dc606d88bf9f7bba689e2cee4e3565537dd/internal/tools/tools.go#L61)
|
||||||
interface**. This interface requires one method:
|
interface**. This interface requires one method:
|
||||||
* `ToolConfigKind() string`: Returns a unique string identifier for your tool
|
* `ToolConfigType() string`: Returns a unique string identifier for your tool
|
||||||
(e.g., `"newdb-tool"`).
|
(e.g., `"newdb-tool"`).
|
||||||
* `Initialize(sources map[string]Source) (Tool, error)`: Creates a new
|
* `Initialize(sources map[string]Source) (Tool, error)`: Creates a new
|
||||||
instance of your tool and validates that it can connect to the specified
|
instance of your tool and validates that it can connect to the specified
|
||||||
@@ -163,19 +172,21 @@ tools.
|
|||||||
parameters][temp-param-doc]. Only run this test if template
|
parameters][temp-param-doc]. Only run this test if template
|
||||||
parameters apply to your tool.
|
parameters apply to your tool.
|
||||||
|
|
||||||
|
* **Add additional tests** for the tools that are not covered by the predefined tests. Every tool must be tested!
|
||||||
|
|
||||||
* **Add the new database to the integration test workflow** in
|
* **Add the new database to the integration test workflow** in
|
||||||
[integration.cloudbuild.yaml](.ci/integration.cloudbuild.yaml).
|
[integration.cloudbuild.yaml](.ci/integration.cloudbuild.yaml).
|
||||||
|
|
||||||
[tool-get]:
|
[tool-get]:
|
||||||
https://github.com/googleapis/genai-toolbox/blob/fd300dc606d88bf9f7bba689e2cee4e3565537dd/tests/tool.go#L31
|
https://github.com/googleapis/genai-toolbox/blob/v0.23.0/tests/tool.go#L41
|
||||||
[tool-call]:
|
[tool-call]:
|
||||||
<https://github.com/googleapis/genai-toolbox/blob/fd300dc606d88bf9f7bba689e2cee4e3565537dd/tests/tool.go#L79>
|
https://github.com/googleapis/genai-toolbox/blob/v0.23.0/tests/tool.go#L229
|
||||||
[mcp-call]:
|
[mcp-call]:
|
||||||
https://github.com/googleapis/genai-toolbox/blob/fd300dc606d88bf9f7bba689e2cee4e3565537dd/tests/tool.go#L554
|
https://github.com/googleapis/genai-toolbox/blob/v0.23.0/tests/tool.go#L789
|
||||||
[execute-sql]:
|
[execute-sql]:
|
||||||
<https://github.com/googleapis/genai-toolbox/blob/fd300dc606d88bf9f7bba689e2cee4e3565537dd/tests/tool.go#L431>
|
https://github.com/googleapis/genai-toolbox/blob/v0.23.0/tests/tool.go#L609
|
||||||
[temp-param]:
|
[temp-param]:
|
||||||
<https://github.com/googleapis/genai-toolbox/blob/fd300dc606d88bf9f7bba689e2cee4e3565537dd/tests/tool.go#L297>
|
https://github.com/googleapis/genai-toolbox/blob/v0.23.0/tests/tool.go#L454
|
||||||
[temp-param-doc]:
|
[temp-param-doc]:
|
||||||
https://googleapis.github.io/genai-toolbox/resources/tools/#template-parameters
|
https://googleapis.github.io/genai-toolbox/resources/tools/#template-parameters
|
||||||
|
|
||||||
@@ -232,7 +243,7 @@ resources.
|
|||||||
| style | Update src code, with only formatting and whitespace updates (e.g. code formatter or linter changes). |
|
| style | Update src code, with only formatting and whitespace updates (e.g. code formatter or linter changes). |
|
||||||
|
|
||||||
Pull requests should always add scope whenever possible. The scope is
|
Pull requests should always add scope whenever possible. The scope is
|
||||||
formatted as `<scope-type>/<scope-kind>` (e.g., `sources/postgres`, or
|
formatted as `<scope-resource>/<scope-type>` (e.g., `sources/postgres`, or
|
||||||
`tools/mssql-sql`).
|
`tools/mssql-sql`).
|
||||||
|
|
||||||
Ideally, **each PR covers only one scope**, if this is
|
Ideally, **each PR covers only one scope**, if this is
|
||||||
@@ -244,4 +255,4 @@ resources.
|
|||||||
* **PR Description:** PR description should **always** be included. It should
|
* **PR Description:** PR description should **always** be included. It should
|
||||||
include a concise description of the changes, it's impact, along with a
|
include a concise description of the changes, it's impact, along with a
|
||||||
summary of the solution. If the PR is related to a specific issue, the issue
|
summary of the solution. If the PR is related to a specific issue, the issue
|
||||||
number should be mentioned in the PR description (e.g. `Fixes #1`).
|
number should be mentioned in the PR description (e.g. `Fixes #1`).
|
||||||
|
|||||||
63
DEVELOPER.md
63
DEVELOPER.md
@@ -47,12 +47,13 @@ Before you begin, ensure you have the following:
|
|||||||
### Tool Naming Conventions
|
### Tool Naming Conventions
|
||||||
|
|
||||||
This section details the purpose and conventions for MCP Toolbox's tools naming
|
This section details the purpose and conventions for MCP Toolbox's tools naming
|
||||||
properties, **tool name** and **tool kind**.
|
properties, **tool name** and **tool type**.
|
||||||
|
|
||||||
```
|
```
|
||||||
cancel_hotel: <- tool name
|
kind: tools
|
||||||
kind: postgres-sql <- tool kind
|
name: cancel_hotel <- tool name
|
||||||
source: my_pg_source
|
type: postgres-sql <- tool type
|
||||||
|
source: my_pg_source
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Tool Name
|
#### Tool Name
|
||||||
@@ -76,17 +77,17 @@ The following guidelines apply to tool names:
|
|||||||
to a function) until they can be validated through extensive testing to ensure
|
to a function) until they can be validated through extensive testing to ensure
|
||||||
they do not negatively impact agent's performances.
|
they do not negatively impact agent's performances.
|
||||||
|
|
||||||
#### Tool Kind
|
#### Tool Type
|
||||||
|
|
||||||
Tool kind serves as a category or type that a user can assign to a tool.
|
Tool type serves as a category or type that a user can assign to a tool.
|
||||||
|
|
||||||
The following guidelines apply to tool kinds:
|
The following guidelines apply to tool types:
|
||||||
|
|
||||||
* Should user hyphens over underscores (e.g. `firestore-list-collections` or
|
* Should use hyphens over underscores (e.g. `firestore-list-collections` or
|
||||||
`firestore_list_colelctions`).
|
`firestore_list_colelctions`).
|
||||||
* Should use product name in name (e.g. `firestore-list-collections` over
|
* Should use product name in name (e.g. `firestore-list-collections` over
|
||||||
`list-collections`).
|
`list-collections`).
|
||||||
* Changes to tool kind are breaking changes and should be avoided.
|
* Changes to tool type are breaking changes and should be avoided.
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
@@ -109,7 +110,7 @@ golangci-lint run --fix
|
|||||||
Execute unit tests locally:
|
Execute unit tests locally:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go test -race -v ./...
|
go test -race -v ./cmd/... ./internal/...
|
||||||
```
|
```
|
||||||
|
|
||||||
### Integration Tests
|
### Integration Tests
|
||||||
@@ -207,6 +208,30 @@ variables for each source.
|
|||||||
* SQLite - setup in the integration test, where we create a temporary database
|
* SQLite - setup in the integration test, where we create a temporary database
|
||||||
file
|
file
|
||||||
|
|
||||||
|
### Link Checking and Fixing with Lychee
|
||||||
|
|
||||||
|
We use **[lychee](https://github.com/lycheeverse/lychee-action)** for repository link checks.
|
||||||
|
|
||||||
|
* To run the checker **locally**, see the [command-line usage guide](https://github.com/lycheeverse/lychee?tab=readme-ov-file#commandline-usage).
|
||||||
|
|
||||||
|
#### Fixing Broken Links
|
||||||
|
|
||||||
|
1. **Update the Link:** Correct the broken URL or update the content where it is used.
|
||||||
|
2. **Ignore the Link:** If you can't fix the link (e.g., due to **external rate-limits** or if it's a **local-only URL**), tell Lychee to **ignore** it.
|
||||||
|
|
||||||
|
* List **regular expressions** or **direct links** in the **[.lycheeignore](https://github.com/googleapis/genai-toolbox/blob/main/.lycheeignore)** file, one entry per line.
|
||||||
|
* **Always add a comment** explaining **why** the link is being skipped to prevent link rot. **Example `.lycheeignore`:**
|
||||||
|
```text
|
||||||
|
# These are email addresses, not standard web URLs, and usually cause check failures.
|
||||||
|
^mailto:.*
|
||||||
|
```
|
||||||
|
> [!NOTE]
|
||||||
|
> To avoid build failures in GitHub Actions, follow the linking pattern demonstrated here: <br>
|
||||||
|
> **Avoid:** (Works in Hugo, breaks Link Checker): `[Read more](docs/setup)` or `[Read more](docs/setup/)` <br>
|
||||||
|
> **Reason:** The link checker cannot find a file named "setup" or a directory with that name containing an index. <br>
|
||||||
|
> **Preferred:** `[Read more](docs/setup.md)` <br>
|
||||||
|
> **Reason:** The GitHub Action finds the physical file. Hugo then uses its internal logic (or render hooks) to resolve this to the correct `/docs/setup/` web URL. <br>
|
||||||
|
|
||||||
### Other GitHub Checks
|
### Other GitHub Checks
|
||||||
|
|
||||||
* License header check (`.github/header-checker-lint.yml`) - Ensures files have
|
* License header check (`.github/header-checker-lint.yml`) - Ensures files have
|
||||||
@@ -280,6 +305,7 @@ There are 3 GHA workflows we use to achieve document versioning:
|
|||||||
Request a repo owner to run the preview deployment workflow on your PR. A
|
Request a repo owner to run the preview deployment workflow on your PR. A
|
||||||
preview link will be automatically added as a comment to your PR.
|
preview link will be automatically added as a comment to your PR.
|
||||||
|
|
||||||
|
|
||||||
#### Maintainers
|
#### Maintainers
|
||||||
|
|
||||||
1. **Inspect Changes:** Review the proposed changes in the PR to ensure they are
|
1. **Inspect Changes:** Review the proposed changes in the PR to ensure they are
|
||||||
@@ -354,6 +380,23 @@ to approve PRs for main. TeamSync is used to create this team from the MDB
|
|||||||
Group `toolbox-contributors`. Googlers who are developing for MCP-Toolbox
|
Group `toolbox-contributors`. Googlers who are developing for MCP-Toolbox
|
||||||
but aren't part of the core team should join this group.
|
but aren't part of the core team should join this group.
|
||||||
|
|
||||||
|
### Issue/PR Triage and SLO
|
||||||
|
After an issue is created, maintainers will assign the following labels:
|
||||||
|
* `Priority` (defaulted to P0)
|
||||||
|
* `Type` (if applicable)
|
||||||
|
* `Product` (if applicable)
|
||||||
|
|
||||||
|
All incoming issues and PRs will follow the following SLO:
|
||||||
|
| Type | Priority | Objective |
|
||||||
|
|-----------------|----------|------------------------------------------------------------------------|
|
||||||
|
| Feature Request | P0 | Must respond within **5 days** |
|
||||||
|
| Process | P0 | Must respond within **5 days** |
|
||||||
|
| Bugs | P0 | Must respond within **5 days**, and resolve/closure within **14 days** |
|
||||||
|
| Bugs | P1 | Must respond within **7 days**, and resolve/closure within **90 days** |
|
||||||
|
| Bugs | P2 | Must respond within **30 days**
|
||||||
|
|
||||||
|
_Types that are not listed in the table do not adhere to any SLO._
|
||||||
|
|
||||||
### Releasing
|
### Releasing
|
||||||
|
|
||||||
Toolbox has two types of releases: versioned and continuous. It uses Google
|
Toolbox has two types of releases: versioned and continuous. It uses Google
|
||||||
|
|||||||
109
README.md
109
README.md
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
# MCP Toolbox for Databases
|
# MCP Toolbox for Databases
|
||||||
|
|
||||||
|
<a href="https://trendshift.io/repositories/13019" target="_blank"><img src="https://trendshift.io/api/badge/repositories/13019" alt="googleapis%2Fgenai-toolbox | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
|
||||||
|
|
||||||
[](https://googleapis.github.io/genai-toolbox/)
|
[](https://googleapis.github.io/genai-toolbox/)
|
||||||
[](https://discord.gg/Dmm69peqjh)
|
[](https://discord.gg/Dmm69peqjh)
|
||||||
[](https://medium.com/@mcp_toolbox)
|
[](https://medium.com/@mcp_toolbox)
|
||||||
@@ -105,6 +107,21 @@ redeploying your application.
|
|||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
|
### Quickstart: Running Toolbox using NPX
|
||||||
|
|
||||||
|
You can run Toolbox directly with a [configuration file](#configuration):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npx @toolbox-sdk/server --tools-file tools.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
This runs the latest version of the toolbox server with your configuration file.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> This method should only be used for non-production use cases such as
|
||||||
|
> experimentation. For any production use-cases, please consider [Installing the
|
||||||
|
> server](#installing-the-server) and then [running it](#running-the-server).
|
||||||
|
|
||||||
### Installing the server
|
### Installing the server
|
||||||
|
|
||||||
For the latest version, check the [releases page][releases] and use the
|
For the latest version, check the [releases page][releases] and use the
|
||||||
@@ -125,7 +142,7 @@ To install Toolbox as a binary:
|
|||||||
>
|
>
|
||||||
> ```sh
|
> ```sh
|
||||||
> # see releases page for other versions
|
> # see releases page for other versions
|
||||||
> export VERSION=0.21.0
|
> export VERSION=0.27.0
|
||||||
> curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/linux/amd64/toolbox
|
> curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/linux/amd64/toolbox
|
||||||
> chmod +x toolbox
|
> chmod +x toolbox
|
||||||
> ```
|
> ```
|
||||||
@@ -138,7 +155,7 @@ To install Toolbox as a binary:
|
|||||||
>
|
>
|
||||||
> ```sh
|
> ```sh
|
||||||
> # see releases page for other versions
|
> # see releases page for other versions
|
||||||
> export VERSION=0.21.0
|
> export VERSION=0.27.0
|
||||||
> curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/darwin/arm64/toolbox
|
> curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/darwin/arm64/toolbox
|
||||||
> chmod +x toolbox
|
> chmod +x toolbox
|
||||||
> ```
|
> ```
|
||||||
@@ -151,21 +168,33 @@ To install Toolbox as a binary:
|
|||||||
>
|
>
|
||||||
> ```sh
|
> ```sh
|
||||||
> # see releases page for other versions
|
> # see releases page for other versions
|
||||||
> export VERSION=0.21.0
|
> export VERSION=0.27.0
|
||||||
> curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/darwin/amd64/toolbox
|
> curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/darwin/amd64/toolbox
|
||||||
> chmod +x toolbox
|
> chmod +x toolbox
|
||||||
> ```
|
> ```
|
||||||
>
|
>
|
||||||
> </details>
|
> </details>
|
||||||
> <details>
|
> <details>
|
||||||
> <summary>Windows (AMD64)</summary>
|
> <summary>Windows (Command Prompt)</summary>
|
||||||
>
|
>
|
||||||
> To install Toolbox as a binary on Windows (AMD64):
|
> To install Toolbox as a binary on Windows (Command Prompt):
|
||||||
|
>
|
||||||
|
> ```cmd
|
||||||
|
> :: see releases page for other versions
|
||||||
|
> set VERSION=0.27.0
|
||||||
|
> curl -o toolbox.exe "https://storage.googleapis.com/genai-toolbox/v%VERSION%/windows/amd64/toolbox.exe"
|
||||||
|
> ```
|
||||||
|
>
|
||||||
|
> </details>
|
||||||
|
> <details>
|
||||||
|
> <summary>Windows (PowerShell)</summary>
|
||||||
|
>
|
||||||
|
> To install Toolbox as a binary on Windows (PowerShell):
|
||||||
>
|
>
|
||||||
> ```powershell
|
> ```powershell
|
||||||
> :: see releases page for other versions
|
> # see releases page for other versions
|
||||||
> set VERSION=0.21.0
|
> $VERSION = "0.27.0"
|
||||||
> curl -o toolbox.exe "https://storage.googleapis.com/genai-toolbox/v%VERSION%/windows/amd64/toolbox.exe"
|
> curl.exe -o toolbox.exe "https://storage.googleapis.com/genai-toolbox/v$VERSION/windows/amd64/toolbox.exe"
|
||||||
> ```
|
> ```
|
||||||
>
|
>
|
||||||
> </details>
|
> </details>
|
||||||
@@ -177,7 +206,7 @@ You can also install Toolbox as a container:
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
# see releases page for other versions
|
# see releases page for other versions
|
||||||
export VERSION=0.21.0
|
export VERSION=0.27.0
|
||||||
docker pull us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:$VERSION
|
docker pull us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:$VERSION
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -201,7 +230,7 @@ To install from source, ensure you have the latest version of
|
|||||||
[Go installed](https://go.dev/doc/install), and then run the following command:
|
[Go installed](https://go.dev/doc/install), and then run the following command:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
go install github.com/googleapis/genai-toolbox@v0.21.0
|
go install github.com/googleapis/genai-toolbox@v0.27.0
|
||||||
```
|
```
|
||||||
<!-- {x-release-please-end} -->
|
<!-- {x-release-please-end} -->
|
||||||
|
|
||||||
@@ -245,7 +274,7 @@ To run Toolbox from binary:
|
|||||||
To run the server after pulling the [container image](#installing-the-server):
|
To run the server after pulling the [container image](#installing-the-server):
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
export VERSION=0.11.0 # Use the version you pulled
|
export VERSION=0.24.0 # Use the version you pulled
|
||||||
docker run -p 5000:5000 \
|
docker run -p 5000:5000 \
|
||||||
-v $(pwd)/tools.yaml:/app/tools.yaml \
|
-v $(pwd)/tools.yaml:/app/tools.yaml \
|
||||||
us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:$VERSION \
|
us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:$VERSION \
|
||||||
@@ -291,6 +320,16 @@ toolbox --tools-file "tools.yaml"
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>NPM</summary>
|
||||||
|
|
||||||
|
To run Toolbox directly without manually downloading the binary (requires Node.js):
|
||||||
|
```sh
|
||||||
|
npx @toolbox-sdk/server --tools-file tools.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
<summary>Gemini CLI</summary>
|
<summary>Gemini CLI</summary>
|
||||||
@@ -901,14 +940,14 @@ Toolbox should have access to. Most tools will have at least one source to
|
|||||||
execute against.
|
execute against.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
sources:
|
kind: sources
|
||||||
my-pg-source:
|
name: my-pg-source
|
||||||
kind: postgres
|
type: postgres
|
||||||
host: 127.0.0.1
|
host: 127.0.0.1
|
||||||
port: 5432
|
port: 5432
|
||||||
database: toolbox_db
|
database: toolbox_db
|
||||||
user: toolbox_user
|
user: toolbox_user
|
||||||
password: my-password
|
password: my-password
|
||||||
```
|
```
|
||||||
|
|
||||||
For more details on configuring different types of sources, see the
|
For more details on configuring different types of sources, see the
|
||||||
@@ -917,19 +956,19 @@ For more details on configuring different types of sources, see the
|
|||||||
### Tools
|
### Tools
|
||||||
|
|
||||||
The `tools` section of a `tools.yaml` define the actions an agent can take: what
|
The `tools` section of a `tools.yaml` define the actions an agent can take: what
|
||||||
kind of tool it is, which source(s) it affects, what parameters it uses, etc.
|
type of tool it is, which source(s) it affects, what parameters it uses, etc.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
tools:
|
kind: tools
|
||||||
search-hotels-by-name:
|
name: search-hotels-by-name
|
||||||
kind: postgres-sql
|
type: postgres-sql
|
||||||
source: my-pg-source
|
source: my-pg-source
|
||||||
description: Search for hotels based on name.
|
description: Search for hotels based on name.
|
||||||
parameters:
|
parameters:
|
||||||
- name: name
|
- name: name
|
||||||
type: string
|
type: string
|
||||||
description: The name of the hotel.
|
description: The name of the hotel.
|
||||||
statement: SELECT * FROM hotels WHERE name ILIKE '%' || $1 || '%';
|
statement: SELECT * FROM hotels WHERE name ILIKE '%' || $1 || '%';
|
||||||
```
|
```
|
||||||
|
|
||||||
For more details on configuring different types of tools, see the
|
For more details on configuring different types of tools, see the
|
||||||
@@ -998,12 +1037,12 @@ The version will be incremented as follows:
|
|||||||
|
|
||||||
### Post-1.0.0 Versioning
|
### Post-1.0.0 Versioning
|
||||||
|
|
||||||
Once the project reaches a stable `1.0.0` release, the versioning will follow
|
Once the project reaches a stable `1.0.0` release, the version number
|
||||||
the more common convention:
|
**`MAJOR.MINOR.PATCH`** will follow the more common convention:
|
||||||
|
|
||||||
- **`MAJOR.MINOR.PATCH`**: Incremented for incompatible API changes.
|
- **`MAJOR`**: Incremented for incompatible API changes.
|
||||||
- **`MAJOR.MINOR.PATCH`**: Incremented for new, backward-compatible functionality.
|
- **`MINOR`**: Incremented for new, backward-compatible functionality.
|
||||||
- **`MAJOR.MINOR.PATCH`**: Incremented for backward-compatible bug fixes.
|
- **`PATCH`**: Incremented for backward-compatible bug fixes.
|
||||||
|
|
||||||
The public API that this applies to is the CLI associated with Toolbox, the
|
The public API that this applies to is the CLI associated with Toolbox, the
|
||||||
interactions with official SDKs, and the definitions in the `tools.yaml` file.
|
interactions with official SDKs, and the definitions in the `tools.yaml` file.
|
||||||
|
|||||||
257
cmd/internal/imports.go
Normal file
257
cmd/internal/imports.go
Normal file
@@ -0,0 +1,257 @@
|
|||||||
|
// Copyright 2026 Google LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
// Import prompt packages for side effect of registration
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/prompts/custom"
|
||||||
|
|
||||||
|
// Import tool packages for side effect of registration
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydbcreatecluster"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydbcreateinstance"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydbcreateuser"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydbgetcluster"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydbgetinstance"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydbgetuser"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydblistclusters"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydblistinstances"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydblistusers"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydbwaitforoperation"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydbainl"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigqueryanalyzecontribution"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigqueryconversationalanalytics"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigqueryexecutesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigqueryforecast"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigquerygetdatasetinfo"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigquerygettableinfo"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigquerylistdatasetids"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigquerylisttableids"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigquerysearchcatalog"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigquerysql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/bigtable"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cassandra/cassandracql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/clickhouse/clickhouseexecutesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/clickhouse/clickhouselistdatabases"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/clickhouse/clickhouselisttables"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/clickhouse/clickhousesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudgda"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcarefhirfetchpage"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcarefhirpatienteverything"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcarefhirpatientsearch"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaregetdataset"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstore"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstoremetrics"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaregetfhirresource"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstore"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstoremetrics"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcarelistdicomstores"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcarelistfhirstores"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcareretrieverendereddicominstance"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaresearchdicominstances"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomseries"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomstudies"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudloggingadmin/cloudloggingadminlistlognames"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudloggingadmin/cloudloggingadminlistresourcetypes"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudloggingadmin/cloudloggingadminquerylogs"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudmonitoring"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsql/cloudsqlcloneinstance"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsql/cloudsqlcreatebackup"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsql/cloudsqlcreatedatabase"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsql/cloudsqlcreateusers"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsql/cloudsqlgetinstances"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsql/cloudsqllistdatabases"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsql/cloudsqllistinstances"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsql/cloudsqlrestorebackup"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsql/cloudsqlwaitforoperation"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsqlmssql/cloudsqlmssqlcreateinstance"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsqlmysql/cloudsqlmysqlcreateinstance"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsqlpg/cloudsqlpgcreateinstances"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsqlpg/cloudsqlpgupgradeprecheck"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cockroachdb/cockroachdbexecutesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cockroachdb/cockroachdblistschemas"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cockroachdb/cockroachdblisttables"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/cockroachdb/cockroachdbsql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/couchbase"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/dataform/dataformcompilelocal"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/dataplex/dataplexlookupentry"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/dataplex/dataplexsearchaspecttypes"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/dataplex/dataplexsearchentries"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/dgraph"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/elasticsearch/elasticsearchesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/firebird/firebirdexecutesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/firebird/firebirdsql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/firestore/firestoreadddocuments"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/firestore/firestoredeletedocuments"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/firestore/firestoregetdocuments"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/firestore/firestoregetrules"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/firestore/firestorelistcollections"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/firestore/firestorequery"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/firestore/firestorequerycollection"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/firestore/firestoreupdatedocument"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/firestore/firestorevalidaterules"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/http"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookeradddashboardelement"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookeradddashboardfilter"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerconversationalanalytics"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercreateprojectfile"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerdeleteprojectfile"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerdevmode"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergenerateembedurl"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetconnectiondatabases"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetconnections"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetconnectionschemas"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetconnectiontablecolumns"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetconnectiontables"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetdashboards"
|
||||||
|
_ "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/lookergetlooks"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetmeasures"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetmodels"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetparameters"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetprojectfile"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetprojectfiles"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetprojects"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerhealthanalyze"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerhealthpulse"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerhealthvacuum"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookermakedashboard"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookermakelook"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerquery"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerquerysql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerqueryurl"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerrundashboard"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerrunlook"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerupdateprojectfile"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookervalidateproject"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mindsdb/mindsdbexecutesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mindsdb/mindsdbsql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbaggregate"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbdeletemany"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbdeleteone"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbfind"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbfindone"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbinsertmany"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbinsertone"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbupdatemany"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbupdateone"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mssql/mssqlexecutesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mssql/mssqllisttables"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mssql/mssqlsql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqlexecutesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqlgetqueryplan"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqllistactivequeries"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqllisttablefragmentation"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqllisttables"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqllisttablesmissinguniqueindexes"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqlsql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/neo4j/neo4jcypher"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/neo4j/neo4jexecutecypher"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/neo4j/neo4jschema"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/oceanbase/oceanbaseexecutesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/oceanbase/oceanbasesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/oracle/oracleexecutesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/oracle/oraclesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgresdatabaseoverview"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgresexecutesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgresgetcolumncardinality"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistactivequeries"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistavailableextensions"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistdatabasestats"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistindexes"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistinstalledextensions"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistlocks"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistpgsettings"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistpublicationtables"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistquerystats"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistroles"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistschemas"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistsequences"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgresliststoredprocedure"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslisttables"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslisttablespaces"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslisttablestats"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslisttriggers"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistviews"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslongrunningtransactions"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgresreplicationstats"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgressql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/redis"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/serverlessspark/serverlesssparkcancelbatch"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/serverlessspark/serverlesssparkcreatepysparkbatch"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/serverlessspark/serverlesssparkcreatesparkbatch"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/serverlessspark/serverlesssparkgetbatch"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/serverlessspark/serverlesssparklistbatches"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/singlestore/singlestoreexecutesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/singlestore/singlestoresql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/snowflake/snowflakeexecutesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/snowflake/snowflakesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/spanner/spannerexecutesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/spanner/spannerlistgraphs"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/spanner/spannerlisttables"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/spanner/spannersql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/sqlite/sqliteexecutesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/sqlite/sqlitesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/tidb/tidbexecutesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/tidb/tidbsql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/trino/trinoexecutesql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/trino/trinosql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/utility/wait"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/valkey"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/yugabytedbsql"
|
||||||
|
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/alloydbadmin"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/alloydbpg"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/bigquery"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/bigtable"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/cassandra"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/clickhouse"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/cloudgda"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/cloudhealthcare"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/cloudloggingadmin"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/cloudmonitoring"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/cloudsqladmin"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlmssql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlmysql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlpg"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/cockroachdb"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/couchbase"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/dataplex"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/dgraph"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/elasticsearch"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/firebird"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/firestore"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/http"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/looker"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/mindsdb"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/mongodb"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/mssql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/mysql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/neo4j"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/oceanbase"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/oracle"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/postgres"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/redis"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/serverlessspark"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/singlestore"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/snowflake"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/spanner"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/sqlite"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/tidb"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/trino"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/valkey"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/yugabytedb"
|
||||||
|
)
|
||||||
139
cmd/internal/invoke/command.go
Normal file
139
cmd/internal/invoke/command.go
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
// Copyright 2026 Google LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package invoke
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/googleapis/genai-toolbox/cmd/internal"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/server"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/server/resources"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/util/parameters"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewCommand(opts *internal.ToolboxOptions) *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "invoke <tool-name> [params]",
|
||||||
|
Short: "Execute a tool directly",
|
||||||
|
Long: `Execute a tool directly with parameters.
|
||||||
|
Params must be a JSON string.
|
||||||
|
Example:
|
||||||
|
toolbox invoke my-tool '{"param1": "value1"}'`,
|
||||||
|
Args: cobra.MinimumNArgs(1),
|
||||||
|
RunE: func(c *cobra.Command, args []string) error {
|
||||||
|
return runInvoke(c, args, opts)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func runInvoke(cmd *cobra.Command, args []string, opts *internal.ToolboxOptions) error {
|
||||||
|
ctx, cancel := context.WithCancel(cmd.Context())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
ctx, shutdown, err := opts.Setup(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = shutdown(ctx)
|
||||||
|
}()
|
||||||
|
|
||||||
|
_, err = opts.LoadConfig(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize Resources
|
||||||
|
sourcesMap, authServicesMap, embeddingModelsMap, toolsMap, toolsetsMap, promptsMap, promptsetsMap, err := server.InitializeConfigs(ctx, opts.Cfg)
|
||||||
|
if err != nil {
|
||||||
|
errMsg := fmt.Errorf("failed to initialize resources: %w", err)
|
||||||
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return errMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
resourceMgr := resources.NewResourceManager(sourcesMap, authServicesMap, embeddingModelsMap, toolsMap, toolsetsMap, promptsMap, promptsetsMap)
|
||||||
|
|
||||||
|
// Execute Tool
|
||||||
|
toolName := args[0]
|
||||||
|
tool, ok := resourceMgr.GetTool(toolName)
|
||||||
|
if !ok {
|
||||||
|
errMsg := fmt.Errorf("tool %q not found", toolName)
|
||||||
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return errMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
var paramsInput string
|
||||||
|
if len(args) > 1 {
|
||||||
|
paramsInput = args[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
params := make(map[string]any)
|
||||||
|
if paramsInput != "" {
|
||||||
|
if err := json.Unmarshal([]byte(paramsInput), ¶ms); err != nil {
|
||||||
|
errMsg := fmt.Errorf("params must be a valid JSON string: %w", err)
|
||||||
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return errMsg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedParams, err := parameters.ParseParams(tool.GetParameters(), params, nil)
|
||||||
|
if err != nil {
|
||||||
|
errMsg := fmt.Errorf("invalid parameters: %w", err)
|
||||||
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return errMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedParams, err = tool.EmbedParams(ctx, parsedParams, resourceMgr.GetEmbeddingModelMap())
|
||||||
|
if err != nil {
|
||||||
|
errMsg := fmt.Errorf("error embedding parameters: %w", err)
|
||||||
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return errMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client Auth not supported for ephemeral CLI call
|
||||||
|
requiresAuth, err := tool.RequiresClientAuthorization(resourceMgr)
|
||||||
|
if err != nil {
|
||||||
|
errMsg := fmt.Errorf("failed to check auth requirements: %w", err)
|
||||||
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return errMsg
|
||||||
|
}
|
||||||
|
if requiresAuth {
|
||||||
|
errMsg := fmt.Errorf("client authorization is not supported")
|
||||||
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return errMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := tool.Invoke(ctx, resourceMgr, parsedParams, "")
|
||||||
|
if err != nil {
|
||||||
|
errMsg := fmt.Errorf("tool execution failed: %w", err)
|
||||||
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return errMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print Result
|
||||||
|
output, err := json.MarshalIndent(result, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
errMsg := fmt.Errorf("failed to marshal result: %w", err)
|
||||||
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return errMsg
|
||||||
|
}
|
||||||
|
fmt.Fprintln(opts.IOStreams.Out, string(output))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
153
cmd/internal/invoke/command_test.go
Normal file
153
cmd/internal/invoke/command_test.go
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
// Copyright 2026 Google LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package invoke
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/googleapis/genai-toolbox/cmd/internal"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/bigquery"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/sqlite"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigquerysql"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/sqlite/sqlitesql"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func invokeCommand(args []string) (string, error) {
|
||||||
|
parentCmd := &cobra.Command{Use: "toolbox"}
|
||||||
|
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
opts := internal.NewToolboxOptions(internal.WithIOStreams(buf, buf))
|
||||||
|
internal.PersistentFlags(parentCmd, opts)
|
||||||
|
|
||||||
|
cmd := NewCommand(opts)
|
||||||
|
parentCmd.AddCommand(cmd)
|
||||||
|
parentCmd.SetArgs(args)
|
||||||
|
|
||||||
|
err := parentCmd.Execute()
|
||||||
|
return buf.String(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInvokeTool(t *testing.T) {
|
||||||
|
// Create a temporary tools file
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
|
||||||
|
toolsFileContent := `
|
||||||
|
sources:
|
||||||
|
my-sqlite:
|
||||||
|
kind: sqlite
|
||||||
|
database: test.db
|
||||||
|
tools:
|
||||||
|
hello-sqlite:
|
||||||
|
kind: sqlite-sql
|
||||||
|
source: my-sqlite
|
||||||
|
description: "hello tool"
|
||||||
|
statement: "SELECT 'hello' as greeting"
|
||||||
|
echo-tool:
|
||||||
|
kind: sqlite-sql
|
||||||
|
source: my-sqlite
|
||||||
|
description: "echo tool"
|
||||||
|
statement: "SELECT ? as msg"
|
||||||
|
parameters:
|
||||||
|
- name: message
|
||||||
|
type: string
|
||||||
|
description: message to echo
|
||||||
|
`
|
||||||
|
|
||||||
|
toolsFilePath := filepath.Join(tmpDir, "tools.yaml")
|
||||||
|
if err := os.WriteFile(toolsFilePath, []byte(toolsFileContent), 0644); err != nil {
|
||||||
|
t.Fatalf("failed to write tools file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tcs := []struct {
|
||||||
|
desc string
|
||||||
|
args []string
|
||||||
|
want string
|
||||||
|
wantErr bool
|
||||||
|
errStr string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "success - basic tool call",
|
||||||
|
args: []string{"invoke", "hello-sqlite", "--tools-file", toolsFilePath},
|
||||||
|
want: `"greeting": "hello"`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "success - tool call with parameters",
|
||||||
|
args: []string{"invoke", "echo-tool", `{"message": "world"}`, "--tools-file", toolsFilePath},
|
||||||
|
want: `"msg": "world"`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "error - tool not found",
|
||||||
|
args: []string{"invoke", "non-existent", "--tools-file", toolsFilePath},
|
||||||
|
wantErr: true,
|
||||||
|
errStr: `tool "non-existent" not found`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "error - invalid JSON params",
|
||||||
|
args: []string{"invoke", "echo-tool", `invalid-json`, "--tools-file", toolsFilePath},
|
||||||
|
wantErr: true,
|
||||||
|
errStr: `params must be a valid JSON string`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tcs {
|
||||||
|
t.Run(tc.desc, func(t *testing.T) {
|
||||||
|
got, err := invokeCommand(tc.args)
|
||||||
|
if (err != nil) != tc.wantErr {
|
||||||
|
t.Fatalf("got error %v, wantErr %v", err, tc.wantErr)
|
||||||
|
}
|
||||||
|
if tc.wantErr && !strings.Contains(err.Error(), tc.errStr) {
|
||||||
|
t.Fatalf("got error %v, want error containing %q", err, tc.errStr)
|
||||||
|
}
|
||||||
|
if !tc.wantErr && !strings.Contains(got, tc.want) {
|
||||||
|
t.Fatalf("got %q, want it to contain %q", got, tc.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInvokeTool_AuthUnsupported(t *testing.T) {
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
toolsFileContent := `
|
||||||
|
sources:
|
||||||
|
my-bq:
|
||||||
|
kind: bigquery
|
||||||
|
project: my-project
|
||||||
|
useClientOAuth: true
|
||||||
|
tools:
|
||||||
|
bq-tool:
|
||||||
|
kind: bigquery-sql
|
||||||
|
source: my-bq
|
||||||
|
description: "bq tool"
|
||||||
|
statement: "SELECT 1"
|
||||||
|
`
|
||||||
|
toolsFilePath := filepath.Join(tmpDir, "auth_tools.yaml")
|
||||||
|
if err := os.WriteFile(toolsFilePath, []byte(toolsFileContent), 0644); err != nil {
|
||||||
|
t.Fatalf("failed to write tools file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
args := []string{"invoke", "bq-tool", "--tools-file", toolsFilePath}
|
||||||
|
_, err := invokeCommand(args)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("expected error for tool requiring client auth, but got nil")
|
||||||
|
}
|
||||||
|
if !strings.Contains(err.Error(), "client authorization is not supported") {
|
||||||
|
t.Fatalf("unexpected error message: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
251
cmd/internal/options.go
Normal file
251
cmd/internal/options.go
Normal file
@@ -0,0 +1,251 @@
|
|||||||
|
// Copyright 2026 Google LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/log"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/prebuiltconfigs"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/server"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/telemetry"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IOStreams struct {
|
||||||
|
In io.Reader
|
||||||
|
Out io.Writer
|
||||||
|
ErrOut io.Writer
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToolboxOptions holds dependencies shared by all commands.
|
||||||
|
type ToolboxOptions struct {
|
||||||
|
IOStreams IOStreams
|
||||||
|
Logger log.Logger
|
||||||
|
Cfg server.ServerConfig
|
||||||
|
ToolsFile string
|
||||||
|
ToolsFiles []string
|
||||||
|
ToolsFolder string
|
||||||
|
PrebuiltConfigs []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Option defines a function that modifies the ToolboxOptions struct.
|
||||||
|
type Option func(*ToolboxOptions)
|
||||||
|
|
||||||
|
// NewToolboxOptions creates a new instance with defaults, then applies any
|
||||||
|
// provided options.
|
||||||
|
func NewToolboxOptions(opts ...Option) *ToolboxOptions {
|
||||||
|
o := &ToolboxOptions{
|
||||||
|
IOStreams: IOStreams{
|
||||||
|
In: os.Stdin,
|
||||||
|
Out: os.Stdout,
|
||||||
|
ErrOut: os.Stderr,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(o)
|
||||||
|
}
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply allows you to update an EXISTING ToolboxOptions instance.
|
||||||
|
// This is useful for "late binding".
|
||||||
|
func (o *ToolboxOptions) Apply(opts ...Option) {
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(o)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithIOStreams updates the IO streams.
|
||||||
|
func WithIOStreams(out, err io.Writer) Option {
|
||||||
|
return func(o *ToolboxOptions) {
|
||||||
|
o.IOStreams.Out = out
|
||||||
|
o.IOStreams.ErrOut = err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup create logger and telemetry instrumentations.
|
||||||
|
func (opts *ToolboxOptions) Setup(ctx context.Context) (context.Context, func(context.Context) error, error) {
|
||||||
|
// If stdio, set logger's out stream (usually DEBUG and INFO logs) to
|
||||||
|
// errStream
|
||||||
|
loggerOut := opts.IOStreams.Out
|
||||||
|
if opts.Cfg.Stdio {
|
||||||
|
loggerOut = opts.IOStreams.ErrOut
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle logger separately from config
|
||||||
|
logger, err := log.NewLogger(opts.Cfg.LoggingFormat.String(), opts.Cfg.LogLevel.String(), loggerOut, opts.IOStreams.ErrOut)
|
||||||
|
if err != nil {
|
||||||
|
return ctx, nil, fmt.Errorf("unable to initialize logger: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = util.WithLogger(ctx, logger)
|
||||||
|
opts.Logger = logger
|
||||||
|
|
||||||
|
// Set up OpenTelemetry
|
||||||
|
otelShutdown, err := telemetry.SetupOTel(ctx, opts.Cfg.Version, opts.Cfg.TelemetryOTLP, opts.Cfg.TelemetryGCP, opts.Cfg.TelemetryServiceName)
|
||||||
|
if err != nil {
|
||||||
|
errMsg := fmt.Errorf("error setting up OpenTelemetry: %w", err)
|
||||||
|
logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return ctx, nil, errMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
shutdownFunc := func(ctx context.Context) error {
|
||||||
|
err := otelShutdown(ctx)
|
||||||
|
if err != nil {
|
||||||
|
errMsg := fmt.Errorf("error shutting down OpenTelemetry: %w", err)
|
||||||
|
logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
instrumentation, err := telemetry.CreateTelemetryInstrumentation(opts.Cfg.Version)
|
||||||
|
if err != nil {
|
||||||
|
errMsg := fmt.Errorf("unable to create telemetry instrumentation: %w", err)
|
||||||
|
logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return ctx, shutdownFunc, errMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = util.WithInstrumentation(ctx, instrumentation)
|
||||||
|
|
||||||
|
return ctx, shutdownFunc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadConfig checks and merge files that should be loaded into the server
|
||||||
|
func (opts *ToolboxOptions) LoadConfig(ctx context.Context) (bool, error) {
|
||||||
|
// Determine if Custom Files should be loaded
|
||||||
|
// Check for explicit custom flags
|
||||||
|
isCustomConfigured := opts.ToolsFile != "" || len(opts.ToolsFiles) > 0 || opts.ToolsFolder != ""
|
||||||
|
|
||||||
|
// Determine if default 'tools.yaml' should be used (No prebuilt AND No custom flags)
|
||||||
|
useDefaultToolsFile := len(opts.PrebuiltConfigs) == 0 && !isCustomConfigured
|
||||||
|
|
||||||
|
if useDefaultToolsFile {
|
||||||
|
opts.ToolsFile = "tools.yaml"
|
||||||
|
isCustomConfigured = true
|
||||||
|
}
|
||||||
|
|
||||||
|
logger, err := util.LoggerFromContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return isCustomConfigured, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var allToolsFiles []ToolsFile
|
||||||
|
|
||||||
|
// Load Prebuilt Configuration
|
||||||
|
|
||||||
|
if len(opts.PrebuiltConfigs) > 0 {
|
||||||
|
slices.Sort(opts.PrebuiltConfigs)
|
||||||
|
sourcesList := strings.Join(opts.PrebuiltConfigs, ", ")
|
||||||
|
logMsg := fmt.Sprintf("Using prebuilt tool configurations for: %s", sourcesList)
|
||||||
|
logger.InfoContext(ctx, logMsg)
|
||||||
|
|
||||||
|
for _, configName := range opts.PrebuiltConfigs {
|
||||||
|
buf, err := prebuiltconfigs.Get(configName)
|
||||||
|
if err != nil {
|
||||||
|
logger.ErrorContext(ctx, err.Error())
|
||||||
|
return isCustomConfigured, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse into ToolsFile struct
|
||||||
|
parsed, err := parseToolsFile(ctx, buf)
|
||||||
|
if err != nil {
|
||||||
|
errMsg := fmt.Errorf("unable to parse prebuilt tool configuration for '%s': %w", configName, err)
|
||||||
|
logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return isCustomConfigured, errMsg
|
||||||
|
}
|
||||||
|
allToolsFiles = append(allToolsFiles, parsed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load Custom Configurations
|
||||||
|
if isCustomConfigured {
|
||||||
|
// Enforce exclusivity among custom flags (tools-file vs tools-files vs tools-folder)
|
||||||
|
if (opts.ToolsFile != "" && len(opts.ToolsFiles) > 0) ||
|
||||||
|
(opts.ToolsFile != "" && opts.ToolsFolder != "") ||
|
||||||
|
(len(opts.ToolsFiles) > 0 && opts.ToolsFolder != "") {
|
||||||
|
errMsg := fmt.Errorf("--tools-file, --tools-files, and --tools-folder flags cannot be used simultaneously")
|
||||||
|
logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return isCustomConfigured, errMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
var customTools ToolsFile
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if len(opts.ToolsFiles) > 0 {
|
||||||
|
// Use tools-files
|
||||||
|
logger.InfoContext(ctx, fmt.Sprintf("Loading and merging %d tool configuration files", len(opts.ToolsFiles)))
|
||||||
|
customTools, err = LoadAndMergeToolsFiles(ctx, opts.ToolsFiles)
|
||||||
|
} else if opts.ToolsFolder != "" {
|
||||||
|
// Use tools-folder
|
||||||
|
logger.InfoContext(ctx, fmt.Sprintf("Loading and merging all YAML files from directory: %s", opts.ToolsFolder))
|
||||||
|
customTools, err = LoadAndMergeToolsFolder(ctx, opts.ToolsFolder)
|
||||||
|
} else {
|
||||||
|
// Use single file (tools-file or default `tools.yaml`)
|
||||||
|
buf, readFileErr := os.ReadFile(opts.ToolsFile)
|
||||||
|
if readFileErr != nil {
|
||||||
|
errMsg := fmt.Errorf("unable to read tool file at %q: %w", opts.ToolsFile, readFileErr)
|
||||||
|
logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return isCustomConfigured, errMsg
|
||||||
|
}
|
||||||
|
customTools, err = parseToolsFile(ctx, buf)
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("unable to parse tool file at %q: %w", opts.ToolsFile, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.ErrorContext(ctx, err.Error())
|
||||||
|
return isCustomConfigured, err
|
||||||
|
}
|
||||||
|
allToolsFiles = append(allToolsFiles, customTools)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modify version string based on loaded configurations
|
||||||
|
if len(opts.PrebuiltConfigs) > 0 {
|
||||||
|
tag := "prebuilt"
|
||||||
|
if isCustomConfigured {
|
||||||
|
tag = "custom"
|
||||||
|
}
|
||||||
|
// prebuiltConfigs is already sorted above
|
||||||
|
for _, configName := range opts.PrebuiltConfigs {
|
||||||
|
opts.Cfg.Version += fmt.Sprintf("+%s.%s", tag, configName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge Everything
|
||||||
|
// This will error if custom tools collide with prebuilt tools
|
||||||
|
finalToolsFile, err := mergeToolsFiles(allToolsFiles...)
|
||||||
|
if err != nil {
|
||||||
|
logger.ErrorContext(ctx, err.Error())
|
||||||
|
return isCustomConfigured, err
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.Cfg.SourceConfigs = finalToolsFile.Sources
|
||||||
|
opts.Cfg.AuthServiceConfigs = finalToolsFile.AuthServices
|
||||||
|
opts.Cfg.EmbeddingModelConfigs = finalToolsFile.EmbeddingModels
|
||||||
|
opts.Cfg.ToolConfigs = finalToolsFile.Tools
|
||||||
|
opts.Cfg.ToolsetConfigs = finalToolsFile.Toolsets
|
||||||
|
opts.Cfg.PromptConfigs = finalToolsFile.Prompts
|
||||||
|
|
||||||
|
return isCustomConfigured, nil
|
||||||
|
}
|
||||||
@@ -12,57 +12,38 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package cmd
|
package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCommandOptions(t *testing.T) {
|
func TestToolboxOptions(t *testing.T) {
|
||||||
w := io.Discard
|
w := io.Discard
|
||||||
tcs := []struct {
|
tcs := []struct {
|
||||||
desc string
|
desc string
|
||||||
isValid func(*Command) error
|
isValid func(*ToolboxOptions) error
|
||||||
option Option
|
option Option
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
desc: "with logger",
|
desc: "with logger",
|
||||||
isValid: func(c *Command) error {
|
isValid: func(o *ToolboxOptions) error {
|
||||||
if c.outStream != w || c.errStream != w {
|
if o.IOStreams.Out != w || o.IOStreams.ErrOut != w {
|
||||||
return errors.New("loggers do not match")
|
return errors.New("loggers do not match")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
option: WithStreams(w, w),
|
option: WithIOStreams(w, w),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range tcs {
|
for _, tc := range tcs {
|
||||||
t.Run(tc.desc, func(t *testing.T) {
|
t.Run(tc.desc, func(t *testing.T) {
|
||||||
got, err := invokeProxyWithOption(tc.option)
|
got := NewToolboxOptions(tc.option)
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := tc.isValid(got); err != nil {
|
if err := tc.isValid(got); err != nil {
|
||||||
t.Errorf("option did not initialize command correctly: %v", err)
|
t.Errorf("option did not initialize command correctly: %v", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func invokeProxyWithOption(o Option) (*Command, error) {
|
|
||||||
c := NewCommand(o)
|
|
||||||
// Keep the test output quiet
|
|
||||||
c.SilenceUsage = true
|
|
||||||
c.SilenceErrors = true
|
|
||||||
// Disable execute behavior
|
|
||||||
c.RunE = func(*cobra.Command, []string) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
err := c.Execute()
|
|
||||||
return c, err
|
|
||||||
}
|
|
||||||
46
cmd/internal/persistent_flags.go
Normal file
46
cmd/internal/persistent_flags.go
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
// Copyright 2026 Google LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/prebuiltconfigs"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PersistentFlags sets up flags that are available for all commands and
|
||||||
|
// subcommands
|
||||||
|
// It is also used to set up persistent flags during subcommand unit tests
|
||||||
|
func PersistentFlags(parentCmd *cobra.Command, opts *ToolboxOptions) {
|
||||||
|
persistentFlags := parentCmd.PersistentFlags()
|
||||||
|
|
||||||
|
persistentFlags.StringVar(&opts.ToolsFile, "tools-file", "", "File path specifying the tool configuration. Cannot be used with --tools-files, or --tools-folder.")
|
||||||
|
persistentFlags.StringSliceVar(&opts.ToolsFiles, "tools-files", []string{}, "Multiple file paths specifying tool configurations. Files will be merged. Cannot be used with --tools-file, or --tools-folder.")
|
||||||
|
persistentFlags.StringVar(&opts.ToolsFolder, "tools-folder", "", "Directory path containing YAML tool configuration files. All .yaml and .yml files in the directory will be loaded and merged. Cannot be used with --tools-file, or --tools-files.")
|
||||||
|
persistentFlags.Var(&opts.Cfg.LogLevel, "log-level", "Specify the minimum level logged. Allowed: 'DEBUG', 'INFO', 'WARN', 'ERROR'.")
|
||||||
|
persistentFlags.Var(&opts.Cfg.LoggingFormat, "logging-format", "Specify logging format to use. Allowed: 'standard' or 'JSON'.")
|
||||||
|
persistentFlags.BoolVar(&opts.Cfg.TelemetryGCP, "telemetry-gcp", false, "Enable exporting directly to Google Cloud Monitoring.")
|
||||||
|
persistentFlags.StringVar(&opts.Cfg.TelemetryOTLP, "telemetry-otlp", "", "Enable exporting using OpenTelemetry Protocol (OTLP) to the specified endpoint (e.g. 'http://127.0.0.1:4318')")
|
||||||
|
persistentFlags.StringVar(&opts.Cfg.TelemetryServiceName, "telemetry-service-name", "toolbox", "Sets the value of the service.name resource attribute for telemetry data.")
|
||||||
|
// Fetch prebuilt tools sources to customize the help description
|
||||||
|
prebuiltHelp := fmt.Sprintf(
|
||||||
|
"Use a prebuilt tool configuration by source type. Allowed: '%s'. Can be specified multiple times.",
|
||||||
|
strings.Join(prebuiltconfigs.GetPrebuiltSources(), "', '"),
|
||||||
|
)
|
||||||
|
persistentFlags.StringSliceVar(&opts.PrebuiltConfigs, "prebuilt", []string{}, prebuiltHelp)
|
||||||
|
persistentFlags.StringSliceVar(&opts.Cfg.UserAgentMetadata, "user-agent-metadata", []string{}, "Appends additional metadata to the User-Agent.")
|
||||||
|
}
|
||||||
214
cmd/internal/skills/command.go
Normal file
214
cmd/internal/skills/command.go
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
// Copyright 2026 Google LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package skills
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
_ "embed"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/googleapis/genai-toolbox/cmd/internal"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/server"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/server/resources"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/tools"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// skillsCmd is the command for generating skills.
|
||||||
|
type skillsCmd struct {
|
||||||
|
*cobra.Command
|
||||||
|
name string
|
||||||
|
description string
|
||||||
|
toolset string
|
||||||
|
outputDir string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCommand creates a new Command.
|
||||||
|
func NewCommand(opts *internal.ToolboxOptions) *cobra.Command {
|
||||||
|
cmd := &skillsCmd{}
|
||||||
|
cmd.Command = &cobra.Command{
|
||||||
|
Use: "skills-generate",
|
||||||
|
Short: "Generate skills from tool configurations",
|
||||||
|
RunE: func(c *cobra.Command, args []string) error {
|
||||||
|
return run(cmd, opts)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Flags().StringVar(&cmd.name, "name", "", "Name of the generated skill.")
|
||||||
|
cmd.Flags().StringVar(&cmd.description, "description", "", "Description of the generated skill")
|
||||||
|
cmd.Flags().StringVar(&cmd.toolset, "toolset", "", "Name of the toolset to convert into a skill. If not provided, all tools will be included.")
|
||||||
|
cmd.Flags().StringVar(&cmd.outputDir, "output-dir", "skills", "Directory to output generated skills")
|
||||||
|
|
||||||
|
_ = cmd.MarkFlagRequired("name")
|
||||||
|
_ = cmd.MarkFlagRequired("description")
|
||||||
|
return cmd.Command
|
||||||
|
}
|
||||||
|
|
||||||
|
func run(cmd *skillsCmd, opts *internal.ToolboxOptions) error {
|
||||||
|
ctx, cancel := context.WithCancel(cmd.Context())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
ctx, shutdown, err := opts.Setup(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = shutdown(ctx)
|
||||||
|
}()
|
||||||
|
|
||||||
|
_, err = opts.LoadConfig(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.MkdirAll(cmd.outputDir, 0755); err != nil {
|
||||||
|
errMsg := fmt.Errorf("error creating output directory: %w", err)
|
||||||
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return errMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.Logger.InfoContext(ctx, fmt.Sprintf("Generating skill '%s'...", cmd.name))
|
||||||
|
|
||||||
|
// Initialize toolbox and collect tools
|
||||||
|
allTools, err := cmd.collectTools(ctx, opts)
|
||||||
|
if err != nil {
|
||||||
|
errMsg := fmt.Errorf("error collecting tools: %w", err)
|
||||||
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return errMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(allTools) == 0 {
|
||||||
|
opts.Logger.InfoContext(ctx, "No tools found to generate.")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the combined skill directory
|
||||||
|
skillPath := filepath.Join(cmd.outputDir, cmd.name)
|
||||||
|
if err := os.MkdirAll(skillPath, 0755); err != nil {
|
||||||
|
errMsg := fmt.Errorf("error creating skill directory: %w", err)
|
||||||
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return errMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate assets directory
|
||||||
|
assetsPath := filepath.Join(skillPath, "assets")
|
||||||
|
if err := os.MkdirAll(assetsPath, 0755); err != nil {
|
||||||
|
errMsg := fmt.Errorf("error creating assets dir: %w", err)
|
||||||
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return errMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate scripts directory
|
||||||
|
scriptsPath := filepath.Join(skillPath, "scripts")
|
||||||
|
if err := os.MkdirAll(scriptsPath, 0755); err != nil {
|
||||||
|
errMsg := fmt.Errorf("error creating scripts dir: %w", err)
|
||||||
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return errMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate over keys to ensure deterministic order
|
||||||
|
var toolNames []string
|
||||||
|
for name := range allTools {
|
||||||
|
toolNames = append(toolNames, name)
|
||||||
|
}
|
||||||
|
sort.Strings(toolNames)
|
||||||
|
|
||||||
|
for _, toolName := range toolNames {
|
||||||
|
// Generate YAML config in asset directory
|
||||||
|
minimizedContent, err := generateToolConfigYAML(opts.Cfg, toolName)
|
||||||
|
if err != nil {
|
||||||
|
errMsg := fmt.Errorf("error generating filtered config for %s: %w", toolName, err)
|
||||||
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return errMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
specificToolsFileName := fmt.Sprintf("%s.yaml", toolName)
|
||||||
|
if minimizedContent != nil {
|
||||||
|
destPath := filepath.Join(assetsPath, specificToolsFileName)
|
||||||
|
if err := os.WriteFile(destPath, minimizedContent, 0644); err != nil {
|
||||||
|
errMsg := fmt.Errorf("error writing filtered config for %s: %w", toolName, err)
|
||||||
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return errMsg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate wrapper script in scripts directory
|
||||||
|
scriptContent, err := generateScriptContent(toolName, specificToolsFileName)
|
||||||
|
if err != nil {
|
||||||
|
errMsg := fmt.Errorf("error generating script content for %s: %w", toolName, err)
|
||||||
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return errMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
scriptFilename := filepath.Join(scriptsPath, fmt.Sprintf("%s.js", toolName))
|
||||||
|
if err := os.WriteFile(scriptFilename, []byte(scriptContent), 0755); err != nil {
|
||||||
|
errMsg := fmt.Errorf("error writing script %s: %w", scriptFilename, err)
|
||||||
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return errMsg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate SKILL.md
|
||||||
|
skillContent, err := generateSkillMarkdown(cmd.name, cmd.description, allTools)
|
||||||
|
if err != nil {
|
||||||
|
errMsg := fmt.Errorf("error generating SKILL.md content: %w", err)
|
||||||
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return errMsg
|
||||||
|
}
|
||||||
|
skillMdPath := filepath.Join(skillPath, "SKILL.md")
|
||||||
|
if err := os.WriteFile(skillMdPath, []byte(skillContent), 0644); err != nil {
|
||||||
|
errMsg := fmt.Errorf("error writing SKILL.md: %w", err)
|
||||||
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
|
return errMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.Logger.InfoContext(ctx, fmt.Sprintf("Successfully generated skill '%s' with %d tools.", cmd.name, len(allTools)))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *skillsCmd) collectTools(ctx context.Context, opts *internal.ToolboxOptions) (map[string]tools.Tool, error) {
|
||||||
|
// Initialize Resources
|
||||||
|
sourcesMap, authServicesMap, embeddingModelsMap, toolsMap, toolsetsMap, promptsMap, promptsetsMap, err := server.InitializeConfigs(ctx, opts.Cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to initialize resources: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resourceMgr := resources.NewResourceManager(sourcesMap, authServicesMap, embeddingModelsMap, toolsMap, toolsetsMap, promptsMap, promptsetsMap)
|
||||||
|
|
||||||
|
result := make(map[string]tools.Tool)
|
||||||
|
|
||||||
|
if c.toolset == "" {
|
||||||
|
return toolsMap, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ts, ok := resourceMgr.GetToolset(c.toolset)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("toolset %q not found", c.toolset)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, t := range ts.Tools {
|
||||||
|
if t != nil {
|
||||||
|
tool := *t
|
||||||
|
result[tool.McpManifest().Name] = tool
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
195
cmd/internal/skills/command_test.go
Normal file
195
cmd/internal/skills/command_test.go
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
// Copyright 2026 Google LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package skills
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/googleapis/genai-toolbox/cmd/internal"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/sources/sqlite"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/sqlite/sqlitesql"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func invokeCommand(args []string) (string, error) {
|
||||||
|
parentCmd := &cobra.Command{Use: "toolbox"}
|
||||||
|
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
opts := internal.NewToolboxOptions(internal.WithIOStreams(buf, buf))
|
||||||
|
internal.PersistentFlags(parentCmd, opts)
|
||||||
|
|
||||||
|
cmd := NewCommand(opts)
|
||||||
|
parentCmd.AddCommand(cmd)
|
||||||
|
parentCmd.SetArgs(args)
|
||||||
|
|
||||||
|
err := parentCmd.Execute()
|
||||||
|
return buf.String(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGenerateSkill(t *testing.T) {
|
||||||
|
// Create a temporary directory for tests
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
outputDir := filepath.Join(tmpDir, "skills")
|
||||||
|
|
||||||
|
// Create a tools.yaml file with a sqlite tool
|
||||||
|
toolsFileContent := `
|
||||||
|
sources:
|
||||||
|
my-sqlite:
|
||||||
|
kind: sqlite
|
||||||
|
database: test.db
|
||||||
|
tools:
|
||||||
|
hello-sqlite:
|
||||||
|
kind: sqlite-sql
|
||||||
|
source: my-sqlite
|
||||||
|
description: "hello tool"
|
||||||
|
statement: "SELECT 'hello' as greeting"
|
||||||
|
`
|
||||||
|
|
||||||
|
toolsFilePath := filepath.Join(tmpDir, "tools.yaml")
|
||||||
|
if err := os.WriteFile(toolsFilePath, []byte(toolsFileContent), 0644); err != nil {
|
||||||
|
t.Fatalf("failed to write tools file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
args := []string{
|
||||||
|
"skills-generate",
|
||||||
|
"--tools-file", toolsFilePath,
|
||||||
|
"--output-dir", outputDir,
|
||||||
|
"--name", "hello-sqlite",
|
||||||
|
"--description", "hello tool",
|
||||||
|
}
|
||||||
|
|
||||||
|
got, err := invokeCommand(args)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("command failed: %v\nOutput: %s", err, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify generated directory structure
|
||||||
|
skillPath := filepath.Join(outputDir, "hello-sqlite")
|
||||||
|
if _, err := os.Stat(skillPath); os.IsNotExist(err) {
|
||||||
|
t.Fatalf("skill directory not created: %s", skillPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check SKILL.md
|
||||||
|
skillMarkdown := filepath.Join(skillPath, "SKILL.md")
|
||||||
|
content, err := os.ReadFile(skillMarkdown)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to read SKILL.md: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedFrontmatter := `---
|
||||||
|
name: hello-sqlite
|
||||||
|
description: hello tool
|
||||||
|
---`
|
||||||
|
if !strings.HasPrefix(string(content), expectedFrontmatter) {
|
||||||
|
t.Errorf("SKILL.md does not have expected frontmatter format.\nExpected prefix:\n%s\nGot:\n%s", expectedFrontmatter, string(content))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.Contains(string(content), "## Usage") {
|
||||||
|
t.Errorf("SKILL.md does not contain '## Usage' section")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.Contains(string(content), "## Scripts") {
|
||||||
|
t.Errorf("SKILL.md does not contain '## Scripts' section")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.Contains(string(content), "### hello-sqlite") {
|
||||||
|
t.Errorf("SKILL.md does not contain '### hello-sqlite' tool header")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check script file
|
||||||
|
scriptFilename := "hello-sqlite.js"
|
||||||
|
scriptPath := filepath.Join(skillPath, "scripts", scriptFilename)
|
||||||
|
if _, err := os.Stat(scriptPath); os.IsNotExist(err) {
|
||||||
|
t.Fatalf("script file not created: %s", scriptPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
scriptContent, err := os.ReadFile(scriptPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to read script file: %v", err)
|
||||||
|
}
|
||||||
|
if !strings.Contains(string(scriptContent), "hello-sqlite") {
|
||||||
|
t.Errorf("script file does not contain expected tool name")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check assets
|
||||||
|
assetPath := filepath.Join(skillPath, "assets", "hello-sqlite.yaml")
|
||||||
|
if _, err := os.Stat(assetPath); os.IsNotExist(err) {
|
||||||
|
t.Fatalf("asset file not created: %s", assetPath)
|
||||||
|
}
|
||||||
|
assetContent, err := os.ReadFile(assetPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to read asset file: %v", err)
|
||||||
|
}
|
||||||
|
if !strings.Contains(string(assetContent), "hello-sqlite") {
|
||||||
|
t.Errorf("asset file does not contain expected tool name")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGenerateSkill_NoConfig(t *testing.T) {
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
outputDir := filepath.Join(tmpDir, "skills")
|
||||||
|
|
||||||
|
args := []string{
|
||||||
|
"skills-generate",
|
||||||
|
"--output-dir", outputDir,
|
||||||
|
"--name", "test",
|
||||||
|
"--description", "test",
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := invokeCommand(args)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("expected command to fail when no configuration is provided and tools.yaml is missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should not have created the directory if no config was processed
|
||||||
|
if _, err := os.Stat(outputDir); !os.IsNotExist(err) {
|
||||||
|
t.Errorf("output directory should not have been created")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGenerateSkill_MissingArguments(t *testing.T) {
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
toolsFilePath := filepath.Join(tmpDir, "tools.yaml")
|
||||||
|
if err := os.WriteFile(toolsFilePath, []byte("tools: {}"), 0644); err != nil {
|
||||||
|
t.Fatalf("failed to write tools file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "missing name",
|
||||||
|
args: []string{"skills-generate", "--tools-file", toolsFilePath, "--description", "test"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "missing description",
|
||||||
|
args: []string{"skills-generate", "--tools-file", toolsFilePath, "--name", "test"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := invokeCommand(tt.args)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expected command to fail due to missing arguments, but it succeeded\nOutput: %s", got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
296
cmd/internal/skills/generator.go
Normal file
296
cmd/internal/skills/generator.go
Normal file
@@ -0,0 +1,296 @@
|
|||||||
|
// Copyright 2026 Google LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package skills
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/goccy/go-yaml"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/server"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/tools"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/util/parameters"
|
||||||
|
)
|
||||||
|
|
||||||
|
const skillTemplate = `---
|
||||||
|
name: {{.SkillName}}
|
||||||
|
description: {{.SkillDescription}}
|
||||||
|
---
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
All scripts can be executed using Node.js. Replace ` + "`" + `<param_name>` + "`" + ` and ` + "`" + `<param_value>` + "`" + ` with actual values.
|
||||||
|
|
||||||
|
**Bash:**
|
||||||
|
` + "`" + `node scripts/<script_name>.js '{"<param_name>": "<param_value>"}'` + "`" + `
|
||||||
|
|
||||||
|
**PowerShell:**
|
||||||
|
` + "`" + `node scripts/<script_name>.js '{\"<param_name>\": \"<param_value>\"}'` + "`" + `
|
||||||
|
|
||||||
|
## Scripts
|
||||||
|
|
||||||
|
{{range .Tools}}
|
||||||
|
### {{.Name}}
|
||||||
|
|
||||||
|
{{.Description}}
|
||||||
|
|
||||||
|
{{.ParametersSchema}}
|
||||||
|
|
||||||
|
---
|
||||||
|
{{end}}
|
||||||
|
`
|
||||||
|
|
||||||
|
type toolTemplateData struct {
|
||||||
|
Name string
|
||||||
|
Description string
|
||||||
|
ParametersSchema string
|
||||||
|
}
|
||||||
|
|
||||||
|
type skillTemplateData struct {
|
||||||
|
SkillName string
|
||||||
|
SkillDescription string
|
||||||
|
Tools []toolTemplateData
|
||||||
|
}
|
||||||
|
|
||||||
|
// generateSkillMarkdown generates the content of the SKILL.md file.
|
||||||
|
// It includes usage instructions and a reference section for each tool in the skill,
|
||||||
|
// detailing its description and parameters.
|
||||||
|
func generateSkillMarkdown(skillName, skillDescription string, toolsMap map[string]tools.Tool) (string, error) {
|
||||||
|
var toolsData []toolTemplateData
|
||||||
|
|
||||||
|
// Order tools based on name
|
||||||
|
var toolNames []string
|
||||||
|
for name := range toolsMap {
|
||||||
|
toolNames = append(toolNames, name)
|
||||||
|
}
|
||||||
|
sort.Strings(toolNames)
|
||||||
|
|
||||||
|
for _, name := range toolNames {
|
||||||
|
tool := toolsMap[name]
|
||||||
|
manifest := tool.Manifest()
|
||||||
|
|
||||||
|
parametersSchema, err := formatParameters(manifest.Parameters)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
toolsData = append(toolsData, toolTemplateData{
|
||||||
|
Name: name,
|
||||||
|
Description: manifest.Description,
|
||||||
|
ParametersSchema: parametersSchema,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
data := skillTemplateData{
|
||||||
|
SkillName: skillName,
|
||||||
|
SkillDescription: skillDescription,
|
||||||
|
Tools: toolsData,
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl, err := template.New("markdown").Parse(skillTemplate)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("error parsing markdown template: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf strings.Builder
|
||||||
|
if err := tmpl.Execute(&buf, data); err != nil {
|
||||||
|
return "", fmt.Errorf("error executing markdown template: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const nodeScriptTemplate = `#!/usr/bin/env node
|
||||||
|
|
||||||
|
const { spawn, execSync } = require('child_process');
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const toolName = "{{.Name}}";
|
||||||
|
const toolsFileName = "{{.ToolsFileName}}";
|
||||||
|
|
||||||
|
function getToolboxPath() {
|
||||||
|
try {
|
||||||
|
const checkCommand = process.platform === 'win32' ? 'where toolbox' : 'which toolbox';
|
||||||
|
const globalPath = execSync(checkCommand, { stdio: 'pipe', encoding: 'utf-8' }).trim();
|
||||||
|
if (globalPath) {
|
||||||
|
return globalPath.split('\n')[0].trim();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore error;
|
||||||
|
}
|
||||||
|
const localPath = path.resolve(__dirname, '../../../toolbox');
|
||||||
|
if (fs.existsSync(localPath)) {
|
||||||
|
return localPath;
|
||||||
|
}
|
||||||
|
throw new Error("Toolbox binary not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
let toolboxBinary;
|
||||||
|
try {
|
||||||
|
toolboxBinary = getToolboxPath();
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error:", err.message);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let configArgs = [];
|
||||||
|
if (toolsFileName) {
|
||||||
|
configArgs.push("--tools-file", path.join(__dirname, "..", "assets", toolsFileName));
|
||||||
|
}
|
||||||
|
|
||||||
|
const args = process.argv.slice(2);
|
||||||
|
const toolboxArgs = [...configArgs, "invoke", toolName, ...args];
|
||||||
|
|
||||||
|
const child = spawn(toolboxBinary, toolboxArgs, { stdio: 'inherit' });
|
||||||
|
|
||||||
|
child.on('close', (code) => {
|
||||||
|
process.exit(code);
|
||||||
|
});
|
||||||
|
|
||||||
|
child.on('error', (err) => {
|
||||||
|
console.error("Error executing toolbox:", err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
`
|
||||||
|
|
||||||
|
type scriptData struct {
|
||||||
|
Name string
|
||||||
|
ToolsFileName string
|
||||||
|
}
|
||||||
|
|
||||||
|
// generateScriptContent creates the content for a Node.js wrapper script.
|
||||||
|
// This script invokes the toolbox CLI with the appropriate configuration
|
||||||
|
// (using a generated tools file) and arguments to execute the specific tool.
|
||||||
|
func generateScriptContent(name string, toolsFileName string) (string, error) {
|
||||||
|
data := scriptData{
|
||||||
|
Name: name,
|
||||||
|
ToolsFileName: toolsFileName,
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl, err := template.New("script").Parse(nodeScriptTemplate)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("error parsing script template: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf strings.Builder
|
||||||
|
if err := tmpl.Execute(&buf, data); err != nil {
|
||||||
|
return "", fmt.Errorf("error executing script template: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// formatParameters converts a list of parameter manifests into a formatted JSON schema string.
|
||||||
|
// This schema is used in the skill documentation to describe the input parameters for a tool.
|
||||||
|
func formatParameters(params []parameters.ParameterManifest) (string, error) {
|
||||||
|
if len(params) == 0 {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
properties := make(map[string]interface{})
|
||||||
|
var required []string
|
||||||
|
|
||||||
|
for _, p := range params {
|
||||||
|
paramMap := map[string]interface{}{
|
||||||
|
"type": p.Type,
|
||||||
|
"description": p.Description,
|
||||||
|
}
|
||||||
|
if p.Default != nil {
|
||||||
|
paramMap["default"] = p.Default
|
||||||
|
}
|
||||||
|
properties[p.Name] = paramMap
|
||||||
|
if p.Required {
|
||||||
|
required = append(required, p.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
schema := map[string]interface{}{
|
||||||
|
"type": "object",
|
||||||
|
"properties": properties,
|
||||||
|
}
|
||||||
|
if len(required) > 0 {
|
||||||
|
schema["required"] = required
|
||||||
|
}
|
||||||
|
|
||||||
|
schemaJSON, err := json.MarshalIndent(schema, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("error generating parameters schema: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("#### Parameters\n\n```json\n%s\n```", string(schemaJSON)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// generateToolConfigYAML generates the YAML configuration for a single tool and its dependency (source).
|
||||||
|
// It extracts the relevant tool and source configurations from the server config and formats them
|
||||||
|
// into a YAML document suitable for inclusion in the skill's assets.
|
||||||
|
func generateToolConfigYAML(cfg server.ServerConfig, toolName string) ([]byte, error) {
|
||||||
|
toolCfg, ok := cfg.ToolConfigs[toolName]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("error finding tool config: %s", toolName)
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
encoder := yaml.NewEncoder(&buf)
|
||||||
|
|
||||||
|
// Process Tool Config
|
||||||
|
toolWrapper := struct {
|
||||||
|
Kind string `yaml:"kind"`
|
||||||
|
Config tools.ToolConfig `yaml:",inline"`
|
||||||
|
}{
|
||||||
|
Kind: "tools",
|
||||||
|
Config: toolCfg,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := encoder.Encode(toolWrapper); err != nil {
|
||||||
|
return nil, fmt.Errorf("error encoding tool config: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process Source Config
|
||||||
|
var toolMap map[string]interface{}
|
||||||
|
b, err := yaml.Marshal(toolCfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error marshaling tool config: %w", err)
|
||||||
|
}
|
||||||
|
if err := yaml.Unmarshal(b, &toolMap); err != nil {
|
||||||
|
return nil, fmt.Errorf("error unmarshaling tool config map: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if sourceName, ok := toolMap["source"].(string); ok && sourceName != "" {
|
||||||
|
sourceCfg, ok := cfg.SourceConfigs[sourceName]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("error finding source config: %s", sourceName)
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceWrapper := struct {
|
||||||
|
Kind string `yaml:"kind"`
|
||||||
|
Config sources.SourceConfig `yaml:",inline"`
|
||||||
|
}{
|
||||||
|
Kind: "sources",
|
||||||
|
Config: sourceCfg,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := encoder.Encode(sourceWrapper); err != nil {
|
||||||
|
return nil, fmt.Errorf("error encoding source config: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
347
cmd/internal/skills/generator_test.go
Normal file
347
cmd/internal/skills/generator_test.go
Normal file
@@ -0,0 +1,347 @@
|
|||||||
|
// Copyright 2026 Google LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package skills
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/server"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/tools"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/util/parameters"
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MockToolConfig struct {
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
Type string `yaml:"type"`
|
||||||
|
Source string `yaml:"source"`
|
||||||
|
Other string `yaml:"other"`
|
||||||
|
Parameters parameters.Parameters `yaml:"parameters"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m MockToolConfig) ToolConfigType() string {
|
||||||
|
return m.Type
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m MockToolConfig) Initialize(map[string]sources.Source) (tools.Tool, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type MockSourceConfig struct {
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
Type string `yaml:"type"`
|
||||||
|
ConnectionString string `yaml:"connection_string"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m MockSourceConfig) SourceConfigType() string {
|
||||||
|
return m.Type
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m MockSourceConfig) Initialize(context.Context, trace.Tracer) (sources.Source, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFormatParameters(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
params []parameters.ParameterManifest
|
||||||
|
wantContains []string
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "empty parameters",
|
||||||
|
params: []parameters.ParameterManifest{},
|
||||||
|
wantContains: []string{""},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single required string parameter",
|
||||||
|
params: []parameters.ParameterManifest{
|
||||||
|
{
|
||||||
|
Name: "param1",
|
||||||
|
Description: "A test parameter",
|
||||||
|
Type: "string",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantContains: []string{
|
||||||
|
"## Parameters",
|
||||||
|
"```json",
|
||||||
|
`"type": "object"`,
|
||||||
|
`"properties": {`,
|
||||||
|
`"param1": {`,
|
||||||
|
`"type": "string"`,
|
||||||
|
`"description": "A test parameter"`,
|
||||||
|
`"required": [`,
|
||||||
|
`"param1"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "mixed parameters with defaults",
|
||||||
|
params: []parameters.ParameterManifest{
|
||||||
|
{
|
||||||
|
Name: "param1",
|
||||||
|
Description: "Param 1",
|
||||||
|
Type: "string",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "param2",
|
||||||
|
Description: "Param 2",
|
||||||
|
Type: "integer",
|
||||||
|
Default: 42,
|
||||||
|
Required: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantContains: []string{
|
||||||
|
`"param1": {`,
|
||||||
|
`"param2": {`,
|
||||||
|
`"default": 42`,
|
||||||
|
`"required": [`,
|
||||||
|
`"param1"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := formatParameters(tt.params)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("formatParameters() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if tt.wantErr {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(tt.params) == 0 {
|
||||||
|
if got != "" {
|
||||||
|
t.Errorf("formatParameters() = %v, want empty string", got)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, want := range tt.wantContains {
|
||||||
|
if !strings.Contains(got, want) {
|
||||||
|
t.Errorf("formatParameters() result missing expected string: %s\nGot:\n%s", want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGenerateSkillMarkdown(t *testing.T) {
|
||||||
|
toolsMap := map[string]tools.Tool{
|
||||||
|
"tool1": server.MockTool{
|
||||||
|
Description: "First tool",
|
||||||
|
Params: []parameters.Parameter{
|
||||||
|
parameters.NewStringParameter("p1", "d1"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
got, err := generateSkillMarkdown("MySkill", "My Description", toolsMap)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("generateSkillMarkdown() error = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedSubstrings := []string{
|
||||||
|
"name: MySkill",
|
||||||
|
"description: My Description",
|
||||||
|
"## Usage",
|
||||||
|
"All scripts can be executed using Node.js",
|
||||||
|
"**Bash:**",
|
||||||
|
"`node scripts/<script_name>.js '{\"<param_name>\": \"<param_value>\"}'`",
|
||||||
|
"**PowerShell:**",
|
||||||
|
"`node scripts/<script_name>.js '{\"<param_name>\": \"<param_value>\"}'`",
|
||||||
|
"## Scripts",
|
||||||
|
"### tool1",
|
||||||
|
"First tool",
|
||||||
|
"## Parameters",
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range expectedSubstrings {
|
||||||
|
if !strings.Contains(got, s) {
|
||||||
|
t.Errorf("generateSkillMarkdown() missing substring %q", s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGenerateScriptContent(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
toolName string
|
||||||
|
toolsFileName string
|
||||||
|
wantContains []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "basic script",
|
||||||
|
toolName: "test-tool",
|
||||||
|
toolsFileName: "",
|
||||||
|
wantContains: []string{
|
||||||
|
`const toolName = "test-tool";`,
|
||||||
|
`const toolsFileName = "";`,
|
||||||
|
`const toolboxArgs = [...configArgs, "invoke", toolName, ...args];`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "script with tools file",
|
||||||
|
toolName: "complex-tool",
|
||||||
|
toolsFileName: "tools.yaml",
|
||||||
|
wantContains: []string{
|
||||||
|
`const toolName = "complex-tool";`,
|
||||||
|
`const toolsFileName = "tools.yaml";`,
|
||||||
|
`configArgs.push("--tools-file", path.join(__dirname, "..", "assets", toolsFileName));`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := generateScriptContent(tt.toolName, tt.toolsFileName)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("generateScriptContent() error = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range tt.wantContains {
|
||||||
|
if !strings.Contains(got, s) {
|
||||||
|
t.Errorf("generateScriptContent() missing substring %q\nGot:\n%s", s, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGenerateToolConfigYAML(t *testing.T) {
|
||||||
|
cfg := server.ServerConfig{
|
||||||
|
ToolConfigs: server.ToolConfigs{
|
||||||
|
"tool1": MockToolConfig{
|
||||||
|
Name: "tool1",
|
||||||
|
Type: "custom-tool",
|
||||||
|
Source: "src1",
|
||||||
|
Other: "foo",
|
||||||
|
},
|
||||||
|
"toolNoSource": MockToolConfig{
|
||||||
|
Name: "toolNoSource",
|
||||||
|
Type: "http",
|
||||||
|
},
|
||||||
|
"toolWithParams": MockToolConfig{
|
||||||
|
Name: "toolWithParams",
|
||||||
|
Type: "custom-tool",
|
||||||
|
Parameters: []parameters.Parameter{
|
||||||
|
parameters.NewStringParameter("param1", "desc1"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"toolWithMissingSource": MockToolConfig{
|
||||||
|
Name: "toolWithMissingSource",
|
||||||
|
Type: "custom-tool",
|
||||||
|
Source: "missing-src",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SourceConfigs: server.SourceConfigs{
|
||||||
|
"src1": MockSourceConfig{
|
||||||
|
Name: "src1",
|
||||||
|
Type: "postgres",
|
||||||
|
ConnectionString: "conn1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
toolName string
|
||||||
|
wantContains []string
|
||||||
|
wantErr bool
|
||||||
|
wantNil bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "tool with source",
|
||||||
|
toolName: "tool1",
|
||||||
|
wantContains: []string{
|
||||||
|
"kind: tools",
|
||||||
|
"name: tool1",
|
||||||
|
"type: custom-tool",
|
||||||
|
"source: src1",
|
||||||
|
"other: foo",
|
||||||
|
"---",
|
||||||
|
"kind: sources",
|
||||||
|
"name: src1",
|
||||||
|
"type: postgres",
|
||||||
|
"connection_string: conn1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "tool without source",
|
||||||
|
toolName: "toolNoSource",
|
||||||
|
wantContains: []string{
|
||||||
|
"kind: tools",
|
||||||
|
"name: toolNoSource",
|
||||||
|
"type: http",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "tool with parameters",
|
||||||
|
toolName: "toolWithParams",
|
||||||
|
wantContains: []string{
|
||||||
|
"kind: tools",
|
||||||
|
"name: toolWithParams",
|
||||||
|
"type: custom-tool",
|
||||||
|
"parameters:",
|
||||||
|
"- name: param1",
|
||||||
|
"type: string",
|
||||||
|
"description: desc1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "non-existent tool",
|
||||||
|
toolName: "missing-tool",
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "tool with missing source config",
|
||||||
|
toolName: "toolWithMissingSource",
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
gotBytes, err := generateToolConfigYAML(cfg, tt.toolName)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("generateToolConfigYAML() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if tt.wantErr {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.wantNil {
|
||||||
|
if gotBytes != nil {
|
||||||
|
t.Errorf("generateToolConfigYAML() expected nil, got %s", string(gotBytes))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
got := string(gotBytes)
|
||||||
|
for _, want := range tt.wantContains {
|
||||||
|
if !strings.Contains(got, want) {
|
||||||
|
t.Errorf("generateToolConfigYAML() result missing expected string: %q\nGot:\n%s", want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
349
cmd/internal/tools_file.go
Normal file
349
cmd/internal/tools_file.go
Normal file
@@ -0,0 +1,349 @@
|
|||||||
|
// Copyright 2026 Google LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/goccy/go-yaml"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/server"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ToolsFile struct {
|
||||||
|
Sources server.SourceConfigs `yaml:"sources"`
|
||||||
|
AuthServices server.AuthServiceConfigs `yaml:"authServices"`
|
||||||
|
EmbeddingModels server.EmbeddingModelConfigs `yaml:"embeddingModels"`
|
||||||
|
Tools server.ToolConfigs `yaml:"tools"`
|
||||||
|
Toolsets server.ToolsetConfigs `yaml:"toolsets"`
|
||||||
|
Prompts server.PromptConfigs `yaml:"prompts"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseEnv replaces environment variables ${ENV_NAME} with their values.
|
||||||
|
// also support ${ENV_NAME:default_value}.
|
||||||
|
func parseEnv(input string) (string, error) {
|
||||||
|
re := regexp.MustCompile(`\$\{(\w+)(:([^}]*))?\}`)
|
||||||
|
|
||||||
|
var err error
|
||||||
|
output := re.ReplaceAllStringFunc(input, func(match string) string {
|
||||||
|
parts := re.FindStringSubmatch(match)
|
||||||
|
|
||||||
|
// extract the variable name
|
||||||
|
variableName := parts[1]
|
||||||
|
if value, found := os.LookupEnv(variableName); found {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
if len(parts) >= 4 && parts[2] != "" {
|
||||||
|
return parts[3]
|
||||||
|
}
|
||||||
|
err = fmt.Errorf("environment variable not found: %q", variableName)
|
||||||
|
return ""
|
||||||
|
})
|
||||||
|
return output, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseToolsFile parses the provided yaml into appropriate configs.
|
||||||
|
func parseToolsFile(ctx context.Context, raw []byte) (ToolsFile, error) {
|
||||||
|
var toolsFile ToolsFile
|
||||||
|
// Replace environment variables if found
|
||||||
|
output, err := parseEnv(string(raw))
|
||||||
|
if err != nil {
|
||||||
|
return toolsFile, fmt.Errorf("error parsing environment variables: %s", err)
|
||||||
|
}
|
||||||
|
raw = []byte(output)
|
||||||
|
|
||||||
|
raw, err = convertToolsFile(raw)
|
||||||
|
if err != nil {
|
||||||
|
return toolsFile, fmt.Errorf("error converting tools file: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse contents
|
||||||
|
toolsFile.Sources, toolsFile.AuthServices, toolsFile.EmbeddingModels, toolsFile.Tools, toolsFile.Toolsets, toolsFile.Prompts, err = server.UnmarshalResourceConfig(ctx, raw)
|
||||||
|
if err != nil {
|
||||||
|
return toolsFile, err
|
||||||
|
}
|
||||||
|
return toolsFile, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertToolsFile(raw []byte) ([]byte, error) {
|
||||||
|
var input yaml.MapSlice
|
||||||
|
decoder := yaml.NewDecoder(bytes.NewReader(raw), yaml.UseOrderedMap())
|
||||||
|
|
||||||
|
// convert to tools file v2
|
||||||
|
var buf bytes.Buffer
|
||||||
|
encoder := yaml.NewEncoder(&buf)
|
||||||
|
|
||||||
|
v1keys := []string{"sources", "authSources", "authServices", "embeddingModels", "tools", "toolsets", "prompts"}
|
||||||
|
for {
|
||||||
|
if err := decoder.Decode(&input); err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, item := range input {
|
||||||
|
key, ok := item.Key.(string)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("unexpected non-string key in input: %v", item.Key)
|
||||||
|
}
|
||||||
|
// check if the key is config file v1's key
|
||||||
|
if slices.Contains(v1keys, key) {
|
||||||
|
// check if value conversion to yaml.MapSlice successfully
|
||||||
|
// fields such as "tools" in toolsets might pass the first check but
|
||||||
|
// fail to convert to MapSlice
|
||||||
|
if slice, ok := item.Value.(yaml.MapSlice); ok {
|
||||||
|
// Deprecated: convert authSources to authServices
|
||||||
|
if key == "authSources" {
|
||||||
|
key = "authServices"
|
||||||
|
}
|
||||||
|
transformed, err := transformDocs(key, slice)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// encode per-doc
|
||||||
|
for _, doc := range transformed {
|
||||||
|
if err := encoder.Encode(doc); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// invalid input will be ignored
|
||||||
|
// we don't want to throw error here since the config could
|
||||||
|
// be valid but with a different order such as:
|
||||||
|
// ---
|
||||||
|
// tools:
|
||||||
|
// - tool_a
|
||||||
|
// kind: toolsets
|
||||||
|
// ---
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// this doc is already v2, encode to buf
|
||||||
|
if err := encoder.Encode(input); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// transformDocs transforms the configuration file from v1 format to v2
|
||||||
|
// yaml.MapSlice will preserve the order in a map
|
||||||
|
func transformDocs(kind string, input yaml.MapSlice) ([]yaml.MapSlice, error) {
|
||||||
|
var transformed []yaml.MapSlice
|
||||||
|
for _, entry := range input {
|
||||||
|
entryName, ok := entry.Key.(string)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("unexpected non-string key for entry in '%s': %v", kind, entry.Key)
|
||||||
|
}
|
||||||
|
entryBody := ProcessValue(entry.Value, kind == "toolsets")
|
||||||
|
|
||||||
|
currentTransformed := yaml.MapSlice{
|
||||||
|
{Key: "kind", Value: kind},
|
||||||
|
{Key: "name", Value: entryName},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge the transformed body into our result
|
||||||
|
if bodySlice, ok := entryBody.(yaml.MapSlice); ok {
|
||||||
|
currentTransformed = append(currentTransformed, bodySlice...)
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("unable to convert entryBody to MapSlice")
|
||||||
|
}
|
||||||
|
transformed = append(transformed, currentTransformed)
|
||||||
|
}
|
||||||
|
return transformed, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProcessValue recursively looks for MapSlices to rename 'kind' -> 'type'
|
||||||
|
func ProcessValue(v any, isToolset bool) any {
|
||||||
|
switch val := v.(type) {
|
||||||
|
case yaml.MapSlice:
|
||||||
|
// creating a new MapSlice is safer for recursive transformation
|
||||||
|
newVal := make(yaml.MapSlice, len(val))
|
||||||
|
for i, item := range val {
|
||||||
|
// Perform renaming
|
||||||
|
if item.Key == "kind" {
|
||||||
|
item.Key = "type"
|
||||||
|
}
|
||||||
|
// Recursive call for nested values (e.g., nested objects or lists)
|
||||||
|
item.Value = ProcessValue(item.Value, false)
|
||||||
|
newVal[i] = item
|
||||||
|
}
|
||||||
|
return newVal
|
||||||
|
case []any:
|
||||||
|
// Process lists: If it's a toolset top-level list, wrap it.
|
||||||
|
if isToolset {
|
||||||
|
return yaml.MapSlice{{Key: "tools", Value: val}}
|
||||||
|
}
|
||||||
|
// Otherwise, recurse into list items (to catch nested objects)
|
||||||
|
newVal := make([]any, len(val))
|
||||||
|
for i := range val {
|
||||||
|
newVal[i] = ProcessValue(val[i], false)
|
||||||
|
}
|
||||||
|
return newVal
|
||||||
|
default:
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mergeToolsFiles merges multiple ToolsFile structs into one.
|
||||||
|
// Detects and raises errors for resource conflicts in sources, authServices, tools, and toolsets.
|
||||||
|
// All resource names (sources, authServices, tools, toolsets) must be unique across all files.
|
||||||
|
func mergeToolsFiles(files ...ToolsFile) (ToolsFile, error) {
|
||||||
|
merged := ToolsFile{
|
||||||
|
Sources: make(server.SourceConfigs),
|
||||||
|
AuthServices: make(server.AuthServiceConfigs),
|
||||||
|
EmbeddingModels: make(server.EmbeddingModelConfigs),
|
||||||
|
Tools: make(server.ToolConfigs),
|
||||||
|
Toolsets: make(server.ToolsetConfigs),
|
||||||
|
Prompts: make(server.PromptConfigs),
|
||||||
|
}
|
||||||
|
|
||||||
|
var conflicts []string
|
||||||
|
|
||||||
|
for fileIndex, file := range files {
|
||||||
|
// Check for conflicts and merge sources
|
||||||
|
for name, source := range file.Sources {
|
||||||
|
if _, exists := merged.Sources[name]; exists {
|
||||||
|
conflicts = append(conflicts, fmt.Sprintf("source '%s' (file #%d)", name, fileIndex+1))
|
||||||
|
} else {
|
||||||
|
merged.Sources[name] = source
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for conflicts and merge authServices
|
||||||
|
for name, authService := range file.AuthServices {
|
||||||
|
if _, exists := merged.AuthServices[name]; exists {
|
||||||
|
conflicts = append(conflicts, fmt.Sprintf("authService '%s' (file #%d)", name, fileIndex+1))
|
||||||
|
} else {
|
||||||
|
merged.AuthServices[name] = authService
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for conflicts and merge embeddingModels
|
||||||
|
for name, em := range file.EmbeddingModels {
|
||||||
|
if _, exists := merged.EmbeddingModels[name]; exists {
|
||||||
|
conflicts = append(conflicts, fmt.Sprintf("embedding model '%s' (file #%d)", name, fileIndex+1))
|
||||||
|
} else {
|
||||||
|
merged.EmbeddingModels[name] = em
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for conflicts and merge tools
|
||||||
|
for name, tool := range file.Tools {
|
||||||
|
if _, exists := merged.Tools[name]; exists {
|
||||||
|
conflicts = append(conflicts, fmt.Sprintf("tool '%s' (file #%d)", name, fileIndex+1))
|
||||||
|
} else {
|
||||||
|
merged.Tools[name] = tool
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for conflicts and merge toolsets
|
||||||
|
for name, toolset := range file.Toolsets {
|
||||||
|
if _, exists := merged.Toolsets[name]; exists {
|
||||||
|
conflicts = append(conflicts, fmt.Sprintf("toolset '%s' (file #%d)", name, fileIndex+1))
|
||||||
|
} else {
|
||||||
|
merged.Toolsets[name] = toolset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for conflicts and merge prompts
|
||||||
|
for name, prompt := range file.Prompts {
|
||||||
|
if _, exists := merged.Prompts[name]; exists {
|
||||||
|
conflicts = append(conflicts, fmt.Sprintf("prompt '%s' (file #%d)", name, fileIndex+1))
|
||||||
|
} else {
|
||||||
|
merged.Prompts[name] = prompt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If conflicts were detected, return an error
|
||||||
|
if len(conflicts) > 0 {
|
||||||
|
return ToolsFile{}, fmt.Errorf("resource conflicts detected:\n - %s\n\nPlease ensure each source, authService, tool, toolset and prompt has a unique name across all files", strings.Join(conflicts, "\n - "))
|
||||||
|
}
|
||||||
|
|
||||||
|
return merged, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadAndMergeToolsFiles loads multiple YAML files and merges them
|
||||||
|
func LoadAndMergeToolsFiles(ctx context.Context, filePaths []string) (ToolsFile, error) {
|
||||||
|
var toolsFiles []ToolsFile
|
||||||
|
|
||||||
|
for _, filePath := range filePaths {
|
||||||
|
buf, err := os.ReadFile(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return ToolsFile{}, fmt.Errorf("unable to read tool file at %q: %w", filePath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
toolsFile, err := parseToolsFile(ctx, buf)
|
||||||
|
if err != nil {
|
||||||
|
return ToolsFile{}, fmt.Errorf("unable to parse tool file at %q: %w", filePath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
toolsFiles = append(toolsFiles, toolsFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
mergedFile, err := mergeToolsFiles(toolsFiles...)
|
||||||
|
if err != nil {
|
||||||
|
return ToolsFile{}, fmt.Errorf("unable to merge tools files: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return mergedFile, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadAndMergeToolsFolder loads all YAML files from a directory and merges them
|
||||||
|
func LoadAndMergeToolsFolder(ctx context.Context, folderPath string) (ToolsFile, error) {
|
||||||
|
// Check if directory exists
|
||||||
|
info, err := os.Stat(folderPath)
|
||||||
|
if err != nil {
|
||||||
|
return ToolsFile{}, fmt.Errorf("unable to access tools folder at %q: %w", folderPath, err)
|
||||||
|
}
|
||||||
|
if !info.IsDir() {
|
||||||
|
return ToolsFile{}, fmt.Errorf("path %q is not a directory", folderPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find all YAML files in the directory
|
||||||
|
pattern := filepath.Join(folderPath, "*.yaml")
|
||||||
|
yamlFiles, err := filepath.Glob(pattern)
|
||||||
|
if err != nil {
|
||||||
|
return ToolsFile{}, fmt.Errorf("error finding YAML files in %q: %w", folderPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also find .yml files
|
||||||
|
ymlPattern := filepath.Join(folderPath, "*.yml")
|
||||||
|
ymlFiles, err := filepath.Glob(ymlPattern)
|
||||||
|
if err != nil {
|
||||||
|
return ToolsFile{}, fmt.Errorf("error finding YML files in %q: %w", folderPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combine both file lists
|
||||||
|
allFiles := append(yamlFiles, ymlFiles...)
|
||||||
|
|
||||||
|
if len(allFiles) == 0 {
|
||||||
|
return ToolsFile{}, fmt.Errorf("no YAML files found in directory %q", folderPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use existing LoadAndMergeToolsFiles function
|
||||||
|
return LoadAndMergeToolsFiles(ctx, allFiles)
|
||||||
|
}
|
||||||
2141
cmd/internal/tools_file_test.go
Normal file
2141
cmd/internal/tools_file_test.go
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,30 +0,0 @@
|
|||||||
// Copyright 2024 Google LLC
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Option is a function that configures a Command.
|
|
||||||
type Option func(*Command)
|
|
||||||
|
|
||||||
// WithStreams overrides the default writer.
|
|
||||||
func WithStreams(out, err io.Writer) Option {
|
|
||||||
return func(c *Command) {
|
|
||||||
c.outStream = out
|
|
||||||
c.errStream = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
708
cmd/root.go
708
cmd/root.go
@@ -23,7 +23,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -31,230 +30,18 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fsnotify/fsnotify"
|
"github.com/fsnotify/fsnotify"
|
||||||
yaml "github.com/goccy/go-yaml"
|
// Importing the cmd/internal package also import packages for side effect of registration
|
||||||
|
"github.com/googleapis/genai-toolbox/cmd/internal"
|
||||||
|
"github.com/googleapis/genai-toolbox/cmd/internal/invoke"
|
||||||
|
"github.com/googleapis/genai-toolbox/cmd/internal/skills"
|
||||||
"github.com/googleapis/genai-toolbox/internal/auth"
|
"github.com/googleapis/genai-toolbox/internal/auth"
|
||||||
"github.com/googleapis/genai-toolbox/internal/log"
|
"github.com/googleapis/genai-toolbox/internal/embeddingmodels"
|
||||||
"github.com/googleapis/genai-toolbox/internal/prebuiltconfigs"
|
|
||||||
"github.com/googleapis/genai-toolbox/internal/prompts"
|
"github.com/googleapis/genai-toolbox/internal/prompts"
|
||||||
"github.com/googleapis/genai-toolbox/internal/server"
|
"github.com/googleapis/genai-toolbox/internal/server"
|
||||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||||
"github.com/googleapis/genai-toolbox/internal/telemetry"
|
|
||||||
"github.com/googleapis/genai-toolbox/internal/tools"
|
"github.com/googleapis/genai-toolbox/internal/tools"
|
||||||
"github.com/googleapis/genai-toolbox/internal/util"
|
"github.com/googleapis/genai-toolbox/internal/util"
|
||||||
|
|
||||||
// Import prompt packages for side effect of registration
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/prompts/custom"
|
|
||||||
|
|
||||||
// Import tool packages for side effect of registration
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydbcreatecluster"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydbcreateinstance"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydbcreateuser"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydbgetcluster"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydbgetinstance"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydbgetuser"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydblistclusters"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydblistinstances"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydblistusers"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydb/alloydbwaitforoperation"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/alloydbainl"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigqueryanalyzecontribution"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigqueryconversationalanalytics"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigqueryexecutesql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigqueryforecast"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigquerygetdatasetinfo"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigquerygettableinfo"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigquerylistdatasetids"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigquerylisttableids"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigquerysearchcatalog"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/bigquery/bigquerysql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/bigtable"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cassandra/cassandracql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/clickhouse/clickhouseexecutesql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/clickhouse/clickhouselistdatabases"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/clickhouse/clickhouselisttables"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/clickhouse/clickhousesql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcarefhirfetchpage"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcarefhirpatienteverything"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcarefhirpatientsearch"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaregetdataset"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstore"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaregetdicomstoremetrics"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaregetfhirresource"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstore"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaregetfhirstoremetrics"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcarelistdicomstores"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcarelistfhirstores"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcareretrieverendereddicominstance"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaresearchdicominstances"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomseries"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudhealthcare/cloudhealthcaresearchdicomstudies"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudmonitoring"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsql/cloudsqlcloneinstance"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsql/cloudsqlcreatedatabase"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsql/cloudsqlcreateusers"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsql/cloudsqlgetinstances"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsql/cloudsqllistdatabases"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsql/cloudsqllistinstances"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsql/cloudsqlwaitforoperation"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsqlmssql/cloudsqlmssqlcreateinstance"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsqlmysql/cloudsqlmysqlcreateinstance"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsqlpg/cloudsqlpgcreateinstances"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/cloudsqlpg/cloudsqlpgupgradeprecheck"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/couchbase"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/dataform/dataformcompilelocal"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/dataplex/dataplexlookupentry"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/dataplex/dataplexsearchaspecttypes"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/dataplex/dataplexsearchentries"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/dgraph"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/elasticsearch/elasticsearchesql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/firebird/firebirdexecutesql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/firebird/firebirdsql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/firestore/firestoreadddocuments"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/firestore/firestoredeletedocuments"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/firestore/firestoregetdocuments"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/firestore/firestoregetrules"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/firestore/firestorelistcollections"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/firestore/firestorequery"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/firestore/firestorequerycollection"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/firestore/firestoreupdatedocument"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/firestore/firestorevalidaterules"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/http"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookeradddashboardelement"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerconversationalanalytics"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookercreateprojectfile"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerdeleteprojectfile"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerdevmode"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergenerateembedurl"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetconnectiondatabases"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetconnections"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetconnectionschemas"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetconnectiontablecolumns"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetconnectiontables"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetdashboards"
|
|
||||||
_ "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/lookergetlooks"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetmeasures"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetmodels"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetparameters"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetprojectfile"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetprojectfiles"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookergetprojects"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerhealthanalyze"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerhealthpulse"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerhealthvacuum"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookermakedashboard"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookermakelook"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerquery"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerquerysql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerqueryurl"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerrundashboard"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerrunlook"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerupdateprojectfile"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mindsdb/mindsdbexecutesql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mindsdb/mindsdbsql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbaggregate"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbdeletemany"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbdeleteone"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbfind"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbfindone"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbinsertmany"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbinsertone"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbupdatemany"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbupdateone"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mssql/mssqlexecutesql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mssql/mssqllisttables"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mssql/mssqlsql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqlexecutesql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqllistactivequeries"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqllisttablefragmentation"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqllisttables"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqllisttablesmissinguniqueindexes"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mysql/mysqlsql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/neo4j/neo4jcypher"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/neo4j/neo4jexecutecypher"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/neo4j/neo4jschema"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/oceanbase/oceanbaseexecutesql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/oceanbase/oceanbasesql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/oracle/oracleexecutesql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/oracle/oraclesql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgresdatabaseoverview"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgresexecutesql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgresgetcolumncardinality"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistactivequeries"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistavailableextensions"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistindexes"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistinstalledextensions"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistlocks"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistquerystats"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistschemas"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistsequences"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslisttables"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslisttriggers"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslistviews"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgreslongrunningtransactions"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgresreplicationstats"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/postgres/postgressql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/redis"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/serverlessspark/serverlesssparkcancelbatch"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/serverlessspark/serverlesssparkgetbatch"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/serverlessspark/serverlesssparklistbatches"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/singlestore/singlestoreexecutesql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/singlestore/singlestoresql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/spanner/spannerexecutesql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/spanner/spannerlistgraphs"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/spanner/spannerlisttables"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/spanner/spannersql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/sqlite/sqliteexecutesql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/sqlite/sqlitesql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/tidb/tidbexecutesql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/tidb/tidbsql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/trino/trinoexecutesql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/trino/trinosql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/utility/wait"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/valkey"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/yugabytedbsql"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/alloydbadmin"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/alloydbpg"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/bigquery"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/bigtable"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/cassandra"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/clickhouse"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/cloudhealthcare"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/cloudmonitoring"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/cloudsqladmin"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlmssql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlmysql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/cloudsqlpg"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/couchbase"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/dataplex"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/dgraph"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/elasticsearch"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/firebird"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/firestore"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/http"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/looker"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/mindsdb"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/mongodb"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/mssql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/mysql"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/neo4j"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/oceanbase"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/oracle"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/postgres"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/redis"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/serverlessspark"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/singlestore"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/spanner"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/sqlite"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/tidb"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/trino"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/valkey"
|
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/sources/yugabytedb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -283,307 +70,95 @@ func semanticVersion() string {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GenerateCommand returns a new Command object with the specified IO streams
|
||||||
|
// This is used for integration test package
|
||||||
|
func GenerateCommand(out, err io.Writer) *cobra.Command {
|
||||||
|
opts := internal.NewToolboxOptions(internal.WithIOStreams(out, err))
|
||||||
|
return NewCommand(opts)
|
||||||
|
}
|
||||||
|
|
||||||
// Execute adds all child commands to the root command and sets flags appropriately.
|
// Execute adds all child commands to the root command and sets flags appropriately.
|
||||||
// This is called by main.main(). It only needs to happen once to the rootCmd.
|
// This is called by main.main(). It only needs to happen once to the rootCmd.
|
||||||
func Execute() {
|
func Execute() {
|
||||||
if err := NewCommand().Execute(); err != nil {
|
// Initialize options
|
||||||
|
opts := internal.NewToolboxOptions()
|
||||||
|
|
||||||
|
if err := NewCommand(opts).Execute(); err != nil {
|
||||||
exit := 1
|
exit := 1
|
||||||
os.Exit(exit)
|
os.Exit(exit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command represents an invocation of the CLI.
|
|
||||||
type Command struct {
|
|
||||||
*cobra.Command
|
|
||||||
|
|
||||||
cfg server.ServerConfig
|
|
||||||
logger log.Logger
|
|
||||||
tools_file string
|
|
||||||
tools_files []string
|
|
||||||
tools_folder string
|
|
||||||
prebuiltConfig string
|
|
||||||
inStream io.Reader
|
|
||||||
outStream io.Writer
|
|
||||||
errStream io.Writer
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCommand returns a Command object representing an invocation of the CLI.
|
// NewCommand returns a Command object representing an invocation of the CLI.
|
||||||
func NewCommand(opts ...Option) *Command {
|
func NewCommand(opts *internal.ToolboxOptions) *cobra.Command {
|
||||||
in := os.Stdin
|
cmd := &cobra.Command{
|
||||||
out := os.Stdout
|
|
||||||
err := os.Stderr
|
|
||||||
|
|
||||||
baseCmd := &cobra.Command{
|
|
||||||
Use: "toolbox",
|
Use: "toolbox",
|
||||||
Version: versionString,
|
Version: versionString,
|
||||||
SilenceErrors: true,
|
SilenceErrors: true,
|
||||||
}
|
}
|
||||||
cmd := &Command{
|
|
||||||
Command: baseCmd,
|
|
||||||
inStream: in,
|
|
||||||
outStream: out,
|
|
||||||
errStream: err,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, o := range opts {
|
|
||||||
o(cmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do not print Usage on runtime error
|
// Do not print Usage on runtime error
|
||||||
cmd.SilenceUsage = true
|
cmd.SilenceUsage = true
|
||||||
|
|
||||||
// Set server version
|
// Set server version
|
||||||
cmd.cfg.Version = versionString
|
opts.Cfg.Version = versionString
|
||||||
|
|
||||||
// set baseCmd in, out and err the same as cmd.
|
// set baseCmd in, out and err the same as cmd.
|
||||||
baseCmd.SetIn(cmd.inStream)
|
cmd.SetIn(opts.IOStreams.In)
|
||||||
baseCmd.SetOut(cmd.outStream)
|
cmd.SetOut(opts.IOStreams.Out)
|
||||||
baseCmd.SetErr(cmd.errStream)
|
cmd.SetErr(opts.IOStreams.ErrOut)
|
||||||
|
|
||||||
|
// setup flags that are common across all commands
|
||||||
|
internal.PersistentFlags(cmd, opts)
|
||||||
|
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
flags.StringVarP(&cmd.cfg.Address, "address", "a", "127.0.0.1", "Address of the interface the server will listen on.")
|
|
||||||
flags.IntVarP(&cmd.cfg.Port, "port", "p", 5000, "Port the server will listen on.")
|
|
||||||
|
|
||||||
flags.StringVar(&cmd.tools_file, "tools_file", "", "File path specifying the tool configuration. Cannot be used with --prebuilt.")
|
flags.StringVarP(&opts.Cfg.Address, "address", "a", "127.0.0.1", "Address of the interface the server will listen on.")
|
||||||
|
flags.IntVarP(&opts.Cfg.Port, "port", "p", 5000, "Port the server will listen on.")
|
||||||
|
|
||||||
|
flags.StringVar(&opts.ToolsFile, "tools_file", "", "File path specifying the tool configuration. Cannot be used with --tools-files, or --tools-folder.")
|
||||||
// deprecate tools_file
|
// deprecate tools_file
|
||||||
_ = flags.MarkDeprecated("tools_file", "please use --tools-file instead")
|
_ = flags.MarkDeprecated("tools_file", "please use --tools-file instead")
|
||||||
flags.StringVar(&cmd.tools_file, "tools-file", "", "File path specifying the tool configuration. Cannot be used with --prebuilt, --tools-files, or --tools-folder.")
|
flags.BoolVar(&opts.Cfg.Stdio, "stdio", false, "Listens via MCP STDIO instead of acting as a remote HTTP server.")
|
||||||
flags.StringSliceVar(&cmd.tools_files, "tools-files", []string{}, "Multiple file paths specifying tool configurations. Files will be merged. Cannot be used with --prebuilt, --tools-file, or --tools-folder.")
|
flags.BoolVar(&opts.Cfg.DisableReload, "disable-reload", false, "Disables dynamic reloading of tools file.")
|
||||||
flags.StringVar(&cmd.tools_folder, "tools-folder", "", "Directory path containing YAML tool configuration files. All .yaml and .yml files in the directory will be loaded and merged. Cannot be used with --prebuilt, --tools-file, or --tools-files.")
|
flags.BoolVar(&opts.Cfg.UI, "ui", false, "Launches the Toolbox UI web server.")
|
||||||
flags.Var(&cmd.cfg.LogLevel, "log-level", "Specify the minimum level logged. Allowed: 'DEBUG', 'INFO', 'WARN', 'ERROR'.")
|
// TODO: Insecure by default. Might consider updating this for v1.0.0
|
||||||
flags.Var(&cmd.cfg.LoggingFormat, "logging-format", "Specify logging format to use. Allowed: 'standard' or 'JSON'.")
|
flags.StringSliceVar(&opts.Cfg.AllowedOrigins, "allowed-origins", []string{"*"}, "Specifies a list of origins permitted to access this server. Defaults to '*'.")
|
||||||
flags.BoolVar(&cmd.cfg.TelemetryGCP, "telemetry-gcp", false, "Enable exporting directly to Google Cloud Monitoring.")
|
flags.StringSliceVar(&opts.Cfg.AllowedHosts, "allowed-hosts", []string{"*"}, "Specifies a list of hosts permitted to access this server. Defaults to '*'.")
|
||||||
flags.StringVar(&cmd.cfg.TelemetryOTLP, "telemetry-otlp", "", "Enable exporting using OpenTelemetry Protocol (OTLP) to the specified endpoint (e.g. 'http://127.0.0.1:4318')")
|
|
||||||
flags.StringVar(&cmd.cfg.TelemetryServiceName, "telemetry-service-name", "toolbox", "Sets the value of the service.name resource attribute for telemetry data.")
|
|
||||||
// Fetch prebuilt tools sources to customize the help description
|
|
||||||
prebuiltHelp := fmt.Sprintf(
|
|
||||||
"Use a prebuilt tool configuration by source type. Cannot be used with --tools-file. Allowed: '%s'.",
|
|
||||||
strings.Join(prebuiltconfigs.GetPrebuiltSources(), "', '"),
|
|
||||||
)
|
|
||||||
flags.StringVar(&cmd.prebuiltConfig, "prebuilt", "", prebuiltHelp)
|
|
||||||
flags.BoolVar(&cmd.cfg.Stdio, "stdio", false, "Listens via MCP STDIO instead of acting as a remote HTTP server.")
|
|
||||||
flags.BoolVar(&cmd.cfg.DisableReload, "disable-reload", false, "Disables dynamic reloading of tools file.")
|
|
||||||
flags.BoolVar(&cmd.cfg.UI, "ui", false, "Launches the Toolbox UI web server.")
|
|
||||||
flags.StringSliceVar(&cmd.cfg.AllowedOrigins, "allowed-origins", []string{"*"}, "Specifies a list of origins permitted to access this server. Defaults to '*'.")
|
|
||||||
|
|
||||||
// wrap RunE command so that we have access to original Command object
|
// wrap RunE command so that we have access to original Command object
|
||||||
cmd.RunE = func(*cobra.Command, []string) error { return run(cmd) }
|
cmd.RunE = func(*cobra.Command, []string) error { return run(cmd, opts) }
|
||||||
|
|
||||||
|
// Register subcommands for tool invocation
|
||||||
|
cmd.AddCommand(invoke.NewCommand(opts))
|
||||||
|
// Register subcommands for skill generation
|
||||||
|
cmd.AddCommand(skills.NewCommand(opts))
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
type ToolsFile struct {
|
func handleDynamicReload(ctx context.Context, toolsFile internal.ToolsFile, s *server.Server) error {
|
||||||
Sources server.SourceConfigs `yaml:"sources"`
|
|
||||||
AuthSources server.AuthServiceConfigs `yaml:"authSources"` // Deprecated: Kept for compatibility.
|
|
||||||
AuthServices server.AuthServiceConfigs `yaml:"authServices"`
|
|
||||||
Tools server.ToolConfigs `yaml:"tools"`
|
|
||||||
Toolsets server.ToolsetConfigs `yaml:"toolsets"`
|
|
||||||
Prompts server.PromptConfigs `yaml:"prompts"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseEnv replaces environment variables ${ENV_NAME} with their values.
|
|
||||||
// also support ${ENV_NAME:default_value}.
|
|
||||||
func parseEnv(input string) (string, error) {
|
|
||||||
re := regexp.MustCompile(`\$\{(\w+)(:([^}]*))?\}`)
|
|
||||||
|
|
||||||
var err error
|
|
||||||
output := re.ReplaceAllStringFunc(input, func(match string) string {
|
|
||||||
parts := re.FindStringSubmatch(match)
|
|
||||||
|
|
||||||
// extract the variable name
|
|
||||||
variableName := parts[1]
|
|
||||||
if value, found := os.LookupEnv(variableName); found {
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
if len(parts) >= 4 && parts[2] != "" {
|
|
||||||
return parts[3]
|
|
||||||
}
|
|
||||||
err = fmt.Errorf("environment variable not found: %q", variableName)
|
|
||||||
return ""
|
|
||||||
})
|
|
||||||
return output, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseToolsFile parses the provided yaml into appropriate configs.
|
|
||||||
func parseToolsFile(ctx context.Context, raw []byte) (ToolsFile, error) {
|
|
||||||
var toolsFile ToolsFile
|
|
||||||
// Replace environment variables if found
|
|
||||||
output, err := parseEnv(string(raw))
|
|
||||||
if err != nil {
|
|
||||||
return toolsFile, fmt.Errorf("error parsing environment variables: %s", err)
|
|
||||||
}
|
|
||||||
raw = []byte(output)
|
|
||||||
|
|
||||||
// Parse contents
|
|
||||||
err = yaml.UnmarshalContext(ctx, raw, &toolsFile, yaml.Strict())
|
|
||||||
if err != nil {
|
|
||||||
return toolsFile, err
|
|
||||||
}
|
|
||||||
return toolsFile, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// mergeToolsFiles merges multiple ToolsFile structs into one.
|
|
||||||
// Detects and raises errors for resource conflicts in sources, authServices, tools, and toolsets.
|
|
||||||
// All resource names (sources, authServices, tools, toolsets) must be unique across all files.
|
|
||||||
func mergeToolsFiles(files ...ToolsFile) (ToolsFile, error) {
|
|
||||||
merged := ToolsFile{
|
|
||||||
Sources: make(server.SourceConfigs),
|
|
||||||
AuthServices: make(server.AuthServiceConfigs),
|
|
||||||
Tools: make(server.ToolConfigs),
|
|
||||||
Toolsets: make(server.ToolsetConfigs),
|
|
||||||
Prompts: make(server.PromptConfigs),
|
|
||||||
}
|
|
||||||
|
|
||||||
var conflicts []string
|
|
||||||
|
|
||||||
for fileIndex, file := range files {
|
|
||||||
// Check for conflicts and merge sources
|
|
||||||
for name, source := range file.Sources {
|
|
||||||
if _, exists := merged.Sources[name]; exists {
|
|
||||||
conflicts = append(conflicts, fmt.Sprintf("source '%s' (file #%d)", name, fileIndex+1))
|
|
||||||
} else {
|
|
||||||
merged.Sources[name] = source
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for conflicts and merge authSources (deprecated, but still support)
|
|
||||||
for name, authSource := range file.AuthSources {
|
|
||||||
if _, exists := merged.AuthSources[name]; exists {
|
|
||||||
conflicts = append(conflicts, fmt.Sprintf("authSource '%s' (file #%d)", name, fileIndex+1))
|
|
||||||
} else {
|
|
||||||
merged.AuthSources[name] = authSource
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for conflicts and merge authServices
|
|
||||||
for name, authService := range file.AuthServices {
|
|
||||||
if _, exists := merged.AuthServices[name]; exists {
|
|
||||||
conflicts = append(conflicts, fmt.Sprintf("authService '%s' (file #%d)", name, fileIndex+1))
|
|
||||||
} else {
|
|
||||||
merged.AuthServices[name] = authService
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for conflicts and merge tools
|
|
||||||
for name, tool := range file.Tools {
|
|
||||||
if _, exists := merged.Tools[name]; exists {
|
|
||||||
conflicts = append(conflicts, fmt.Sprintf("tool '%s' (file #%d)", name, fileIndex+1))
|
|
||||||
} else {
|
|
||||||
merged.Tools[name] = tool
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for conflicts and merge toolsets
|
|
||||||
for name, toolset := range file.Toolsets {
|
|
||||||
if _, exists := merged.Toolsets[name]; exists {
|
|
||||||
conflicts = append(conflicts, fmt.Sprintf("toolset '%s' (file #%d)", name, fileIndex+1))
|
|
||||||
} else {
|
|
||||||
merged.Toolsets[name] = toolset
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for conflicts and merge prompts
|
|
||||||
for name, prompt := range file.Prompts {
|
|
||||||
if _, exists := merged.Prompts[name]; exists {
|
|
||||||
conflicts = append(conflicts, fmt.Sprintf("prompt '%s' (file #%d)", name, fileIndex+1))
|
|
||||||
} else {
|
|
||||||
merged.Prompts[name] = prompt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If conflicts were detected, return an error
|
|
||||||
if len(conflicts) > 0 {
|
|
||||||
return ToolsFile{}, fmt.Errorf("resource conflicts detected:\n - %s\n\nPlease ensure each source, authService, tool, toolset and prompt has a unique name across all files", strings.Join(conflicts, "\n - "))
|
|
||||||
}
|
|
||||||
|
|
||||||
return merged, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// loadAndMergeToolsFiles loads multiple YAML files and merges them
|
|
||||||
func loadAndMergeToolsFiles(ctx context.Context, filePaths []string) (ToolsFile, error) {
|
|
||||||
var toolsFiles []ToolsFile
|
|
||||||
|
|
||||||
for _, filePath := range filePaths {
|
|
||||||
buf, err := os.ReadFile(filePath)
|
|
||||||
if err != nil {
|
|
||||||
return ToolsFile{}, fmt.Errorf("unable to read tool file at %q: %w", filePath, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
toolsFile, err := parseToolsFile(ctx, buf)
|
|
||||||
if err != nil {
|
|
||||||
return ToolsFile{}, fmt.Errorf("unable to parse tool file at %q: %w", filePath, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
toolsFiles = append(toolsFiles, toolsFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
mergedFile, err := mergeToolsFiles(toolsFiles...)
|
|
||||||
if err != nil {
|
|
||||||
return ToolsFile{}, fmt.Errorf("unable to merge tools files: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return mergedFile, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// loadAndMergeToolsFolder loads all YAML files from a directory and merges them
|
|
||||||
func loadAndMergeToolsFolder(ctx context.Context, folderPath string) (ToolsFile, error) {
|
|
||||||
// Check if directory exists
|
|
||||||
info, err := os.Stat(folderPath)
|
|
||||||
if err != nil {
|
|
||||||
return ToolsFile{}, fmt.Errorf("unable to access tools folder at %q: %w", folderPath, err)
|
|
||||||
}
|
|
||||||
if !info.IsDir() {
|
|
||||||
return ToolsFile{}, fmt.Errorf("path %q is not a directory", folderPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find all YAML files in the directory
|
|
||||||
pattern := filepath.Join(folderPath, "*.yaml")
|
|
||||||
yamlFiles, err := filepath.Glob(pattern)
|
|
||||||
if err != nil {
|
|
||||||
return ToolsFile{}, fmt.Errorf("error finding YAML files in %q: %w", folderPath, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Also find .yml files
|
|
||||||
ymlPattern := filepath.Join(folderPath, "*.yml")
|
|
||||||
ymlFiles, err := filepath.Glob(ymlPattern)
|
|
||||||
if err != nil {
|
|
||||||
return ToolsFile{}, fmt.Errorf("error finding YML files in %q: %w", folderPath, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Combine both file lists
|
|
||||||
allFiles := append(yamlFiles, ymlFiles...)
|
|
||||||
|
|
||||||
if len(allFiles) == 0 {
|
|
||||||
return ToolsFile{}, fmt.Errorf("no YAML files found in directory %q", folderPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use existing loadAndMergeToolsFiles function
|
|
||||||
return loadAndMergeToolsFiles(ctx, allFiles)
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleDynamicReload(ctx context.Context, toolsFile ToolsFile, s *server.Server) error {
|
|
||||||
logger, err := util.LoggerFromContext(ctx)
|
logger, err := util.LoggerFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
sourcesMap, authServicesMap, toolsMap, toolsetsMap, promptsMap, promptsetsMap, err := validateReloadEdits(ctx, toolsFile)
|
sourcesMap, authServicesMap, embeddingModelsMap, toolsMap, toolsetsMap, promptsMap, promptsetsMap, err := validateReloadEdits(ctx, toolsFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errMsg := fmt.Errorf("unable to validate reloaded edits: %w", err)
|
errMsg := fmt.Errorf("unable to validate reloaded edits: %w", err)
|
||||||
logger.WarnContext(ctx, errMsg.Error())
|
logger.WarnContext(ctx, errMsg.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
s.ResourceMgr.SetResources(sourcesMap, authServicesMap, toolsMap, toolsetsMap, promptsMap, promptsetsMap)
|
s.ResourceMgr.SetResources(sourcesMap, authServicesMap, embeddingModelsMap, toolsMap, toolsetsMap, promptsMap, promptsetsMap)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// validateReloadEdits checks that the reloaded tools file configs can initialized without failing
|
// validateReloadEdits checks that the reloaded tools file configs can initialized without failing
|
||||||
func validateReloadEdits(
|
func validateReloadEdits(
|
||||||
ctx context.Context, toolsFile ToolsFile,
|
ctx context.Context, toolsFile internal.ToolsFile,
|
||||||
) (map[string]sources.Source, map[string]auth.AuthService, map[string]tools.Tool, map[string]tools.Toolset, map[string]prompts.Prompt, map[string]prompts.Promptset, error,
|
) (map[string]sources.Source, map[string]auth.AuthService, map[string]embeddingmodels.EmbeddingModel, map[string]tools.Tool, map[string]tools.Toolset, map[string]prompts.Prompt, map[string]prompts.Promptset, error,
|
||||||
) {
|
) {
|
||||||
logger, err := util.LoggerFromContext(ctx)
|
logger, err := util.LoggerFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -601,22 +176,23 @@ func validateReloadEdits(
|
|||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
reloadedConfig := server.ServerConfig{
|
reloadedConfig := server.ServerConfig{
|
||||||
Version: versionString,
|
Version: versionString,
|
||||||
SourceConfigs: toolsFile.Sources,
|
SourceConfigs: toolsFile.Sources,
|
||||||
AuthServiceConfigs: toolsFile.AuthServices,
|
AuthServiceConfigs: toolsFile.AuthServices,
|
||||||
ToolConfigs: toolsFile.Tools,
|
EmbeddingModelConfigs: toolsFile.EmbeddingModels,
|
||||||
ToolsetConfigs: toolsFile.Toolsets,
|
ToolConfigs: toolsFile.Tools,
|
||||||
PromptConfigs: toolsFile.Prompts,
|
ToolsetConfigs: toolsFile.Toolsets,
|
||||||
|
PromptConfigs: toolsFile.Prompts,
|
||||||
}
|
}
|
||||||
|
|
||||||
sourcesMap, authServicesMap, toolsMap, toolsetsMap, promptsMap, promptsetsMap, err := server.InitializeConfigs(ctx, reloadedConfig)
|
sourcesMap, authServicesMap, embeddingModelsMap, toolsMap, toolsetsMap, promptsMap, promptsetsMap, err := server.InitializeConfigs(ctx, reloadedConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errMsg := fmt.Errorf("unable to initialize reloaded configs: %w", err)
|
errMsg := fmt.Errorf("unable to initialize reloaded configs: %w", err)
|
||||||
logger.WarnContext(ctx, errMsg.Error())
|
logger.WarnContext(ctx, errMsg.Error())
|
||||||
return nil, nil, nil, nil, nil, nil, err
|
return nil, nil, nil, nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return sourcesMap, authServicesMap, toolsMap, toolsetsMap, promptsMap, promptsetsMap, nil
|
return sourcesMap, authServicesMap, embeddingModelsMap, toolsMap, toolsetsMap, promptsMap, promptsetsMap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// watchChanges checks for changes in the provided yaml tools file(s) or folder.
|
// watchChanges checks for changes in the provided yaml tools file(s) or folder.
|
||||||
@@ -707,18 +283,18 @@ func watchChanges(ctx context.Context, watchDirs map[string]bool, watchedFiles m
|
|||||||
|
|
||||||
case <-debounce.C:
|
case <-debounce.C:
|
||||||
debounce.Stop()
|
debounce.Stop()
|
||||||
var reloadedToolsFile ToolsFile
|
var reloadedToolsFile internal.ToolsFile
|
||||||
|
|
||||||
if watchingFolder {
|
if watchingFolder {
|
||||||
logger.DebugContext(ctx, "Reloading tools folder.")
|
logger.DebugContext(ctx, "Reloading tools folder.")
|
||||||
reloadedToolsFile, err = loadAndMergeToolsFolder(ctx, folderToWatch)
|
reloadedToolsFile, err = internal.LoadAndMergeToolsFolder(ctx, folderToWatch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.WarnContext(ctx, "error loading tools folder %s", err)
|
logger.WarnContext(ctx, "error loading tools folder %s", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.DebugContext(ctx, "Reloading tools file(s).")
|
logger.DebugContext(ctx, "Reloading tools file(s).")
|
||||||
reloadedToolsFile, err = loadAndMergeToolsFiles(ctx, slices.Collect(maps.Keys(watchedFiles)))
|
reloadedToolsFile, err = internal.LoadAndMergeToolsFiles(ctx, slices.Collect(maps.Keys(watchedFiles)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.WarnContext(ctx, "error loading tools files %s", err)
|
logger.WarnContext(ctx, "error loading tools files %s", err)
|
||||||
continue
|
continue
|
||||||
@@ -762,7 +338,7 @@ func resolveWatcherInputs(toolsFile string, toolsFiles []string, toolsFolder str
|
|||||||
return watchDirs, watchedFiles
|
return watchDirs, watchedFiles
|
||||||
}
|
}
|
||||||
|
|
||||||
func run(cmd *Command) error {
|
func run(cmd *cobra.Command, opts *internal.ToolboxOptions) error {
|
||||||
ctx, cancel := context.WithCancel(cmd.Context())
|
ctx, cancel := context.WithCancel(cmd.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
@@ -779,165 +355,40 @@ func run(cmd *Command) error {
|
|||||||
}
|
}
|
||||||
switch s {
|
switch s {
|
||||||
case syscall.SIGINT:
|
case syscall.SIGINT:
|
||||||
cmd.logger.DebugContext(sCtx, "Received SIGINT signal to shutdown.")
|
opts.Logger.DebugContext(sCtx, "Received SIGINT signal to shutdown.")
|
||||||
case syscall.SIGTERM:
|
case syscall.SIGTERM:
|
||||||
cmd.logger.DebugContext(sCtx, "Sending SIGTERM signal to shutdown.")
|
opts.Logger.DebugContext(sCtx, "Sending SIGTERM signal to shutdown.")
|
||||||
}
|
}
|
||||||
cancel()
|
cancel()
|
||||||
}(ctx)
|
}(ctx)
|
||||||
|
|
||||||
// If stdio, set logger's out stream (usually DEBUG and INFO logs) to errStream
|
ctx, shutdown, err := opts.Setup(ctx)
|
||||||
loggerOut := cmd.outStream
|
|
||||||
if cmd.cfg.Stdio {
|
|
||||||
loggerOut = cmd.errStream
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle logger separately from config
|
|
||||||
switch strings.ToLower(cmd.cfg.LoggingFormat.String()) {
|
|
||||||
case "json":
|
|
||||||
logger, err := log.NewStructuredLogger(loggerOut, cmd.errStream, cmd.cfg.LogLevel.String())
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to initialize logger: %w", err)
|
|
||||||
}
|
|
||||||
cmd.logger = logger
|
|
||||||
case "standard":
|
|
||||||
logger, err := log.NewStdLogger(loggerOut, cmd.errStream, cmd.cfg.LogLevel.String())
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to initialize logger: %w", err)
|
|
||||||
}
|
|
||||||
cmd.logger = logger
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("logging format invalid")
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = util.WithLogger(ctx, cmd.logger)
|
|
||||||
|
|
||||||
// Set up OpenTelemetry
|
|
||||||
otelShutdown, err := telemetry.SetupOTel(ctx, cmd.cfg.Version, cmd.cfg.TelemetryOTLP, cmd.cfg.TelemetryGCP, cmd.cfg.TelemetryServiceName)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errMsg := fmt.Errorf("error setting up OpenTelemetry: %w", err)
|
return err
|
||||||
cmd.logger.ErrorContext(ctx, errMsg.Error())
|
|
||||||
return errMsg
|
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
err := otelShutdown(ctx)
|
_ = shutdown(ctx)
|
||||||
if err != nil {
|
|
||||||
errMsg := fmt.Errorf("error shutting down OpenTelemetry: %w", err)
|
|
||||||
cmd.logger.ErrorContext(ctx, errMsg.Error())
|
|
||||||
}
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
var toolsFile ToolsFile
|
isCustomConfigured, err := opts.LoadConfig(ctx)
|
||||||
|
|
||||||
if cmd.prebuiltConfig != "" {
|
|
||||||
// Make sure --prebuilt and --tools-file/--tools-files/--tools-folder flags are mutually exclusive
|
|
||||||
if cmd.tools_file != "" || len(cmd.tools_files) > 0 || cmd.tools_folder != "" {
|
|
||||||
errMsg := fmt.Errorf("--prebuilt and --tools-file/--tools-files/--tools-folder flags cannot be used simultaneously")
|
|
||||||
cmd.logger.ErrorContext(ctx, errMsg.Error())
|
|
||||||
return errMsg
|
|
||||||
}
|
|
||||||
// Use prebuilt tools
|
|
||||||
buf, err := prebuiltconfigs.Get(cmd.prebuiltConfig)
|
|
||||||
if err != nil {
|
|
||||||
cmd.logger.ErrorContext(ctx, err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logMsg := fmt.Sprint("Using prebuilt tool configuration for ", cmd.prebuiltConfig)
|
|
||||||
cmd.logger.InfoContext(ctx, logMsg)
|
|
||||||
// Append prebuilt.source to Version string for the User Agent
|
|
||||||
cmd.cfg.Version += "+prebuilt." + cmd.prebuiltConfig
|
|
||||||
|
|
||||||
toolsFile, err = parseToolsFile(ctx, buf)
|
|
||||||
if err != nil {
|
|
||||||
errMsg := fmt.Errorf("unable to parse prebuilt tool configuration: %w", err)
|
|
||||||
cmd.logger.ErrorContext(ctx, errMsg.Error())
|
|
||||||
return errMsg
|
|
||||||
}
|
|
||||||
} else if len(cmd.tools_files) > 0 {
|
|
||||||
// Make sure --tools-file, --tools-files, and --tools-folder flags are mutually exclusive
|
|
||||||
if cmd.tools_file != "" || cmd.tools_folder != "" {
|
|
||||||
errMsg := fmt.Errorf("--tools-file, --tools-files, and --tools-folder flags cannot be used simultaneously")
|
|
||||||
cmd.logger.ErrorContext(ctx, errMsg.Error())
|
|
||||||
return errMsg
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use multiple tools files
|
|
||||||
cmd.logger.InfoContext(ctx, fmt.Sprintf("Loading and merging %d tool configuration files", len(cmd.tools_files)))
|
|
||||||
var err error
|
|
||||||
toolsFile, err = loadAndMergeToolsFiles(ctx, cmd.tools_files)
|
|
||||||
if err != nil {
|
|
||||||
cmd.logger.ErrorContext(ctx, err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else if cmd.tools_folder != "" {
|
|
||||||
// Make sure --tools-folder and other flags are mutually exclusive
|
|
||||||
if cmd.tools_file != "" || len(cmd.tools_files) > 0 {
|
|
||||||
errMsg := fmt.Errorf("--tools-file, --tools-files, and --tools-folder flags cannot be used simultaneously")
|
|
||||||
cmd.logger.ErrorContext(ctx, errMsg.Error())
|
|
||||||
return errMsg
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use tools folder
|
|
||||||
cmd.logger.InfoContext(ctx, fmt.Sprintf("Loading and merging all YAML files from directory: %s", cmd.tools_folder))
|
|
||||||
var err error
|
|
||||||
toolsFile, err = loadAndMergeToolsFolder(ctx, cmd.tools_folder)
|
|
||||||
if err != nil {
|
|
||||||
cmd.logger.ErrorContext(ctx, err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Set default value of tools-file flag to tools.yaml
|
|
||||||
if cmd.tools_file == "" {
|
|
||||||
cmd.tools_file = "tools.yaml"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read single tool file contents
|
|
||||||
buf, err := os.ReadFile(cmd.tools_file)
|
|
||||||
if err != nil {
|
|
||||||
errMsg := fmt.Errorf("unable to read tool file at %q: %w", cmd.tools_file, err)
|
|
||||||
cmd.logger.ErrorContext(ctx, errMsg.Error())
|
|
||||||
return errMsg
|
|
||||||
}
|
|
||||||
|
|
||||||
toolsFile, err = parseToolsFile(ctx, buf)
|
|
||||||
if err != nil {
|
|
||||||
errMsg := fmt.Errorf("unable to parse tool file at %q: %w", cmd.tools_file, err)
|
|
||||||
cmd.logger.ErrorContext(ctx, errMsg.Error())
|
|
||||||
return errMsg
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.cfg.SourceConfigs, cmd.cfg.AuthServiceConfigs, cmd.cfg.ToolConfigs, cmd.cfg.ToolsetConfigs, cmd.cfg.PromptConfigs = toolsFile.Sources, toolsFile.AuthServices, toolsFile.Tools, toolsFile.Toolsets, toolsFile.Prompts
|
|
||||||
|
|
||||||
authSourceConfigs := toolsFile.AuthSources
|
|
||||||
if authSourceConfigs != nil {
|
|
||||||
cmd.logger.WarnContext(ctx, "`authSources` is deprecated, use `authServices` instead")
|
|
||||||
cmd.cfg.AuthServiceConfigs = authSourceConfigs
|
|
||||||
}
|
|
||||||
|
|
||||||
instrumentation, err := telemetry.CreateTelemetryInstrumentation(versionString)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errMsg := fmt.Errorf("unable to create telemetry instrumentation: %w", err)
|
return err
|
||||||
cmd.logger.ErrorContext(ctx, errMsg.Error())
|
|
||||||
return errMsg
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = util.WithInstrumentation(ctx, instrumentation)
|
|
||||||
|
|
||||||
// start server
|
// start server
|
||||||
s, err := server.NewServer(ctx, cmd.cfg)
|
s, err := server.NewServer(ctx, opts.Cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errMsg := fmt.Errorf("toolbox failed to initialize: %w", err)
|
errMsg := fmt.Errorf("toolbox failed to initialize: %w", err)
|
||||||
cmd.logger.ErrorContext(ctx, errMsg.Error())
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
return errMsg
|
return errMsg
|
||||||
}
|
}
|
||||||
|
|
||||||
// run server in background
|
// run server in background
|
||||||
srvErr := make(chan error)
|
srvErr := make(chan error)
|
||||||
if cmd.cfg.Stdio {
|
if opts.Cfg.Stdio {
|
||||||
go func() {
|
go func() {
|
||||||
defer close(srvErr)
|
defer close(srvErr)
|
||||||
err = s.ServeStdio(ctx, cmd.inStream, cmd.outStream)
|
err = s.ServeStdio(ctx, opts.IOStreams.In, opts.IOStreams.Out)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
srvErr <- err
|
srvErr <- err
|
||||||
}
|
}
|
||||||
@@ -946,12 +397,12 @@ func run(cmd *Command) error {
|
|||||||
err = s.Listen(ctx)
|
err = s.Listen(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errMsg := fmt.Errorf("toolbox failed to start listener: %w", err)
|
errMsg := fmt.Errorf("toolbox failed to start listener: %w", err)
|
||||||
cmd.logger.ErrorContext(ctx, errMsg.Error())
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
return errMsg
|
return errMsg
|
||||||
}
|
}
|
||||||
cmd.logger.InfoContext(ctx, "Server ready to serve!")
|
opts.Logger.InfoContext(ctx, "Server ready to serve!")
|
||||||
if cmd.cfg.UI {
|
if opts.Cfg.UI {
|
||||||
cmd.logger.InfoContext(ctx, fmt.Sprintf("Toolbox UI is up and running at: http://%s:%d/ui", cmd.cfg.Address, cmd.cfg.Port))
|
opts.Logger.InfoContext(ctx, fmt.Sprintf("Toolbox UI is up and running at: http://%s:%d/ui", opts.Cfg.Address, opts.Cfg.Port))
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
@@ -963,9 +414,8 @@ func run(cmd *Command) error {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
watchDirs, watchedFiles := resolveWatcherInputs(cmd.tools_file, cmd.tools_files, cmd.tools_folder)
|
if isCustomConfigured && !opts.Cfg.DisableReload {
|
||||||
|
watchDirs, watchedFiles := resolveWatcherInputs(opts.ToolsFile, opts.ToolsFiles, opts.ToolsFolder)
|
||||||
if !cmd.cfg.DisableReload {
|
|
||||||
// start watching the file(s) or folder for changes to trigger dynamic reloading
|
// start watching the file(s) or folder for changes to trigger dynamic reloading
|
||||||
go watchChanges(ctx, watchDirs, watchedFiles, s)
|
go watchChanges(ctx, watchDirs, watchedFiles, s)
|
||||||
}
|
}
|
||||||
@@ -975,13 +425,13 @@ func run(cmd *Command) error {
|
|||||||
case err := <-srvErr:
|
case err := <-srvErr:
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errMsg := fmt.Errorf("toolbox crashed with the following error: %w", err)
|
errMsg := fmt.Errorf("toolbox crashed with the following error: %w", err)
|
||||||
cmd.logger.ErrorContext(ctx, errMsg.Error())
|
opts.Logger.ErrorContext(ctx, errMsg.Error())
|
||||||
return errMsg
|
return errMsg
|
||||||
}
|
}
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
shutdownContext, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
shutdownContext, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
cmd.logger.WarnContext(shutdownContext, "Shutting down gracefully...")
|
opts.Logger.WarnContext(shutdownContext, "Shutting down gracefully...")
|
||||||
err := s.Shutdown(shutdownContext)
|
err := s.Shutdown(shutdownContext)
|
||||||
if err == context.DeadlineExceeded {
|
if err == context.DeadlineExceeded {
|
||||||
return fmt.Errorf("graceful shutdown timed out... forcing exit")
|
return fmt.Errorf("graceful shutdown timed out... forcing exit")
|
||||||
|
|||||||
1604
cmd/root_test.go
1604
cmd/root_test.go
File diff suppressed because it is too large
Load Diff
@@ -1 +1 @@
|
|||||||
0.21.0
|
0.27.0
|
||||||
|
|||||||
@@ -23,6 +23,14 @@ To connect to the database to explore and query data, search the MCP store for t
|
|||||||
|
|
||||||
In the Antigravity MCP Store, click the "Install" button.
|
In the Antigravity MCP Store, click the "Install" button.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> On first use, the installation process automatically downloads and uses
|
||||||
|
> [MCP Toolbox](https://www.npmjs.com/package/@toolbox-sdk/server)
|
||||||
|
> `>=0.26.0`. To update MCP Toolbox, use:
|
||||||
|
> ```npm i -g @toolbox-sdk/server@latest```
|
||||||
|
> To always run the latest version, update the MCP server configuration to use:
|
||||||
|
> ```npx -y @toolbox-sdk/server@latest --prebuilt alloydb-postgres-admin```.
|
||||||
|
|
||||||
You'll now be able to see all enabled tools in the "Tools" tab.
|
You'll now be able to see all enabled tools in the "Tools" tab.
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
|
|||||||
@@ -27,6 +27,13 @@ For AlloyDB infrastructure management, search the MCP store for the AlloyDB for
|
|||||||
## Install & Configuration
|
## Install & Configuration
|
||||||
|
|
||||||
1. In the Antigravity MCP Store, click the "Install" button.
|
1. In the Antigravity MCP Store, click the "Install" button.
|
||||||
|
> [!NOTE]
|
||||||
|
> On first use, the installation process automatically downloads and uses
|
||||||
|
> [MCP Toolbox](https://www.npmjs.com/package/@toolbox-sdk/server)
|
||||||
|
> `>=0.26.0`. To update MCP Toolbox, use:
|
||||||
|
> ```npm i -g @toolbox-sdk/server@latest```
|
||||||
|
> To always run the latest version, update the MCP server configuration to use:
|
||||||
|
> ```npx -y @toolbox-sdk/server@latest --prebuilt alloydb-postgres```.
|
||||||
|
|
||||||
2. Add the required inputs for your [cluster](https://docs.cloud.google.com/alloydb/docs/cluster-list) in the configuration pop-up, then click "Save". You can update this configuration at any time in the "Configure" tab.
|
2. Add the required inputs for your [cluster](https://docs.cloud.google.com/alloydb/docs/cluster-list) in the configuration pop-up, then click "Save". You can update this configuration at any time in the "Configure" tab.
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,13 @@ An editor configured to use the BigQuery MCP server can use its AI capabilities
|
|||||||
## Install & Configuration
|
## Install & Configuration
|
||||||
|
|
||||||
1. In the Antigravity MCP Store, click the "Install" button.
|
1. In the Antigravity MCP Store, click the "Install" button.
|
||||||
|
> [!NOTE]
|
||||||
|
> On first use, the installation process automatically downloads and uses
|
||||||
|
> [MCP Toolbox](https://www.npmjs.com/package/@toolbox-sdk/server)
|
||||||
|
> `>=0.26.0`. To update MCP Toolbox, use:
|
||||||
|
> ```npm i -g @toolbox-sdk/server@latest```
|
||||||
|
> To always run the latest version, update the MCP server configuration to use:
|
||||||
|
> ```npx -y @toolbox-sdk/server@latest --prebuilt bigquery```.
|
||||||
|
|
||||||
2. Add the required inputs in the configuration pop-up, then click "Save". You can update this configuration at any time in the "Configure" tab.
|
2. Add the required inputs in the configuration pop-up, then click "Save". You can update this configuration at any time in the "Configure" tab.
|
||||||
|
|
||||||
@@ -68,6 +75,7 @@ The BigQuery MCP server is configured using environment variables.
|
|||||||
export BIGQUERY_PROJECT="<your-gcp-project-id>"
|
export BIGQUERY_PROJECT="<your-gcp-project-id>"
|
||||||
export BIGQUERY_LOCATION="<your-dataset-location>" # Optional
|
export BIGQUERY_LOCATION="<your-dataset-location>" # Optional
|
||||||
export BIGQUERY_USE_CLIENT_OAUTH="true" # Optional
|
export BIGQUERY_USE_CLIENT_OAUTH="true" # Optional
|
||||||
|
export BIGQUERY_SCOPES="<comma-separated-scopes>" # Optional
|
||||||
```
|
```
|
||||||
|
|
||||||
Add the following configuration to your MCP client (e.g., `settings.json` for Gemini CLI, `mcp_config.json` for Antigravity):
|
Add the following configuration to your MCP client (e.g., `settings.json` for Gemini CLI, `mcp_config.json` for Antigravity):
|
||||||
|
|||||||
@@ -23,6 +23,14 @@ To connect to the database to explore and query data, search the MCP store for t
|
|||||||
|
|
||||||
In the Antigravity MCP Store, click the "Install" button.
|
In the Antigravity MCP Store, click the "Install" button.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> On first use, the installation process automatically downloads and uses
|
||||||
|
> [MCP Toolbox](https://www.npmjs.com/package/@toolbox-sdk/server)
|
||||||
|
> `>=0.26.0`. To update MCP Toolbox, use:
|
||||||
|
> ```npm i -g @toolbox-sdk/server@latest```
|
||||||
|
> To always run the latest version, update the MCP server configuration to use:
|
||||||
|
> ```npx -y @toolbox-sdk/server@latest --prebuilt cloud-sql-mssql-admin```.
|
||||||
|
|
||||||
You'll now be able to see all enabled tools in the "Tools" tab.
|
You'll now be able to see all enabled tools in the "Tools" tab.
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
|
|||||||
@@ -24,6 +24,13 @@ For Cloud SQL infrastructure management, search the MCP store for the Cloud SQL
|
|||||||
## Install & Configuration
|
## Install & Configuration
|
||||||
|
|
||||||
1. In the Antigravity MCP Store, click the "Install" button.
|
1. In the Antigravity MCP Store, click the "Install" button.
|
||||||
|
> [!NOTE]
|
||||||
|
> On first use, the installation process automatically downloads and uses
|
||||||
|
> [MCP Toolbox](https://www.npmjs.com/package/@toolbox-sdk/server)
|
||||||
|
> `>=0.26.0`. To update MCP Toolbox, use:
|
||||||
|
> ```npm i -g @toolbox-sdk/server@latest```
|
||||||
|
> To always run the latest version, update the MCP server configuration to use:
|
||||||
|
> ```npx -y @toolbox-sdk/server@latest --prebuilt cloud-sql-mssql```.
|
||||||
|
|
||||||
2. Add the required inputs for your [instance](https://cloud.google.com/sql/docs/sqlserver/instance-info) in the configuration pop-up, then click "Save". You can update this configuration at any time in the "Configure" tab.
|
2. Add the required inputs for your [instance](https://cloud.google.com/sql/docs/sqlserver/instance-info) in the configuration pop-up, then click "Save". You can update this configuration at any time in the "Configure" tab.
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,14 @@ To connect to the database to explore and query data, search the MCP store for t
|
|||||||
|
|
||||||
In the Antigravity MCP Store, click the "Install" button.
|
In the Antigravity MCP Store, click the "Install" button.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> On first use, the installation process automatically downloads and uses
|
||||||
|
> [MCP Toolbox](https://www.npmjs.com/package/@toolbox-sdk/server)
|
||||||
|
> `>=0.26.0`. To update MCP Toolbox, use:
|
||||||
|
> ```npm i -g @toolbox-sdk/server@latest```
|
||||||
|
> To always run the latest version, update the MCP server configuration to use:
|
||||||
|
> ```npx -y @toolbox-sdk/server@latest --prebuilt cloud-sql-mysql-admin```.
|
||||||
|
|
||||||
You'll now be able to see all enabled tools in the "Tools" tab.
|
You'll now be able to see all enabled tools in the "Tools" tab.
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
|
|||||||
@@ -26,6 +26,13 @@ For Cloud SQL infrastructure management, search the MCP store for the Cloud SQL
|
|||||||
## Install & Configuration
|
## Install & Configuration
|
||||||
|
|
||||||
1. In the Antigravity MCP Store, click the "Install" button.
|
1. In the Antigravity MCP Store, click the "Install" button.
|
||||||
|
> [!NOTE]
|
||||||
|
> On first use, the installation process automatically downloads and uses
|
||||||
|
> [MCP Toolbox](https://www.npmjs.com/package/@toolbox-sdk/server)
|
||||||
|
> `>=0.26.0`. To update MCP Toolbox, use:
|
||||||
|
> ```npm i -g @toolbox-sdk/server@latest```
|
||||||
|
> To always run the latest version, update the MCP server configuration to use:
|
||||||
|
> ```npx -y @toolbox-sdk/server@latest --prebuilt cloud-sql-mysql```.
|
||||||
|
|
||||||
2. Add the required inputs for your [instance](https://cloud.google.com/sql/docs/mysql/instance-info) in the configuration pop-up, then click "Save". You can update this configuration at any time in the "Configure" tab.
|
2. Add the required inputs for your [instance](https://cloud.google.com/sql/docs/mysql/instance-info) in the configuration pop-up, then click "Save". You can update this configuration at any time in the "Configure" tab.
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,14 @@ To connect to the database to explore and query data, search the MCP store for t
|
|||||||
|
|
||||||
In the Antigravity MCP Store, click the "Install" button.
|
In the Antigravity MCP Store, click the "Install" button.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> On first use, the installation process automatically downloads and uses
|
||||||
|
> [MCP Toolbox](https://www.npmjs.com/package/@toolbox-sdk/server)
|
||||||
|
> `>=0.26.0`. To update MCP Toolbox, use:
|
||||||
|
> ```npm i -g @toolbox-sdk/server@latest```
|
||||||
|
> To always run the latest version, update the MCP server configuration to use:
|
||||||
|
> ```npx -y @toolbox-sdk/server@latest --prebuilt cloud-sql-postgres-admin```.
|
||||||
|
|
||||||
You'll now be able to see all enabled tools in the "Tools" tab.
|
You'll now be able to see all enabled tools in the "Tools" tab.
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
|
|||||||
@@ -26,6 +26,13 @@ For Cloud SQL infrastructure management, search the MCP store for the Cloud SQL
|
|||||||
## Install & Configuration
|
## Install & Configuration
|
||||||
|
|
||||||
1. In the Antigravity MCP Store, click the "Install" button.
|
1. In the Antigravity MCP Store, click the "Install" button.
|
||||||
|
> [!NOTE]
|
||||||
|
> On first use, the installation process automatically downloads and uses
|
||||||
|
> [MCP Toolbox](https://www.npmjs.com/package/@toolbox-sdk/server)
|
||||||
|
> `>=0.26.0`. To update MCP Toolbox, use:
|
||||||
|
> ```npm i -g @toolbox-sdk/server@latest```
|
||||||
|
> To always run the latest version, update the MCP server configuration to use:
|
||||||
|
> ```npx -y @toolbox-sdk/server@latest --prebuilt cloud-sql-postgres```.
|
||||||
|
|
||||||
2. Add the required inputs for your [instance](https://cloud.google.com/sql/docs/postgres/instance-info) in the configuration pop-up, then click "Save". You can update this configuration at any time in the "Configure" tab.
|
2. Add the required inputs for your [instance](https://cloud.google.com/sql/docs/postgres/instance-info) in the configuration pop-up, then click "Save". You can update this configuration at any time in the "Configure" tab.
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,13 @@ An editor configured to use the Dataplex MCP server can use its AI capabilities
|
|||||||
## Install & Configuration
|
## Install & Configuration
|
||||||
|
|
||||||
1. In the Antigravity MCP Store, click the "Install" button.
|
1. In the Antigravity MCP Store, click the "Install" button.
|
||||||
|
> [!NOTE]
|
||||||
|
> On first use, the installation process automatically downloads and uses
|
||||||
|
> [MCP Toolbox](https://www.npmjs.com/package/@toolbox-sdk/server)
|
||||||
|
> `>=0.26.0`. To update MCP Toolbox, use:
|
||||||
|
> ```npm i -g @toolbox-sdk/server@latest```
|
||||||
|
> To always run the latest version, update the MCP server configuration to use:
|
||||||
|
> ```npx -y @toolbox-sdk/server@latest --prebuilt dataplex```.
|
||||||
|
|
||||||
2. Add the required inputs in the configuration pop-up, then click "Save". You can update this configuration at any time in the "Configure" tab.
|
2. Add the required inputs in the configuration pop-up, then click "Save". You can update this configuration at any time in the "Configure" tab.
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,13 @@ An editor configured to use the Looker MCP server can use its AI capabilities to
|
|||||||
## Install & Configuration
|
## Install & Configuration
|
||||||
|
|
||||||
1. In the Antigravity MCP Store, click the "Install" button.
|
1. In the Antigravity MCP Store, click the "Install" button.
|
||||||
|
> [!NOTE]
|
||||||
|
> On first use, the installation process automatically downloads and uses
|
||||||
|
> [MCP Toolbox](https://www.npmjs.com/package/@toolbox-sdk/server)
|
||||||
|
> `>=0.26.0`. To update MCP Toolbox, use:
|
||||||
|
> ```npm i -g @toolbox-sdk/server@latest```
|
||||||
|
> To always run the latest version, update the MCP server configuration to use:
|
||||||
|
> ```npx -y @toolbox-sdk/server@latest --prebuilt looker```.
|
||||||
|
|
||||||
2. Add the required inputs for your [instance](https://docs.cloud.google.com/looker/docs/set-up-and-administer-looker) in the configuration pop-up, then click "Save". You can update this configuration at any time in the "Configure" tab.
|
2. Add the required inputs for your [instance](https://docs.cloud.google.com/looker/docs/set-up-and-administer-looker) in the configuration pop-up, then click "Save". You can update this configuration at any time in the "Configure" tab.
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,13 @@ An editor configured to use the Cloud Spanner MCP server can use its AI capabili
|
|||||||
## Install & Configuration
|
## Install & Configuration
|
||||||
|
|
||||||
1. In the Antigravity MCP Store, click the "Install" button.
|
1. In the Antigravity MCP Store, click the "Install" button.
|
||||||
|
> [!NOTE]
|
||||||
|
> On first use, the installation process automatically downloads and uses
|
||||||
|
> [MCP Toolbox](https://www.npmjs.com/package/@toolbox-sdk/server)
|
||||||
|
> `>=0.26.0`. To update MCP Toolbox, use:
|
||||||
|
> ```npm i -g @toolbox-sdk/server@latest```
|
||||||
|
> To always run the latest version, update the MCP server configuration to use:
|
||||||
|
> ```npx -y @toolbox-sdk/server@latest --prebuilt spanner```.
|
||||||
|
|
||||||
2. Add the required inputs for your [instance](https://docs.cloud.google.com/spanner/docs/instances) in the configuration pop-up, then click "Save". You can update this configuration at any time in the "Configure" tab.
|
2. Add the required inputs for your [instance](https://docs.cloud.google.com/spanner/docs/instances) in the configuration pop-up, then click "Save". You can update this configuration at any time in the "Configure" tab.
|
||||||
|
|
||||||
|
|||||||
@@ -11,11 +11,18 @@ The MCP Toolbox for Databases Server gives AI-powered development tools the abil
|
|||||||
|
|
||||||
## Install & Configuration
|
## Install & Configuration
|
||||||
|
|
||||||
1. In the Antigravity MCP Store, click the "Install" button.
|
1. In the Antigravity MCP Store, click the **Install** button. A configuration window will appear.
|
||||||
|
> [!NOTE]
|
||||||
|
> On first use, the installation process automatically downloads and uses
|
||||||
|
> [MCP Toolbox](https://www.npmjs.com/package/@toolbox-sdk/server)
|
||||||
|
> `>=0.26.0`. To update MCP Toolbox, use:
|
||||||
|
> ```npm i -g @toolbox-sdk/server@latest```
|
||||||
|
> To always run the latest version, update the MCP server configuration to use:
|
||||||
|
> ```npx -y @toolbox-sdk/server@latest```.
|
||||||
|
|
||||||
2. Create your [`tools.yaml` configuration file](https://googleapis.github.io/genai-toolbox/getting-started/configure/).
|
3. Create your [`tools.yaml` configuration file](https://googleapis.github.io/genai-toolbox/getting-started/configure/).
|
||||||
|
|
||||||
3. Click "View raw config" and update the `tools.yaml` path with the full absolute path to your file.
|
4. In the configuration window, enter the full absolute path to your `tools.yaml` file and click **Save**.
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> If you encounter issues with Windows Defender blocking the execution, you may need to configure an allowlist. See [Configure exclusions for Microsoft Defender Antivirus](https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/configure-exclusions-microsoft-defender-antivirus?view=o365-worldwide) for more details.
|
> If you encounter issues with Windows Defender blocking the execution, you may need to configure an allowlist. See [Configure exclusions for Microsoft Defender Antivirus](https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/configure-exclusions-microsoft-defender-antivirus?view=o365-worldwide) for more details.
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ most popular issues, so make sure to +1 ones you are the most interested in.
|
|||||||
## Can Toolbox be used for non-database tools?
|
## Can Toolbox be used for non-database tools?
|
||||||
|
|
||||||
**Yes!** While Toolbox is primarily focused on databases, it also supports generic
|
**Yes!** While Toolbox is primarily focused on databases, it also supports generic
|
||||||
**HTTP tools** (`kind: http`). These allow you to connect your agents to REST APIs
|
**HTTP tools** (`type: http`). These allow you to connect your agents to REST APIs
|
||||||
and other web services, enabling workflows that extend beyond database interactions.
|
and other web services, enabling workflows that extend beyond database interactions.
|
||||||
|
|
||||||
For configuration details, see the [HTTP Tools documentation](../resources/tools/http/http.md).
|
For configuration details, see the [HTTP Tools documentation](../resources/tools/http/http.md).
|
||||||
|
|||||||
18
docs/en/blogs/_index.md
Normal file
18
docs/en/blogs/_index.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
title: "Featured Articles"
|
||||||
|
weight: 3
|
||||||
|
description: Toolbox Medium Blogs
|
||||||
|
manualLink: "https://medium.com/@mcp_toolbox"
|
||||||
|
manualLinkTarget: _blank
|
||||||
|
---
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Redirecting to Featured Articles</title>
|
||||||
|
<link rel="canonical" href="https://medium.com/@mcp_toolbox"/>
|
||||||
|
<meta http-equiv="refresh" content="0;url=https://medium.com/@mcp_toolbox"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>If you are not automatically redirected, please <a href="https://medium.com/@mcp_toolbox">follow this link to our articles</a>.</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -64,7 +64,7 @@ The structured logging outputs log as JSON:
|
|||||||
"timestamp":"2024-11-04T16:45:11.987299-08:00",
|
"timestamp":"2024-11-04T16:45:11.987299-08:00",
|
||||||
"severity":"ERROR",
|
"severity":"ERROR",
|
||||||
"logging.googleapis.com/sourceLocation":{...},
|
"logging.googleapis.com/sourceLocation":{...},
|
||||||
"message":"unable to parse tool file at \"tools.yaml\": \"cloud-sql-postgres1\" is not a valid kind of data source"
|
"message":"unable to parse tool file at \"tools.yaml\": \"cloud-sql-postgres1\" is not a valid type of data source"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -183,11 +183,11 @@ Protocol (OTLP). If you would like to use a collector, please refer to this
|
|||||||
|
|
||||||
The following flags are used to determine Toolbox's telemetry configuration:
|
The following flags are used to determine Toolbox's telemetry configuration:
|
||||||
|
|
||||||
| **flag** | **type** | **description** |
|
| **flag** | **type** | **description** |
|
||||||
|----------------------------|----------|------------------------------------------------------------------------------------------------------------------|
|
|----------------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| `--telemetry-gcp` | bool | Enable exporting directly to Google Cloud Monitoring. Default is `false`. |
|
| `--telemetry-gcp` | bool | Enable exporting directly to Google Cloud Monitoring. Default is `false`. |
|
||||||
| `--telemetry-otlp` | string | Enable exporting using OpenTelemetry Protocol (OTLP) to the specified endpoint (e.g. "<http://127.0.0.1:4318>"). |
|
| `--telemetry-otlp` | string | Enable exporting using OpenTelemetry Protocol (OTLP) to the specified endpoint (e.g. "127.0.0.1:4318"). To pass an insecure endpoint here, set environment variable `OTEL_EXPORTER_OTLP_INSECURE=true`. |
|
||||||
| `--telemetry-service-name` | string | Sets the value of the `service.name` resource attribute. Default is `toolbox`. |
|
| `--telemetry-service-name` | string | Sets the value of the `service.name` resource attribute. Default is `toolbox`. |
|
||||||
|
|
||||||
In addition to the flags noted above, you can also make additional configuration
|
In addition to the flags noted above, you can also make additional configuration
|
||||||
for OpenTelemetry via the [General SDK Configuration][sdk-configuration] through
|
for OpenTelemetry via the [General SDK Configuration][sdk-configuration] through
|
||||||
@@ -207,5 +207,5 @@ To enable Google Cloud Exporter:
|
|||||||
To enable OTLP Exporter, provide Collector endpoint:
|
To enable OTLP Exporter, provide Collector endpoint:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./toolbox --telemetry-otlp="http://127.0.0.1:4553"
|
./toolbox --telemetry-otlp="127.0.0.1:4553"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -234,7 +234,7 @@
|
|||||||
},
|
},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"version = \"0.21.0\" # x-release-please-version\n",
|
"version = \"0.27.0\" # x-release-please-version\n",
|
||||||
"! curl -O https://storage.googleapis.com/genai-toolbox/v{version}/linux/amd64/toolbox\n",
|
"! curl -O https://storage.googleapis.com/genai-toolbox/v{version}/linux/amd64/toolbox\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Make the binary executable\n",
|
"# Make the binary executable\n",
|
||||||
@@ -300,78 +300,89 @@
|
|||||||
"# You can also upload a tools file and use that to run toolbox.\n",
|
"# You can also upload a tools file and use that to run toolbox.\n",
|
||||||
"tools_file_name = \"tools.yml\"\n",
|
"tools_file_name = \"tools.yml\"\n",
|
||||||
"file_content = f\"\"\"\n",
|
"file_content = f\"\"\"\n",
|
||||||
"sources:\n",
|
"kind: sources\n",
|
||||||
" my-pg-source:\n",
|
"name: my-pg-source\n",
|
||||||
" kind: postgres\n",
|
"type: postgres\n",
|
||||||
" host: 127.0.0.1\n",
|
"host: 127.0.0.1\n",
|
||||||
" port: 5432\n",
|
"port: 5432\n",
|
||||||
" database: toolbox_db\n",
|
"database: toolbox_db\n",
|
||||||
" user: toolbox_user\n",
|
"user: toolbox_user\n",
|
||||||
" password: my-password\n",
|
"password: my-password\n",
|
||||||
|
"---\n",
|
||||||
|
"kind: tools\n",
|
||||||
|
"name: search-hotels-by-name\n",
|
||||||
|
"type: postgres-sql\n",
|
||||||
|
"source: my-pg-source\n",
|
||||||
|
"description: Search for hotels based on name.\n",
|
||||||
|
"parameters:\n",
|
||||||
|
" - name: name\n",
|
||||||
|
" type: string\n",
|
||||||
|
" description: The name of the hotel.\n",
|
||||||
|
"statement: SELECT * FROM hotels WHERE name ILIKE '%' || \\$1 || '%';\n",
|
||||||
|
"---\n",
|
||||||
|
"kind: tools\n",
|
||||||
|
"name: search-hotels-by-location\n",
|
||||||
|
"type: postgres-sql\n",
|
||||||
|
"source: my-pg-source\n",
|
||||||
|
"description: Search for hotels based on location.\n",
|
||||||
|
"parameters:\n",
|
||||||
|
" - name: location\n",
|
||||||
|
" type: string\n",
|
||||||
|
" description: The location of the hotel.\n",
|
||||||
|
"statement: SELECT * FROM hotels WHERE location ILIKE '%' || \\$1 || '%';\n",
|
||||||
|
"---\n",
|
||||||
|
"kind: tools\n",
|
||||||
|
"name: book-hotel\n",
|
||||||
|
"type: postgres-sql\n",
|
||||||
|
"source: my-pg-source\n",
|
||||||
|
"description: >-\n",
|
||||||
|
" Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not.\n",
|
||||||
|
"parameters:\n",
|
||||||
|
" - name: hotel_id\n",
|
||||||
|
" type: string\n",
|
||||||
|
" description: The ID of the hotel to book.\n",
|
||||||
|
"statement: UPDATE hotels SET booked = B'1' WHERE id = \\$1;\n",
|
||||||
|
"---\n",
|
||||||
|
"kind: tools\n",
|
||||||
|
"name: update-hotel\n",
|
||||||
|
"type: postgres-sql\n",
|
||||||
|
"source: my-pg-source\n",
|
||||||
|
"description: >-\n",
|
||||||
|
" Update a hotel's check-in and check-out dates by its ID. Returns a message\n",
|
||||||
|
" indicating whether the hotel was successfully updated or not.\n",
|
||||||
|
"parameters:\n",
|
||||||
|
" - name: hotel_id\n",
|
||||||
|
" type: string\n",
|
||||||
|
" description: The ID of the hotel to update.\n",
|
||||||
|
" - name: checkin_date\n",
|
||||||
|
" type: string\n",
|
||||||
|
" description: The new check-in date of the hotel.\n",
|
||||||
|
" - name: checkout_date\n",
|
||||||
|
" type: string\n",
|
||||||
|
" description: The new check-out date of the hotel.\n",
|
||||||
|
"statement: >-\n",
|
||||||
|
" UPDATE hotels SET checkin_date = CAST(\\$2 as date), checkout_date = CAST(\\$3\n",
|
||||||
|
" as date) WHERE id = \\$1;\n",
|
||||||
|
"---\n",
|
||||||
|
"kind: tools\n",
|
||||||
|
"name: cancel-hotel\n",
|
||||||
|
"type: postgres-sql\n",
|
||||||
|
"source: my-pg-source\n",
|
||||||
|
"description: Cancel a hotel by its ID.\n",
|
||||||
|
"parameters:\n",
|
||||||
|
" - name: hotel_id\n",
|
||||||
|
" type: string\n",
|
||||||
|
" description: The ID of the hotel to cancel.\n",
|
||||||
|
"statement: UPDATE hotels SET booked = B'0' WHERE id = \\$1;\n",
|
||||||
|
"---\n",
|
||||||
|
"kind: toolsets\n",
|
||||||
|
"name: my-toolset\n",
|
||||||
"tools:\n",
|
"tools:\n",
|
||||||
" search-hotels-by-name:\n",
|
" - search-hotels-by-name\n",
|
||||||
" kind: postgres-sql\n",
|
" - search-hotels-by-location\n",
|
||||||
" source: my-pg-source\n",
|
" - book-hotel\n",
|
||||||
" description: Search for hotels based on name.\n",
|
" - update-hotel\n",
|
||||||
" parameters:\n",
|
" - cancel-hotel\n",
|
||||||
" - name: name\n",
|
|
||||||
" type: string\n",
|
|
||||||
" description: The name of the hotel.\n",
|
|
||||||
" statement: SELECT * FROM hotels WHERE name ILIKE '%' || \\$1 || '%';\n",
|
|
||||||
" search-hotels-by-location:\n",
|
|
||||||
" kind: postgres-sql\n",
|
|
||||||
" source: my-pg-source\n",
|
|
||||||
" description: Search for hotels based on location.\n",
|
|
||||||
" parameters:\n",
|
|
||||||
" - name: location\n",
|
|
||||||
" type: string\n",
|
|
||||||
" description: The location of the hotel.\n",
|
|
||||||
" statement: SELECT * FROM hotels WHERE location ILIKE '%' || \\$1 || '%';\n",
|
|
||||||
" book-hotel:\n",
|
|
||||||
" kind: postgres-sql\n",
|
|
||||||
" source: my-pg-source\n",
|
|
||||||
" description: >-\n",
|
|
||||||
" Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not.\n",
|
|
||||||
" parameters:\n",
|
|
||||||
" - name: hotel_id\n",
|
|
||||||
" type: string\n",
|
|
||||||
" description: The ID of the hotel to book.\n",
|
|
||||||
" statement: UPDATE hotels SET booked = B'1' WHERE id = \\$1;\n",
|
|
||||||
" update-hotel:\n",
|
|
||||||
" kind: postgres-sql\n",
|
|
||||||
" source: my-pg-source\n",
|
|
||||||
" description: >-\n",
|
|
||||||
" Update a hotel's check-in and check-out dates by its ID. Returns a message\n",
|
|
||||||
" indicating whether the hotel was successfully updated or not.\n",
|
|
||||||
" parameters:\n",
|
|
||||||
" - name: hotel_id\n",
|
|
||||||
" type: string\n",
|
|
||||||
" description: The ID of the hotel to update.\n",
|
|
||||||
" - name: checkin_date\n",
|
|
||||||
" type: string\n",
|
|
||||||
" description: The new check-in date of the hotel.\n",
|
|
||||||
" - name: checkout_date\n",
|
|
||||||
" type: string\n",
|
|
||||||
" description: The new check-out date of the hotel.\n",
|
|
||||||
" statement: >-\n",
|
|
||||||
" UPDATE hotels SET checkin_date = CAST(\\$2 as date), checkout_date = CAST(\\$3\n",
|
|
||||||
" as date) WHERE id = \\$1;\n",
|
|
||||||
" cancel-hotel:\n",
|
|
||||||
" kind: postgres-sql\n",
|
|
||||||
" source: my-pg-source\n",
|
|
||||||
" description: Cancel a hotel by its ID.\n",
|
|
||||||
" parameters:\n",
|
|
||||||
" - name: hotel_id\n",
|
|
||||||
" type: string\n",
|
|
||||||
" description: The ID of the hotel to cancel.\n",
|
|
||||||
" statement: UPDATE hotels SET booked = B'0' WHERE id = \\$1;\n",
|
|
||||||
"toolsets:\n",
|
|
||||||
" my-toolset:\n",
|
|
||||||
" - search-hotels-by-name\n",
|
|
||||||
" - search-hotels-by-location\n",
|
|
||||||
" - book-hotel\n",
|
|
||||||
" - update-hotel\n",
|
|
||||||
" - cancel-hotel\n",
|
|
||||||
"\"\"\""
|
"\"\"\""
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -509,8 +520,7 @@
|
|||||||
},
|
},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"! pip install toolbox-core --quiet\n",
|
"! pip install google-adk[toolbox] --quiet"
|
||||||
"! pip install google-adk --quiet"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -525,14 +535,18 @@
|
|||||||
"from google.adk.runners import Runner\n",
|
"from google.adk.runners import Runner\n",
|
||||||
"from google.adk.sessions import InMemorySessionService\n",
|
"from google.adk.sessions import InMemorySessionService\n",
|
||||||
"from google.adk.artifacts.in_memory_artifact_service import InMemoryArtifactService\n",
|
"from google.adk.artifacts.in_memory_artifact_service import InMemoryArtifactService\n",
|
||||||
|
"from google.adk.tools.toolbox_toolset import ToolboxToolset\n",
|
||||||
"from google.genai import types\n",
|
"from google.genai import types\n",
|
||||||
"from toolbox_core import ToolboxSyncClient\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"import os\n",
|
"import os\n",
|
||||||
"# TODO(developer): replace this with your Google API key\n",
|
"# TODO(developer): replace this with your Google API key\n",
|
||||||
"os.environ['GOOGLE_API_KEY'] = \"<GOOGLE_API_KEY>\"\n",
|
"os.environ['GOOGLE_API_KEY'] = \"<GOOGLE_API_KEY>\"\n",
|
||||||
"\n",
|
"\n",
|
||||||
"toolbox_client = ToolboxSyncClient(\"http://127.0.0.1:5000\")\n",
|
"# Configure toolset\n",
|
||||||
|
"toolset = ToolboxToolset(\n",
|
||||||
|
" server_url=\"http://127.0.0.1:5000\",\n",
|
||||||
|
" toolset_name=\"my-toolset\"\n",
|
||||||
|
")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"prompt = \"\"\"\n",
|
"prompt = \"\"\"\n",
|
||||||
" You're a helpful hotel assistant. You handle hotel searching, booking and\n",
|
" You're a helpful hotel assistant. You handle hotel searching, booking and\n",
|
||||||
@@ -549,7 +563,7 @@
|
|||||||
" name='hotel_agent',\n",
|
" name='hotel_agent',\n",
|
||||||
" description='A helpful AI assistant.',\n",
|
" description='A helpful AI assistant.',\n",
|
||||||
" instruction=prompt,\n",
|
" instruction=prompt,\n",
|
||||||
" tools=toolbox_client.load_toolset(\"my-toolset\"),\n",
|
" tools=[toolset],\n",
|
||||||
")\n",
|
")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"session_service = InMemorySessionService()\n",
|
"session_service = InMemorySessionService()\n",
|
||||||
|
|||||||
@@ -36,14 +36,14 @@ Toolbox should have access to. Most tools will have at least one source to
|
|||||||
execute against.
|
execute against.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
sources:
|
kind: sources
|
||||||
my-pg-source:
|
name: my-pg-source
|
||||||
kind: postgres
|
type: postgres
|
||||||
host: 127.0.0.1
|
host: 127.0.0.1
|
||||||
port: 5432
|
port: 5432
|
||||||
database: toolbox_db
|
database: toolbox_db
|
||||||
user: ${USER_NAME}
|
user: ${USER_NAME}
|
||||||
password: ${PASSWORD}
|
password: ${PASSWORD}
|
||||||
```
|
```
|
||||||
|
|
||||||
For more details on configuring different types of sources, see the
|
For more details on configuring different types of sources, see the
|
||||||
@@ -52,20 +52,20 @@ For more details on configuring different types of sources, see the
|
|||||||
### Tools
|
### Tools
|
||||||
|
|
||||||
The `tools` section of your `tools.yaml` defines the actions your agent can
|
The `tools` section of your `tools.yaml` defines the actions your agent can
|
||||||
take: what kind of tool it is, which source(s) it affects, what parameters it
|
take: what type of tool it is, which source(s) it affects, what parameters it
|
||||||
uses, etc.
|
uses, etc.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
tools:
|
kind: tools
|
||||||
search-hotels-by-name:
|
name: search-hotels-by-name
|
||||||
kind: postgres-sql
|
type: postgres-sql
|
||||||
source: my-pg-source
|
source: my-pg-source
|
||||||
description: Search for hotels based on name.
|
description: Search for hotels based on name.
|
||||||
parameters:
|
parameters:
|
||||||
- name: name
|
- name: name
|
||||||
type: string
|
type: string
|
||||||
description: The name of the hotel.
|
description: The name of the hotel.
|
||||||
statement: SELECT * FROM hotels WHERE name ILIKE '%' || $1 || '%';
|
statement: SELECT * FROM hotels WHERE name ILIKE '%' || $1 || '%';
|
||||||
```
|
```
|
||||||
|
|
||||||
For more details on configuring different types of tools, see the
|
For more details on configuring different types of tools, see the
|
||||||
@@ -78,13 +78,17 @@ that you want to be able to load together. This can be useful for defining
|
|||||||
different sets for different agents or different applications.
|
different sets for different agents or different applications.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
toolsets:
|
kind: toolsets
|
||||||
my_first_toolset:
|
name: my_first_toolset
|
||||||
- my_first_tool
|
tools:
|
||||||
- my_second_tool
|
- my_first_tool
|
||||||
my_second_toolset:
|
- my_second_tool
|
||||||
- my_second_tool
|
---
|
||||||
- my_third_tool
|
kind: toolsets
|
||||||
|
name: my_second_toolset
|
||||||
|
tools:
|
||||||
|
- my_second_tool
|
||||||
|
- my_third_tool
|
||||||
```
|
```
|
||||||
|
|
||||||
You can load toolsets by name:
|
You can load toolsets by name:
|
||||||
@@ -103,14 +107,14 @@ The `prompts` section of your `tools.yaml` defines the templates containing
|
|||||||
structured messages and instructions for interacting with language models.
|
structured messages and instructions for interacting with language models.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
prompts:
|
kind: prompts
|
||||||
code_review:
|
name: code_review
|
||||||
description: "Asks the LLM to analyze code quality and suggest improvements."
|
description: "Asks the LLM to analyze code quality and suggest improvements."
|
||||||
messages:
|
messages:
|
||||||
- content: "Please review the following code for quality, correctness, and potential improvements: \n\n{{.code}}"
|
- content: "Please review the following code for quality, correctness, and potential improvements: \n\n{{.code}}"
|
||||||
arguments:
|
arguments:
|
||||||
- name: "code"
|
- name: "code"
|
||||||
description: "The code to review"
|
description: "The code to review"
|
||||||
```
|
```
|
||||||
|
|
||||||
For more details on configuring different types of prompts, see the
|
For more details on configuring different types of prompts, see the
|
||||||
|
|||||||
@@ -16,6 +16,12 @@ Databases” as its initial development predated MCP, but was renamed to align
|
|||||||
with recently added MCP compatibility.
|
with recently added MCP compatibility.
|
||||||
{{< /notice >}}
|
{{< /notice >}}
|
||||||
|
|
||||||
|
{{< notice note >}}
|
||||||
|
This document has been updated to support the configuration file v2 format. To
|
||||||
|
view documentation with configuration file v1 format, please navigate to the
|
||||||
|
top-right menu and select versions v0.26.0 or older.
|
||||||
|
{{< /notice >}}
|
||||||
|
|
||||||
## Why Toolbox?
|
## Why Toolbox?
|
||||||
|
|
||||||
Toolbox helps you build Gen AI tools that let your agents access data in your
|
Toolbox helps you build Gen AI tools that let your agents access data in your
|
||||||
@@ -71,6 +77,22 @@ redeploying your application.
|
|||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
|
### Quickstart: Running Toolbox using NPX
|
||||||
|
|
||||||
|
You can run Toolbox directly with a [configuration file](../configure.md):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npx @toolbox-sdk/server --tools-file tools.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
This runs the latest version of the toolbox server with your configuration file.
|
||||||
|
|
||||||
|
{{< notice note >}}
|
||||||
|
This method should only be used for non-production use cases such as
|
||||||
|
experimentation. For any production use-cases, please consider [Installing the
|
||||||
|
server](#installing-the-server) and then [running it](#running-the-server).
|
||||||
|
{{< /notice >}}
|
||||||
|
|
||||||
### Installing the server
|
### Installing the server
|
||||||
|
|
||||||
For the latest version, check the [releases page][releases] and use the
|
For the latest version, check the [releases page][releases] and use the
|
||||||
@@ -87,7 +109,7 @@ To install Toolbox as a binary on Linux (AMD64):
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
# see releases page for other versions
|
# see releases page for other versions
|
||||||
export VERSION=0.21.0
|
export VERSION=0.27.0
|
||||||
curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/linux/amd64/toolbox
|
curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/linux/amd64/toolbox
|
||||||
chmod +x toolbox
|
chmod +x toolbox
|
||||||
```
|
```
|
||||||
@@ -98,7 +120,7 @@ To install Toolbox as a binary on macOS (Apple Silicon):
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
# see releases page for other versions
|
# see releases page for other versions
|
||||||
export VERSION=0.21.0
|
export VERSION=0.27.0
|
||||||
curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/darwin/arm64/toolbox
|
curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/darwin/arm64/toolbox
|
||||||
chmod +x toolbox
|
chmod +x toolbox
|
||||||
```
|
```
|
||||||
@@ -109,19 +131,29 @@ To install Toolbox as a binary on macOS (Intel):
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
# see releases page for other versions
|
# see releases page for other versions
|
||||||
export VERSION=0.21.0
|
export VERSION=0.27.0
|
||||||
curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/darwin/amd64/toolbox
|
curl -L -o toolbox https://storage.googleapis.com/genai-toolbox/v$VERSION/darwin/amd64/toolbox
|
||||||
chmod +x toolbox
|
chmod +x toolbox
|
||||||
```
|
```
|
||||||
|
|
||||||
{{% /tab %}}
|
{{% /tab %}}
|
||||||
{{% tab header="Windows (AMD64)" lang="en" %}}
|
{{% tab header="Windows (Command Prompt)" lang="en" %}}
|
||||||
To install Toolbox as a binary on Windows (AMD64):
|
To install Toolbox as a binary on Windows (Command Prompt):
|
||||||
|
|
||||||
|
```cmd
|
||||||
|
:: see releases page for other versions
|
||||||
|
set VERSION=0.27.0
|
||||||
|
curl -o toolbox.exe "https://storage.googleapis.com/genai-toolbox/v%VERSION%/windows/amd64/toolbox.exe"
|
||||||
|
```
|
||||||
|
|
||||||
|
{{% /tab %}}
|
||||||
|
{{% tab header="Windows (PowerShell)" lang="en" %}}
|
||||||
|
To install Toolbox as a binary on Windows (PowerShell):
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
:: see releases page for other versions
|
# see releases page for other versions
|
||||||
set VERSION=0.21.0
|
$VERSION = "0.27.0"
|
||||||
curl -o toolbox.exe "https://storage.googleapis.com/genai-toolbox/v%VERSION%/windows/amd64/toolbox.exe"
|
curl.exe -o toolbox.exe "https://storage.googleapis.com/genai-toolbox/v$VERSION/windows/amd64/toolbox.exe"
|
||||||
```
|
```
|
||||||
|
|
||||||
{{% /tab %}}
|
{{% /tab %}}
|
||||||
@@ -132,7 +164,7 @@ You can also install Toolbox as a container:
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
# see releases page for other versions
|
# see releases page for other versions
|
||||||
export VERSION=0.21.0
|
export VERSION=0.27.0
|
||||||
docker pull us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:$VERSION
|
docker pull us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:$VERSION
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -151,7 +183,7 @@ To install from source, ensure you have the latest version of
|
|||||||
[Go installed](https://go.dev/doc/install), and then run the following command:
|
[Go installed](https://go.dev/doc/install), and then run the following command:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
go install github.com/googleapis/genai-toolbox@v0.21.0
|
go install github.com/googleapis/genai-toolbox@v0.27.0
|
||||||
```
|
```
|
||||||
|
|
||||||
{{% /tab %}}
|
{{% /tab %}}
|
||||||
@@ -421,13 +453,12 @@ README.](https://github.com/googleapis/mcp-toolbox-sdk-js/tree/main/packages/too
|
|||||||
|
|
||||||
#### Go
|
#### Go
|
||||||
|
|
||||||
Once you've installed the [Toolbox Go
|
|
||||||
SDK](https://pkg.go.dev/github.com/googleapis/mcp-toolbox-sdk-go/core), you can load
|
|
||||||
tools:
|
|
||||||
|
|
||||||
{{< tabpane text=true persist=header >}}
|
{{< tabpane text=true persist=header >}}
|
||||||
{{% tab header="Core" lang="en" %}}
|
{{% tab header="Core" lang="en" %}}
|
||||||
|
|
||||||
|
Once you've installed the [Go Core SDK](https://pkg.go.dev/github.com/googleapis/mcp-toolbox-sdk-go/core), you can load
|
||||||
|
tools:
|
||||||
|
|
||||||
{{< highlight go >}}
|
{{< highlight go >}}
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@@ -459,6 +490,9 @@ func main() {
|
|||||||
{{% /tab %}}
|
{{% /tab %}}
|
||||||
{{% tab header="LangChain Go" lang="en" %}}
|
{{% tab header="LangChain Go" lang="en" %}}
|
||||||
|
|
||||||
|
Once you've installed the [Go Core SDK](https://pkg.go.dev/github.com/googleapis/mcp-toolbox-sdk-go/core), you can load
|
||||||
|
tools:
|
||||||
|
|
||||||
{{< highlight go >}}
|
{{< highlight go >}}
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@@ -508,12 +542,15 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
{{< /highlight >}}
|
{{< /highlight >}}
|
||||||
For end-to-end samples on using the Toolbox Go SDK with LangChain Go, see the [project's
|
|
||||||
samples](https://github.com/googleapis/mcp-toolbox-sdk-go/tree/main/core/samples)
|
For end-to-end samples on using the Toolbox Go SDK with LangChain Go, see the [module's samples](https://github.com/googleapis/mcp-toolbox-sdk-go/tree/main/core/samples)
|
||||||
|
|
||||||
{{% /tab %}}
|
{{% /tab %}}
|
||||||
{{% tab header="Genkit Go" lang="en" %}}
|
{{% tab header="Genkit Go" lang="en" %}}
|
||||||
|
|
||||||
|
Once you've installed the [Go TBGenkit SDK](https://pkg.go.dev/github.com/googleapis/mcp-toolbox-sdk-go/tbgenkit), you can load
|
||||||
|
tools:
|
||||||
|
|
||||||
{{< highlight go >}}
|
{{< highlight go >}}
|
||||||
package main
|
package main
|
||||||
import (
|
import (
|
||||||
@@ -554,12 +591,14 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
{{< /highlight >}}
|
{{< /highlight >}}
|
||||||
For end-to-end samples on using the Toolbox Go SDK with Genkit Go, see the [project's
|
For end-to-end samples on using the Toolbox Go SDK with Genkit Go, see the [module's samples](https://github.com/googleapis/mcp-toolbox-sdk-go/tree/main/tbgenkit/samples)
|
||||||
samples](https://github.com/googleapis/mcp-toolbox-sdk-go/tree/main/tbgenkit/samples)
|
|
||||||
|
|
||||||
{{% /tab %}}
|
{{% /tab %}}
|
||||||
{{% tab header="Go GenAI" lang="en" %}}
|
{{% tab header="Go GenAI" lang="en" %}}
|
||||||
|
|
||||||
|
Once you've installed the [Go Core SDK](https://pkg.go.dev/github.com/googleapis/mcp-toolbox-sdk-go/core), you can load
|
||||||
|
tools:
|
||||||
|
|
||||||
{{< highlight go >}}
|
{{< highlight go >}}
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@@ -610,13 +649,15 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
{{< /highlight >}}
|
{{< /highlight >}}
|
||||||
For end-to-end samples on using the Toolbox Go SDK with Go GenAI, see the [project's
|
For end-to-end samples on using the Toolbox Go SDK with Go GenAI, see the [module's samples](https://github.com/googleapis/mcp-toolbox-sdk-go/tree/main/core/samples)
|
||||||
samples](https://github.com/googleapis/mcp-toolbox-sdk-go/tree/main/core/samples)
|
|
||||||
|
|
||||||
{{% /tab %}}
|
{{% /tab %}}
|
||||||
|
|
||||||
{{% tab header="OpenAI Go" lang="en" %}}
|
{{% tab header="OpenAI Go" lang="en" %}}
|
||||||
|
|
||||||
|
Once you've installed the [Go Core SDK](https://pkg.go.dev/github.com/googleapis/mcp-toolbox-sdk-go/core), you can load
|
||||||
|
tools:
|
||||||
|
|
||||||
{{< highlight go >}}
|
{{< highlight go >}}
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@@ -665,13 +706,15 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
{{< /highlight >}}
|
{{< /highlight >}}
|
||||||
For end-to-end samples on using the Toolbox Go SDK with OpenAI Go, see the [project's
|
For end-to-end samples on using the Toolbox Go SDK with OpenAI Go, see the [module's samples](https://github.com/googleapis/mcp-toolbox-sdk-go/tree/main/core/samples)
|
||||||
samples](https://github.com/googleapis/mcp-toolbox-sdk-go/tree/main/core/samples)
|
|
||||||
|
|
||||||
{{% /tab %}}
|
{{% /tab %}}
|
||||||
|
|
||||||
{{% tab header="ADK Go" lang="en" %}}
|
{{% tab header="ADK Go" lang="en" %}}
|
||||||
|
|
||||||
|
Once you've installed the [Go TBADK SDK](https://pkg.go.dev/github.com/googleapis/mcp-toolbox-sdk-go/tbadk), you can load
|
||||||
|
tools:
|
||||||
|
|
||||||
{{< highlight go >}}
|
{{< highlight go >}}
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@@ -700,8 +743,7 @@ func main() {
|
|||||||
|
|
||||||
{{< /highlight >}}
|
{{< /highlight >}}
|
||||||
|
|
||||||
For end-to-end samples on using the Toolbox Go SDK with ADK Go, see the [project's
|
For end-to-end samples on using the Toolbox Go SDK with ADK Go, see the [module's samples](https://github.com/googleapis/mcp-toolbox-sdk-go/tree/main/tbadk/samples)
|
||||||
samples](https://github.com/googleapis/mcp-toolbox-sdk-go/tree/main/tbadk/samples)
|
|
||||||
|
|
||||||
{{% /tab %}}
|
{{% /tab %}}
|
||||||
{{< /tabpane >}}
|
{{< /tabpane >}}
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 241 KiB After Width: | Height: | Size: 271 KiB |
@@ -52,7 +52,7 @@ runtime](https://research.google.com/colaboratory/local-runtimes.html).
|
|||||||
{{< tabpane persist=header >}}
|
{{< tabpane persist=header >}}
|
||||||
{{< tab header="ADK" lang="bash" >}}
|
{{< tab header="ADK" lang="bash" >}}
|
||||||
|
|
||||||
pip install toolbox-core
|
pip install google-adk[toolbox]
|
||||||
{{< /tab >}}
|
{{< /tab >}}
|
||||||
{{< tab header="Langchain" lang="bash" >}}
|
{{< tab header="Langchain" lang="bash" >}}
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ pip install toolbox-core
|
|||||||
{{< tabpane persist=header >}}
|
{{< tabpane persist=header >}}
|
||||||
{{< tab header="ADK" lang="bash" >}}
|
{{< tab header="ADK" lang="bash" >}}
|
||||||
|
|
||||||
pip install google-adk
|
# No other dependencies required for ADK
|
||||||
{{< /tab >}}
|
{{< /tab >}}
|
||||||
{{< tab header="Langchain" lang="bash" >}}
|
{{< tab header="Langchain" lang="bash" >}}
|
||||||
|
|
||||||
@@ -115,7 +115,7 @@ pip install google-genai
|
|||||||
|
|
||||||
1. Update `my_agent/agent.py` with the following content to connect to Toolbox:
|
1. Update `my_agent/agent.py` with the following content to connect to Toolbox:
|
||||||
```py
|
```py
|
||||||
{{< include "quickstart/python/adk/quickstart.py" >}}
|
{{< regionInclude "quickstart/python/adk/quickstart.py" "quickstart" >}}
|
||||||
```
|
```
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
|
|||||||
@@ -39,14 +39,39 @@ from Toolbox.
|
|||||||
go mod init main
|
go mod init main
|
||||||
```
|
```
|
||||||
|
|
||||||
1. In a new terminal, install the
|
1. In a new terminal, install the Go SDK Module:
|
||||||
[SDK](https://pkg.go.dev/github.com/googleapis/mcp-toolbox-sdk-go).
|
{{< notice warning >}}
|
||||||
|
Breaking Change Notice: As of version `0.6.0`, this SDK has transitioned to a multi-module structure.
|
||||||
|
* For new versions (`v0.6.0`+): You must import specific modules (e.g., `go get github.com/googleapis/mcp-toolbox-sdk-go/core`).
|
||||||
|
* For older versions (`v0.5.1` and below): The SDK remains a single-module library (`go get github.com/googleapis/mcp-toolbox-sdk-go`).
|
||||||
|
* Please update your imports and `go.mod` accordingly when upgrading.
|
||||||
|
{{< /notice >}}
|
||||||
|
|
||||||
```bash
|
{{< tabpane persist=header >}}
|
||||||
go get github.com/googleapis/mcp-toolbox-sdk-go
|
{{< tab header="LangChain Go" lang="bash" >}}
|
||||||
```
|
go get github.com/googleapis/mcp-toolbox-sdk-go/core
|
||||||
|
{{< /tab >}}
|
||||||
|
|
||||||
1. Create a new file named `hotelagent.go` and copy the following code to create
|
{{< tab header="Genkit Go" lang="bash" >}}
|
||||||
|
go get github.com/googleapis/mcp-toolbox-sdk-go/core
|
||||||
|
go get github.com/googleapis/mcp-toolbox-sdk-go/tbgenkit
|
||||||
|
{{< /tab >}}
|
||||||
|
|
||||||
|
{{< tab header="Go GenAI" lang="bash" >}}
|
||||||
|
go get github.com/googleapis/mcp-toolbox-sdk-go/core
|
||||||
|
{{< /tab >}}
|
||||||
|
|
||||||
|
{{< tab header="OpenAI Go" lang="bash" >}}
|
||||||
|
go get github.com/googleapis/mcp-toolbox-sdk-go/core
|
||||||
|
{{< /tab >}}
|
||||||
|
|
||||||
|
{{< tab header="ADK Go" lang="bash" >}}
|
||||||
|
go get github.com/googleapis/mcp-toolbox-sdk-go/core
|
||||||
|
go get github.com/googleapis/mcp-toolbox-sdk-go/tbadk
|
||||||
|
{{< /tab >}}
|
||||||
|
{{< /tabpane >}}
|
||||||
|
|
||||||
|
2. Create a new file named `hotelagent.go` and copy the following code to create
|
||||||
an agent:
|
an agent:
|
||||||
|
|
||||||
{{< tabpane persist=header >}}
|
{{< tabpane persist=header >}}
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ In this section, we will download Toolbox, configure our tools in a
|
|||||||
<!-- {x-release-please-start-version} -->
|
<!-- {x-release-please-start-version} -->
|
||||||
```bash
|
```bash
|
||||||
export OS="linux/amd64" # one of linux/amd64, darwin/arm64, darwin/amd64, or windows/amd64
|
export OS="linux/amd64" # one of linux/amd64, darwin/arm64, darwin/amd64, or windows/amd64
|
||||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.21.0/$OS/toolbox
|
curl -O https://storage.googleapis.com/genai-toolbox/v0.27.0/$OS/toolbox
|
||||||
```
|
```
|
||||||
<!-- {x-release-please-end} -->
|
<!-- {x-release-please-end} -->
|
||||||
|
|
||||||
@@ -125,78 +125,89 @@ In this section, we will download Toolbox, configure our tools in a
|
|||||||
{{< /notice >}}
|
{{< /notice >}}
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
sources:
|
kind: sources
|
||||||
my-pg-source:
|
name: my-pg-source
|
||||||
kind: postgres
|
type: postgres
|
||||||
host: 127.0.0.1
|
host: 127.0.0.1
|
||||||
port: 5432
|
port: 5432
|
||||||
database: toolbox_db
|
database: toolbox_db
|
||||||
user: toolbox_user
|
user: toolbox_user
|
||||||
password: my-password
|
password: my-password
|
||||||
|
---
|
||||||
|
kind: tools
|
||||||
|
name: search-hotels-by-name
|
||||||
|
type: postgres-sql
|
||||||
|
source: my-pg-source
|
||||||
|
description: Search for hotels based on name.
|
||||||
|
parameters:
|
||||||
|
- name: name
|
||||||
|
type: string
|
||||||
|
description: The name of the hotel.
|
||||||
|
statement: SELECT * FROM hotels WHERE name ILIKE '%' || $1 || '%';
|
||||||
|
---
|
||||||
|
kind: tools
|
||||||
|
name: search-hotels-by-location
|
||||||
|
type: postgres-sql
|
||||||
|
source: my-pg-source
|
||||||
|
description: Search for hotels based on location.
|
||||||
|
parameters:
|
||||||
|
- name: location
|
||||||
|
type: string
|
||||||
|
description: The location of the hotel.
|
||||||
|
statement: SELECT * FROM hotels WHERE location ILIKE '%' || $1 || '%';
|
||||||
|
---
|
||||||
|
kind: tools
|
||||||
|
name: book-hotel
|
||||||
|
type: postgres-sql
|
||||||
|
source: my-pg-source
|
||||||
|
description: >-
|
||||||
|
Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not.
|
||||||
|
parameters:
|
||||||
|
- name: hotel_id
|
||||||
|
type: string
|
||||||
|
description: The ID of the hotel to book.
|
||||||
|
statement: UPDATE hotels SET booked = B'1' WHERE id = $1;
|
||||||
|
---
|
||||||
|
kind: tools
|
||||||
|
name: update-hotel
|
||||||
|
type: postgres-sql
|
||||||
|
source: my-pg-source
|
||||||
|
description: >-
|
||||||
|
Update a hotel's check-in and check-out dates by its ID. Returns a message
|
||||||
|
indicating whether the hotel was successfully updated or not.
|
||||||
|
parameters:
|
||||||
|
- name: hotel_id
|
||||||
|
type: string
|
||||||
|
description: The ID of the hotel to update.
|
||||||
|
- name: checkin_date
|
||||||
|
type: string
|
||||||
|
description: The new check-in date of the hotel.
|
||||||
|
- name: checkout_date
|
||||||
|
type: string
|
||||||
|
description: The new check-out date of the hotel.
|
||||||
|
statement: >-
|
||||||
|
UPDATE hotels SET checkin_date = CAST($2 as date), checkout_date = CAST($3
|
||||||
|
as date) WHERE id = $1;
|
||||||
|
---
|
||||||
|
kind: tools
|
||||||
|
name: cancel-hotel
|
||||||
|
type: postgres-sql
|
||||||
|
source: my-pg-source
|
||||||
|
description: Cancel a hotel by its ID.
|
||||||
|
parameters:
|
||||||
|
- name: hotel_id
|
||||||
|
type: string
|
||||||
|
description: The ID of the hotel to cancel.
|
||||||
|
statement: UPDATE hotels SET booked = B'0' WHERE id = $1;
|
||||||
|
---
|
||||||
|
kind: toolsets
|
||||||
|
name: my-toolset
|
||||||
tools:
|
tools:
|
||||||
search-hotels-by-name:
|
- search-hotels-by-name
|
||||||
kind: postgres-sql
|
- search-hotels-by-location
|
||||||
source: my-pg-source
|
- book-hotel
|
||||||
description: Search for hotels based on name.
|
- update-hotel
|
||||||
parameters:
|
- cancel-hotel
|
||||||
- name: name
|
|
||||||
type: string
|
|
||||||
description: The name of the hotel.
|
|
||||||
statement: SELECT * FROM hotels WHERE name ILIKE '%' || $1 || '%';
|
|
||||||
search-hotels-by-location:
|
|
||||||
kind: postgres-sql
|
|
||||||
source: my-pg-source
|
|
||||||
description: Search for hotels based on location.
|
|
||||||
parameters:
|
|
||||||
- name: location
|
|
||||||
type: string
|
|
||||||
description: The location of the hotel.
|
|
||||||
statement: SELECT * FROM hotels WHERE location ILIKE '%' || $1 || '%';
|
|
||||||
book-hotel:
|
|
||||||
kind: postgres-sql
|
|
||||||
source: my-pg-source
|
|
||||||
description: >-
|
|
||||||
Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not.
|
|
||||||
parameters:
|
|
||||||
- name: hotel_id
|
|
||||||
type: string
|
|
||||||
description: The ID of the hotel to book.
|
|
||||||
statement: UPDATE hotels SET booked = B'1' WHERE id = $1;
|
|
||||||
update-hotel:
|
|
||||||
kind: postgres-sql
|
|
||||||
source: my-pg-source
|
|
||||||
description: >-
|
|
||||||
Update a hotel's check-in and check-out dates by its ID. Returns a message
|
|
||||||
indicating whether the hotel was successfully updated or not.
|
|
||||||
parameters:
|
|
||||||
- name: hotel_id
|
|
||||||
type: string
|
|
||||||
description: The ID of the hotel to update.
|
|
||||||
- name: checkin_date
|
|
||||||
type: string
|
|
||||||
description: The new check-in date of the hotel.
|
|
||||||
- name: checkout_date
|
|
||||||
type: string
|
|
||||||
description: The new check-out date of the hotel.
|
|
||||||
statement: >-
|
|
||||||
UPDATE hotels SET checkin_date = CAST($2 as date), checkout_date = CAST($3
|
|
||||||
as date) WHERE id = $1;
|
|
||||||
cancel-hotel:
|
|
||||||
kind: postgres-sql
|
|
||||||
source: my-pg-source
|
|
||||||
description: Cancel a hotel by its ID.
|
|
||||||
parameters:
|
|
||||||
- name: hotel_id
|
|
||||||
type: string
|
|
||||||
description: The ID of the hotel to cancel.
|
|
||||||
statement: UPDATE hotels SET booked = B'0' WHERE id = $1;
|
|
||||||
toolsets:
|
|
||||||
my-toolset:
|
|
||||||
- search-hotels-by-name
|
|
||||||
- search-hotels-by-location
|
|
||||||
- book-hotel
|
|
||||||
- update-hotel
|
|
||||||
- cancel-hotel
|
|
||||||
```
|
```
|
||||||
|
|
||||||
For more info on tools, check out the
|
For more info on tools, check out the
|
||||||
|
|||||||
251
docs/en/getting-started/prompts_quickstart_gemini_cli.md
Normal file
251
docs/en/getting-started/prompts_quickstart_gemini_cli.md
Normal file
@@ -0,0 +1,251 @@
|
|||||||
|
---
|
||||||
|
title: "Prompts using Gemini CLI"
|
||||||
|
type: docs
|
||||||
|
weight: 5
|
||||||
|
description: >
|
||||||
|
How to get started using Toolbox prompts locally with PostgreSQL and [Gemini CLI](https://pypi.org/project/gemini-cli/).
|
||||||
|
---
|
||||||
|
|
||||||
|
## Before you begin
|
||||||
|
|
||||||
|
This guide assumes you have already done the following:
|
||||||
|
|
||||||
|
1. Installed [PostgreSQL 16+ and the `psql` client][install-postgres].
|
||||||
|
|
||||||
|
[install-postgres]: https://www.postgresql.org/download/
|
||||||
|
|
||||||
|
## Step 1: Set up your database
|
||||||
|
|
||||||
|
In this section, we will create a database, insert some data that needs to be
|
||||||
|
accessed by our agent, and create a database user for Toolbox to connect with.
|
||||||
|
|
||||||
|
1. Connect to postgres using the `psql` command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
psql -h 127.0.0.1 -U postgres
|
||||||
|
```
|
||||||
|
|
||||||
|
Here, `postgres` denotes the default postgres superuser.
|
||||||
|
|
||||||
|
{{< notice info >}}
|
||||||
|
|
||||||
|
#### **Having trouble connecting?**
|
||||||
|
|
||||||
|
* **Password Prompt:** If you are prompted for a password for the `postgres`
|
||||||
|
user and do not know it (or a blank password doesn't work), your PostgreSQL
|
||||||
|
installation might require a password or a different authentication method.
|
||||||
|
* **`FATAL: role "postgres" does not exist`:** This error means the default
|
||||||
|
`postgres` superuser role isn't available under that name on your system.
|
||||||
|
* **`Connection refused`:** Ensure your PostgreSQL server is actually running.
|
||||||
|
You can typically check with `sudo systemctl status postgresql` and start it
|
||||||
|
with `sudo systemctl start postgresql` on Linux systems.
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
#### **Common Solution**
|
||||||
|
|
||||||
|
For password issues or if the `postgres` role seems inaccessible directly, try
|
||||||
|
switching to the `postgres` operating system user first. This user often has
|
||||||
|
permission to connect without a password for local connections (this is called
|
||||||
|
peer authentication).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -i -u postgres
|
||||||
|
psql -h 127.0.0.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Once you are in the `psql` shell using this method, you can proceed with the
|
||||||
|
database creation steps below. Afterwards, type `\q` to exit `psql`, and then
|
||||||
|
`exit` to return to your normal user shell.
|
||||||
|
|
||||||
|
If desired, once connected to `psql` as the `postgres` OS user, you can set a
|
||||||
|
password for the `postgres` *database* user using: `ALTER USER postgres WITH
|
||||||
|
PASSWORD 'your_chosen_password';`. This would allow direct connection with `-U
|
||||||
|
postgres` and a password next time.
|
||||||
|
{{< /notice >}}
|
||||||
|
|
||||||
|
1. Create a new database and a new user:
|
||||||
|
|
||||||
|
{{< notice tip >}}
|
||||||
|
For a real application, it's best to follow the principle of least permission
|
||||||
|
and only grant the privileges your application needs.
|
||||||
|
{{< /notice >}}
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE USER toolbox_user WITH PASSWORD 'my-password';
|
||||||
|
|
||||||
|
CREATE DATABASE toolbox_db;
|
||||||
|
GRANT ALL PRIVILEGES ON DATABASE toolbox_db TO toolbox_user;
|
||||||
|
|
||||||
|
ALTER DATABASE toolbox_db OWNER TO toolbox_user;
|
||||||
|
```
|
||||||
|
|
||||||
|
1. End the database session:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
\q
|
||||||
|
```
|
||||||
|
|
||||||
|
(If you used `sudo -i -u postgres` and then `psql`, remember you might also
|
||||||
|
need to type `exit` after `\q` to leave the `postgres` user's shell
|
||||||
|
session.)
|
||||||
|
|
||||||
|
1. Connect to your database with your new user:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
psql -h 127.0.0.1 -U toolbox_user -d toolbox_db
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Create the required tables using the following commands:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE users (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
username VARCHAR(50) NOT NULL,
|
||||||
|
email VARCHAR(100) UNIQUE NOT NULL,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE restaurants (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
name VARCHAR(100) NOT NULL,
|
||||||
|
location VARCHAR(100)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE reviews (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
user_id INT REFERENCES users(id),
|
||||||
|
restaurant_id INT REFERENCES restaurants(id),
|
||||||
|
rating INT CHECK (rating >= 1 AND rating <= 5),
|
||||||
|
review_text TEXT,
|
||||||
|
is_published BOOLEAN DEFAULT false,
|
||||||
|
moderation_status VARCHAR(50) DEFAULT 'pending_manual_review',
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Insert dummy data into the tables.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
INSERT INTO users (id, username, email) VALUES
|
||||||
|
(123, 'jane_d', 'jane.d@example.com'),
|
||||||
|
(124, 'john_s', 'john.s@example.com'),
|
||||||
|
(125, 'sam_b', 'sam.b@example.com');
|
||||||
|
|
||||||
|
INSERT INTO restaurants (id, name, location) VALUES
|
||||||
|
(455, 'Pizza Palace', '123 Main St'),
|
||||||
|
(456, 'The Corner Bistro', '456 Oak Ave'),
|
||||||
|
(457, 'Sushi Spot', '789 Pine Ln');
|
||||||
|
|
||||||
|
INSERT INTO reviews (user_id, restaurant_id, rating, review_text, is_published, moderation_status) VALUES
|
||||||
|
(124, 455, 5, 'Best pizza in town! The crust was perfect.', true, 'approved'),
|
||||||
|
(125, 457, 4, 'Great sushi, very fresh. A bit pricey but worth it.', true, 'approved'),
|
||||||
|
(123, 457, 5, 'Absolutely loved the dragon roll. Will be back!', true, 'approved'),
|
||||||
|
(123, 456, 4, 'The atmosphere was lovely and the food was great. My photo upload might have been weird though.', false, 'pending_manual_review'),
|
||||||
|
(125, 456, 1, 'This review contains inappropriate language.', false, 'rejected');
|
||||||
|
```
|
||||||
|
|
||||||
|
1. End the database session:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
\q
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 2: Configure Toolbox
|
||||||
|
|
||||||
|
Create a file named `tools.yaml`. This file defines the database connection, the
|
||||||
|
SQL tools available, and the prompts the agents will use.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
kind: sources
|
||||||
|
name: my-foodiefind-db
|
||||||
|
type: postgres
|
||||||
|
host: 127.0.0.1
|
||||||
|
port: 5432
|
||||||
|
database: toolbox_db
|
||||||
|
user: toolbox_user
|
||||||
|
password: my-password
|
||||||
|
---
|
||||||
|
kind: tools
|
||||||
|
name: find_user_by_email
|
||||||
|
type: postgres-sql
|
||||||
|
source: my-foodiefind-db
|
||||||
|
description: Find a user's ID by their email address.
|
||||||
|
parameters:
|
||||||
|
- name: email
|
||||||
|
type: string
|
||||||
|
description: The email address of the user to find.
|
||||||
|
statement: SELECT id FROM users WHERE email = $1;
|
||||||
|
---
|
||||||
|
kind: tools
|
||||||
|
name: find_restaurant_by_name
|
||||||
|
type: postgres-sql
|
||||||
|
source: my-foodiefind-db
|
||||||
|
description: Find a restaurant's ID by its exact name.
|
||||||
|
parameters:
|
||||||
|
- name: name
|
||||||
|
type: string
|
||||||
|
description: The name of the restaurant to find.
|
||||||
|
statement: SELECT id FROM restaurants WHERE name = $1;
|
||||||
|
---
|
||||||
|
kind: tools
|
||||||
|
name: find_review_by_user_and_restaurant
|
||||||
|
type: postgres-sql
|
||||||
|
source: my-foodiefind-db
|
||||||
|
description: Find the full record for a specific review using the user's ID and the restaurant's ID.
|
||||||
|
parameters:
|
||||||
|
- name: user_id
|
||||||
|
type: integer
|
||||||
|
description: The numerical ID of the user.
|
||||||
|
- name: restaurant_id
|
||||||
|
type: integer
|
||||||
|
description: The numerical ID of the restaurant.
|
||||||
|
statement: SELECT * FROM reviews WHERE user_id = $1 AND restaurant_id = $2;
|
||||||
|
---
|
||||||
|
kind: prompts
|
||||||
|
name: investigate_missing_review
|
||||||
|
description: "Investigates a user's missing review by finding the user, restaurant, and the review itself, then analyzing its status."
|
||||||
|
arguments:
|
||||||
|
- name: "user_email"
|
||||||
|
description: "The email of the user who wrote the review."
|
||||||
|
- name: "restaurant_name"
|
||||||
|
description: "The name of the restaurant being reviewed."
|
||||||
|
messages:
|
||||||
|
- content: >-
|
||||||
|
**Goal:** Find the review written by the user with email '{{.user_email}}' for the restaurant named '{{.restaurant_name}}' and understand its status.
|
||||||
|
**Workflow:**
|
||||||
|
1. Use the `find_user_by_email` tool with the email '{{.user_email}}' to get the `user_id`.
|
||||||
|
2. Use the `find_restaurant_by_name` tool with the name '{{.restaurant_name}}' to get the `restaurant_id`.
|
||||||
|
3. Use the `find_review_by_user_and_restaurant` tool with the `user_id` and `restaurant_id` you just found.
|
||||||
|
4. Analyze the results from the final tool call. Examine the `is_published` and `moderation_status` fields and explain the review's status to the user in a clear, human-readable sentence.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 3: Connect to Gemini CLI
|
||||||
|
|
||||||
|
Configure the Gemini CLI to talk to your local Toolbox MCP server.
|
||||||
|
|
||||||
|
1. Open or create your Gemini settings file: `~/.gemini/settings.json`.
|
||||||
|
2. Add the following configuration to the file:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"MCPToolbox": {
|
||||||
|
"httpUrl": "http://localhost:5000/mcp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mcp": {
|
||||||
|
"allowed": ["MCPToolbox"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
3. Start Gemini CLI using
|
||||||
|
```sh
|
||||||
|
gemini
|
||||||
|
```
|
||||||
|
In case Gemini CLI is already running, use `/mcp refresh` to refresh the MCP server.
|
||||||
|
|
||||||
|
4. Use gemini slash commands to run your prompt:
|
||||||
|
```sh
|
||||||
|
/investigate_missing_review --user_email="jane.d@example.com" --restaurant_name="The Corner Bistro"
|
||||||
|
```
|
||||||
@@ -3,40 +3,43 @@ module adkgo-quickstart
|
|||||||
go 1.24.4
|
go 1.24.4
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/googleapis/mcp-toolbox-sdk-go v0.4.0
|
github.com/googleapis/mcp-toolbox-sdk-go/tbadk v0.6.0
|
||||||
google.golang.org/adk v0.1.0
|
google.golang.org/adk v0.3.0
|
||||||
google.golang.org/genai v1.35.0
|
google.golang.org/genai v1.45.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.123.0 // indirect
|
cloud.google.com/go v0.123.0 // indirect
|
||||||
cloud.google.com/go/auth v0.17.0 // indirect
|
cloud.google.com/go/auth v0.18.1 // indirect
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.9.0 // indirect
|
cloud.google.com/go/compute/metadata v0.9.0 // indirect
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||||
github.com/go-logr/logr v1.4.3 // indirect
|
github.com/go-logr/logr v1.4.3 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/google/go-cmp v0.7.0 // indirect
|
github.com/google/go-cmp v0.7.0 // indirect
|
||||||
github.com/google/s2a-go v0.1.9 // indirect
|
github.com/google/s2a-go v0.1.9 // indirect
|
||||||
|
github.com/google/safehtml v0.1.0 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.3.11 // indirect
|
||||||
github.com/googleapis/gax-go/v2 v2.15.0 // indirect
|
github.com/googleapis/gax-go/v2 v2.16.0 // indirect
|
||||||
|
github.com/googleapis/mcp-toolbox-sdk-go/core v0.6.2 // indirect
|
||||||
github.com/gorilla/websocket v1.5.3 // indirect
|
github.com/gorilla/websocket v1.5.3 // indirect
|
||||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect
|
||||||
go.opentelemetry.io/otel v1.38.0 // indirect
|
go.opentelemetry.io/otel v1.39.0 // indirect
|
||||||
go.opentelemetry.io/otel/metric v1.38.0 // indirect
|
go.opentelemetry.io/otel/metric v1.39.0 // indirect
|
||||||
go.opentelemetry.io/otel/sdk v1.38.0 // indirect
|
go.opentelemetry.io/otel/sdk v1.39.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.38.0 // indirect
|
go.opentelemetry.io/otel/trace v1.39.0 // indirect
|
||||||
golang.org/x/crypto v0.43.0 // indirect
|
golang.org/x/crypto v0.47.0 // indirect
|
||||||
golang.org/x/net v0.46.0 // indirect
|
golang.org/x/net v0.49.0 // indirect
|
||||||
golang.org/x/oauth2 v0.32.0 // indirect
|
golang.org/x/oauth2 v0.34.0 // indirect
|
||||||
golang.org/x/sys v0.37.0 // indirect
|
golang.org/x/sys v0.40.0 // indirect
|
||||||
golang.org/x/text v0.30.0 // indirect
|
golang.org/x/text v0.33.0 // indirect
|
||||||
google.golang.org/api v0.255.0 // indirect
|
google.golang.org/api v0.265.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect
|
||||||
google.golang.org/grpc v1.76.0 // indirect
|
google.golang.org/grpc v1.78.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.10 // indirect
|
google.golang.org/protobuf v1.36.11 // indirect
|
||||||
rsc.io/omap v1.2.0 // indirect
|
rsc.io/omap v1.2.0 // indirect
|
||||||
rsc.io/ordered v1.1.1 // indirect
|
rsc.io/ordered v1.1.1 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY=
|
|||||||
cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
|
cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
|
||||||
cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE=
|
cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE=
|
||||||
cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU=
|
cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU=
|
||||||
cloud.google.com/go/auth v0.17.0 h1:74yCm7hCj2rUyyAocqnFzsAYXgJhrG26XCFimrc/Kz4=
|
cloud.google.com/go/auth v0.18.1 h1:IwTEx92GFUo2pJ6Qea0EU3zYvKnTAeRCODxfA/G5UWs=
|
||||||
cloud.google.com/go/auth v0.17.0/go.mod h1:6wv/t5/6rOPAX4fJiRjKkJCvswLwdet7G8+UGXt7nCQ=
|
cloud.google.com/go/auth v0.18.1/go.mod h1:GfTYoS9G3CWpRA3Va9doKN9mjPGRS+v41jmZAhBzbrA=
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
||||||
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
|
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
|
||||||
@@ -14,21 +14,21 @@ cloud.google.com/go/monitoring v1.24.3 h1:dde+gMNc0UhPZD1Azu6at2e79bfdztVDS5lvhO
|
|||||||
cloud.google.com/go/monitoring v1.24.3/go.mod h1:nYP6W0tm3N9H/bOw8am7t62YTzZY+zUeQ+Bi6+2eonI=
|
cloud.google.com/go/monitoring v1.24.3/go.mod h1:nYP6W0tm3N9H/bOw8am7t62YTzZY+zUeQ+Bi6+2eonI=
|
||||||
cloud.google.com/go/secretmanager v1.16.0 h1:19QT7ZsLJ8FSP1k+4esQvuCD7npMJml6hYzilxVyT+k=
|
cloud.google.com/go/secretmanager v1.16.0 h1:19QT7ZsLJ8FSP1k+4esQvuCD7npMJml6hYzilxVyT+k=
|
||||||
cloud.google.com/go/secretmanager v1.16.0/go.mod h1://C/e4I8D26SDTz1f3TQcddhcmiC3rMEl0S1Cakvs3Q=
|
cloud.google.com/go/secretmanager v1.16.0/go.mod h1://C/e4I8D26SDTz1f3TQcddhcmiC3rMEl0S1Cakvs3Q=
|
||||||
cloud.google.com/go/storage v1.57.1 h1:gzao6odNJ7dR3XXYvAgPK+Iw4fVPPznEPPyNjbaVkq8=
|
cloud.google.com/go/storage v1.59.2 h1:gmOAuG1opU8YvycMNpP+DvHfT9BfzzK5Cy+arP+Nocw=
|
||||||
cloud.google.com/go/storage v1.57.1/go.mod h1:329cwlpzALLgJuu8beyJ/uvQznDHpa2U5lGjWednkzg=
|
cloud.google.com/go/storage v1.59.2/go.mod h1:cMWbtM+anpC74gn6qjLh+exqYcfmB9Hqe5z6adx+CLI=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 h1:owcC2UnmsZycprQ5RfRgjydWhuoxg71LUfyiQdijZuM=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0 h1:lhhYARPUu3LmHysQ/igznQphfzynnqI3D75oUyw1HXk=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0/go.mod h1:ZPpqegjbE99EPKsu3iUWV22A04wzGPcAY/ziSIQEEgs=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0/go.mod h1:l9rva3ApbBpEJxSNYnwT9N4CDLrWgtq3u8736C5hyJw=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 h1:Ron4zCA/yk6U7WOBXhTJcDpsUBG9npumK6xw2auFltQ=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.54.0 h1:s0WlVbf9qpvkh1c/uDAPElam0WrL7fHRIidgZJ7UqZI=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0/go.mod h1:cSgYe11MCNYunTnRXrKiR/tHc0eoKjICUuWpNZoVCOo=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.54.0/go.mod h1:Mf6O40IAyB9zR/1J8nGDDPirZQQPbYJni8Yisy7NTMc=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cncf/xds/go v0.0.0-20251014123835-2ee22ca58382 h1:5IeUoAZvqwF6LcCnV99NbhrGKN6ihZgahJv5jKjmZ3k=
|
github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f h1:Y8xYupdHxryycyPlc9Y+bSQAYZnetRJ70VMVKm5CKI0=
|
||||||
github.com/cncf/xds/go v0.0.0-20251014123835-2ee22ca58382/go.mod h1:HlzOvOjVBOfTGSRXRyY0OiCS/3J1akRGQQpRO/7zyF4=
|
github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f/go.mod h1:HlzOvOjVBOfTGSRXRyY0OiCS/3J1akRGQQpRO/7zyF4=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M=
|
github.com/envoyproxy/go-control-plane v0.13.5-0.20251024222203-75eaa193e329 h1:K+fnvUM0VZ7ZFJf0n4L/BRlnsb9pL/GuDG6FqaH+PwM=
|
||||||
github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo=
|
github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo=
|
||||||
github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs=
|
github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs=
|
||||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
|
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
|
||||||
@@ -50,14 +50,18 @@ github.com/google/jsonschema-go v0.3.0 h1:6AH2TxVNtk3IlvkkhjrtbUc4S8AvO0Xii0DxIy
|
|||||||
github.com/google/jsonschema-go v0.3.0/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE=
|
github.com/google/jsonschema-go v0.3.0/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE=
|
||||||
github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
|
github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
|
||||||
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
|
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
|
||||||
|
github.com/google/safehtml v0.1.0 h1:EwLKo8qawTKfsi0orxcQAZzu07cICaBeFMegAU9eaT8=
|
||||||
|
github.com/google/safehtml v0.1.0/go.mod h1:L4KWwDsUJdECRAEpZoBn3O64bQaywRscowZjJAzjHnU=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.11 h1:vAe81Msw+8tKUxi2Dqh/NZMz7475yUvmRIkXr4oN2ao=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.11/go.mod h1:RFV7MUdlb7AgEq2v7FmMCfeSMCllAzWxFgRdusoGks8=
|
||||||
github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo=
|
github.com/googleapis/gax-go/v2 v2.16.0 h1:iHbQmKLLZrexmb0OSsNGTeSTS0HO4YvFOG8g5E4Zd0Y=
|
||||||
github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc=
|
github.com/googleapis/gax-go/v2 v2.16.0/go.mod h1:o1vfQjjNZn4+dPnRdl/4ZD7S9414Y4xA+a/6Icj6l14=
|
||||||
github.com/googleapis/mcp-toolbox-sdk-go v0.4.0 h1:SYJRZzmOyXs9anKp+dfq4rprO92KKnxNyJCCsLkW7nw=
|
github.com/googleapis/mcp-toolbox-sdk-go/core v0.6.2 h1:RgO6nEjldaORHgHVcTisxDsYHXLBki1/qIoyjdCVhuw=
|
||||||
github.com/googleapis/mcp-toolbox-sdk-go v0.4.0/go.mod h1:ivRLILO1B72J2HWCjSStemdhTWccjfW9FnEj4SAM81w=
|
github.com/googleapis/mcp-toolbox-sdk-go/core v0.6.2/go.mod h1:aIdj9c1UgMC9cCS6ZrT4x0TraBFg6R/Nt1CiOHOaMfk=
|
||||||
|
github.com/googleapis/mcp-toolbox-sdk-go/tbadk v0.6.0 h1:ckkDvuMnNlG6NB+GOvzBk9nVqw2niz2IpnlrlUb4ONk=
|
||||||
|
github.com/googleapis/mcp-toolbox-sdk-go/tbadk v0.6.0/go.mod h1:/CCFw4zUiRpPdr6DaiksLR0AblH1OMAFdfNfXbtqE20=
|
||||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
|
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
|
||||||
@@ -76,50 +80,52 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6
|
|||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ=
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg=
|
||||||
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
|
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
|
||||||
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
|
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
|
||||||
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
|
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
|
||||||
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
|
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
|
||||||
go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
|
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
|
||||||
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
|
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
|
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
|
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
|
||||||
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
|
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
|
||||||
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
|
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
|
||||||
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
|
||||||
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
|
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
|
||||||
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
|
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
|
||||||
golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY=
|
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
|
||||||
golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||||
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||||
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||||
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
|
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
||||||
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
||||||
|
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
||||||
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
||||||
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||||
google.golang.org/adk v0.1.0 h1:+w/fHuqRVolotOATlujRA+2DKUuDrFH2poRdEX2QjB8=
|
google.golang.org/adk v0.3.0 h1:gitgAKnET1F1+fFZc7VSAEo7cjK+D39mnRyqIRTzyzY=
|
||||||
google.golang.org/adk v0.1.0/go.mod h1:NvtSLoNx7UzZIiUAI1KoJQLMmt9sG3oCgiCx1TLqKFw=
|
google.golang.org/adk v0.3.0/go.mod h1:iE1Kgc8JtYHiNxfdLa9dxcV4DqTn0D8q4eqhBi012Ak=
|
||||||
google.golang.org/api v0.255.0 h1:OaF+IbRwOottVCYV2wZan7KUq7UeNUQn1BcPc4K7lE4=
|
google.golang.org/api v0.265.0 h1:FZvfUdI8nfmuNrE34aOWFPmLC+qRBEiNm3JdivTvAAU=
|
||||||
google.golang.org/api v0.255.0/go.mod h1:d1/EtvCLdtiWEV4rAEHDHGh2bCnqsWhw+M8y2ECN4a8=
|
google.golang.org/api v0.265.0/go.mod h1:uAvfEl3SLUj/7n6k+lJutcswVojHPp2Sp08jWCu8hLY=
|
||||||
google.golang.org/genai v1.35.0 h1:Jo6g25CzVqFzGrX5mhWyBgQqXAUzxcx5jeK7U74zv9c=
|
google.golang.org/genai v1.45.0 h1:s80ZpS42XW0zu/ogiOtenCio17nJ7reEFJjoCftukpA=
|
||||||
google.golang.org/genai v1.35.0/go.mod h1:A3kkl0nyBjyFlNjgxIwKq70julKbIxpSxqKO5gw/gmk=
|
google.golang.org/genai v1.45.0/go.mod h1:A3kkl0nyBjyFlNjgxIwKq70julKbIxpSxqKO5gw/gmk=
|
||||||
google.golang.org/genproto v0.0.0-20251014184007-4626949a642f h1:vLd1CJuJOUgV6qijD7KT5Y2ZtC97ll4dxjTUappMnbo=
|
google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217 h1:GvESR9BIyHUahIb0NcTum6itIWtdoglGX+rnGxm2934=
|
||||||
google.golang.org/genproto v0.0.0-20251014184007-4626949a642f/go.mod h1:PI3KrSadr00yqfv6UDvgZGFsmLqeRIwt8x4p5Oo7CdM=
|
google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:yJ2HH4EHEDTd3JiLmhds6NkJ17ITVYOdV3m3VKOnws0=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20251014184007-4626949a642f h1:OiFuztEyBivVKDvguQJYWq1yDcfAHIID/FVrPR4oiI0=
|
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20251014184007-4626949a642f/go.mod h1:kprOiu9Tr0JYyD6DORrc4Hfyk3RFXqkQ3ctHEum3ZbM=
|
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda h1:i/Q+bfisr7gq6feoJnS/DlpdwEL4ihp41fvRiM3Ork0=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 h1:H86B94AW+VfJWDqFeEbBPhEtHzJwJfTbgE2lZa54ZAQ=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||||
google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A=
|
google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc=
|
||||||
google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c=
|
google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U=
|
||||||
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||||
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
rsc.io/omap v1.2.0 h1:c1M8jchnHbzmJALzGLclfH3xDWXrPxSUHXzH5C+8Kdw=
|
rsc.io/omap v1.2.0 h1:c1M8jchnHbzmJALzGLclfH3xDWXrPxSUHXzH5C+8Kdw=
|
||||||
|
|||||||
@@ -3,35 +3,37 @@ module genai-quickstart
|
|||||||
go 1.24.6
|
go 1.24.6
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/googleapis/mcp-toolbox-sdk-go v0.4.0
|
github.com/googleapis/mcp-toolbox-sdk-go/core v0.6.2
|
||||||
google.golang.org/genai v1.35.0
|
google.golang.org/genai v1.36.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.123.0 // indirect
|
cloud.google.com/go v0.123.0 // indirect
|
||||||
cloud.google.com/go/auth v0.17.0 // indirect
|
cloud.google.com/go/auth v0.18.1 // indirect
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.9.0 // indirect
|
cloud.google.com/go/compute/metadata v0.9.0 // indirect
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||||
github.com/go-logr/logr v1.4.3 // indirect
|
github.com/go-logr/logr v1.4.3 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/google/go-cmp v0.7.0 // indirect
|
github.com/google/go-cmp v0.7.0 // indirect
|
||||||
github.com/google/s2a-go v0.1.9 // indirect
|
github.com/google/s2a-go v0.1.9 // indirect
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/googleapis/gax-go/v2 v2.15.0 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.3.11 // indirect
|
||||||
|
github.com/googleapis/gax-go/v2 v2.16.0 // indirect
|
||||||
github.com/gorilla/websocket v1.5.3 // indirect
|
github.com/gorilla/websocket v1.5.3 // indirect
|
||||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect
|
||||||
go.opentelemetry.io/otel v1.38.0 // indirect
|
go.opentelemetry.io/otel v1.39.0 // indirect
|
||||||
go.opentelemetry.io/otel/metric v1.38.0 // indirect
|
go.opentelemetry.io/otel/metric v1.39.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.38.0 // indirect
|
go.opentelemetry.io/otel/trace v1.39.0 // indirect
|
||||||
golang.org/x/crypto v0.45.0 // indirect
|
golang.org/x/crypto v0.47.0 // indirect
|
||||||
golang.org/x/net v0.47.0 // indirect
|
golang.org/x/net v0.49.0 // indirect
|
||||||
golang.org/x/oauth2 v0.32.0 // indirect
|
golang.org/x/oauth2 v0.34.0 // indirect
|
||||||
golang.org/x/sys v0.38.0 // indirect
|
golang.org/x/sys v0.40.0 // indirect
|
||||||
golang.org/x/text v0.31.0 // indirect
|
golang.org/x/text v0.33.0 // indirect
|
||||||
google.golang.org/api v0.255.0 // indirect
|
google.golang.org/api v0.265.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect
|
||||||
google.golang.org/grpc v1.76.0 // indirect
|
google.golang.org/grpc v1.78.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.10 // indirect
|
google.golang.org/protobuf v1.36.11 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY=
|
|||||||
cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
|
cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
|
||||||
cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE=
|
cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE=
|
||||||
cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU=
|
cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU=
|
||||||
cloud.google.com/go/auth v0.17.0 h1:74yCm7hCj2rUyyAocqnFzsAYXgJhrG26XCFimrc/Kz4=
|
cloud.google.com/go/auth v0.18.1 h1:IwTEx92GFUo2pJ6Qea0EU3zYvKnTAeRCODxfA/G5UWs=
|
||||||
cloud.google.com/go/auth v0.17.0/go.mod h1:6wv/t5/6rOPAX4fJiRjKkJCvswLwdet7G8+UGXt7nCQ=
|
cloud.google.com/go/auth v0.18.1/go.mod h1:GfTYoS9G3CWpRA3Va9doKN9mjPGRS+v41jmZAhBzbrA=
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
||||||
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
|
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
|
||||||
@@ -14,21 +14,21 @@ cloud.google.com/go/monitoring v1.24.3 h1:dde+gMNc0UhPZD1Azu6at2e79bfdztVDS5lvhO
|
|||||||
cloud.google.com/go/monitoring v1.24.3/go.mod h1:nYP6W0tm3N9H/bOw8am7t62YTzZY+zUeQ+Bi6+2eonI=
|
cloud.google.com/go/monitoring v1.24.3/go.mod h1:nYP6W0tm3N9H/bOw8am7t62YTzZY+zUeQ+Bi6+2eonI=
|
||||||
cloud.google.com/go/secretmanager v1.16.0 h1:19QT7ZsLJ8FSP1k+4esQvuCD7npMJml6hYzilxVyT+k=
|
cloud.google.com/go/secretmanager v1.16.0 h1:19QT7ZsLJ8FSP1k+4esQvuCD7npMJml6hYzilxVyT+k=
|
||||||
cloud.google.com/go/secretmanager v1.16.0/go.mod h1://C/e4I8D26SDTz1f3TQcddhcmiC3rMEl0S1Cakvs3Q=
|
cloud.google.com/go/secretmanager v1.16.0/go.mod h1://C/e4I8D26SDTz1f3TQcddhcmiC3rMEl0S1Cakvs3Q=
|
||||||
cloud.google.com/go/storage v1.57.1 h1:gzao6odNJ7dR3XXYvAgPK+Iw4fVPPznEPPyNjbaVkq8=
|
cloud.google.com/go/storage v1.59.2 h1:gmOAuG1opU8YvycMNpP+DvHfT9BfzzK5Cy+arP+Nocw=
|
||||||
cloud.google.com/go/storage v1.57.1/go.mod h1:329cwlpzALLgJuu8beyJ/uvQznDHpa2U5lGjWednkzg=
|
cloud.google.com/go/storage v1.59.2/go.mod h1:cMWbtM+anpC74gn6qjLh+exqYcfmB9Hqe5z6adx+CLI=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 h1:owcC2UnmsZycprQ5RfRgjydWhuoxg71LUfyiQdijZuM=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0 h1:lhhYARPUu3LmHysQ/igznQphfzynnqI3D75oUyw1HXk=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0/go.mod h1:ZPpqegjbE99EPKsu3iUWV22A04wzGPcAY/ziSIQEEgs=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0/go.mod h1:l9rva3ApbBpEJxSNYnwT9N4CDLrWgtq3u8736C5hyJw=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 h1:Ron4zCA/yk6U7WOBXhTJcDpsUBG9npumK6xw2auFltQ=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.54.0 h1:s0WlVbf9qpvkh1c/uDAPElam0WrL7fHRIidgZJ7UqZI=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0/go.mod h1:cSgYe11MCNYunTnRXrKiR/tHc0eoKjICUuWpNZoVCOo=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.54.0/go.mod h1:Mf6O40IAyB9zR/1J8nGDDPirZQQPbYJni8Yisy7NTMc=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cncf/xds/go v0.0.0-20251014123835-2ee22ca58382 h1:5IeUoAZvqwF6LcCnV99NbhrGKN6ihZgahJv5jKjmZ3k=
|
github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f h1:Y8xYupdHxryycyPlc9Y+bSQAYZnetRJ70VMVKm5CKI0=
|
||||||
github.com/cncf/xds/go v0.0.0-20251014123835-2ee22ca58382/go.mod h1:HlzOvOjVBOfTGSRXRyY0OiCS/3J1akRGQQpRO/7zyF4=
|
github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f/go.mod h1:HlzOvOjVBOfTGSRXRyY0OiCS/3J1akRGQQpRO/7zyF4=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M=
|
github.com/envoyproxy/go-control-plane v0.13.5-0.20251024222203-75eaa193e329 h1:K+fnvUM0VZ7ZFJf0n4L/BRlnsb9pL/GuDG6FqaH+PwM=
|
||||||
github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo=
|
github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo=
|
||||||
github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs=
|
github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs=
|
||||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
|
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
|
||||||
@@ -50,12 +50,12 @@ github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
|
|||||||
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
|
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.11 h1:vAe81Msw+8tKUxi2Dqh/NZMz7475yUvmRIkXr4oN2ao=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.11/go.mod h1:RFV7MUdlb7AgEq2v7FmMCfeSMCllAzWxFgRdusoGks8=
|
||||||
github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo=
|
github.com/googleapis/gax-go/v2 v2.16.0 h1:iHbQmKLLZrexmb0OSsNGTeSTS0HO4YvFOG8g5E4Zd0Y=
|
||||||
github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc=
|
github.com/googleapis/gax-go/v2 v2.16.0/go.mod h1:o1vfQjjNZn4+dPnRdl/4ZD7S9414Y4xA+a/6Icj6l14=
|
||||||
github.com/googleapis/mcp-toolbox-sdk-go v0.4.0 h1:SYJRZzmOyXs9anKp+dfq4rprO92KKnxNyJCCsLkW7nw=
|
github.com/googleapis/mcp-toolbox-sdk-go/core v0.6.2 h1:RgO6nEjldaORHgHVcTisxDsYHXLBki1/qIoyjdCVhuw=
|
||||||
github.com/googleapis/mcp-toolbox-sdk-go v0.4.0/go.mod h1:ivRLILO1B72J2HWCjSStemdhTWccjfW9FnEj4SAM81w=
|
github.com/googleapis/mcp-toolbox-sdk-go/core v0.6.2/go.mod h1:aIdj9c1UgMC9cCS6ZrT4x0TraBFg6R/Nt1CiOHOaMfk=
|
||||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
|
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
|
||||||
@@ -74,45 +74,45 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6
|
|||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ=
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg=
|
||||||
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
|
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
|
||||||
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
|
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
|
||||||
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
|
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
|
||||||
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
|
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
|
||||||
go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
|
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
|
||||||
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
|
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
|
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
|
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
|
||||||
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
|
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
|
||||||
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
|
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
|
||||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
|
||||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
|
||||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
|
||||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
|
||||||
golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY=
|
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
|
||||||
golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
||||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
||||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
||||||
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
||||||
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
||||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||||
google.golang.org/api v0.255.0 h1:OaF+IbRwOottVCYV2wZan7KUq7UeNUQn1BcPc4K7lE4=
|
google.golang.org/api v0.265.0 h1:FZvfUdI8nfmuNrE34aOWFPmLC+qRBEiNm3JdivTvAAU=
|
||||||
google.golang.org/api v0.255.0/go.mod h1:d1/EtvCLdtiWEV4rAEHDHGh2bCnqsWhw+M8y2ECN4a8=
|
google.golang.org/api v0.265.0/go.mod h1:uAvfEl3SLUj/7n6k+lJutcswVojHPp2Sp08jWCu8hLY=
|
||||||
google.golang.org/genai v1.35.0 h1:Jo6g25CzVqFzGrX5mhWyBgQqXAUzxcx5jeK7U74zv9c=
|
google.golang.org/genai v1.36.0 h1:sJCIjqTAmwrtAIaemtTiKkg2TO1RxnYEusTmEQ3nGxM=
|
||||||
google.golang.org/genai v1.35.0/go.mod h1:A3kkl0nyBjyFlNjgxIwKq70julKbIxpSxqKO5gw/gmk=
|
google.golang.org/genai v1.36.0/go.mod h1:A3kkl0nyBjyFlNjgxIwKq70julKbIxpSxqKO5gw/gmk=
|
||||||
google.golang.org/genproto v0.0.0-20251014184007-4626949a642f h1:vLd1CJuJOUgV6qijD7KT5Y2ZtC97ll4dxjTUappMnbo=
|
google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217 h1:GvESR9BIyHUahIb0NcTum6itIWtdoglGX+rnGxm2934=
|
||||||
google.golang.org/genproto v0.0.0-20251014184007-4626949a642f/go.mod h1:PI3KrSadr00yqfv6UDvgZGFsmLqeRIwt8x4p5Oo7CdM=
|
google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:yJ2HH4EHEDTd3JiLmhds6NkJ17ITVYOdV3m3VKOnws0=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20251014184007-4626949a642f h1:OiFuztEyBivVKDvguQJYWq1yDcfAHIID/FVrPR4oiI0=
|
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20251014184007-4626949a642f/go.mod h1:kprOiu9Tr0JYyD6DORrc4Hfyk3RFXqkQ3ctHEum3ZbM=
|
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda h1:i/Q+bfisr7gq6feoJnS/DlpdwEL4ihp41fvRiM3Ork0=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 h1:H86B94AW+VfJWDqFeEbBPhEtHzJwJfTbgE2lZa54ZAQ=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||||
google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A=
|
google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc=
|
||||||
google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c=
|
google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U=
|
||||||
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||||
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|||||||
@@ -3,17 +3,19 @@ module genkit-quickstart
|
|||||||
go 1.24.6
|
go 1.24.6
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/firebase/genkit/go v1.2.0
|
github.com/firebase/genkit/go v1.4.0
|
||||||
github.com/googleapis/mcp-toolbox-sdk-go v0.4.0
|
github.com/googleapis/mcp-toolbox-sdk-go/core v0.6.2
|
||||||
|
github.com/googleapis/mcp-toolbox-sdk-go/tbgenkit v0.6.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.123.0 // indirect
|
cloud.google.com/go v0.123.0 // indirect
|
||||||
cloud.google.com/go/auth v0.17.0 // indirect
|
cloud.google.com/go/auth v0.18.1 // indirect
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.9.0 // indirect
|
cloud.google.com/go/compute/metadata v0.9.0 // indirect
|
||||||
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
||||||
github.com/buger/jsonparser v1.1.1 // indirect
|
github.com/buger/jsonparser v1.1.1 // indirect
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||||
github.com/go-logr/logr v1.4.3 // indirect
|
github.com/go-logr/logr v1.4.3 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
@@ -22,8 +24,8 @@ require (
|
|||||||
github.com/google/go-cmp v0.7.0 // indirect
|
github.com/google/go-cmp v0.7.0 // indirect
|
||||||
github.com/google/s2a-go v0.1.9 // indirect
|
github.com/google/s2a-go v0.1.9 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.3.11 // indirect
|
||||||
github.com/googleapis/gax-go/v2 v2.15.0 // indirect
|
github.com/googleapis/gax-go/v2 v2.16.0 // indirect
|
||||||
github.com/gorilla/websocket v1.5.3 // indirect
|
github.com/gorilla/websocket v1.5.3 // indirect
|
||||||
github.com/invopop/jsonschema v0.13.0 // indirect
|
github.com/invopop/jsonschema v0.13.0 // indirect
|
||||||
github.com/mailru/easyjson v0.9.0 // indirect
|
github.com/mailru/easyjson v0.9.0 // indirect
|
||||||
@@ -35,19 +37,19 @@ require (
|
|||||||
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
|
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
|
||||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect
|
||||||
go.opentelemetry.io/otel v1.38.0 // indirect
|
go.opentelemetry.io/otel v1.39.0 // indirect
|
||||||
go.opentelemetry.io/otel/metric v1.38.0 // indirect
|
go.opentelemetry.io/otel/metric v1.39.0 // indirect
|
||||||
go.opentelemetry.io/otel/sdk v1.38.0 // indirect
|
go.opentelemetry.io/otel/sdk v1.39.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.38.0 // indirect
|
go.opentelemetry.io/otel/trace v1.39.0 // indirect
|
||||||
golang.org/x/crypto v0.43.0 // indirect
|
golang.org/x/crypto v0.47.0 // indirect
|
||||||
golang.org/x/net v0.46.0 // indirect
|
golang.org/x/net v0.49.0 // indirect
|
||||||
golang.org/x/oauth2 v0.32.0 // indirect
|
golang.org/x/oauth2 v0.34.0 // indirect
|
||||||
golang.org/x/sys v0.37.0 // indirect
|
golang.org/x/sys v0.40.0 // indirect
|
||||||
golang.org/x/text v0.30.0 // indirect
|
golang.org/x/text v0.33.0 // indirect
|
||||||
google.golang.org/api v0.255.0 // indirect
|
google.golang.org/api v0.265.0 // indirect
|
||||||
google.golang.org/genai v1.34.0 // indirect
|
google.golang.org/genai v1.41.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect
|
||||||
google.golang.org/grpc v1.76.0 // indirect
|
google.golang.org/grpc v1.78.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.10 // indirect
|
google.golang.org/protobuf v1.36.11 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY=
|
|||||||
cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
|
cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
|
||||||
cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE=
|
cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE=
|
||||||
cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU=
|
cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU=
|
||||||
cloud.google.com/go/auth v0.17.0 h1:74yCm7hCj2rUyyAocqnFzsAYXgJhrG26XCFimrc/Kz4=
|
cloud.google.com/go/auth v0.18.1 h1:IwTEx92GFUo2pJ6Qea0EU3zYvKnTAeRCODxfA/G5UWs=
|
||||||
cloud.google.com/go/auth v0.17.0/go.mod h1:6wv/t5/6rOPAX4fJiRjKkJCvswLwdet7G8+UGXt7nCQ=
|
cloud.google.com/go/auth v0.18.1/go.mod h1:GfTYoS9G3CWpRA3Va9doKN9mjPGRS+v41jmZAhBzbrA=
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
||||||
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
|
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
|
||||||
@@ -14,34 +14,34 @@ cloud.google.com/go/monitoring v1.24.3 h1:dde+gMNc0UhPZD1Azu6at2e79bfdztVDS5lvhO
|
|||||||
cloud.google.com/go/monitoring v1.24.3/go.mod h1:nYP6W0tm3N9H/bOw8am7t62YTzZY+zUeQ+Bi6+2eonI=
|
cloud.google.com/go/monitoring v1.24.3/go.mod h1:nYP6W0tm3N9H/bOw8am7t62YTzZY+zUeQ+Bi6+2eonI=
|
||||||
cloud.google.com/go/secretmanager v1.16.0 h1:19QT7ZsLJ8FSP1k+4esQvuCD7npMJml6hYzilxVyT+k=
|
cloud.google.com/go/secretmanager v1.16.0 h1:19QT7ZsLJ8FSP1k+4esQvuCD7npMJml6hYzilxVyT+k=
|
||||||
cloud.google.com/go/secretmanager v1.16.0/go.mod h1://C/e4I8D26SDTz1f3TQcddhcmiC3rMEl0S1Cakvs3Q=
|
cloud.google.com/go/secretmanager v1.16.0/go.mod h1://C/e4I8D26SDTz1f3TQcddhcmiC3rMEl0S1Cakvs3Q=
|
||||||
cloud.google.com/go/storage v1.57.1 h1:gzao6odNJ7dR3XXYvAgPK+Iw4fVPPznEPPyNjbaVkq8=
|
cloud.google.com/go/storage v1.59.2 h1:gmOAuG1opU8YvycMNpP+DvHfT9BfzzK5Cy+arP+Nocw=
|
||||||
cloud.google.com/go/storage v1.57.1/go.mod h1:329cwlpzALLgJuu8beyJ/uvQznDHpa2U5lGjWednkzg=
|
cloud.google.com/go/storage v1.59.2/go.mod h1:cMWbtM+anpC74gn6qjLh+exqYcfmB9Hqe5z6adx+CLI=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 h1:owcC2UnmsZycprQ5RfRgjydWhuoxg71LUfyiQdijZuM=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0 h1:lhhYARPUu3LmHysQ/igznQphfzynnqI3D75oUyw1HXk=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0/go.mod h1:ZPpqegjbE99EPKsu3iUWV22A04wzGPcAY/ziSIQEEgs=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0/go.mod h1:l9rva3ApbBpEJxSNYnwT9N4CDLrWgtq3u8736C5hyJw=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 h1:Ron4zCA/yk6U7WOBXhTJcDpsUBG9npumK6xw2auFltQ=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.54.0 h1:s0WlVbf9qpvkh1c/uDAPElam0WrL7fHRIidgZJ7UqZI=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0/go.mod h1:cSgYe11MCNYunTnRXrKiR/tHc0eoKjICUuWpNZoVCOo=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.54.0/go.mod h1:Mf6O40IAyB9zR/1J8nGDDPirZQQPbYJni8Yisy7NTMc=
|
||||||
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
|
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
|
||||||
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
|
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
|
||||||
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
|
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
|
||||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cncf/xds/go v0.0.0-20251014123835-2ee22ca58382 h1:5IeUoAZvqwF6LcCnV99NbhrGKN6ihZgahJv5jKjmZ3k=
|
github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f h1:Y8xYupdHxryycyPlc9Y+bSQAYZnetRJ70VMVKm5CKI0=
|
||||||
github.com/cncf/xds/go v0.0.0-20251014123835-2ee22ca58382/go.mod h1:HlzOvOjVBOfTGSRXRyY0OiCS/3J1akRGQQpRO/7zyF4=
|
github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f/go.mod h1:HlzOvOjVBOfTGSRXRyY0OiCS/3J1akRGQQpRO/7zyF4=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M=
|
github.com/envoyproxy/go-control-plane v0.13.5-0.20251024222203-75eaa193e329 h1:K+fnvUM0VZ7ZFJf0n4L/BRlnsb9pL/GuDG6FqaH+PwM=
|
||||||
github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo=
|
github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo=
|
||||||
github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs=
|
github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs=
|
||||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
|
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
|
||||||
github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
|
github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
|
||||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
github.com/firebase/genkit/go v1.2.0 h1:C31p32vdMZhhSSQQvXouH/kkcleTH4jlgFmpqlJtBS4=
|
github.com/firebase/genkit/go v1.4.0 h1:CP1hNWk7z0hosyY53zMH6MFKFO1fMLtj58jGPllQo6I=
|
||||||
github.com/firebase/genkit/go v1.2.0/go.mod h1:ru1cIuxG1s3HeUjhnadVveDJ1yhinj+j+uUh0f0pyxE=
|
github.com/firebase/genkit/go v1.4.0/go.mod h1:HX6m7QOaGc3MDNr/DrpQZrzPLzxeuLxrkTvfFtCYlGw=
|
||||||
github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs=
|
github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs=
|
||||||
github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
|
github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
|
||||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
@@ -61,12 +61,14 @@ github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
|
|||||||
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
|
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.11 h1:vAe81Msw+8tKUxi2Dqh/NZMz7475yUvmRIkXr4oN2ao=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.11/go.mod h1:RFV7MUdlb7AgEq2v7FmMCfeSMCllAzWxFgRdusoGks8=
|
||||||
github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo=
|
github.com/googleapis/gax-go/v2 v2.16.0 h1:iHbQmKLLZrexmb0OSsNGTeSTS0HO4YvFOG8g5E4Zd0Y=
|
||||||
github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc=
|
github.com/googleapis/gax-go/v2 v2.16.0/go.mod h1:o1vfQjjNZn4+dPnRdl/4ZD7S9414Y4xA+a/6Icj6l14=
|
||||||
github.com/googleapis/mcp-toolbox-sdk-go v0.4.0 h1:SYJRZzmOyXs9anKp+dfq4rprO92KKnxNyJCCsLkW7nw=
|
github.com/googleapis/mcp-toolbox-sdk-go/core v0.6.2 h1:RgO6nEjldaORHgHVcTisxDsYHXLBki1/qIoyjdCVhuw=
|
||||||
github.com/googleapis/mcp-toolbox-sdk-go v0.4.0/go.mod h1:ivRLILO1B72J2HWCjSStemdhTWccjfW9FnEj4SAM81w=
|
github.com/googleapis/mcp-toolbox-sdk-go/core v0.6.2/go.mod h1:aIdj9c1UgMC9cCS6ZrT4x0TraBFg6R/Nt1CiOHOaMfk=
|
||||||
|
github.com/googleapis/mcp-toolbox-sdk-go/tbgenkit v0.6.0 h1:rHsn35szMNM/XZ4yRm4XX6l3fSUUZh2IgO5Ny0Nmmlc=
|
||||||
|
github.com/googleapis/mcp-toolbox-sdk-go/tbgenkit v0.6.0/go.mod h1:uBXIcLYu/cokhL4d1Yf1DdHMvD8GGKCJvcG4oWO5zRA=
|
||||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E=
|
github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E=
|
||||||
@@ -111,48 +113,48 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6
|
|||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ=
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg=
|
||||||
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
|
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
|
||||||
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
|
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
|
||||||
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
|
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
|
||||||
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
|
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
|
||||||
go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
|
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
|
||||||
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
|
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
|
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
|
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
|
||||||
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
|
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
|
||||||
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
|
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
|
||||||
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
|
||||||
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
|
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
|
||||||
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
|
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
|
||||||
golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY=
|
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
|
||||||
golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||||
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||||
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||||
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
|
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
||||||
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
||||||
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
||||||
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
||||||
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
||||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||||
google.golang.org/api v0.255.0 h1:OaF+IbRwOottVCYV2wZan7KUq7UeNUQn1BcPc4K7lE4=
|
google.golang.org/api v0.265.0 h1:FZvfUdI8nfmuNrE34aOWFPmLC+qRBEiNm3JdivTvAAU=
|
||||||
google.golang.org/api v0.255.0/go.mod h1:d1/EtvCLdtiWEV4rAEHDHGh2bCnqsWhw+M8y2ECN4a8=
|
google.golang.org/api v0.265.0/go.mod h1:uAvfEl3SLUj/7n6k+lJutcswVojHPp2Sp08jWCu8hLY=
|
||||||
google.golang.org/genai v1.34.0 h1:lPRJRO+HqRX1SwFo1Xb/22nZ5MBEPUbXDl61OoDxlbY=
|
google.golang.org/genai v1.41.0 h1:ayXl75LjTmqTu0y94yr96d17gIb4zF8gWVzX2TgioEY=
|
||||||
google.golang.org/genai v1.34.0/go.mod h1:7pAilaICJlQBonjKKJNhftDFv3SREhZcTe9F6nRcjbg=
|
google.golang.org/genai v1.41.0/go.mod h1:A3kkl0nyBjyFlNjgxIwKq70julKbIxpSxqKO5gw/gmk=
|
||||||
google.golang.org/genproto v0.0.0-20251014184007-4626949a642f h1:vLd1CJuJOUgV6qijD7KT5Y2ZtC97ll4dxjTUappMnbo=
|
google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217 h1:GvESR9BIyHUahIb0NcTum6itIWtdoglGX+rnGxm2934=
|
||||||
google.golang.org/genproto v0.0.0-20251014184007-4626949a642f/go.mod h1:PI3KrSadr00yqfv6UDvgZGFsmLqeRIwt8x4p5Oo7CdM=
|
google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:yJ2HH4EHEDTd3JiLmhds6NkJ17ITVYOdV3m3VKOnws0=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20251014184007-4626949a642f h1:OiFuztEyBivVKDvguQJYWq1yDcfAHIID/FVrPR4oiI0=
|
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20251014184007-4626949a642f/go.mod h1:kprOiu9Tr0JYyD6DORrc4Hfyk3RFXqkQ3ctHEum3ZbM=
|
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda h1:i/Q+bfisr7gq6feoJnS/DlpdwEL4ihp41fvRiM3Ork0=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 h1:H86B94AW+VfJWDqFeEbBPhEtHzJwJfTbgE2lZa54ZAQ=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||||
google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A=
|
google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc=
|
||||||
google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c=
|
google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U=
|
||||||
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||||
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
|
|||||||
@@ -3,20 +3,21 @@ module langchan-quickstart
|
|||||||
go 1.24.6
|
go 1.24.6
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/googleapis/mcp-toolbox-sdk-go v0.4.0
|
github.com/googleapis/mcp-toolbox-sdk-go/core v0.6.2
|
||||||
github.com/tmc/langchaingo v0.1.14
|
github.com/tmc/langchaingo v0.1.14
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.123.0 // indirect
|
cloud.google.com/go v0.123.0 // indirect
|
||||||
cloud.google.com/go/ai v0.7.0 // indirect
|
cloud.google.com/go/ai v0.7.0 // indirect
|
||||||
cloud.google.com/go/aiplatform v1.105.0 // indirect
|
cloud.google.com/go/aiplatform v1.109.0 // indirect
|
||||||
cloud.google.com/go/auth v0.17.0 // indirect
|
cloud.google.com/go/auth v0.18.1 // indirect
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.9.0 // indirect
|
cloud.google.com/go/compute/metadata v0.9.0 // indirect
|
||||||
cloud.google.com/go/iam v1.5.3 // indirect
|
cloud.google.com/go/iam v1.5.3 // indirect
|
||||||
cloud.google.com/go/longrunning v0.6.7 // indirect
|
cloud.google.com/go/longrunning v0.7.0 // indirect
|
||||||
cloud.google.com/go/vertexai v0.12.0 // indirect
|
cloud.google.com/go/vertexai v0.12.0 // indirect
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/dlclark/regexp2 v1.10.0 // indirect
|
github.com/dlclark/regexp2 v1.10.0 // indirect
|
||||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||||
github.com/go-logr/logr v1.4.3 // indirect
|
github.com/go-logr/logr v1.4.3 // indirect
|
||||||
@@ -24,26 +25,26 @@ require (
|
|||||||
github.com/google/generative-ai-go v0.15.1 // indirect
|
github.com/google/generative-ai-go v0.15.1 // indirect
|
||||||
github.com/google/s2a-go v0.1.9 // indirect
|
github.com/google/s2a-go v0.1.9 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.3.11 // indirect
|
||||||
github.com/googleapis/gax-go/v2 v2.15.0 // indirect
|
github.com/googleapis/gax-go/v2 v2.16.0 // indirect
|
||||||
github.com/pkoukk/tiktoken-go v0.1.6 // indirect
|
github.com/pkoukk/tiktoken-go v0.1.6 // indirect
|
||||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect
|
||||||
go.opentelemetry.io/otel v1.38.0 // indirect
|
go.opentelemetry.io/otel v1.39.0 // indirect
|
||||||
go.opentelemetry.io/otel/metric v1.38.0 // indirect
|
go.opentelemetry.io/otel/metric v1.39.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.38.0 // indirect
|
go.opentelemetry.io/otel/trace v1.39.0 // indirect
|
||||||
golang.org/x/crypto v0.43.0 // indirect
|
golang.org/x/crypto v0.47.0 // indirect
|
||||||
golang.org/x/net v0.46.0 // indirect
|
golang.org/x/net v0.49.0 // indirect
|
||||||
golang.org/x/oauth2 v0.32.0 // indirect
|
golang.org/x/oauth2 v0.34.0 // indirect
|
||||||
golang.org/x/sync v0.17.0 // indirect
|
golang.org/x/sync v0.19.0 // indirect
|
||||||
golang.org/x/sys v0.37.0 // indirect
|
golang.org/x/sys v0.40.0 // indirect
|
||||||
golang.org/x/text v0.30.0 // indirect
|
golang.org/x/text v0.33.0 // indirect
|
||||||
golang.org/x/time v0.14.0 // indirect
|
golang.org/x/time v0.14.0 // indirect
|
||||||
google.golang.org/api v0.255.0 // indirect
|
google.golang.org/api v0.265.0 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20251014184007-4626949a642f // indirect
|
google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20251014184007-4626949a642f // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect
|
||||||
google.golang.org/grpc v1.76.0 // indirect
|
google.golang.org/grpc v1.78.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.10 // indirect
|
google.golang.org/protobuf v1.36.11 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,41 +4,41 @@ cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE=
|
|||||||
cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU=
|
cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU=
|
||||||
cloud.google.com/go/ai v0.7.0 h1:P6+b5p4gXlza5E+u7uvcgYlzZ7103ACg70YdZeC6oGE=
|
cloud.google.com/go/ai v0.7.0 h1:P6+b5p4gXlza5E+u7uvcgYlzZ7103ACg70YdZeC6oGE=
|
||||||
cloud.google.com/go/ai v0.7.0/go.mod h1:7ozuEcraovh4ABsPbrec3o4LmFl9HigNI3D5haxYeQo=
|
cloud.google.com/go/ai v0.7.0/go.mod h1:7ozuEcraovh4ABsPbrec3o4LmFl9HigNI3D5haxYeQo=
|
||||||
cloud.google.com/go/aiplatform v1.105.0 h1:Tbc2iEp7vbzgk6Vs4QexfNo8/nl+E+Na+FEreRZdhcM=
|
cloud.google.com/go/aiplatform v1.109.0 h1:A1on/tr2Y7EwhW4M1dtuVMWioxFD5oiacZ85MOi9HH8=
|
||||||
cloud.google.com/go/aiplatform v1.105.0/go.mod h1:4rwKOMdubQOND81AlO3EckcskvEFCYSzXKfn42GMm8k=
|
cloud.google.com/go/aiplatform v1.109.0/go.mod h1:4rwKOMdubQOND81AlO3EckcskvEFCYSzXKfn42GMm8k=
|
||||||
cloud.google.com/go/auth v0.17.0 h1:74yCm7hCj2rUyyAocqnFzsAYXgJhrG26XCFimrc/Kz4=
|
cloud.google.com/go/auth v0.18.1 h1:IwTEx92GFUo2pJ6Qea0EU3zYvKnTAeRCODxfA/G5UWs=
|
||||||
cloud.google.com/go/auth v0.17.0/go.mod h1:6wv/t5/6rOPAX4fJiRjKkJCvswLwdet7G8+UGXt7nCQ=
|
cloud.google.com/go/auth v0.18.1/go.mod h1:GfTYoS9G3CWpRA3Va9doKN9mjPGRS+v41jmZAhBzbrA=
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
||||||
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
|
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
|
||||||
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
|
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
|
||||||
cloud.google.com/go/iam v1.5.3 h1:+vMINPiDF2ognBJ97ABAYYwRgsaqxPbQDlMnbHMjolc=
|
cloud.google.com/go/iam v1.5.3 h1:+vMINPiDF2ognBJ97ABAYYwRgsaqxPbQDlMnbHMjolc=
|
||||||
cloud.google.com/go/iam v1.5.3/go.mod h1:MR3v9oLkZCTlaqljW6Eb2d3HGDGK5/bDv93jhfISFvU=
|
cloud.google.com/go/iam v1.5.3/go.mod h1:MR3v9oLkZCTlaqljW6Eb2d3HGDGK5/bDv93jhfISFvU=
|
||||||
cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE=
|
cloud.google.com/go/longrunning v0.7.0 h1:FV0+SYF1RIj59gyoWDRi45GiYUMM3K1qO51qoboQT1E=
|
||||||
cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY=
|
cloud.google.com/go/longrunning v0.7.0/go.mod h1:ySn2yXmjbK9Ba0zsQqunhDkYi0+9rlXIwnoAf+h+TPY=
|
||||||
cloud.google.com/go/monitoring v1.24.3 h1:dde+gMNc0UhPZD1Azu6at2e79bfdztVDS5lvhOdsgaE=
|
cloud.google.com/go/monitoring v1.24.3 h1:dde+gMNc0UhPZD1Azu6at2e79bfdztVDS5lvhOdsgaE=
|
||||||
cloud.google.com/go/monitoring v1.24.3/go.mod h1:nYP6W0tm3N9H/bOw8am7t62YTzZY+zUeQ+Bi6+2eonI=
|
cloud.google.com/go/monitoring v1.24.3/go.mod h1:nYP6W0tm3N9H/bOw8am7t62YTzZY+zUeQ+Bi6+2eonI=
|
||||||
cloud.google.com/go/secretmanager v1.16.0 h1:19QT7ZsLJ8FSP1k+4esQvuCD7npMJml6hYzilxVyT+k=
|
cloud.google.com/go/secretmanager v1.16.0 h1:19QT7ZsLJ8FSP1k+4esQvuCD7npMJml6hYzilxVyT+k=
|
||||||
cloud.google.com/go/secretmanager v1.16.0/go.mod h1://C/e4I8D26SDTz1f3TQcddhcmiC3rMEl0S1Cakvs3Q=
|
cloud.google.com/go/secretmanager v1.16.0/go.mod h1://C/e4I8D26SDTz1f3TQcddhcmiC3rMEl0S1Cakvs3Q=
|
||||||
cloud.google.com/go/storage v1.57.1 h1:gzao6odNJ7dR3XXYvAgPK+Iw4fVPPznEPPyNjbaVkq8=
|
cloud.google.com/go/storage v1.59.2 h1:gmOAuG1opU8YvycMNpP+DvHfT9BfzzK5Cy+arP+Nocw=
|
||||||
cloud.google.com/go/storage v1.57.1/go.mod h1:329cwlpzALLgJuu8beyJ/uvQznDHpa2U5lGjWednkzg=
|
cloud.google.com/go/storage v1.59.2/go.mod h1:cMWbtM+anpC74gn6qjLh+exqYcfmB9Hqe5z6adx+CLI=
|
||||||
cloud.google.com/go/vertexai v0.12.0 h1:zTadEo/CtsoyRXNx3uGCncoWAP1H2HakGqwznt+iMo8=
|
cloud.google.com/go/vertexai v0.12.0 h1:zTadEo/CtsoyRXNx3uGCncoWAP1H2HakGqwznt+iMo8=
|
||||||
cloud.google.com/go/vertexai v0.12.0/go.mod h1:8u+d0TsvBfAAd2x5R6GMgbYhsLgo3J7lmP4bR8g2ig8=
|
cloud.google.com/go/vertexai v0.12.0/go.mod h1:8u+d0TsvBfAAd2x5R6GMgbYhsLgo3J7lmP4bR8g2ig8=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 h1:owcC2UnmsZycprQ5RfRgjydWhuoxg71LUfyiQdijZuM=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0 h1:lhhYARPUu3LmHysQ/igznQphfzynnqI3D75oUyw1HXk=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0/go.mod h1:ZPpqegjbE99EPKsu3iUWV22A04wzGPcAY/ziSIQEEgs=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0/go.mod h1:l9rva3ApbBpEJxSNYnwT9N4CDLrWgtq3u8736C5hyJw=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 h1:Ron4zCA/yk6U7WOBXhTJcDpsUBG9npumK6xw2auFltQ=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.54.0 h1:s0WlVbf9qpvkh1c/uDAPElam0WrL7fHRIidgZJ7UqZI=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0/go.mod h1:cSgYe11MCNYunTnRXrKiR/tHc0eoKjICUuWpNZoVCOo=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.54.0/go.mod h1:Mf6O40IAyB9zR/1J8nGDDPirZQQPbYJni8Yisy7NTMc=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cncf/xds/go v0.0.0-20251014123835-2ee22ca58382 h1:5IeUoAZvqwF6LcCnV99NbhrGKN6ihZgahJv5jKjmZ3k=
|
github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f h1:Y8xYupdHxryycyPlc9Y+bSQAYZnetRJ70VMVKm5CKI0=
|
||||||
github.com/cncf/xds/go v0.0.0-20251014123835-2ee22ca58382/go.mod h1:HlzOvOjVBOfTGSRXRyY0OiCS/3J1akRGQQpRO/7zyF4=
|
github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f/go.mod h1:HlzOvOjVBOfTGSRXRyY0OiCS/3J1akRGQQpRO/7zyF4=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
|
github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
|
||||||
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||||
github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M=
|
github.com/envoyproxy/go-control-plane v0.13.5-0.20251024222203-75eaa193e329 h1:K+fnvUM0VZ7ZFJf0n4L/BRlnsb9pL/GuDG6FqaH+PwM=
|
||||||
github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo=
|
github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo=
|
||||||
github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs=
|
github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs=
|
||||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
|
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
|
||||||
@@ -62,12 +62,12 @@ github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
|
|||||||
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
|
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.11 h1:vAe81Msw+8tKUxi2Dqh/NZMz7475yUvmRIkXr4oN2ao=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.11/go.mod h1:RFV7MUdlb7AgEq2v7FmMCfeSMCllAzWxFgRdusoGks8=
|
||||||
github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo=
|
github.com/googleapis/gax-go/v2 v2.16.0 h1:iHbQmKLLZrexmb0OSsNGTeSTS0HO4YvFOG8g5E4Zd0Y=
|
||||||
github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc=
|
github.com/googleapis/gax-go/v2 v2.16.0/go.mod h1:o1vfQjjNZn4+dPnRdl/4ZD7S9414Y4xA+a/6Icj6l14=
|
||||||
github.com/googleapis/mcp-toolbox-sdk-go v0.4.0 h1:SYJRZzmOyXs9anKp+dfq4rprO92KKnxNyJCCsLkW7nw=
|
github.com/googleapis/mcp-toolbox-sdk-go/core v0.6.2 h1:RgO6nEjldaORHgHVcTisxDsYHXLBki1/qIoyjdCVhuw=
|
||||||
github.com/googleapis/mcp-toolbox-sdk-go v0.4.0/go.mod h1:ivRLILO1B72J2HWCjSStemdhTWccjfW9FnEj4SAM81w=
|
github.com/googleapis/mcp-toolbox-sdk-go/core v0.6.2/go.mod h1:aIdj9c1UgMC9cCS6ZrT4x0TraBFg6R/Nt1CiOHOaMfk=
|
||||||
github.com/pkoukk/tiktoken-go v0.1.6 h1:JF0TlJzhTbrI30wCvFuiw6FzP2+/bR+FIxUdgEAcUsw=
|
github.com/pkoukk/tiktoken-go v0.1.6 h1:JF0TlJzhTbrI30wCvFuiw6FzP2+/bR+FIxUdgEAcUsw=
|
||||||
github.com/pkoukk/tiktoken-go v0.1.6/go.mod h1:9NiV+i9mJKGj1rYOT+njbv+ZwA/zJxYdewGl6qVatpg=
|
github.com/pkoukk/tiktoken-go v0.1.6/go.mod h1:9NiV+i9mJKGj1rYOT+njbv+ZwA/zJxYdewGl6qVatpg=
|
||||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
|
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
|
||||||
@@ -90,44 +90,44 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6
|
|||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ=
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg=
|
||||||
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
|
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
|
||||||
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
|
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
|
||||||
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
|
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
|
||||||
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
|
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
|
||||||
go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
|
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
|
||||||
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
|
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
|
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
|
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
|
||||||
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
|
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
|
||||||
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
|
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
|
||||||
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
|
||||||
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
|
||||||
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
|
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
|
||||||
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
|
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
|
||||||
golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY=
|
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
|
||||||
golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||||
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||||
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||||
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
|
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
||||||
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
||||||
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
||||||
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
||||||
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
||||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||||
google.golang.org/api v0.255.0 h1:OaF+IbRwOottVCYV2wZan7KUq7UeNUQn1BcPc4K7lE4=
|
google.golang.org/api v0.265.0 h1:FZvfUdI8nfmuNrE34aOWFPmLC+qRBEiNm3JdivTvAAU=
|
||||||
google.golang.org/api v0.255.0/go.mod h1:d1/EtvCLdtiWEV4rAEHDHGh2bCnqsWhw+M8y2ECN4a8=
|
google.golang.org/api v0.265.0/go.mod h1:uAvfEl3SLUj/7n6k+lJutcswVojHPp2Sp08jWCu8hLY=
|
||||||
google.golang.org/genproto v0.0.0-20251014184007-4626949a642f h1:vLd1CJuJOUgV6qijD7KT5Y2ZtC97ll4dxjTUappMnbo=
|
google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217 h1:GvESR9BIyHUahIb0NcTum6itIWtdoglGX+rnGxm2934=
|
||||||
google.golang.org/genproto v0.0.0-20251014184007-4626949a642f/go.mod h1:PI3KrSadr00yqfv6UDvgZGFsmLqeRIwt8x4p5Oo7CdM=
|
google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:yJ2HH4EHEDTd3JiLmhds6NkJ17ITVYOdV3m3VKOnws0=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20251014184007-4626949a642f h1:OiFuztEyBivVKDvguQJYWq1yDcfAHIID/FVrPR4oiI0=
|
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20251014184007-4626949a642f/go.mod h1:kprOiu9Tr0JYyD6DORrc4Hfyk3RFXqkQ3ctHEum3ZbM=
|
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda h1:i/Q+bfisr7gq6feoJnS/DlpdwEL4ihp41fvRiM3Ork0=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 h1:H86B94AW+VfJWDqFeEbBPhEtHzJwJfTbgE2lZa54ZAQ=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||||
google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A=
|
google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc=
|
||||||
google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c=
|
google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U=
|
||||||
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||||
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
|||||||
@@ -3,36 +3,38 @@ module openai-quickstart
|
|||||||
go 1.24.6
|
go 1.24.6
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/googleapis/mcp-toolbox-sdk-go v0.4.0
|
github.com/googleapis/mcp-toolbox-sdk-go/core v0.6.2
|
||||||
github.com/openai/openai-go/v3 v3.8.1
|
github.com/openai/openai-go/v3 v3.8.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go/auth v0.17.0 // indirect
|
cloud.google.com/go/auth v0.18.1 // indirect
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.9.0 // indirect
|
cloud.google.com/go/compute/metadata v0.9.0 // indirect
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||||
github.com/go-logr/logr v1.4.3 // indirect
|
github.com/go-logr/logr v1.4.3 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/google/s2a-go v0.1.9 // indirect
|
github.com/google/s2a-go v0.1.9 // indirect
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/googleapis/gax-go/v2 v2.15.0 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.3.11 // indirect
|
||||||
|
github.com/googleapis/gax-go/v2 v2.16.0 // indirect
|
||||||
github.com/tidwall/gjson v1.18.0 // indirect
|
github.com/tidwall/gjson v1.18.0 // indirect
|
||||||
github.com/tidwall/match v1.1.1 // indirect
|
github.com/tidwall/match v1.1.1 // indirect
|
||||||
github.com/tidwall/pretty v1.2.1 // indirect
|
github.com/tidwall/pretty v1.2.1 // indirect
|
||||||
github.com/tidwall/sjson v1.2.5 // indirect
|
github.com/tidwall/sjson v1.2.5 // indirect
|
||||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect
|
||||||
go.opentelemetry.io/otel v1.38.0 // indirect
|
go.opentelemetry.io/otel v1.39.0 // indirect
|
||||||
go.opentelemetry.io/otel/metric v1.38.0 // indirect
|
go.opentelemetry.io/otel/metric v1.39.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.38.0 // indirect
|
go.opentelemetry.io/otel/trace v1.39.0 // indirect
|
||||||
golang.org/x/crypto v0.43.0 // indirect
|
golang.org/x/crypto v0.47.0 // indirect
|
||||||
golang.org/x/net v0.46.0 // indirect
|
golang.org/x/net v0.49.0 // indirect
|
||||||
golang.org/x/oauth2 v0.32.0 // indirect
|
golang.org/x/oauth2 v0.34.0 // indirect
|
||||||
golang.org/x/sys v0.37.0 // indirect
|
golang.org/x/sys v0.40.0 // indirect
|
||||||
golang.org/x/text v0.30.0 // indirect
|
golang.org/x/text v0.33.0 // indirect
|
||||||
google.golang.org/api v0.255.0 // indirect
|
google.golang.org/api v0.265.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect
|
||||||
google.golang.org/grpc v1.76.0 // indirect
|
google.golang.org/grpc v1.78.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.10 // indirect
|
google.golang.org/protobuf v1.36.11 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY=
|
|||||||
cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
|
cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
|
||||||
cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE=
|
cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE=
|
||||||
cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU=
|
cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU=
|
||||||
cloud.google.com/go/auth v0.17.0 h1:74yCm7hCj2rUyyAocqnFzsAYXgJhrG26XCFimrc/Kz4=
|
cloud.google.com/go/auth v0.18.1 h1:IwTEx92GFUo2pJ6Qea0EU3zYvKnTAeRCODxfA/G5UWs=
|
||||||
cloud.google.com/go/auth v0.17.0/go.mod h1:6wv/t5/6rOPAX4fJiRjKkJCvswLwdet7G8+UGXt7nCQ=
|
cloud.google.com/go/auth v0.18.1/go.mod h1:GfTYoS9G3CWpRA3Va9doKN9mjPGRS+v41jmZAhBzbrA=
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
||||||
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
|
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
|
||||||
@@ -14,21 +14,21 @@ cloud.google.com/go/monitoring v1.24.3 h1:dde+gMNc0UhPZD1Azu6at2e79bfdztVDS5lvhO
|
|||||||
cloud.google.com/go/monitoring v1.24.3/go.mod h1:nYP6W0tm3N9H/bOw8am7t62YTzZY+zUeQ+Bi6+2eonI=
|
cloud.google.com/go/monitoring v1.24.3/go.mod h1:nYP6W0tm3N9H/bOw8am7t62YTzZY+zUeQ+Bi6+2eonI=
|
||||||
cloud.google.com/go/secretmanager v1.16.0 h1:19QT7ZsLJ8FSP1k+4esQvuCD7npMJml6hYzilxVyT+k=
|
cloud.google.com/go/secretmanager v1.16.0 h1:19QT7ZsLJ8FSP1k+4esQvuCD7npMJml6hYzilxVyT+k=
|
||||||
cloud.google.com/go/secretmanager v1.16.0/go.mod h1://C/e4I8D26SDTz1f3TQcddhcmiC3rMEl0S1Cakvs3Q=
|
cloud.google.com/go/secretmanager v1.16.0/go.mod h1://C/e4I8D26SDTz1f3TQcddhcmiC3rMEl0S1Cakvs3Q=
|
||||||
cloud.google.com/go/storage v1.57.1 h1:gzao6odNJ7dR3XXYvAgPK+Iw4fVPPznEPPyNjbaVkq8=
|
cloud.google.com/go/storage v1.59.2 h1:gmOAuG1opU8YvycMNpP+DvHfT9BfzzK5Cy+arP+Nocw=
|
||||||
cloud.google.com/go/storage v1.57.1/go.mod h1:329cwlpzALLgJuu8beyJ/uvQznDHpa2U5lGjWednkzg=
|
cloud.google.com/go/storage v1.59.2/go.mod h1:cMWbtM+anpC74gn6qjLh+exqYcfmB9Hqe5z6adx+CLI=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 h1:owcC2UnmsZycprQ5RfRgjydWhuoxg71LUfyiQdijZuM=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0 h1:lhhYARPUu3LmHysQ/igznQphfzynnqI3D75oUyw1HXk=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0/go.mod h1:ZPpqegjbE99EPKsu3iUWV22A04wzGPcAY/ziSIQEEgs=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0/go.mod h1:l9rva3ApbBpEJxSNYnwT9N4CDLrWgtq3u8736C5hyJw=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 h1:Ron4zCA/yk6U7WOBXhTJcDpsUBG9npumK6xw2auFltQ=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.54.0 h1:s0WlVbf9qpvkh1c/uDAPElam0WrL7fHRIidgZJ7UqZI=
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0/go.mod h1:cSgYe11MCNYunTnRXrKiR/tHc0eoKjICUuWpNZoVCOo=
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.54.0/go.mod h1:Mf6O40IAyB9zR/1J8nGDDPirZQQPbYJni8Yisy7NTMc=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cncf/xds/go v0.0.0-20251014123835-2ee22ca58382 h1:5IeUoAZvqwF6LcCnV99NbhrGKN6ihZgahJv5jKjmZ3k=
|
github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f h1:Y8xYupdHxryycyPlc9Y+bSQAYZnetRJ70VMVKm5CKI0=
|
||||||
github.com/cncf/xds/go v0.0.0-20251014123835-2ee22ca58382/go.mod h1:HlzOvOjVBOfTGSRXRyY0OiCS/3J1akRGQQpRO/7zyF4=
|
github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f/go.mod h1:HlzOvOjVBOfTGSRXRyY0OiCS/3J1akRGQQpRO/7zyF4=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M=
|
github.com/envoyproxy/go-control-plane v0.13.5-0.20251024222203-75eaa193e329 h1:K+fnvUM0VZ7ZFJf0n4L/BRlnsb9pL/GuDG6FqaH+PwM=
|
||||||
github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo=
|
github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo=
|
||||||
github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs=
|
github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs=
|
||||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
|
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
|
||||||
@@ -50,12 +50,12 @@ github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
|
|||||||
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
|
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.11 h1:vAe81Msw+8tKUxi2Dqh/NZMz7475yUvmRIkXr4oN2ao=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.11/go.mod h1:RFV7MUdlb7AgEq2v7FmMCfeSMCllAzWxFgRdusoGks8=
|
||||||
github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo=
|
github.com/googleapis/gax-go/v2 v2.16.0 h1:iHbQmKLLZrexmb0OSsNGTeSTS0HO4YvFOG8g5E4Zd0Y=
|
||||||
github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc=
|
github.com/googleapis/gax-go/v2 v2.16.0/go.mod h1:o1vfQjjNZn4+dPnRdl/4ZD7S9414Y4xA+a/6Icj6l14=
|
||||||
github.com/googleapis/mcp-toolbox-sdk-go v0.4.0 h1:SYJRZzmOyXs9anKp+dfq4rprO92KKnxNyJCCsLkW7nw=
|
github.com/googleapis/mcp-toolbox-sdk-go/core v0.6.2 h1:RgO6nEjldaORHgHVcTisxDsYHXLBki1/qIoyjdCVhuw=
|
||||||
github.com/googleapis/mcp-toolbox-sdk-go v0.4.0/go.mod h1:ivRLILO1B72J2HWCjSStemdhTWccjfW9FnEj4SAM81w=
|
github.com/googleapis/mcp-toolbox-sdk-go/core v0.6.2/go.mod h1:aIdj9c1UgMC9cCS6ZrT4x0TraBFg6R/Nt1CiOHOaMfk=
|
||||||
github.com/openai/openai-go/v3 v3.8.1 h1:b+YWsmwqXnbpSHWQEntZAkKciBZ5CJXwL68j+l59UDg=
|
github.com/openai/openai-go/v3 v3.8.1 h1:b+YWsmwqXnbpSHWQEntZAkKciBZ5CJXwL68j+l59UDg=
|
||||||
github.com/openai/openai-go/v3 v3.8.1/go.mod h1:UOpNxkqC9OdNXNUfpNByKOtB4jAL0EssQXq5p8gO0Xs=
|
github.com/openai/openai-go/v3 v3.8.1/go.mod h1:UOpNxkqC9OdNXNUfpNByKOtB4jAL0EssQXq5p8gO0Xs=
|
||||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
|
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
|
||||||
@@ -84,43 +84,43 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6
|
|||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ=
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg=
|
||||||
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
|
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
|
||||||
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
|
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
|
||||||
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
|
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
|
||||||
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
|
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
|
||||||
go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
|
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
|
||||||
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
|
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
|
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
|
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
|
||||||
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
|
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
|
||||||
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
|
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
|
||||||
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
|
||||||
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
|
||||||
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
|
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
|
||||||
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
|
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
|
||||||
golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY=
|
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
|
||||||
golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||||
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||||
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||||
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
|
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
||||||
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
||||||
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
||||||
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
||||||
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
||||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||||
google.golang.org/api v0.255.0 h1:OaF+IbRwOottVCYV2wZan7KUq7UeNUQn1BcPc4K7lE4=
|
google.golang.org/api v0.265.0 h1:FZvfUdI8nfmuNrE34aOWFPmLC+qRBEiNm3JdivTvAAU=
|
||||||
google.golang.org/api v0.255.0/go.mod h1:d1/EtvCLdtiWEV4rAEHDHGh2bCnqsWhw+M8y2ECN4a8=
|
google.golang.org/api v0.265.0/go.mod h1:uAvfEl3SLUj/7n6k+lJutcswVojHPp2Sp08jWCu8hLY=
|
||||||
google.golang.org/genproto v0.0.0-20251014184007-4626949a642f h1:vLd1CJuJOUgV6qijD7KT5Y2ZtC97ll4dxjTUappMnbo=
|
google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217 h1:GvESR9BIyHUahIb0NcTum6itIWtdoglGX+rnGxm2934=
|
||||||
google.golang.org/genproto v0.0.0-20251014184007-4626949a642f/go.mod h1:PI3KrSadr00yqfv6UDvgZGFsmLqeRIwt8x4p5Oo7CdM=
|
google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:yJ2HH4EHEDTd3JiLmhds6NkJ17ITVYOdV3m3VKOnws0=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20251014184007-4626949a642f h1:OiFuztEyBivVKDvguQJYWq1yDcfAHIID/FVrPR4oiI0=
|
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20251014184007-4626949a642f/go.mod h1:kprOiu9Tr0JYyD6DORrc4Hfyk3RFXqkQ3ctHEum3ZbM=
|
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda h1:i/Q+bfisr7gq6feoJnS/DlpdwEL4ihp41fvRiM3Ork0=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 h1:H86B94AW+VfJWDqFeEbBPhEtHzJwJfTbgE2lZa54ZAQ=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||||
google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A=
|
google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc=
|
||||||
google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c=
|
google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U=
|
||||||
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||||
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var goldenKeywords = []string{"Hilton Basel", "Hyatt Regency", "book"}
|
||||||
|
|
||||||
func TestQuickstartSample(t *testing.T) {
|
func TestQuickstartSample(t *testing.T) {
|
||||||
framework := os.Getenv("ORCH_NAME")
|
framework := os.Getenv("ORCH_NAME")
|
||||||
if framework == "" {
|
if framework == "" {
|
||||||
@@ -59,16 +61,10 @@ func TestQuickstartSample(t *testing.T) {
|
|||||||
t.Fatal("Script ran successfully but produced no output.")
|
t.Fatal("Script ran successfully but produced no output.")
|
||||||
}
|
}
|
||||||
|
|
||||||
goldenFile, err := os.ReadFile("../golden.txt")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Could not read golden.txt to check for keywords: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
keywords := strings.Split(string(goldenFile), "\n")
|
|
||||||
var missingKeywords []string
|
var missingKeywords []string
|
||||||
outputLower := strings.ToLower(actualOutput)
|
outputLower := strings.ToLower(actualOutput)
|
||||||
|
|
||||||
for _, keyword := range keywords {
|
for _, keyword := range goldenKeywords {
|
||||||
kw := strings.TrimSpace(keyword)
|
kw := strings.TrimSpace(keyword)
|
||||||
if kw != "" && !strings.Contains(outputLower, strings.ToLower(kw)) {
|
if kw != "" && !strings.Contains(outputLower, strings.ToLower(kw)) {
|
||||||
missingKeywords = append(missingKeywords, kw)
|
missingKeywords = append(missingKeywords, kw)
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
Hilton Basel
|
|
||||||
Hyatt Regency
|
|
||||||
book
|
|
||||||
@@ -48,9 +48,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@google-cloud/storage": {
|
"node_modules/@google-cloud/storage": {
|
||||||
"version": "7.18.0",
|
"version": "7.19.0",
|
||||||
"resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.19.0.tgz",
|
||||||
"integrity": "sha512-r3ZwDMiz4nwW6R922Z1pwpePxyRwE5GdevYX63hRmAQUkUQJcBH/79EnQPDv5cOv1mFBgevdNWQfi3tie3dHrQ==",
|
"integrity": "sha512-n2FjE7NAOYyshogdc7KQOl/VZb4sneqPjWouSyia9CMDdMhRX5+RIbqalNmC7LOLzuLAN89VlF2HvG8na9G+zQ==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
"abort-controller": "^3.0.0",
|
"abort-controller": "^3.0.0",
|
||||||
"async-retry": "^1.3.3",
|
"async-retry": "^1.3.3",
|
||||||
"duplexify": "^4.1.3",
|
"duplexify": "^4.1.3",
|
||||||
"fast-xml-parser": "^4.4.1",
|
"fast-xml-parser": "^5.3.4",
|
||||||
"gaxios": "^6.0.2",
|
"gaxios": "^6.0.2",
|
||||||
"google-auth-library": "^9.6.3",
|
"google-auth-library": "^9.6.3",
|
||||||
"html-entities": "^2.5.2",
|
"html-entities": "^2.5.2",
|
||||||
@@ -989,9 +989,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/fast-xml-parser": {
|
"node_modules/fast-xml-parser": {
|
||||||
"version": "4.5.3",
|
"version": "5.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.5.tgz",
|
||||||
"integrity": "sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==",
|
"integrity": "sha512-JeaA2Vm9ffQKp9VjvfzObuMCjUYAp5WDYhRYL5LrBPY/jUDlUtOvDfot0vKSkB9tuX885BDHjtw4fZadD95wnA==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@@ -1001,7 +1001,7 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"strnum": "^1.1.1"
|
"strnum": "^2.1.2"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"fxparser": "src/cli/cli.js"
|
"fxparser": "src/cli/cli.js"
|
||||||
@@ -1525,12 +1525,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jws": {
|
"node_modules/jws": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz",
|
||||||
"integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
|
"integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jwa": "^2.0.0",
|
"jwa": "^2.0.1",
|
||||||
"safe-buffer": "^5.0.1"
|
"safe-buffer": "^5.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1835,9 +1835,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/qs": {
|
"node_modules/qs": {
|
||||||
"version": "6.14.0",
|
"version": "6.14.1",
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz",
|
||||||
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
|
"integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==",
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"side-channel": "^1.1.0"
|
"side-channel": "^1.1.0"
|
||||||
@@ -2251,9 +2251,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/strnum": {
|
"node_modules/strnum": {
|
||||||
"version": "1.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz",
|
||||||
"integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==",
|
"integrity": "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
|
|||||||
@@ -569,11 +569,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jws": {
|
"node_modules/jws": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz",
|
||||||
"integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
|
"integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jwa": "^2.0.0",
|
"jwa": "^2.0.1",
|
||||||
"safe-buffer": "^5.0.1"
|
"safe-buffer": "^5.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -24,12 +24,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@dabh/diagnostics": {
|
"node_modules/@dabh/diagnostics": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.8.tgz",
|
||||||
"integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==",
|
"integrity": "sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q==",
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"colorspace": "1.1.x",
|
"@so-ric/colorspace": "^1.1.6",
|
||||||
"enabled": "2.0.x",
|
"enabled": "2.0.x",
|
||||||
"kuler": "^2.0.0"
|
"kuler": "^2.0.0"
|
||||||
}
|
}
|
||||||
@@ -578,9 +579,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@google-cloud/firestore": {
|
"node_modules/@google-cloud/firestore": {
|
||||||
"version": "7.11.3",
|
"version": "7.11.6",
|
||||||
"resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.11.3.tgz",
|
"resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.11.6.tgz",
|
||||||
"integrity": "sha512-qsM3/WHpawF07SRVvEJJVRwhYzM7o9qtuksyuqnrMig6fxIrwWnsezECWsG/D5TyYru51Fv5c/RTqNDQ2yU+4w==",
|
"integrity": "sha512-EW/O8ktzwLfyWBOsNuhRoMi8lrC3clHM5LVFhGvO1HCsLozCOOXRAlHrYBoE6HL42Sc8yYMuCb2XqcnJ4OOEpw==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -2887,6 +2889,17 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
||||||
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
|
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@so-ric/colorspace": {
|
||||||
|
"version": "1.1.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@so-ric/colorspace/-/colorspace-1.1.6.tgz",
|
||||||
|
"integrity": "sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"color": "^5.0.2",
|
||||||
|
"text-hex": "1.0.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@toolbox-sdk/core": {
|
"node_modules/@toolbox-sdk/core": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@toolbox-sdk/core/-/core-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@toolbox-sdk/core/-/core-0.1.2.tgz",
|
||||||
@@ -3338,13 +3351,13 @@
|
|||||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||||
},
|
},
|
||||||
"node_modules/axios": {
|
"node_modules/axios": {
|
||||||
"version": "1.12.2",
|
"version": "1.13.5",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz",
|
||||||
"integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==",
|
"integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"follow-redirects": "^1.15.6",
|
"follow-redirects": "^1.15.11",
|
||||||
"form-data": "^4.0.4",
|
"form-data": "^4.0.5",
|
||||||
"proxy-from-env": "^1.1.0"
|
"proxy-from-env": "^1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -3376,22 +3389,23 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/body-parser": {
|
"node_modules/body-parser": {
|
||||||
"version": "1.20.3",
|
"version": "1.20.4",
|
||||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz",
|
||||||
"integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
|
"integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bytes": "3.1.2",
|
"bytes": "~3.1.2",
|
||||||
"content-type": "~1.0.5",
|
"content-type": "~1.0.5",
|
||||||
"debug": "2.6.9",
|
"debug": "2.6.9",
|
||||||
"depd": "2.0.0",
|
"depd": "2.0.0",
|
||||||
"destroy": "1.2.0",
|
"destroy": "~1.2.0",
|
||||||
"http-errors": "2.0.0",
|
"http-errors": "~2.0.1",
|
||||||
"iconv-lite": "0.4.24",
|
"iconv-lite": "~0.4.24",
|
||||||
"on-finished": "2.4.1",
|
"on-finished": "~2.4.1",
|
||||||
"qs": "6.13.0",
|
"qs": "~6.14.0",
|
||||||
"raw-body": "2.5.2",
|
"raw-body": "~2.5.3",
|
||||||
"type-is": "~1.6.18",
|
"type-is": "~1.6.18",
|
||||||
"unpipe": "1.0.0"
|
"unpipe": "~1.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.8",
|
"node": ">= 0.8",
|
||||||
@@ -3406,11 +3420,40 @@
|
|||||||
"ms": "2.0.0"
|
"ms": "2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/body-parser/node_modules/http-errors": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"depd": "~2.0.0",
|
||||||
|
"inherits": "~2.0.4",
|
||||||
|
"setprototypeof": "~1.2.0",
|
||||||
|
"statuses": "~2.0.2",
|
||||||
|
"toidentifier": "~1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/body-parser/node_modules/ms": {
|
"node_modules/body-parser/node_modules/ms": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
||||||
},
|
},
|
||||||
|
"node_modules/body-parser/node_modules/statuses": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/buffer-equal-constant-time": {
|
"node_modules/buffer-equal-constant-time": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||||
@@ -3434,6 +3477,7 @@
|
|||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||||
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
|
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
@@ -3484,38 +3528,53 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/color": {
|
"node_modules/color": {
|
||||||
"version": "3.2.1",
|
"version": "5.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/color/-/color-5.0.3.tgz",
|
||||||
"integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==",
|
"integrity": "sha512-ezmVcLR3xAVp8kYOm4GS45ZLLgIE6SPAFoduLr6hTDajwb3KZ2F46gulK3XpcwRFb5KKGCSezCBAY4Dw4HsyXA==",
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"color-convert": "^1.9.3",
|
"color-convert": "^3.1.3",
|
||||||
"color-string": "^1.6.0"
|
"color-string": "^2.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/color-convert": {
|
"node_modules/color-convert": {
|
||||||
"version": "1.9.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-3.1.3.tgz",
|
||||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
"integrity": "sha512-fasDH2ont2GqF5HpyO4w0+BcewlhHEZOFn9c1ckZdHpJ56Qb7MHhH/IcJZbBGgvdtwdwNbLvxiBEdg336iA9Sg==",
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"color-name": "1.1.3"
|
"color-name": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/color-name": {
|
"node_modules/color-name": {
|
||||||
"version": "1.1.3",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-2.1.0.tgz",
|
||||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
|
"integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==",
|
||||||
"optional": true
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.20"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"node_modules/color-string": {
|
"node_modules/color-string": {
|
||||||
"version": "1.9.1",
|
"version": "2.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/color-string/-/color-string-2.1.4.tgz",
|
||||||
"integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
|
"integrity": "sha512-Bb6Cq8oq0IjDOe8wJmi4JeNn763Xs9cfrBcaylK1tPypWzyoy2G3l90v9k64kjphl/ZJjPIShFztenRomi8WTg==",
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"color-name": "^1.0.0",
|
"color-name": "^2.0.0"
|
||||||
"simple-swizzle": "^0.2.2"
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/colorette": {
|
"node_modules/colorette": {
|
||||||
@@ -3523,16 +3582,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
|
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
|
||||||
"integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w=="
|
"integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w=="
|
||||||
},
|
},
|
||||||
"node_modules/colorspace": {
|
|
||||||
"version": "1.1.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz",
|
|
||||||
"integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==",
|
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
|
||||||
"color": "^3.1.3",
|
|
||||||
"text-hex": "1.0.x"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/combined-stream": {
|
"node_modules/combined-stream": {
|
||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||||
@@ -3830,38 +3879,39 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/express": {
|
"node_modules/express": {
|
||||||
"version": "4.21.2",
|
"version": "4.22.1",
|
||||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
|
"resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz",
|
||||||
"integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
|
"integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"accepts": "~1.3.8",
|
"accepts": "~1.3.8",
|
||||||
"array-flatten": "1.1.1",
|
"array-flatten": "1.1.1",
|
||||||
"body-parser": "1.20.3",
|
"body-parser": "~1.20.3",
|
||||||
"content-disposition": "0.5.4",
|
"content-disposition": "~0.5.4",
|
||||||
"content-type": "~1.0.4",
|
"content-type": "~1.0.4",
|
||||||
"cookie": "0.7.1",
|
"cookie": "~0.7.1",
|
||||||
"cookie-signature": "1.0.6",
|
"cookie-signature": "~1.0.6",
|
||||||
"debug": "2.6.9",
|
"debug": "2.6.9",
|
||||||
"depd": "2.0.0",
|
"depd": "2.0.0",
|
||||||
"encodeurl": "~2.0.0",
|
"encodeurl": "~2.0.0",
|
||||||
"escape-html": "~1.0.3",
|
"escape-html": "~1.0.3",
|
||||||
"etag": "~1.8.1",
|
"etag": "~1.8.1",
|
||||||
"finalhandler": "1.3.1",
|
"finalhandler": "~1.3.1",
|
||||||
"fresh": "0.5.2",
|
"fresh": "~0.5.2",
|
||||||
"http-errors": "2.0.0",
|
"http-errors": "~2.0.0",
|
||||||
"merge-descriptors": "1.0.3",
|
"merge-descriptors": "1.0.3",
|
||||||
"methods": "~1.1.2",
|
"methods": "~1.1.2",
|
||||||
"on-finished": "2.4.1",
|
"on-finished": "~2.4.1",
|
||||||
"parseurl": "~1.3.3",
|
"parseurl": "~1.3.3",
|
||||||
"path-to-regexp": "0.1.12",
|
"path-to-regexp": "~0.1.12",
|
||||||
"proxy-addr": "~2.0.7",
|
"proxy-addr": "~2.0.7",
|
||||||
"qs": "6.13.0",
|
"qs": "~6.14.0",
|
||||||
"range-parser": "~1.2.1",
|
"range-parser": "~1.2.1",
|
||||||
"safe-buffer": "5.2.1",
|
"safe-buffer": "5.2.1",
|
||||||
"send": "0.19.0",
|
"send": "~0.19.0",
|
||||||
"serve-static": "1.16.2",
|
"serve-static": "~1.16.2",
|
||||||
"setprototypeof": "1.2.0",
|
"setprototypeof": "1.2.0",
|
||||||
"statuses": "2.0.1",
|
"statuses": "~2.0.1",
|
||||||
"type-is": "~1.6.18",
|
"type-is": "~1.6.18",
|
||||||
"utils-merge": "1.0.1",
|
"utils-merge": "1.0.1",
|
||||||
"vary": "~1.1.2"
|
"vary": "~1.1.2"
|
||||||
@@ -4198,9 +4248,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/form-data": {
|
"node_modules/form-data": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
|
||||||
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
|
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"asynckit": "^0.4.0",
|
"asynckit": "^0.4.0",
|
||||||
"combined-stream": "^1.0.8",
|
"combined-stream": "^1.0.8",
|
||||||
@@ -4904,6 +4955,7 @@
|
|||||||
"version": "0.4.24",
|
"version": "0.4.24",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"safer-buffer": ">= 2.1.2 < 3"
|
"safer-buffer": ">= 2.1.2 < 3"
|
||||||
},
|
},
|
||||||
@@ -4935,12 +4987,6 @@
|
|||||||
"node": ">= 0.10"
|
"node": ">= 0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/is-arrayish": {
|
|
||||||
"version": "0.3.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
|
|
||||||
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"node_modules/is-core-module": {
|
"node_modules/is-core-module": {
|
||||||
"version": "2.16.1",
|
"version": "2.16.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
|
||||||
@@ -5081,13 +5127,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jsonwebtoken/node_modules/jws": {
|
"node_modules/jsonwebtoken/node_modules/jws": {
|
||||||
"version": "3.2.2",
|
"version": "3.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.3.tgz",
|
||||||
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
|
"integrity": "sha512-byiJ0FLRdLdSVSReO/U4E7RoEyOCKnEnEPMjq3HxWtvzLsV08/i5RQKsFVNkCldrCaPr2vDNAOMsfs8T/Hze7g==",
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jwa": "^1.4.1",
|
"jwa": "^1.4.2",
|
||||||
"safe-buffer": "^5.0.1"
|
"safe-buffer": "^5.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -5120,11 +5167,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jws": {
|
"node_modules/jws": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz",
|
||||||
"integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
|
"integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jwa": "^2.0.0",
|
"jwa": "^2.0.1",
|
||||||
"safe-buffer": "^5.0.1"
|
"safe-buffer": "^5.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -5391,9 +5439,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/node-forge": {
|
"node_modules/node-forge": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.3.tgz",
|
||||||
"integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==",
|
"integrity": "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==",
|
||||||
|
"license": "(BSD-3-Clause OR GPL-2.0)",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -5661,11 +5710,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/qs": {
|
"node_modules/qs": {
|
||||||
"version": "6.13.0",
|
"version": "6.14.1",
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz",
|
||||||
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
|
"integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"side-channel": "^1.0.6"
|
"side-channel": "^1.1.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.6"
|
"node": ">=0.6"
|
||||||
@@ -5683,19 +5733,49 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/raw-body": {
|
"node_modules/raw-body": {
|
||||||
"version": "2.5.2",
|
"version": "2.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz",
|
||||||
"integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
|
"integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bytes": "3.1.2",
|
"bytes": "~3.1.2",
|
||||||
"http-errors": "2.0.0",
|
"http-errors": "~2.0.1",
|
||||||
"iconv-lite": "0.4.24",
|
"iconv-lite": "~0.4.24",
|
||||||
"unpipe": "1.0.0"
|
"unpipe": "~1.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/raw-body/node_modules/http-errors": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"depd": "~2.0.0",
|
||||||
|
"inherits": "~2.0.4",
|
||||||
|
"setprototypeof": "~1.2.0",
|
||||||
|
"statuses": "~2.0.2",
|
||||||
|
"toidentifier": "~1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/raw-body/node_modules/statuses": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/readable-stream": {
|
"node_modules/readable-stream": {
|
||||||
"version": "3.6.2",
|
"version": "3.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||||
@@ -5813,7 +5893,8 @@
|
|||||||
"node_modules/safer-buffer": {
|
"node_modules/safer-buffer": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
"version": "7.7.2",
|
"version": "7.7.2",
|
||||||
@@ -5973,15 +6054,6 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/simple-swizzle": {
|
|
||||||
"version": "0.2.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
|
|
||||||
"integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
|
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
|
||||||
"is-arrayish": "^0.3.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/source-map": {
|
"node_modules/source-map": {
|
||||||
"version": "0.6.1",
|
"version": "0.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||||
@@ -6168,6 +6240,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
|
||||||
"integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==",
|
"integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==",
|
||||||
|
"license": "MIT",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"node_modules/thriftrw": {
|
"node_modules/thriftrw": {
|
||||||
@@ -6351,13 +6424,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/winston": {
|
"node_modules/winston": {
|
||||||
"version": "3.17.0",
|
"version": "3.19.0",
|
||||||
"resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/winston/-/winston-3.19.0.tgz",
|
||||||
"integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==",
|
"integrity": "sha512-LZNJgPzfKR+/J3cHkxcpHKpKKvGfDZVPS4hfJCc4cCG0CgYzvlD6yE/S3CIL/Yt91ak327YCpiF/0MyeZHEHKA==",
|
||||||
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@colors/colors": "^1.6.0",
|
"@colors/colors": "^1.6.0",
|
||||||
"@dabh/diagnostics": "^2.0.2",
|
"@dabh/diagnostics": "^2.0.8",
|
||||||
"async": "^3.2.3",
|
"async": "^3.2.3",
|
||||||
"is-stream": "^2.0.0",
|
"is-stream": "^2.0.0",
|
||||||
"logform": "^2.7.0",
|
"logform": "^2.7.0",
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export async function main() {
|
|||||||
|
|
||||||
for (const query of queries) {
|
for (const query of queries) {
|
||||||
conversationHistory.push({ role: "user", content: [{ text: query }] });
|
conversationHistory.push({ role: "user", content: [{ text: query }] });
|
||||||
const response = await ai.generate({
|
let response = await ai.generate({
|
||||||
messages: conversationHistory,
|
messages: conversationHistory,
|
||||||
tools: tools,
|
tools: tools,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,7 +18,8 @@
|
|||||||
"node_modules/@cfworker/json-schema": {
|
"node_modules/@cfworker/json-schema": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@cfworker/json-schema/-/json-schema-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@cfworker/json-schema/-/json-schema-4.1.1.tgz",
|
||||||
"integrity": "sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og=="
|
"integrity": "sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og==",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/@google/generative-ai": {
|
"node_modules/@google/generative-ai": {
|
||||||
"version": "0.24.1",
|
"version": "0.24.1",
|
||||||
@@ -45,9 +46,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@langchain/core": {
|
"node_modules/@langchain/core": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.8",
|
||||||
"resolved": "https://registry.npmjs.org/@langchain/core/-/core-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@langchain/core/-/core-1.1.8.tgz",
|
||||||
"integrity": "sha512-yJ6JHcU9psjnQbzRFkXjIdNTA+3074dA+2pHdH8ewvQCSleSk6JcjkCMIb5+NASjeMoi1ZuntlLKVsNqF38YxA==",
|
"integrity": "sha512-kIUidOgc0ZdyXo4Ahn9Zas+OayqOfk4ZoKPi7XaDipNSWSApc2+QK5BVcjvwtzxstsNOrmXJiJWEN6WPF/MvAw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -56,10 +57,9 @@
|
|||||||
"camelcase": "6",
|
"camelcase": "6",
|
||||||
"decamelize": "1.2.0",
|
"decamelize": "1.2.0",
|
||||||
"js-tiktoken": "^1.0.12",
|
"js-tiktoken": "^1.0.12",
|
||||||
"langsmith": "^0.3.64",
|
"langsmith": ">=0.4.0 <1.0.0",
|
||||||
"mustache": "^4.2.0",
|
"mustache": "^4.2.0",
|
||||||
"p-queue": "^6.6.2",
|
"p-queue": "^6.6.2",
|
||||||
"p-retry": "^7.0.0",
|
|
||||||
"uuid": "^10.0.0",
|
"uuid": "^10.0.0",
|
||||||
"zod": "^3.25.76 || ^4"
|
"zod": "^3.25.76 || ^4"
|
||||||
},
|
},
|
||||||
@@ -67,25 +67,10 @@
|
|||||||
"node": ">=20"
|
"node": ">=20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@langchain/core/node_modules/p-retry": {
|
|
||||||
"version": "7.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-7.1.0.tgz",
|
|
||||||
"integrity": "sha512-xL4PiFRQa/f9L9ZvR4/gUCRNus4N8YX80ku8kv9Jqz+ZokkiZLM0bcvX0gm1F3PDi9SPRsww1BDsTWgE6Y1GLQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"is-network-error": "^1.1.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=20"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@langchain/google-genai": {
|
"node_modules/@langchain/google-genai": {
|
||||||
"version": "2.0.0",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/@langchain/google-genai/-/google-genai-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@langchain/google-genai/-/google-genai-2.1.3.tgz",
|
||||||
"integrity": "sha512-PaAWkogQdF+Y2bhhXWXUrC2nO7sTgWLtobBbZl/0V8Aa1F/KG2wrMECie3S17bAdFu/6VmQOuFFrlgSMwQC5KA==",
|
"integrity": "sha512-ZdlFK/N10GyU6ATzkM01Sk1rlHBoy36Q/MawGD1SyXdD2lQxZxuQZjFWewj6uzWQ2Nnjj70EvU/kmmHVPn6sfQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@google/generative-ai": "^0.24.0",
|
"@google/generative-ai": "^0.24.0",
|
||||||
@@ -95,7 +80,7 @@
|
|||||||
"node": ">=20"
|
"node": ">=20"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@langchain/core": "1.1.0"
|
"@langchain/core": "1.1.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@langchain/google-genai/node_modules/uuid": {
|
"node_modules/@langchain/google-genai/node_modules/uuid": {
|
||||||
@@ -241,6 +226,7 @@
|
|||||||
"version": "5.2.0",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
|
||||||
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
|
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
},
|
},
|
||||||
@@ -324,6 +310,7 @@
|
|||||||
"version": "6.3.0",
|
"version": "6.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
|
||||||
"integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
|
"integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
},
|
},
|
||||||
@@ -436,6 +423,7 @@
|
|||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||||
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
|
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
@@ -814,18 +802,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/is-network-error": {
|
|
||||||
"version": "1.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.0.tgz",
|
|
||||||
"integrity": "sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=16"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/isexe": {
|
"node_modules/isexe": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||||
@@ -849,6 +825,7 @@
|
|||||||
"version": "1.0.21",
|
"version": "1.0.21",
|
||||||
"resolved": "https://registry.npmjs.org/js-tiktoken/-/js-tiktoken-1.0.21.tgz",
|
"resolved": "https://registry.npmjs.org/js-tiktoken/-/js-tiktoken-1.0.21.tgz",
|
||||||
"integrity": "sha512-biOj/6M5qdgx5TKjDnFT1ymSpM5tbd3ylwDtrQvFQSu0Z7bBYko2dF+W/aUkXUPuk6IVpRxk/3Q2sHOzGlS36g==",
|
"integrity": "sha512-biOj/6M5qdgx5TKjDnFT1ymSpM5tbd3ylwDtrQvFQSu0Z7bBYko2dF+W/aUkXUPuk6IVpRxk/3Q2sHOzGlS36g==",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"base64-js": "^1.5.1"
|
"base64-js": "^1.5.1"
|
||||||
}
|
}
|
||||||
@@ -872,22 +849,24 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jws": {
|
"node_modules/jws": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz",
|
||||||
"integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
|
"integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jwa": "^2.0.0",
|
"jwa": "^2.0.1",
|
||||||
"safe-buffer": "^5.0.1"
|
"safe-buffer": "^5.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/langchain": {
|
"node_modules/langchain": {
|
||||||
"version": "1.0.2",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/langchain/-/langchain-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/langchain/-/langchain-1.2.3.tgz",
|
||||||
"integrity": "sha512-He/xvjVl8DHESvdaW6Dpyba72OaLCAfS2CyOm1aWrlJ4C38dKXyTIxphtld8hiii6MWX7qMSmu2EaUwWBx2STg==",
|
"integrity": "sha512-3k986xJuqg4az53JxV5LnGlOzIXF1d9Kq6Y9s7XjitvzhpsbFuTDV5/kiF4cx3pkNGyw0mUXC4tLz9RxucO0hw==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@langchain/langgraph": "^1.0.0",
|
"@langchain/langgraph": "^1.0.0",
|
||||||
"@langchain/langgraph-checkpoint": "^1.0.0",
|
"@langchain/langgraph-checkpoint": "^1.0.0",
|
||||||
"langsmith": "~0.3.74",
|
"langsmith": ">=0.4.0 <1.0.0",
|
||||||
"uuid": "^10.0.0",
|
"uuid": "^10.0.0",
|
||||||
"zod": "^3.25.76 || ^4"
|
"zod": "^3.25.76 || ^4"
|
||||||
},
|
},
|
||||||
@@ -895,19 +874,19 @@
|
|||||||
"node": ">=20"
|
"node": ">=20"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@langchain/core": "^1.0.0"
|
"@langchain/core": "1.1.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/langsmith": {
|
"node_modules/langsmith": {
|
||||||
"version": "0.3.77",
|
"version": "0.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/langsmith/-/langsmith-0.3.77.tgz",
|
"resolved": "https://registry.npmjs.org/langsmith/-/langsmith-0.5.2.tgz",
|
||||||
"integrity": "sha512-wbS/9IX/hOAsOEOtPj8kCS8H0tFHaelwQ97gTONRtIfoPPLd9MMUmhk0KQB5DdsGAI5abg966+f0dZ/B+YRRzg==",
|
"integrity": "sha512-CfkcQsiajtTWknAcyItvJsKEQdY2VgDpm6U8pRI9wnM07mevnOv5EF+RcqWGwx37SEUxtyi2RXMwnKW8b06JtA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/uuid": "^10.0.0",
|
"@types/uuid": "^10.0.0",
|
||||||
"chalk": "^4.1.2",
|
"chalk": "^4.1.2",
|
||||||
"console-table-printer": "^2.12.1",
|
"console-table-printer": "^2.12.1",
|
||||||
"p-queue": "^6.6.2",
|
"p-queue": "^6.6.2",
|
||||||
"p-retry": "4",
|
|
||||||
"semver": "^7.6.3",
|
"semver": "^7.6.3",
|
||||||
"uuid": "^10.0.0"
|
"uuid": "^10.0.0"
|
||||||
},
|
},
|
||||||
@@ -995,6 +974,7 @@
|
|||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz",
|
||||||
"integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==",
|
"integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"mustache": "bin/mustache"
|
"mustache": "bin/mustache"
|
||||||
}
|
}
|
||||||
@@ -1433,7 +1413,6 @@
|
|||||||
"version": "3.25.76",
|
"version": "3.25.76",
|
||||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
|
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
|
||||||
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
|
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
|
||||||
"peer": true,
|
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/colinhacks"
|
"url": "https://github.com/sponsors/colinhacks"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -882,11 +882,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jws": {
|
"node_modules/jws": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz",
|
||||||
"integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
|
"integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jwa": "^2.0.0",
|
"jwa": "^2.0.1",
|
||||||
"safe-buffer": "^5.0.1"
|
"safe-buffer": "^5.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -974,9 +975,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lodash": {
|
"node_modules/lodash": {
|
||||||
"version": "4.17.21",
|
"version": "4.17.23",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
|
||||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
"integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/magic-bytes.js": {
|
"node_modules/magic-bytes.js": {
|
||||||
"version": "1.12.1",
|
"version": "1.12.1",
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ const quickstartPath = path.join(orchDir, "quickstart.js");
|
|||||||
|
|
||||||
const { main: runAgent } = await import(quickstartPath);
|
const { main: runAgent } = await import(quickstartPath);
|
||||||
|
|
||||||
const GOLDEN_FILE_PATH = path.resolve(__dirname, "../golden.txt");
|
const GOLDEN_KEYWORDS = ["Hilton Basel", "Hyatt Regency", "book"];
|
||||||
|
|
||||||
describe(`${ORCH_NAME} Quickstart Agent`, () => {
|
describe(`${ORCH_NAME} Quickstart Agent`, () => {
|
||||||
let capturedOutput = [];
|
let capturedOutput = [];
|
||||||
@@ -52,11 +52,8 @@ describe(`${ORCH_NAME} Quickstart Agent`, () => {
|
|||||||
"Assertion Failed: Script ran successfully but produced no output."
|
"Assertion Failed: Script ran successfully but produced no output."
|
||||||
);
|
);
|
||||||
|
|
||||||
const goldenFile = fs.readFileSync(GOLDEN_FILE_PATH, "utf8");
|
|
||||||
const keywords = goldenFile.split("\n").filter((kw) => kw.trim() !== "");
|
|
||||||
const missingKeywords = [];
|
const missingKeywords = [];
|
||||||
|
for (const keyword of GOLDEN_KEYWORDS) {
|
||||||
for (const keyword of keywords) {
|
|
||||||
if (!actualOutput.toLowerCase().includes(keyword.toLowerCase())) {
|
if (!actualOutput.toLowerCase().includes(keyword.toLowerCase())) {
|
||||||
missingKeywords.push(keyword);
|
missingKeywords.push(keyword);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,57 @@
|
|||||||
|
# [START quickstart]
|
||||||
|
import asyncio
|
||||||
|
|
||||||
from google.adk import Agent
|
from google.adk import Agent
|
||||||
from google.adk.apps import App
|
from google.adk.apps import App
|
||||||
from toolbox_core import ToolboxSyncClient
|
from google.adk.runners import InMemoryRunner
|
||||||
|
from google.adk.tools.toolbox_toolset import ToolboxToolset
|
||||||
|
from google.genai.types import Content, Part
|
||||||
|
|
||||||
|
prompt = """
|
||||||
|
You're a helpful hotel assistant. You handle hotel searching, booking and
|
||||||
|
cancellations. When the user searches for a hotel, mention it's name, id,
|
||||||
|
location and price tier. Always mention hotel ids while performing any
|
||||||
|
searches. This is very important for any operations. For any bookings or
|
||||||
|
cancellations, please provide the appropriate confirmation. Be sure to
|
||||||
|
update checkin or checkout dates if mentioned by the user.
|
||||||
|
Don't ask for confirmations from the user.
|
||||||
|
"""
|
||||||
|
|
||||||
# TODO(developer): update the TOOLBOX_URL to your toolbox endpoint
|
# TODO(developer): update the TOOLBOX_URL to your toolbox endpoint
|
||||||
client = ToolboxSyncClient("http://127.0.0.1:5000")
|
toolset = ToolboxToolset(
|
||||||
|
server_url="http://127.0.0.1:5000",
|
||||||
|
)
|
||||||
|
|
||||||
root_agent = Agent(
|
root_agent = Agent(
|
||||||
name='root_agent',
|
name='hotel_assistant',
|
||||||
model='gemini-2.5-flash',
|
model='gemini-2.5-flash',
|
||||||
instruction="You are a helpful AI assistant designed to provide accurate and useful information.",
|
instruction=prompt,
|
||||||
tools=client.load_toolset(),
|
tools=[toolset],
|
||||||
)
|
)
|
||||||
|
|
||||||
app = App(root_agent=root_agent, name="my_agent")
|
app = App(root_agent=root_agent, name="my_agent")
|
||||||
|
# [END quickstart]
|
||||||
|
|
||||||
|
queries = [
|
||||||
|
"Find hotels in Basel with Basel in its name.",
|
||||||
|
"Can you book the Hilton Basel for me?",
|
||||||
|
"Oh wait, this is too expensive. Please cancel it and book the Hyatt Regency instead.",
|
||||||
|
"My check in dates would be from April 10, 2024 to April 19, 2024.",
|
||||||
|
]
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
runner = InMemoryRunner(app=app)
|
||||||
|
session = await runner.session_service.create_session(
|
||||||
|
app_name=app.name, user_id="test_user"
|
||||||
|
)
|
||||||
|
|
||||||
|
for query in queries:
|
||||||
|
print(f"\nUser: {query}")
|
||||||
|
user_message = Content(parts=[Part.from_text(text=query)])
|
||||||
|
|
||||||
|
async for event in runner.run_async(user_id="test_user", session_id=session.id, new_message=user_message):
|
||||||
|
if event.is_final_response() and event.content and event.content.parts:
|
||||||
|
print(f"Agent: {event.content.parts[0].text}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(main())
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
google-adk==1.19.0
|
google-adk[toolbox]==1.23.0
|
||||||
toolbox-core==0.5.3
|
pytest==9.0.2
|
||||||
pytest==9.0.1
|
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
google-genai==1.52.0
|
google-genai==1.57.0
|
||||||
toolbox-core==0.5.3
|
toolbox-core==0.5.4
|
||||||
pytest==9.0.1
|
pytest==9.0.2
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
langchain==1.1.0
|
langchain==1.2.2
|
||||||
langchain-google-vertexai==3.1.0
|
langchain-google-vertexai==3.2.1
|
||||||
langgraph==1.0.4
|
langgraph==1.0.5
|
||||||
toolbox-langchain==0.5.3
|
toolbox-langchain==0.5.4
|
||||||
pytest==9.0.1
|
pytest==9.0.2
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
llama-index==0.14.8
|
llama-index==0.14.12
|
||||||
llama-index-llms-google-genai==0.7.3
|
llama-index-llms-google-genai==0.8.3
|
||||||
toolbox-llamaindex==0.5.3
|
toolbox-llamaindex==0.5.4
|
||||||
pytest==9.0.1
|
pytest==9.0.2
|
||||||
|
|||||||
@@ -24,48 +24,35 @@ module_path = f"python.{ORCH_NAME}.quickstart"
|
|||||||
quickstart = importlib.import_module(module_path)
|
quickstart = importlib.import_module(module_path)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
GOLDEN_KEYWORDS = ["Hilton Basel", "Hyatt Regency", "book"]
|
||||||
def golden_keywords():
|
|
||||||
"""Loads expected keywords from the golden.txt file."""
|
|
||||||
golden_file_path = Path("../golden.txt")
|
|
||||||
if not golden_file_path.exists():
|
|
||||||
pytest.fail(f"Golden file not found: {golden_file_path}")
|
|
||||||
try:
|
|
||||||
with open(golden_file_path, 'r') as f:
|
|
||||||
return [line.strip() for line in f.readlines() if line.strip()]
|
|
||||||
except Exception as e:
|
|
||||||
pytest.fail(f"Could not read golden.txt: {e}")
|
|
||||||
|
|
||||||
|
|
||||||
# --- Execution Tests ---
|
# --- Execution Tests ---
|
||||||
class TestExecution:
|
class TestExecution:
|
||||||
"""Test framework execution and output validation."""
|
"""Test framework execution and output validation."""
|
||||||
|
|
||||||
|
_cached_output = None
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
@pytest.fixture(scope="function")
|
||||||
def script_output(self, capsys):
|
def script_output(self, capsys):
|
||||||
"""Run the quickstart function and return its output."""
|
"""Run the quickstart function and return its output."""
|
||||||
|
if TestExecution._cached_output is None:
|
||||||
# TODO: Add better validation for ADK once we have a way to capture its
|
|
||||||
# output.
|
|
||||||
if ORCH_NAME == "adk":
|
|
||||||
return quickstart.app.root_agent.name
|
|
||||||
else:
|
|
||||||
asyncio.run(quickstart.main())
|
asyncio.run(quickstart.main())
|
||||||
|
out, err = capsys.readouterr()
|
||||||
return capsys.readouterr()
|
TestExecution._cached_output = (out, err)
|
||||||
|
|
||||||
|
class Output:
|
||||||
|
def __init__(self, out, err):
|
||||||
|
self.out = out
|
||||||
|
self.err = err
|
||||||
|
|
||||||
|
return Output(*TestExecution._cached_output)
|
||||||
|
|
||||||
def test_script_runs_without_errors(self, script_output):
|
def test_script_runs_without_errors(self, script_output):
|
||||||
"""Test that the script runs and produces no stderr."""
|
"""Test that the script runs and produces no stderr."""
|
||||||
if ORCH_NAME == "adk":
|
|
||||||
return
|
|
||||||
assert script_output.err == "", f"Script produced stderr: {script_output.err}"
|
assert script_output.err == "", f"Script produced stderr: {script_output.err}"
|
||||||
|
|
||||||
def test_keywords_in_output(self, script_output, golden_keywords):
|
def test_keywords_in_output(self, script_output):
|
||||||
"""Test that expected keywords are present in the script's output."""
|
"""Test that expected keywords are present in the script's output."""
|
||||||
|
|
||||||
if ORCH_NAME == "adk":
|
|
||||||
assert script_output == "root_agent"
|
|
||||||
return
|
|
||||||
output = script_output.out
|
output = script_output.out
|
||||||
missing_keywords = [kw for kw in golden_keywords if kw not in output]
|
missing_keywords = [kw for kw in GOLDEN_KEYWORDS if kw.lower() not in output.lower()]
|
||||||
assert not missing_keywords, f"Missing keywords in output: {missing_keywords}"
|
assert not missing_keywords, f"Missing keywords in output: {missing_keywords}"
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ In this section, we will download Toolbox, configure our tools in a
|
|||||||
<!-- {x-release-please-start-version} -->
|
<!-- {x-release-please-start-version} -->
|
||||||
```bash
|
```bash
|
||||||
export OS="linux/amd64" # one of linux/amd64, darwin/arm64, darwin/amd64, or windows/amd64
|
export OS="linux/amd64" # one of linux/amd64, darwin/arm64, darwin/amd64, or windows/amd64
|
||||||
curl -O https://storage.googleapis.com/genai-toolbox/v0.21.0/$OS/toolbox
|
curl -O https://storage.googleapis.com/genai-toolbox/v0.27.0/$OS/toolbox
|
||||||
```
|
```
|
||||||
<!-- {x-release-please-end} -->
|
<!-- {x-release-please-end} -->
|
||||||
|
|
||||||
@@ -33,78 +33,89 @@ In this section, we will download Toolbox, configure our tools in a
|
|||||||
{{< /notice >}}
|
{{< /notice >}}
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
sources:
|
kind: sources
|
||||||
my-pg-source:
|
name: my-pg-source
|
||||||
kind: postgres
|
type: postgres
|
||||||
host: 127.0.0.1
|
host: 127.0.0.1
|
||||||
port: 5432
|
port: 5432
|
||||||
database: toolbox_db
|
database: toolbox_db
|
||||||
user: ${USER_NAME}
|
user: toolbox_user
|
||||||
password: ${PASSWORD}
|
password: my-password
|
||||||
|
---
|
||||||
|
kind: tools
|
||||||
|
name: search-hotels-by-name
|
||||||
|
type: postgres-sql
|
||||||
|
source: my-pg-source
|
||||||
|
description: Search for hotels based on name.
|
||||||
|
parameters:
|
||||||
|
- name: name
|
||||||
|
type: string
|
||||||
|
description: The name of the hotel.
|
||||||
|
statement: SELECT * FROM hotels WHERE name ILIKE '%' || $1 || '%';
|
||||||
|
---
|
||||||
|
kind: tools
|
||||||
|
name: search-hotels-by-location
|
||||||
|
type: postgres-sql
|
||||||
|
source: my-pg-source
|
||||||
|
description: Search for hotels based on location.
|
||||||
|
parameters:
|
||||||
|
- name: location
|
||||||
|
type: string
|
||||||
|
description: The location of the hotel.
|
||||||
|
statement: SELECT * FROM hotels WHERE location ILIKE '%' || $1 || '%';
|
||||||
|
---
|
||||||
|
kind: tools
|
||||||
|
name: book-hotel
|
||||||
|
type: postgres-sql
|
||||||
|
source: my-pg-source
|
||||||
|
description: >-
|
||||||
|
Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not.
|
||||||
|
parameters:
|
||||||
|
- name: hotel_id
|
||||||
|
type: string
|
||||||
|
description: The ID of the hotel to book.
|
||||||
|
statement: UPDATE hotels SET booked = B'1' WHERE id = $1;
|
||||||
|
---
|
||||||
|
kind: tools
|
||||||
|
name: update-hotel
|
||||||
|
type: postgres-sql
|
||||||
|
source: my-pg-source
|
||||||
|
description: >-
|
||||||
|
Update a hotel's check-in and check-out dates by its ID. Returns a message
|
||||||
|
indicating whether the hotel was successfully updated or not.
|
||||||
|
parameters:
|
||||||
|
- name: hotel_id
|
||||||
|
type: string
|
||||||
|
description: The ID of the hotel to update.
|
||||||
|
- name: checkin_date
|
||||||
|
type: string
|
||||||
|
description: The new check-in date of the hotel.
|
||||||
|
- name: checkout_date
|
||||||
|
type: string
|
||||||
|
description: The new check-out date of the hotel.
|
||||||
|
statement: >-
|
||||||
|
UPDATE hotels SET checkin_date = CAST($2 as date), checkout_date = CAST($3
|
||||||
|
as date) WHERE id = $1;
|
||||||
|
---
|
||||||
|
kind: tools
|
||||||
|
name: cancel-hotel
|
||||||
|
type: postgres-sql
|
||||||
|
source: my-pg-source
|
||||||
|
description: Cancel a hotel by its ID.
|
||||||
|
parameters:
|
||||||
|
- name: hotel_id
|
||||||
|
type: string
|
||||||
|
description: The ID of the hotel to cancel.
|
||||||
|
statement: UPDATE hotels SET booked = B'0' WHERE id = $1;
|
||||||
|
---
|
||||||
|
kind: toolsets
|
||||||
|
name: my-toolset
|
||||||
tools:
|
tools:
|
||||||
search-hotels-by-name:
|
- search-hotels-by-name
|
||||||
kind: postgres-sql
|
- search-hotels-by-location
|
||||||
source: my-pg-source
|
- book-hotel
|
||||||
description: Search for hotels based on name.
|
- update-hotel
|
||||||
parameters:
|
- cancel-hotel
|
||||||
- name: name
|
|
||||||
type: string
|
|
||||||
description: The name of the hotel.
|
|
||||||
statement: SELECT * FROM hotels WHERE name ILIKE '%' || $1 || '%';
|
|
||||||
search-hotels-by-location:
|
|
||||||
kind: postgres-sql
|
|
||||||
source: my-pg-source
|
|
||||||
description: Search for hotels based on location.
|
|
||||||
parameters:
|
|
||||||
- name: location
|
|
||||||
type: string
|
|
||||||
description: The location of the hotel.
|
|
||||||
statement: SELECT * FROM hotels WHERE location ILIKE '%' || $1 || '%';
|
|
||||||
book-hotel:
|
|
||||||
kind: postgres-sql
|
|
||||||
source: my-pg-source
|
|
||||||
description: >-
|
|
||||||
Book a hotel by its ID. If the hotel is successfully booked, returns a NULL, raises an error if not.
|
|
||||||
parameters:
|
|
||||||
- name: hotel_id
|
|
||||||
type: string
|
|
||||||
description: The ID of the hotel to book.
|
|
||||||
statement: UPDATE hotels SET booked = B'1' WHERE id = $1;
|
|
||||||
update-hotel:
|
|
||||||
kind: postgres-sql
|
|
||||||
source: my-pg-source
|
|
||||||
description: >-
|
|
||||||
Update a hotel's check-in and check-out dates by its ID. Returns a message
|
|
||||||
indicating whether the hotel was successfully updated or not.
|
|
||||||
parameters:
|
|
||||||
- name: hotel_id
|
|
||||||
type: string
|
|
||||||
description: The ID of the hotel to update.
|
|
||||||
- name: checkin_date
|
|
||||||
type: string
|
|
||||||
description: The new check-in date of the hotel.
|
|
||||||
- name: checkout_date
|
|
||||||
type: string
|
|
||||||
description: The new check-out date of the hotel.
|
|
||||||
statement: >-
|
|
||||||
UPDATE hotels SET checkin_date = CAST($2 as date), checkout_date = CAST($3
|
|
||||||
as date) WHERE id = $1;
|
|
||||||
cancel-hotel:
|
|
||||||
kind: postgres-sql
|
|
||||||
source: my-pg-source
|
|
||||||
description: Cancel a hotel by its ID.
|
|
||||||
parameters:
|
|
||||||
- name: hotel_id
|
|
||||||
type: string
|
|
||||||
description: The ID of the hotel to cancel.
|
|
||||||
statement: UPDATE hotels SET booked = B'0' WHERE id = $1;
|
|
||||||
toolsets:
|
|
||||||
my-toolset:
|
|
||||||
- search-hotels-by-name
|
|
||||||
- search-hotels-by-location
|
|
||||||
- book-hotel
|
|
||||||
- update-hotel
|
|
||||||
- cancel-hotel
|
|
||||||
```
|
```
|
||||||
|
|
||||||
For more info on tools, check out the `Resources` section of the docs.
|
For more info on tools, check out the `Resources` section of the docs.
|
||||||
|
|||||||
@@ -48,11 +48,13 @@ instance, database and users:
|
|||||||
* `roles/cloudsql.editor`: Provides permissions to manage existing resources.
|
* `roles/cloudsql.editor`: Provides permissions to manage existing resources.
|
||||||
* All `viewer` tools
|
* All `viewer` tools
|
||||||
* `create_database`
|
* `create_database`
|
||||||
|
* `create_backup`
|
||||||
* `roles/cloudsql.admin`: Provides full control over all resources.
|
* `roles/cloudsql.admin`: Provides full control over all resources.
|
||||||
* All `editor` and `viewer` tools
|
* All `editor` and `viewer` tools
|
||||||
* `create_instance`
|
* `create_instance`
|
||||||
* `create_user`
|
* `create_user`
|
||||||
* `clone_instance`
|
* `clone_instance`
|
||||||
|
* `restore_backup`
|
||||||
|
|
||||||
## Install MCP Toolbox
|
## Install MCP Toolbox
|
||||||
|
|
||||||
@@ -299,6 +301,8 @@ instances and interacting with your database:
|
|||||||
* **create_user**: Creates a new user in a Cloud SQL instance.
|
* **create_user**: Creates a new user in a Cloud SQL instance.
|
||||||
* **wait_for_operation**: Waits for a Cloud SQL operation to complete.
|
* **wait_for_operation**: Waits for a Cloud SQL operation to complete.
|
||||||
* **clone_instance**: Creates a clone of an existing Cloud SQL for SQL Server instance.
|
* **clone_instance**: Creates a clone of an existing Cloud SQL for SQL Server instance.
|
||||||
|
* **create_backup**: Creates a backup on a Cloud SQL instance.
|
||||||
|
* **restore_backup**: Restores a backup of a Cloud SQL instance.
|
||||||
|
|
||||||
{{< notice note >}}
|
{{< notice note >}}
|
||||||
Prebuilt tools are pre-1.0, so expect some tool changes between versions. LLMs
|
Prebuilt tools are pre-1.0, so expect some tool changes between versions. LLMs
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user