Skip to content

Feat: Emit GOOGLE_GENAI_USE_ENTERPRISE from adk create and adk deploy - #286

Open
AmaadMartin wants to merge 2 commits into
feat/gemini-init-params-enterprise-env-gatefrom
feat/adopt-google-genai-use-enterprise-env-var
Open

Feat: Emit GOOGLE_GENAI_USE_ENTERPRISE from adk create and adk deploy#286
AmaadMartin wants to merge 2 commits into
feat/gemini-init-params-enterprise-env-gatefrom
feat/adopt-google-genai-use-enterprise-env-var

Conversation

@AmaadMartin

@AmaadMartin AmaadMartin commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Please ensure you have read the contribution guide before creating a pull request.

Link to Issue or Description of Change

  1. Link to an existing issue (if applicable):
    Closes: #issue_number
    Related: #issue_number
  2. Or, if no issue exists, describe the change:
    Problem: adk-python renamed the environment variable that selects the enterprise (Vertex AI) backend from GOOGLE_GENAI_USE_VERTEXAI to GOOGLE_GENAI_USE_ENTERPRISE. adk-js still emits the deprecated name from the two places it generates config for users, so every project scaffolded with adk create and every container built by adk deploy cloud_run starts life on a deprecated variable:
  • dev/src/cli/cli_create.ts:167,176 — the generated .env
  • dev/src/cli/deploy/deploy_utils.ts:103 — the ENV line in the generated Dockerfile

Solution: switch both writers to GOOGLE_GENAI_USE_ENTERPRISE, matching the reference implementation field-for-field (adk-python/src/google/adk/cli/cli_create.py:119,121 and cli_deploy.py:85, both of which emit the new name only). The change is three string swaps; no new abstraction, flag, or helper.

This is a stacked PR — it must not merge before BOTH read-side PRs land. See the next section.

Collision check (required, and it found something)

gh pr list --repo AmaadMartin/adk-js --state open --limit 100 --json number,title,headRefName
gh pr diff <n> --repo AmaadMartin/adk-js --name-only     # every plausibly adjacent PR

The read side of this feature — teaching the runtime to accept the new variable — is already split across two live sibling PRs, so none of it is reimplemented here:

PR Branch Lands
#265 feat/enterprise-mode-variant-resolution isEnterpriseModeEnabled() + variant_utils.ts + vertex_ai_utils.ts
#267 feat/gemini-init-params-enterprise-env-gate isEnterpriseModeEnabled() + google_llm.ts (this PR's base)

