Compare commits

...

107 Commits

Author SHA1 Message Date
Harsh Jha
10532bebc2 Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-09 17:39:36 +05:30
Harsh Jha
d93a23b35a chore: fix auth 2025-09-09 17:39:05 +05:30
Harsh Jha
c323dc4618 Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-09 17:29:43 +05:30
Harsh Jha
feadcfbef0 chore: added pkg of wget 2025-09-09 17:29:16 +05:30
Harsh Jha
e06e802f5e Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-09 17:25:07 +05:30
Harsh Jha
5b7bcf0715 chore: fix wget cmd 2025-09-09 17:24:33 +05:30
Harsh Jha
71dd32de60 Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-09 17:21:32 +05:30
Harsh Jha
5615f4636d chore: fix of cloudsql 2025-09-09 17:21:08 +05:30
Harsh Jha
68a85b80e7 Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-09 17:11:09 +05:30
Harsh Jha
b44bfec6cc chore: fix toolbox instance 2025-09-09 17:10:43 +05:30
Harsh Jha
55635cedf6 Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-09 16:47:17 +05:30
Harsh Jha
a9b84d6165 chore: fix toolbox url 2025-09-09 16:46:49 +05:30
Harsh Jha
c23c5c9e8f Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-09 12:11:51 +05:30
Harsh Jha
beb524de67 chore: fix variable name of version of toolbox 2025-09-09 12:11:24 +05:30
Harsh Jha
c3257fe912 Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-09 12:07:19 +05:30
Harsh Jha
4fa243063c removed log of secret value 2025-09-09 12:06:56 +05:30
Harsh Jha
7b69829a4b Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-09 11:59:18 +05:30
Harsh Jha
ea9e4f323a chore: removed cloudsql steps 2025-09-09 11:58:49 +05:30
Harsh Jha
aded6630b6 Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-09 11:42:36 +05:30
Harsh Jha
674e98875a fix: removed extra steps 2025-09-09 11:36:36 +05:30
Harsh Jha
82e901b193 chore: added license for quickstart_py.yaml 2025-09-08 11:57:59 +05:30
Harsh Jha
6f43a283fa added os package in langchain 2025-09-08 11:44:08 +05:30
Harsh Jha
51f6c4a946 fix: version for llamaindex packages 2025-09-08 11:36:14 +05:30
Harsh Jha
577e094330 fix: version of langchain packages 2025-09-08 11:23:59 +05:30
Harsh Jha
3399f4ed61 updated verison 2025-09-04 18:59:08 +05:30
Harsh Jha
bed5ce5d71 updated 2025-09-04 18:48:38 +05:30
Harsh Jha
6db2fcbcfa updated 2025-09-04 18:33:48 +05:30
Harsh Jha
05bb6820e2 Merge branch 'main' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-04 18:33:06 +05:30
Harsh Jha
b754ce9e34 updated 2025-09-04 18:18:03 +05:30
Harsh Jha
2a9138dd01 updated 2025-09-04 18:11:57 +05:30
Harsh Jha
a366f99524 quickstart update 2025-09-04 17:39:07 +05:30
Harsh Jha
37eb54d693 updated 2025-09-04 17:32:45 +05:30
Harsh Jha
8e5908251e update 2025-09-04 17:23:39 +05:30
Harsh Jha
fd814cdf27 update 2025-09-04 17:14:42 +05:30
Harsh Jha
7df5d8975c updated quickstart 2025-09-04 17:06:38 +05:30
Harsh Jha
d09dd1ac76 updated quickstart.py 2025-09-04 17:02:30 +05:30
Harsh Jha
4e022ef3ef updated 2025-09-04 16:46:40 +05:30
Harsh Jha
2b9710ffef quickstart.py updated 2025-09-04 16:39:37 +05:30
Harsh Jha
653a9f0f46 modified for quickstart.py for toolbox url 2025-09-04 16:30:43 +05:30
Harsh Jha
8df929fcd4 Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-04 13:47:34 +05:30
Harsh Jha
7280065c23 updated 2025-09-04 13:47:05 +05:30
Harsh Jha
ce83384393 Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-04 13:37:09 +05:30
Harsh Jha
34c4edf1ae debug for pg password 2025-09-04 13:36:40 +05:30
Harsh Jha
6ae1039f4a Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-04 13:25:33 +05:30
Harsh Jha
d85ae4fb78 updated 2025-09-04 13:25:07 +05:30
Harsh Jha
8f77e081b5 Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-04 13:11:02 +05:30
Harsh Jha
a5bc7d8110 updated 2025-09-04 13:10:33 +05:30
Harsh Jha
3a1814f9e6 Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-04 13:03:12 +05:30
Harsh Jha
9e45500df6 updated 2025-09-04 13:02:44 +05:30
Harsh Jha
b80a4d8612 Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-04 12:53:37 +05:30
Harsh Jha
69fcd51966 updated 2025-09-04 12:52:58 +05:30
Harsh Jha
e7708ef17e Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-04 12:48:21 +05:30
Harsh Jha
1cd05b6fc1 update 2025-09-04 12:47:50 +05:30
Harsh Jha
e195a5bc74 Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-04 12:39:23 +05:30
Harsh Jha
54827c46c8 fixed: quickstart_py.yaml 2025-09-04 12:37:21 +05:30
Harsh Jha
f28074285c Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-04 12:26:30 +05:30
Harsh Jha
2355ca5a96 added psql cmd 2025-09-04 12:26:00 +05:30
Harsh Jha
9160aad696 Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-04 12:19:15 +05:30
Harsh Jha
46eb49245e updated 2025-09-04 12:17:34 +05:30
Harsh Jha
ff31de5eb2 Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-04 12:00:13 +05:30
Harsh Jha
a3c4306897 updated quickstart_py.yaml 2025-09-04 11:59:34 +05:30
Harsh Jha
a295585367 Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-04 11:54:18 +05:30
Harsh Jha
1571daa145 updated quickstart_py.yaml 2025-09-04 11:53:42 +05:30
Harsh Jha
371f03e0ed updated quickstart_py.yaml 2025-09-04 11:52:28 +05:30
Harsh Jha
39e3250a70 Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-03 19:51:26 +05:30
Harsh Jha
b462583ccf chore: updated ci files 2025-09-03 19:50:51 +05:30
Harsh Jha
06042e6731 Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-03 18:55:11 +05:30
Harsh Jha
94adbbd992 updated quickstart_py.yaml 2025-09-03 18:54:11 +05:30
Harsh Jha
7abec9e53e Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-03 18:39:28 +05:30
Harsh Jha
577c37f0df chore: updated quickstart_py.yaml 2025-09-03 18:38:46 +05:30
Harsh Jha
a07a8aa2d7 Merge branch 'sts-py-sh' of https://github.com/googleapis/genai-toolbox into sts-py-sh-eg 2025-09-03 18:16:54 +05:30
Harsh Jha
05662f1410 chore(ci): update quickstart_py.yaml 2025-09-03 18:14:34 +05:30
Harsh Jha
7c7b3b6305 renamed sample function to run_application 2025-09-03 18:10:33 +05:30
Harsh Jha
3bae22efcf chore(ci): update _GCP_PROJECT_NUMBER value in quickstart_py.yaml 2025-09-03 18:07:12 +05:30
Harsh Jha
9bde22bfce feat(ci): add ci files for py sample workflow 2025-09-03 17:50:25 +05:30
Harsh Jha
8c1467d8a9 Merge branch 'main' into sts-python-test 2025-09-03 10:53:23 +05:30
Harsh Jha
623b91af84 Merge branch 'main' into sts-python-test 2025-09-02 15:28:47 +05:30
Harsh Jha
e1cc144e72 Remove unnecessary newline in run_application function 2025-09-02 15:26:56 +05:30
Harsh Jha
1a0386b360 chore(python/quickstart): address multiple review comments in sample code 2025-09-02 15:25:48 +05:30
Harsh Jha
7dfdede4be test: Remove redundant script output check from tests 2025-09-02 15:17:50 +05:30
Harsh Jha
25e116584a fix(python/quickstart): pin exact versions in requirements.txt 2025-09-02 15:17:50 +05:30
Harsh Jha
e0d6c1f6d8 fix(python/quickstart): revert code sample in all python quickstart examples 2025-09-02 15:17:50 +05:30
Harsh Jha
7ffb0e2d82 feat: Implement language-agnostic snippet shortcode 2025-09-02 15:17:50 +05:30
Harsh Jha
0e23d73ea2 refactor(docs): Fix Table of Contents and optimize region include shortcode 2025-09-02 15:17:50 +05:30
Harsh Jha
79adf9d70b refactor(docs): Replace duplicated content with a shared shortcode 2025-09-02 15:17:50 +05:30
Harsh Jha
c97b89555e feat: Add shortcode for including file regions 2025-09-02 15:17:50 +05:30
Harsh Jha
018edb5d61 Merge branch 'main' into sts-python-test 2025-09-01 10:43:51 +05:30
Harsh Jha
a5beea5756 chore(docs/python): remove compile-time test from quickstart samples 2025-09-01 10:42:40 +05:30
Harsh Jha
1130354ac5 refactor: replace duplicate snippet code with regionInclude 2025-08-29 10:47:03 +05:30
Harsh Jha
28021d760e Merge branch 'main' of https://github.com/googleapis/genai-toolbox into sts-python-test 2025-08-29 10:39:56 +05:30
Harsh Jha
ff7f34bba6 feat: remove duplicate snippet shortcode 2025-08-29 10:39:44 +05:30
Harsh Jha
a93ab0c25a Merge branch 'main' into sts-python-test 2025-08-28 17:17:01 +05:30
Harsh Jha
921db2a546 refactor(test): update quickstart tests to only check for error-free execution 2025-08-28 16:08:34 +05:30
Harsh Jha
5b7cc83472 feat: add pytest-based test infrastructure for Python quickstart frameworks 2025-08-21 14:27:04 +05:30
Harsh Jha
e5922a69ec Merge branch 'sample-testing-strategy-python' of https://github.com/googleapis/genai-toolbox into sts-python-test 2025-08-20 19:46:37 +05:30
Harsh Jha
faa79cd3c1 Update quickstart.py 2025-08-20 18:21:11 +05:30
Harsh Jha
959941d4ae feat(adk): add Python quickstart testing infrastructure with requirements.txt, golden.txt, and quickstart_test.py 2025-08-20 18:14:31 +05:30
Harsh Jha
7dc77fec19 fix(quickstart): remove angle brackets from ToolboxSyncClient URL in Python ADK 2025-08-20 18:09:48 +05:30
Harsh Jha
061f38382e feat(python): add quickstart samples for adk, core, langchain, and llamaindex 2025-08-19 17:14:44 +05:30
Harsh Jha
64e64a0d51 Update quickstart docs and shortcodes for improved region includes 2025-08-19 16:34:13 +05:30
Anmol Shukla
5e0a1b03ab Merge branch 'main' into docs/add-region-shortcode 2025-08-19 14:28:14 +05:30
Anmol Shukla
b7cf0562ed Merge branch 'main' into docs/add-region-shortcode 2025-08-18 14:16:04 +05:30
Anmol Shukla
8309816f44 Merge branch 'main' into docs/add-region-shortcode 2025-08-14 15:12:34 +05:30
Harsh Jha
114a0c91d8 feat: Implement language-agnostic snippet shortcode 2025-08-05 14:39:53 +05:30
Harsh Jha
5f1e4b940c refactor(docs): Fix Table of Contents and optimize region include shortcode 2025-08-01 19:56:13 +05:30
Harsh Jha
e0b6d2d26b refactor(docs): Replace duplicated content with a shared shortcode 2025-07-31 18:52:46 +05:30
Harsh Jha
590bfaf4d3 feat: Add shortcode for including file regions 2025-07-31 11:31:19 +05:30
15 changed files with 398 additions and 52 deletions

