mirror of
https://github.com/openai/codex.git
synced 2026-11-08 20:40:33 +00:00
Reauthenticate runtime requests before reusing WebSocket access (#60055)
## Why An open WebSocket can remain usable after its runtime is paused. Runtime-authenticated requests need a fresh handshake to revalidate access before submitting more work. ## What changed - Reconnect before each runtime-authenticated Responses request and skip speculative preconnection. Preserve turn routing when the runtime identity is unchanged. - Open a fresh connection for each runtime-authenticated Guardian classification instead of prewarming or reusing pooled sockets. - Preserve HTTP fallback for unsupported upgrades and connection failures, while propagating authentication, authorization, rate-limit, and policy errors. ## Testing Add regression coverage for pause and unpause behavior, credential changes, fresh assertions, and Guardian HTTP and WebSocket transports in both runtime authentication modes. GitOrigin-RevId: 9f650147260da5cbbf5bb23dfff0af095fff3955
This commit is contained in:
@@ -316,7 +316,8 @@ pub struct ModelClient {
|
||||
/// A turn-scoped streaming session created from a [`ModelClient`].
|
||||
///
|
||||
/// The session establishes a Responses WebSocket connection lazily and reuses it across multiple
|
||||
/// requests within the turn. It also caches per-turn state:
|
||||
/// requests within the turn. Runtime-authenticated requests reconnect between requests to
|
||||
/// revalidate the registered credential source. It also caches per-turn state:
|
||||
///
|
||||
/// - The last full request, so subsequent calls can reuse incremental websocket request payloads
|
||||
/// only when the current request is an incremental extension of the previous one.
|
||||
@@ -1745,7 +1746,10 @@ impl ModelClientSession {
|
||||
session_telemetry: &SessionTelemetry,
|
||||
responses_metadata: &CodexResponsesMetadata,
|
||||
) -> Result<()> {
|
||||
if !self.client.responses_websocket_enabled() {
|
||||
// Runtime admission belongs to the request that will use the connection.
|
||||
if !self.client.responses_websocket_enabled()
|
||||
|| self.client.state.provider.runtime_auth().is_some()
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
let provider = Arc::clone(&self.client.state.provider);
|
||||
@@ -1860,8 +1864,10 @@ impl ModelClientSession {
|
||||
};
|
||||
let connection_key = ResponsesConnectionKey::new(&api_provider, auth_revision);
|
||||
let reset_reason = match self.websocket_session.connection.as_ref() {
|
||||
// Reauthenticate before each runtime request; an open socket cannot prove liveness.
|
||||
Some(_)
|
||||
if self.websocket_session.responses_headers != *responses_headers
|
||||
if runtime_id.is_some()
|
||||
|| self.websocket_session.responses_headers != *responses_headers
|
||||
|| self.websocket_session.connection_key.as_ref() != Some(&connection_key)
|
||||
|| self.websocket_session.runtime_id != runtime_id
|
||||
|| self.websocket_session.parent_routing_affinity
|
||||
|
||||
Reference in New Issue
Block a user