This PR is the write side only and is uncontested: no open PR touches the GOOGLE_GENAI_USE_* lines in cli_create.ts or deploy_utils.ts. (#203 edits cli_create.ts for injectable gcloud defaults and #259 edits cli_create_test.ts for env hermeticity, but neither touches these lines; #279 edits the Agent Engine deploy CLI, not deploy_utils.ts.)

Merge order — both are required, for different reasons. Flipping the writers without the readers is a hard regression, so:

Also worth flagging to a human: #265 and #267 each independently add isEnterpriseModeEnabled() to core/src/utils/env_aware_utils.ts, so they conflict with each other and need reconciling before either merges. If #265 is dropped rather than merged, its two one-line call-site swaps must be folded in before this PR lands.

Version-skew caveat (deliberately accepted, not fixed here)

@google/adk-devtools writes these files and @google/adk reads them, and they publish as separate packages. A user pairing a new devtools with an old core gets config their runtime does not understand. For adk create this is not reachable — the generated package.json (dev/src/cli/cli_create.ts:46-61) pins no @google/adk at all, so a fresh project always resolves a current core. For adk deploy cloud_run it is reachable, because the generated Dockerfile copies the user's own package.json/package-lock.json/node_modules.

I considered emitting both variable names from the Dockerfile for a deprecation window and rejected it, because it would: (a) diverge from adk-python/src/google/adk/cli/cli_deploy.py:85, which emits only ENV GOOGLE_GENAI_USE_ENTERPRISE=1 — generated output is observable across the language boundary, so parity wins there; (b) keep writing the deprecated name this change exists to stop writing; and (c) add compatibility machinery with no defined removal trigger. This is the same exposure adk-python accepted for the same rename. Happy to revisit if a maintainer prefers the dual-write.

No suppressions

No any, @ts-expect-error, @ts-ignore, eslint-disable, or coverage-ignore was added anywhere in this diff.

Testing Plan

Please describe the tests that you ran to verify your changes. This is required for all PRs that are not small documentation or typo fixes.
Unit Tests:
[x] I have added or updated unit tests for my change.
[x] All unit tests pass locally.

GitHub Actions did not run on this PR, so it was validated locally instead. .github/workflows/validation.yaml triggers on pull_request: branches: [main], and this PR targets feat/gemini-init-params-enterprise-env-gate, so the workflow never fires — only auto-assign reported. Every job that workflow would have run was executed locally on the exact pushed commit (b1424b6c):

validation.yaml step Command Result
Check for secrets leaks npx secretlint "dev/**/*" exit 0
Build packages npm run build exit 0
Run tests npx vitest run --project unit:dev dev/test/cli/cli_create_test.ts dev/test/cli/cli_deploy_cloud_run_test.ts 23 passed (23), 2 files
Run lint check npm run lint exit 0
Run format check npm run format:check exit 0 — "All matched files use Prettier code style!"
Run documentation build check npm run docs:check exit 0

The workflow's test step is npm run test:coverage, which runs the entire repository suite; per the contribution workflow for this change only the two directly affected test files were run rather than the full suite.

npm run ts:check reports pre-existing errors in 48 files across the test tree; the count is identical (48) on this branch and on its base, so this change introduces none. None are in dev/.

One note on running these locally: cli_create_test.ts > should handle Vertex AI selection with gcloud defaults fails on a workstation that has ambient GOOGLE_CLOUD_PROJECT/GOOGLE_CLOUD_LOCATION exported. It fails identically on the unmodified base commit, and passes here under env -u GOOGLE_CLOUD_PROJECT -u GOOGLE_CLOUD_LOCATION. That hermeticity gap is what #203/#259/#281 address; it is untouched by this PR.

What the tests pin. createDockerFileContent previously had no assertion at all on its ENV block, and the =0 line on the API-key path was unasserted, so both were free to regress. Each changed line now has a positive assertion (new name present) and a negative one (legacy name absent) — the negative is what actually pins the rename rather than merely the presence of the new name. No existing test was deleted, skipped, or weakened; the one existing assertion that changed (cli_create_test.ts:131) was retargeted from the old name to the new one, which is the behaviour change itself.

Proof each test can fail. Every assertion was run against mutated source and confirmed to FAIL:

# Mutation Test Failure
1 cli_create.ts:176GOOGLE_GENAI_USE_VERTEXAI=1 should set Vertex AI env vars if project/region provided AssertionError: expected "spy" to be called with arguments: [ StringContaining ".env", …(1) ]
2 cli_create.ts:167GOOGLE_GENAI_USE_VERTEXAI=0 should set Google AI env vars if api key provided same AssertionError on the .env spy
3 deploy_utils.ts:103ENV GOOGLE_GENAI_USE_VERTEXAI=1 should set the enterprise backend env var... AssertionError: expected '\nFROM node:lts-alpine…' to contain 'ENV GOOGLE_GENAI_USE_ENTERPRISE=1'
4 emit both names from generateEnvFile should set Vertex AI env vars if project/region provided fails on StringNotContaining "GOOGLE_GENAI_USE_VERTEXAI" — proves the negative assertion carries independent signal, since the positive one still passes
5 emit both names in the Dockerfile should set the enterprise backend env var... AssertionError: expected '\nFROM node:lts-alpine…' not to contain 'GOOGLE_GENAI_USE_VERTEXAI'

Mutations 4 and 5 matter: without them the suite would pass a dual-write implementation, and the rename would not actually be pinned.

Manual End-to-End (E2E) Tests:
Please provide instructions on how to manually test your changes, including any necessary setup or configuration.

Run against a real local build, real CLI, real filesystem, no mocks:

npm run build
cd "$(mktemp -d)"
node <adk-js>/dev/dist/esm/cli_entrypoint.js create demo-vertex --project <your-project> --region us-central1 --yes
node <adk-js>/dev/dist/esm/cli_entrypoint.js create demo-key    --api_key <your-key>     --yes

Observed:

demo-vertex/.env            demo-key/.env
GOOGLE_CLOUD_PROJECT=…      GOOGLE_API_KEY=…
GOOGLE_CLOUD_LOCATION=…     GOOGLE_GENAI_USE_ENTERPRISE=0
GOOGLE_GENAI_USE_ENTERPRISE=1

grep -r GOOGLE_GENAI_USE_VERTEXAI demo-vertex demo-key --exclude-dir=node_modules → no hits.

Then loading demo-vertex/.env into the process and constructing Gemini against the workspace build — the step that would have caught the regression described above:

vertexai   : true
apiBackend : VERTEX_AI
project    : <your-project>

…with no deprecation warning, and with no API key present. Backward compatibility, using a .env on the legacy name instead:

WARN: [ADK] GOOGLE_GENAI_USE_VERTEXAI is deprecated, please use GOOGLE_GENAI_USE_ENTERPRISE instead
vertexai   : true
apiBackend : VERTEX_AI

Repeating the first check against the published @google/adk (which lacks the read side) reproduces the exact regression this stack exists to prevent — Error: API key must be provided via constructor or GOOGLE_GENAI_API_KEY or GEMINI_API_KEY environment variable. — which is why the merge-order note above is not theoretical.

Finally, calling the real createDockerFileContent:

ENV PATH="/home/myuser/.local/bin:$PATH"
ENV GOOGLE_GENAI_USE_ENTERPRISE=1
ENV GOOGLE_CLOUD_PROJECT=…
ENV GOOGLE_CLOUD_LOCATION=…
contains legacy name: false

Unrelated pre-existing bug found while doing this, filed separately rather than fixed here: adk create --api_key K writes GOOGLE_API_KEY, but geminiInitParams only falls back to GOOGLE_GENAI_API_KEY/GEMINI_API_KEY (google_llm.ts:401-403), so that scaffold cannot start. It reproduces identically with the old GOOGLE_GENAI_USE_VERTEXAI=0 line, so it is not a regression from this change and is out of scope.

Checklist

[x] I have read the CONTRIBUTING.md document.
[x] I have performed a self-review of my own code.
[x] I have commented my code, particularly in hard-to-understand areas.
[x] I have added tests that prove my fix is effective or that my feature works.
[x] New and existing unit tests pass locally with my changes.

Amaad Martin added 2 commits July 29, 2026 21:02
adk-python renamed the backend selector env var from
GOOGLE_GENAI_USE_VERTEXAI to GOOGLE_GENAI_USE_ENTERPRISE. Scaffold new
projects onto the current name so they no longer start life on a
deprecated variable.

The generated .env is only safe on the new name because the runtime now
accepts it (isEnterpriseModeEnabled, this branch's base). Assert the
legacy name is absent so the rename itself is pinned, and assert the
previously unchecked =0 line on the API-key path.
Matches adk-python's _DOCKERFILE_TEMPLATE. createDockerFileContent had no
assertion on its ENV block at all, so add one covering both the new name
and the absence of the deprecated one.
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