Skip to content

Migrate high-volume-document-analyzer recipe to contrib/python and upgrade model references - #2623

Draft
happyhuman wants to merge 4 commits into
mainfrom
agent/update-doc-analyzer-sample
Draft

happyhuman wants to merge 4 commits into
mainfrom
agent/update-doc-analyzer-sample

Conversation

@happyhuman

@happyhuman happyhuman commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator

What

Migrates the high-volume-document-analyzer recipe from the retired python/agents/ location to contrib/python/high-volume-document-analyzer. Updates default generative model references to gemini-3.5-flash, bootstraps environment variables in __init__.py prior to agent imports, standardizes .env.example placeholders with <TODO: update-this-value>, adds manifest.yaml and tests/test_runnability.py, aligns pyproject.toml, removes hardcoded fallback model defaults on environment reads, and updates uv.lock.

Why

Recipes located in root <language>/agents/ directories are retired under repository policy, and changes made inside those frozen paths fail CI validation. Moving to contrib/python/high-volume-document-analyzer brings the recipe into compliance with active contribution paths. Upgrading deprecated gemini-2.5-flash references to gemini-3.5-flash aligns with supported model tiers. Loading environment variables in __init__.py before importing submodules ensures module-level configurations resolve correctly from .env and .env.example, while removing hardcoded model fallbacks in Python code ensures all defaults remain centrally discoverable.

How it works

  • Relocated python/agents/high-volume-document-analyzer to contrib/python/high-volume-document-analyzer.
  • Added manifest.yaml specifying standalone application metadata and active status.
  • Added tests/test_runnability.py to verify root agent import and initialization.
  • Bootstrapped environment configuration in __init__.py using load_dotenv for .env and .env.example before importing agent.
  • Removed redundant load_dotenv() calls from agent.py and process_toolset.py.
  • Removed hardcoded fallback model literals from agent.py, document_toolset.py, and deployment_utils/deploy.py.
  • Standardized placeholder strings in .env.example using <TODO: update-this-value>.
  • Updated integration test to skip gracefully when a live GOOGLE_CLOUD_PROJECT is not configured.
  • Aligned pyproject.toml dependencies and lockfile.

Testing

Ran repo validators from repository root:

$ uv run validate contrib/python/high-volume-document-analyzer
============================================================
  Manifest validation
============================================================
[PASS] All 1 recipe manifest(s) are present and valid.

============================================================
  Structure validation
============================================================
[PASS] All 1 recipe(s) passed structural checks.

============================================================
  README validation
============================================================
[PASS] All 1 recipe README(s) are present and valid.

============================================================
  Placement validation
============================================================
[PASS] Every recipe under skills/ is correctly placed.

============================================================
  Summary
============================================================
  [PASS] Manifest validation
  [PASS] Structure validation
  [PASS] README validation
  [PASS] Placement validation

Ran formatters, linters, env var checker, and pyproject check:

$ uv run ruff format --check contrib/python/high-volume-document-analyzer && uv run ruff check contrib/python/high-volume-document-analyzer && uv run python .github/scripts/check_env_vars.py contrib/python/high-volume-document-analyzer && uv run python .github/scripts/check_recipe_pyproject.py contrib/python/high-volume-document-analyzer
15 files already formatted
All checks passed!
[PASS] contrib/python/high-volume-document-analyzer/.env.example: every environment variable read in Python source is declared (14 detected, 0 in the OS allowlist, 14 declared).
[PASS] contrib/python/high-volume-document-analyzer/pyproject.toml: name, requires-python, description and default index all satisfy the repo rules.

Ran test suite via pytest:

$ uv run pytest -v
============================= test session starts ==============================
platform linux -- Python 3.12.12, pytest-9.1.1, pluggy-1.6.0 -- /usr/local/google/home/shahins/agent-work/b-559874122/contrib/python/high-volume-document-analyzer/.venv/bin/python
cachedir: .pytest_cache
rootdir: /usr/local/google/home/shahins/agent-work/b-559874122/contrib/python/high-volume-document-analyzer
configfile: pyproject.toml
plugins: asyncio-1.4.0, anyio-4.15.1
asyncio: mode=Mode.STRICT, debug=False, asyncio_default_fixture_loop_scope=function, asyncio_default_test_loop_scope=function
collecting ... collected 6 items

tests/integration/test_agent_integration.py::test_agent_responds SKIPPED [ 16%]
tests/test_runnability.py::test_agent_runnability PASSED                 [ 33%]
tests/unit/test_agent_unit.py::test_agent_initialization PASSED          [ 50%]
tests/unit/test_document_toolset.py::test_analyze_document_reset_search PASSED [ 66%]
tests/unit/test_process_toolset.py::test_fetch_mock_urls PASSED          [ 83%]
tests/unit/test_process_toolset.py::test_fetch_real_urls_empty_on_error PASSED [100%]

=================== 5 passed, 1 skipped, 2 warnings in 4.67s ===================

Boundary: Local testing verifies unit tests, tool mocking, runnability tests, linting, manifest validation, environment variable mapping, and structure rules. Live Agent Engine deployments and external Secret Manager credentials require configured GCP resources and are skipped in local unit verification.

Notes for the reviewer

  • Integration tests require a live GCP project with Vertex AI enabled and are skipped automatically when GOOGLE_CLOUD_PROJECT is not configured or set to a placeholder.
  • Author and maintainer metadata in pyproject.toml reflects the original sample authors.

@happyhuman happyhuman self-assigned this Sep 11, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Automated Maintainability review — 2 finding(s).

