Allow provider selection for gateway OAuth reads and logins (#59819)

## Why

Gateway OAuth reads and logins previously used only the current provider, preventing clients from authorizing another configured provider without changing the default.

## What changed

- Add optional `modelProvider` params to `account/gatewayOAuth/read` and `account/gatewayOAuth/login`, preserving current-provider behavior for omitted or null params and selectors.
- Validate explicit providers against current managed policy without changing the default or any thread's provider.
- Retain readiness state across providers and send `account/gatewayOAuth/changed` notifications for every configured provider sharing the changed credential.
- Update protocol schemas, TypeScript types, Python models, and documentation.

## Testing

Add coverage for non-default provider login, retained readiness when alternating providers, notifications for shared credentials without starting login, and legacy TypeScript request compatibility.

GitOrigin-RevId: cfd472c322b821fe36b8c133a8de774f4ba48534
This commit is contained in:
Abhinav
2026-11-06 04:02:11 +00:00
committed by copyberry
parent a142c90e26
commit aece559654
22 changed files with 561 additions and 71 deletions
@@ -1842,12 +1842,32 @@ class GatewayOAuthCancelResponse(BaseModel):
)
class GatewayOAuthLoginParams(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
model_provider: Annotated[
str | None,
Field(alias="modelProvider", description="Defaults to the current provider when omitted."),
] = None
class GatewayOAuthLoginResponse(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
class GatewayOAuthReadParams(BaseModel):
model_config = ConfigDict(
populate_by_name=True,
)
model_provider: Annotated[
str | None,
Field(alias="modelProvider", description="Defaults to the current provider when omitted."),
] = None
class GatewayOAuthStatus(Enum):
not_ready = "notReady"
started = "started"
@@ -3086,6 +3106,14 @@ class NonSteerableTurnKind(Enum):
compact = "compact"
class NullableGatewayOAuthLoginParams(RootModel[GatewayOAuthLoginParams | None]):
root: Annotated[GatewayOAuthLoginParams | None, Field(title="Nullable_GatewayOAuthLoginParams")]
class NullableGatewayOAuthReadParams(RootModel[GatewayOAuthReadParams | None]):
root: Annotated[GatewayOAuthReadParams | None, Field(title="Nullable_GatewayOAuthReadParams")]
class NullableGetAccountRateLimitsParams(RootModel[GetAccountRateLimitsParams | None]):
root: Annotated[
GetAccountRateLimitsParams | None, Field(title="Nullable_GetAccountRateLimitsParams")
@@ -7956,7 +7984,7 @@ class AccountGatewayOAuthReadRequest(BaseModel):
method: Annotated[
Literal["account/gatewayOAuth/read"], Field(title="Account/gatewayOAuth/readRequestMethod")
]
params: Annotated[None, Field(None)] = None
params: GatewayOAuthReadParams | None = None
class AccountGatewayOAuthLoginRequest(BaseModel):
@@ -7968,7 +7996,7 @@ class AccountGatewayOAuthLoginRequest(BaseModel):
Literal["account/gatewayOAuth/login"],
Field(title="Account/gatewayOAuth/loginRequestMethod"),
]
params: Annotated[None, Field(None)] = None
params: GatewayOAuthLoginParams | None = None
class AccountGatewayOAuthCancelRequest(BaseModel):