Enforce authoritative Gmail profile over model-chosen profile in tool calls#287
Merged
Merged
Conversation
…ol calls apply_runtime_defaults_to_mcp_payload only filled a blank or "default"/"primary" placeholder profile for gmail_* tools, so an explicit profile the MODEL chose passed straight through. Observed live: qwen3:8b emitted gmail_list_messages with profile="zhan-gmail" (an account whose OAuth refresh token is expired/revoked) even though the valid "vonwitbrock-gmail" profile was selected and tests green in the settings UI. The call hard-failed with invalid_grant and the whole turn failed. Which Gmail account to use is an identity/credential decision the caller's selection owns, not the model. Enforce the authoritative profile (request- selected, resolved request-first at orchestrator merge, else the configured default) over ANY supplied profile that differs. When no authoritative default is resolved (default_gmail_profile is None, e.g. deterministic/scheduled workflows) the supplied value is left untouched, so this does not disturb workflow steps that set a profile deterministically. Telemetry distinguishes blank-fill / placeholder-replacement / enforced-override and records the overridden profile. Tests: tests/backend/test_mcp_tool_bridge_gmail_profile.py. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem (observed live)
A turn ("Tell me what I should do with my last 8 emails") failed because qwen3:8b emitted
gmail_list_messageswithprofile: "zhan-gmail"— an account whose OAuth refresh token is expired/revoked (invalid_grant … RefreshError) — even thoughvonwitbrock-gmailwas selected and "Test Gmail access" passes in the settings UI. The call hard-failed and the whole turn failed (decision: failed; it never reachedtask_create).Root cause:
apply_runtime_defaults_to_mcp_payloadonly filled the gmailprofilewhen the model left it blank or as a"default"/"primary"placeholder. An explicit profile the model chose itself passed straight through — so the model, not the user's selection, decided which Gmail account (credential) to use, and picked a dead one.Change
Which Gmail account to use is an identity/credential decision the caller's selection owns, not the model. For
gmail_*tools, enforce the authoritative profile (request-selected — already resolved request-first at the orchestrator merge — else the configured default) over any supplied profile that differs, including an explicit model-chosen one.Safety: when no authoritative default is resolved (
default_gmail_profile is None, e.g. deterministic/scheduled workflows), the supplied value is left untouched — so workflow steps that set a profile deterministically are unaffected. Telemetry distinguishesdefault_gmail_profile(blank fill) /…_placeholder_replacement/…_enforced_overrideand records the overridden profile.This does not depend on any
.envvalue: it enforces whatever authoritative profile is resolved (request selection preferred, env default as fallback).Tests
tests/backend/test_mcp_tool_bridge_gmail_profile.py(6): override of an explicit wrong profile, blank fill, placeholder replacement, no-op when matching, no enforcement when default is None (deterministic-workflow safety), and gmail-only scoping. Green.Notes / not in scope
🤖 Generated with Claude Code