load_dotenv(override=True)
PROJECT_ID = os.getenv("GOOGLE_CLOUD_PROJECT")
LOCATION = os.getenv("GOOGLE_CLOUD_LOCATION", "us-central1")
LOCATION = os.getenv("GOOGLE_CLOUD_LOCATION", "us-east1")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Avoid hardcoding fallback default values on environment variable reads. Default values belong in .env.example where they can be easily discovered.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Removed the fallback default value from os.getenv('GOOGLE_CLOUD_LOCATION') in deploy.py so the value is solely sourced from the environment and .env.example.

CHUNK_SIZE = int(os.getenv("BATCH_SIZE", "10"))
MODEL_NAME = os.getenv("MODEL_NAME_DOC_PROCESSING", "gemini-2.5-flash")
LOCATION = os.getenv("GOOGLE_CLOUD_LOCATION", "us-central1")
LOCATION = os.getenv("GOOGLE_CLOUD_LOCATION", "us-east1")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Avoid hardcoding fallback default values on environment variable reads. Default values belong in .env.example where they can be easily discovered.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Removed the fallback default value from os.getenv('GOOGLE_CLOUD_LOCATION') in document_toolset.py so the value is solely sourced from the environment and .env.example.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Automated Security review — 2 finding(s).

load_dotenv(override=True)
PROJECT_ID = os.getenv("GOOGLE_CLOUD_PROJECT")
LOCATION = os.getenv("GOOGLE_CLOUD_LOCATION", "us-central1")
LOCATION = os.getenv("GOOGLE_CLOUD_LOCATION", "us-east1")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Avoid hardcoding default values on environment variable reads. The fallback value should instead be placed in .env.example so it remains easily discoverable.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Removed the fallback default value from os.getenv('GOOGLE_CLOUD_LOCATION') in deploy.py so the value is solely sourced from the environment and .env.example.

CHUNK_SIZE = int(os.getenv("BATCH_SIZE", "10"))
MODEL_NAME = os.getenv("MODEL_NAME_DOC_PROCESSING", "gemini-2.5-flash")
LOCATION = os.getenv("GOOGLE_CLOUD_LOCATION", "us-central1")
LOCATION = os.getenv("GOOGLE_CLOUD_LOCATION", "us-east1")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Avoid hardcoding default values on environment variable reads. The fallback value should instead be placed in .env.example so it remains easily discoverable.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Removed the fallback default value from os.getenv('GOOGLE_CLOUD_LOCATION') in document_toolset.py so the value is solely sourced from the environment and .env.example.

@happyhuman happyhuman changed the title Upgrade region, dependencies, and lockfile for high-volume-document-analyzer recipe Migrate high-volume-document-analyzer recipe to contrib/python and upgrade model references Sep 14, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Automated House Rules review — 1 finding(s).

Also, on lines this PR does not change:

  • contrib/python/high-volume-document-analyzer/.env.example:6 — [MINOR] "your-project-id" is a stub committed as if it were a real value. Someone copying this file has no way to tell it needs replacing; use <TODO: update-this-value> (.agents/skills/extract-python-environment-variables/)

"""Verify agent.py imports and defines the expected globals."""
# provide a dummy GCP project and patch google.auth.default() so import-time
# credential lookups don't need ADC — the setup must happen before the import.
os.environ.setdefault("GOOGLE_CLOUD_PROJECT", "test-project")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[MINOR] env read carries a hardcoded default (second argument is a hardcoded default); 20 occurrence(s) across 6 file(s). Defaults belong in .env.example, not in the code (contrib/python/high-volume-document-analyzer/tests/test_runnability.py:24; and 5 more)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Standardized placeholder strings in .env.example using <TODO: update-this-value> and removed hardcoded fallback defaults on runtime environment reads.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Automated Correctness review — 1 finding(s).


Round 2 · 4 of this PR's 25 automated comments used · this round is capped at 2 across all reviewers · after this round only Security and Correctness run.

# Load variables from .env if present. In production the environment is
# already populated by the platform (Cloud Run, GKE, etc.), so a missing
# .env is expected and not an error.
load_dotenv()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[MAJOR] Can we please call load_dotenv() before importing agent? Since agent.py and the toolset modules read environment variables at the module level during import, importing them first means they won't use the values from .env.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Moved load_dotenv() in __init__.py before importing agent (and added fallback loading for .env.example), and removed redundant load_dotenv() calls from submodules.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Automated Security review — 1 finding(s).


Round 2 · 4 of this PR's 25 automated comments used · this round is capped at 2 across all reviewers · after this round only Security and Correctness run.

name="document_analyzer_agent",
description="Agent that analyzes document collections in chunks to answer user questions.",
model=os.getenv("MODEL_NAME_AGENT", "gemini-2.5-flash"),
model=os.getenv("MODEL_NAME_AGENT", "gemini-3.5-flash"),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[MAJOR] Is there a reason we are hardcoding defaults on environment reads here? Perhaps we can read MODEL_NAME_AGENT and MODEL_NAME_DOC_PROCESSING directly without fallbacks to avoid hardcoded model literals in non-test Python, as the defaults belong in .env.example (there are four instances of this, see .github/workflows/python-validate-recipe.yml:324).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Removed hardcoded fallback model defaults from os.getenv('MODEL_NAME_AGENT') and os.getenv('MODEL_NAME_DOC_PROCESSING') across agent.py, document_toolset.py, and deploy.py, delegating defaults to .env.example.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant