Repository navigation
Python: Skip Gemini connection settings when a genai.Client is injected - #9969
Mehedi Hasan (Mahdi-Hasan) wants to merge 4 commits into
Conversation
Gemini chat and embedding constructors parsed GOOGLE_API_KEY, the Enterprise/Vertex mode flags, project, and location before using an injected genai.Client. An invalid ambient value such as GOOGLE_GENAI_USE_ENTERPRISE=not-a-bool failed construction even though the caller's client needs none of those settings. With an injected client only the model settings are now loaded. Mode and service URL come from the SDK client. Owned-client validation is unchanged. Fixes microsoft#9959 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
/review |
There was a problem hiding this comment.
MAF Automated Review — Iteration 1
Result: Findings reported
Scope: full PR (1 commit(s)): f6499d118251
Model: gpt-5.6-sol
Overview
The PR cleanly avoids parsing ambient connection settings when a caller supplies a Gemini SDK client, while retaining model resolution, owned-client validation, routing from exposed SDK state, and caller ownership. The new tests cover invalid ambient mode values and SDK clients whose private mode field is available. One compatibility gap remains: explicit mode no longer reaches the existing fallback when that private SDK field is absent, which can misclassify a Vertex client and alter request behavior.
Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
1 verified finding remained after source verification (1 medium) across 1 file. Details are attached to the affected lines below.
Affected areas: python/packages/gemini/agent_framework_gemini/_sdk_client.py
|
|
||
| def load_gemini_settings(*, client: genai.Client | None, **kwargs: Any) -> GoogleGeminiSettings: | ||
| """Load ``GOOGLE_*`` settings, skipping auth, mode, project, and location for an injected client.""" | ||
| settings_type: type[Any] = GoogleGeminiSettings if client is None else _GoogleGeminiModelSettings |
There was a problem hiding this comment.
When an injected client does not expose a boolean _api_client.vertexai, this model-only schema drops explicit enterprise/vertexai values before resolve_vertexai_mode() can use its existing fallback, so a Vertex client is classified as Developer API. That changes Vertex embedding batching and can send an unsupported multi-content request. Please keep skipping ambient connection settings, but preserve an explicitly supplied mode as the fallback when SDK state is unavailable.
There was a problem hiding this comment.
Fixed in d37fe55. An injected client still skips the GOOGLE_* connection settings, but explicit enterprise/vertexai arguments are kept as the fallback. New tests cover an SDK client with no boolean _api_client.vertexai for chat and embeddings; they fail without the fix.
An injected genai.Client still skips GOOGLE_* connection settings, but explicit enterprise/vertexai arguments are now kept. resolve_vertexai_mode() uses them when the SDK client does not expose a boolean _api_client.vertexai, so a Vertex client is not treated as the Developer API. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
Explicit enterprise/vertexai overrides are not validated for injected clients, which can accept values like "false" and select the wrong service URL, while two messages also inaccurately describe model environment fallback.
2 open issues
Review effort: Lite
| for key in ("genai_use_enterprise", "genai_use_vertexai"): | ||
| if kwargs.get(key) is not None: | ||
| settings[key] = kwargs[key] |
There was a problem hiding this comment.
Fixed in fd0c7a3. Explicit enterprise/vertexai values for an injected client now get the same bool check (and error message) an owned client gets from load_settings. Environment mode is still not read. Added tests for chat and embeddings that pass "false".
| client: Preconfigured ``genai.Client``; the caller retains ownership of it. When provided, the | ||
| API key, project, and location arguments and environment settings are not read. Explicit mode | ||
| arguments only apply when the client does not expose its own mode. |
There was a problem hiding this comment.
Fixed in fd0c7a3. The chat and embedding docstrings now say only connection settings are skipped, and that GOOGLE_MODEL / GOOGLE_EMBEDDING_MODEL still apply.
Explicit enterprise/vertexai arguments kept for an injected client now get the same bool check an owned client gets from load_settings, so a string like "false" is rejected instead of resolving to Vertex AI. Docstrings now say GOOGLE_MODEL / GOOGLE_EMBEDDING_MODEL still apply to injected clients. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>


Motivation & Context
Gemini chat and embedding constructors call
load_settings()for the API key, Enterprise/Vertex mode, project, and location before using an injectedgenai.Client. None of these are needed for a caller-supplied client. An invalid ambient value still fails construction, e.g.GOOGLE_GENAI_USE_ENTERPRISE=not-a-boolraisesValueErroreven with a valid client.Description & Review Guide
load_gemini_settings()in_sdk_client.py. With an injected client it loads a private model-only TypedDict (model,embedding_model). Otherwise it loadsGoogleGeminiSettingsas before.RawGeminiChatClientandRawGeminiEmbeddingClientuse it.load_settingsskips override keys that aren't in the TypedDict, so the constructors pass the same arguments as before.clientnow say which settings are not read.enterprise=/vertexai=/project=/location=/api_key=arguments are ignored on that path. Before, mode was only used as a fallback when the SDK client did not expose_api_client.vertexai.GOOGLE_MODEL/GOOGLE_EMBEDDING_MODEL, then the existing default or error.Related Issue
Fixes #9959
AI Assistance
AI assistance details: implementation, tests, and this description. The issue's repro was re-run against a real
genai.Clientbefore and after the change.Contribution Checklist
breaking changelabel (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.🤖 Generated with Claude Code