107
.ci/quickstart_py.sh Normal file
View File

@@ -0,0 +1,107 @@
#!/bin/bash
set -e
set -u
TABLE_NAME="hotels"
QUICKSTART_PYTHON_DIR="docs/en/getting-started/quickstart/python"
TOOLBOX_SETUP_DIR="/workspace/toolbox_setup"
apt-get update && apt-get install -y postgresql-client python3-venv curl wget
if [ ! -d "$QUICKSTART_PYTHON_DIR" ]; then
exit 1
fi
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=$!
export PGHOST=127.0.0.1
export PGPORT=5432
export PGPASSWORD="$DB_PASSWORD"
export GOOGLE_API_KEY="$GOOGLE_API_KEY"
mkdir -p "${TOOLBOX_SETUP_DIR}"
echo "${TOOLS_YAML_CONTENT}" > "${TOOLBOX_SETUP_DIR}/tools.yaml"
if [ ! -f "${TOOLBOX_SETUP_DIR}/tools.yaml" ]; then echo "Failed to create tools.yaml"; exit 1; fi
curl -L "https://storage.googleapis.com/genai-toolbox/v${VERSION}/linux/amd64/toolbox" -o "${TOOLBOX_SETUP_DIR}/toolbox"
chmod +x "${TOOLBOX_SETUP_DIR}/toolbox"
if [ ! -f "${TOOLBOX_SETUP_DIR}/toolbox" ]; then echo "Failed to download toolbox"; exit 1; fi
echo "--- Starting Toolbox Server ---"
cd "${TOOLBOX_SETUP_DIR}"
./toolbox --tools-file ./tools.yaml &
TOOLBOX_PID=$!
cd "/workspace"
sleep 5
cleanup_all() {
kill $TOOLBOX_PID || true
kill $PROXY_PID || true
}
trap cleanup_all EXIT
for ORCH_DIR in "$QUICKSTART_PYTHON_DIR"/*/; do
if [ ! -d "$ORCH_DIR" ]; then
continue
fi
(
set -e
ORCH_NAME=$(basename "$ORCH_DIR")
cleanup_orch() {
psql -h "$PGHOST" -p "$PGPORT" -U "$DB_USER" -d "$DATABASE_NAME" -c "DROP TABLE IF EXISTS $TABLE_NAME;"
if [ -d ".venv" ]; then
rm -rf ".venv"
fi
}
trap cleanup_orch EXIT
cd "$ORCH_DIR"
psql -h "$PGHOST" -p "$PGPORT" -U "$DB_USER" -d "$DATABASE_NAME" <<EOF
CREATE TABLE $TABLE_NAME (
id INTEGER NOT NULL PRIMARY KEY,
name VARCHAR NOT NULL,
location VARCHAR NOT NULL,
price_tier VARCHAR NOT NULL,
checkin_date DATE NOT NULL,
checkout_date DATE NOT NULL,
booked BIT NOT NULL
);
INSERT INTO $TABLE_NAME (id, name, location, price_tier, checkin_date, checkout_date, booked)
VALUES
(1, 'Hilton Basel', 'Basel', 'Luxury', '2024-04-22', '2024-04-20', B'0'),
(2, 'Marriott Zurich', 'Zurich', 'Upscale', '2024-04-14', '2024-04-21', B'0'),
(3, 'Hyatt Regency Basel', 'Basel', 'Upper Upscale', '2024-04-02', '2024-04-20', B'0'),
(4, 'Radisson Blu Lucerne', 'Lucerne', 'Midscale', '2024-04-24', '2024-04-05', B'0'),
(5, 'Best Western Bern', 'Bern', 'Upper Midscale', '2024-04-23', '2024-04-01', B'0'),
(6, 'InterContinental Geneva', 'Geneva', 'Luxury', '2024-04-23', '2024-04-28', B'0'),
(7, 'Sheraton Zurich', 'Zurich', 'Upper Upscale', '2024-04-27', '2024-04-02', B'0'),
(8, 'Holiday Inn Basel', 'Basel', 'Upper Midscale', '2024-04-24', '2024-04-09', B'0'),
(9, 'Courtyard Zurich', 'Zurich', 'Upscale', '2024-04-03', '2024-04-13', B'0'),
(10, 'Comfort Inn Bern', 'Bern', 'Midscale', '2024-04-04', '2024-04-16', B'0');
EOF
VENV_DIR=".venv"
python3 -m venv "$VENV_DIR"
source "$VENV_DIR/bin/activate"
if [ -f "requirements.txt" ]; then
pip install -r requirements.txt
else
echo "Warning: requirements.txt not found. Skipping."
fi
echo "Running tests for $ORCH_NAME..."
pytest
)
done

57
.ci/quickstart_py.yaml Normal file
View File

@@ -0,0 +1,57 @@
# 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.
substitutions:
_GCP_PROJECT: "your-project-id"
_CLOUD_SQL_INSTANCE: "project-id:region:instance-name"
_DATABASE_NAME: "db-name"
_DB_USER: "db-user"
_TOOLS_YAML_SECRET: "tools yaml secret"
_API_KEY_SECRET: "api key secret"
_DB_PASS_SECRET: "db pass secret"
_GCP_PROJECT_NUMBER: "your-project-number"
steps:
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
id: 'run-psql-commands'
entrypoint: 'bash'
args:
- -c
- |
set -ex
export VERSION=$(cat ./cmd/version.txt)
chmod +x .ci/quickstart_py.sh
.ci/quickstart_py.sh
env:
- 'CLOUD_SQL_INSTANCE=${_CLOUD_SQL_INSTANCE}'
- 'GCP_PROJECT=${_GCP_PROJECT}'
- 'DATABASE_NAME=${_DATABASE_NAME}'
- 'DB_USER=${_DB_USER}'
secretEnv: ['TOOLS_YAML_CONTENT', 'GOOGLE_API_KEY', 'DB_PASSWORD']
availableSecrets:
secretManager:
- versionName: projects/${_GCP_PROJECT}/secrets/${_TOOLS_YAML_SECRET}/versions/latest
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: 1800s
options:
logging: CLOUD_LOGGING_ONLY

View File

@@ -0,0 +1,3 @@
Hilton Basel
Hyatt Regency
book

View File

@@ -1,19 +1,21 @@
import asyncio
import os
from google.adk.agents import Agent
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.adk.artifacts.in_memory_artifact_service import InMemoryArtifactService
from google.genai import types
from toolbox_core import ToolboxSyncClient
import asyncio
import os
from toolbox_core import ToolboxSyncClient # Corrected import
# TODO(developer): replace this with your Google API key
os.environ['GOOGLE_API_KEY'] = 'your-api-key'
os.environ['GOOGLE_API_KEY']
async def main():
with ToolboxSyncClient("http://127.0.0.1:5000") as toolbox_client:
host = os.environ.get("TOOLBOX_HOST", "127.0.0.1")
toolbox_url = f"http://{host}:5000"
with ToolboxSyncClient(toolbox_url) as toolbox_client:
prompt = """
You're a helpful hotel assistant. You handle hotel searching, booking and
@@ -35,7 +37,7 @@ async def main():
session_service = InMemorySessionService()
artifacts_service = InMemoryArtifactService()
session = await session_service.create_session(
session = session_service.create_session(
state={}, app_name='hotel_agent', user_id='123'
)
runner = Runner(

View File

@@ -0,0 +1,38 @@
import os
import pytest
from pathlib import Path
import asyncio
from quickstart import main
@pytest.fixture(scope="module")
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 ---
class TestADKExecution:
"""Test ADK framework execution and output validation."""
@pytest.fixture(scope="function")
def script_output(self, capsys):
"""Run the quickstart function and return its output."""
asyncio.run(main())
return capsys.readouterr()
def test_script_runs_without_errors(self, script_output):
"""Test that the script runs and produces no stderr."""
assert script_output.err == "", f"Script produced stderr: {script_output.err}"
def test_keywords_in_output(self, script_output, golden_keywords):
"""Test that expected keywords are present in the script's output."""
output = script_output.out
missing_keywords = [kw for kw in golden_keywords if kw not in output]
assert not missing_keywords, f"Missing keywords in output: {missing_keywords}"

View File

@@ -0,0 +1,3 @@
google-adk==0.1.0
toolbox-core==0.5.0
pytest==7.0.0

View File

@@ -1,5 +1,5 @@
import asyncio
import os
from google import genai
from google.genai.types import (
Content,
@@ -30,7 +30,9 @@ queries = [
]
async def main():
async with ToolboxClient("http://127.0.0.1:5000") as toolbox_client:
host = os.environ.get("TOOLBOX_HOST", "127.0.0.1")
toolbox_url = f"http://{host}:5000"
async with ToolboxClient(toolbox_url) as toolbox_client:
# The toolbox_tools list contains Python callables (functions/methods) designed for LLM tool-use
# integration. While this example uses Google's genai client, these callables can be adapted for
@@ -39,7 +41,7 @@ async def main():
# provided wrapper packages, which handle framework-specific boilerplate.
toolbox_tools = await toolbox_client.load_toolset("my-toolset")
genai_client = genai.Client(
vertexai=True, project="project-id", location="us-central1"
vertexai=True, project=os.environ.get("GCP_PROJECT"), location="us-central1"
)
genai_tools = [
@@ -68,41 +70,47 @@ async def main():
)
history.append(response.candidates[0].content)
function_response_parts = []
for function_call in response.function_calls:
fn_name = function_call.name
# The tools are sorted alphabetically
if fn_name == "search-hotels-by-name":
function_result = await toolbox_tools[3](**function_call.args)
elif fn_name == "search-hotels-by-location":
function_result = await toolbox_tools[2](**function_call.args)
elif fn_name == "book-hotel":
function_result = await toolbox_tools[0](**function_call.args)
elif fn_name == "update-hotel":
function_result = await toolbox_tools[4](**function_call.args)
elif fn_name == "cancel-hotel":
function_result = await toolbox_tools[1](**function_call.args)
else:
raise ValueError("Function name not present.")
function_response = {"result": function_result}
function_response_part = Part.from_function_response(
name=function_call.name,
response=function_response,
)
function_response_parts.append(function_response_part)
if response.function_calls:
for function_call in response.function_calls:
fn_name = function_call.name
# The tools are sorted alphabetically
if fn_name == "search-hotels-by-name":
function_result = await toolbox_tools[3](**function_call.args)
elif fn_name == "search-hotels-by-location":
function_result = await toolbox_tools[2](**function_call.args)
elif fn_name == "book-hotel":
function_result = await toolbox_tools[0](**function_call.args)
elif fn_name == "update-hotel":
function_result = await toolbox_tools[4](**function_call.args)
elif fn_name == "cancel-hotel":
function_result = await toolbox_tools[1](**function_call.args)
else:
raise ValueError(f"Function name {fn_name} not present.")
function_response = {"result": function_result}
function_response_part = Part.from_function_response(
name=function_call.name,
response=function_response,
)
function_response_parts.append(function_response_part)
if function_response_parts:
tool_response_content = Content(role="tool", parts=function_response_parts)
history.append(tool_response_content)
response2 = genai_client.models.generate_content(
model="gemini-2.0-flash-001",
contents=history,
config=GenerateContentConfig(
tools=genai_tools,
),
)
final_model_response_content = response2.candidates[0].content
history.append(final_model_response_content)
print(response2.text)
response2 = genai_client.models.generate_content(
model="gemini-2.0-flash-001",
contents=history,
config=GenerateContentConfig(
tools=genai_tools,
),
)
final_model_response_content = response2.candidates[0].content
history.append(final_model_response_content)
print(response2.text)
else:
print(response.text)
asyncio.run(main())
if __name__ == "__main__":
asyncio.run(main())

View File

@@ -0,0 +1,38 @@
import os
import pytest
from pathlib import Path
import asyncio
from quickstart import main
@pytest.fixture(scope="module")
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 ---
class TestADKExecution:
"""Test ADK framework execution and output validation."""
@pytest.fixture(scope="function")
def script_output(self, capsys):
"""Run the quickstart function and return its output."""
asyncio.run(main())
return capsys.readouterr()
def test_script_runs_without_errors(self, script_output):
"""Test that the script runs and produces no stderr."""
assert script_output.err == "", f"Script produced stderr: {script_output.err}"
def test_keywords_in_output(self, script_output, golden_keywords):
"""Test that expected keywords are present in the script's output."""
output = script_output.out
missing_keywords = [kw for kw in golden_keywords if kw not in output]
assert not missing_keywords, f"Missing keywords in output: {missing_keywords}"

View File

@@ -0,0 +1,3 @@
google-genai==1.33.0
toolbox-core==0.5.0
pytest==7.0.0

View File

@@ -1,5 +1,7 @@
import asyncio
import os
from langgraph.prebuilt import create_react_agent
# TODO(developer): replace this with another import if needed
@@ -38,8 +40,10 @@ async def main():
# model = ChatAnthropic(model="claude-3-5-sonnet-20240620")
# Load the tools from the Toolbox server
async with ToolboxClient("http://127.0.0.1:5000") as client:
tools = await client.aload_toolset()
host = os.environ.get("TOOLBOX_HOST", "127.0.0.1")
toolbox_url = f"http://{host}:5000"
async with ToolboxClient(toolbox_url) as toolbox_client:
tools = await toolbox_client.aload_toolset()
agent = create_react_agent(model, tools, checkpointer=MemorySaver())

View File

@@ -0,0 +1,38 @@
import os
import pytest
from pathlib import Path
import asyncio
from quickstart import main
@pytest.fixture(scope="module")
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 ---
class TestADKExecution:
"""Test ADK framework execution and output validation."""
@pytest.fixture(scope="function")
def script_output(self, capsys):
"""Run the quickstart function and return its output."""
asyncio.run(main())
return capsys.readouterr()
def test_script_runs_without_errors(self, script_output):
"""Test that the script runs and produces no stderr."""
assert script_output.err == "", f"Script produced stderr: {script_output.err}"
def test_keywords_in_output(self, script_output, golden_keywords):
"""Test that expected keywords are present in the script's output."""
output = script_output.out
missing_keywords = [kw for kw in golden_keywords if kw not in output]
assert not missing_keywords, f"Missing keywords in output: {missing_keywords}"

View File

@@ -0,0 +1,5 @@
langchain==0.3.27
langchain-google-vertexai==2.0.28
langgraph==0.6.7
toolbox-langchain==0.5.0
pytest==8.4.2

View File

@@ -2,13 +2,9 @@ import asyncio
import os
from llama_index.core.agent.workflow import AgentWorkflow
from llama_index.core.workflow import Context
# TODO(developer): replace this with another import if needed
from llama_index.llms.google_genai import GoogleGenAI
# from llama_index.llms.anthropic import Anthropic
from toolbox_llamaindex import ToolboxClient
@@ -34,7 +30,7 @@ async def main():
# TODO(developer): replace this with another model if needed
llm = GoogleGenAI(
model="gemini-2.0-flash-001",
vertexai_config={"project": "project-id", "location": "us-central1"},
vertexai_config={"project": os.environ.get("GCP_PROJECT", "project-id"), "location": "us-central1"},
)
# llm = GoogleGenAI(
# api_key=os.getenv("GOOGLE_API_KEY"),
@@ -46,8 +42,10 @@ async def main():
# )
# Load the tools from the Toolbox server
async with ToolboxClient("http://127.0.0.1:5000") as client:
tools = await client.aload_toolset()
host = os.environ.get("TOOLBOX_HOST", "127.0.0.1")
toolbox_url = f"http://{host}:5000"
async with ToolboxClient(toolbox_url) as toolbox_client:
tools = await toolbox_client.aload_toolset()
agent = AgentWorkflow.from_tools_or_functions(
tools,

View File

@@ -0,0 +1,38 @@
import os
import pytest
from pathlib import Path
import asyncio
from quickstart import main
@pytest.fixture(scope="module")
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 ---
class TestADKExecution:
"""Test ADK framework execution and output validation."""
@pytest.fixture(scope="function")
def script_output(self, capsys):
"""Run the quickstart function and return its output."""
asyncio.run(main())
return capsys.readouterr()
def test_script_runs_without_errors(self, script_output):
"""Test that the script runs and produces no stderr."""
assert script_output.err == "", f"Script produced stderr: {script_output.err}"
def test_keywords_in_output(self, script_output, golden_keywords):
"""Test that expected keywords are present in the script's output."""
output = script_output.out
missing_keywords = [kw for kw in golden_keywords if kw not in output]
assert not missing_keywords, f"Missing keywords in output: {missing_keywords}"

View File

@@ -0,0 +1,4 @@
llama-index==0.13.6
llama-index-llms-google-genai==0.3.0
toolbox-llamaindex==0.5.0
pytest==8.4.2