Route Guardian requests through /responses with identifying headers (#45736)

## What changed

- Replace dedicated Guardian endpoints with `/responses`, sending `x-codex-guardian: reviewer` or `x-codex-guardian: classifier` for eligible Codex backend requests over HTTP and WebSocket.
- Add model-scoped thread headers, recheck backend authentication on each request attempt, and reconnect WebSockets when the applicable headers change.
- Retain `features.guardianv2.free_guardian` for configuration compatibility while removing its routing gate; the backend now controls Guardian billing.

## Testing

Update tests for reviewer and classifier headers, model and authentication scoping, HTTP fallback, WebSocket reuse, and parent-response metadata across retries.

GitOrigin-RevId: 1c2b3c458ab77fb40aae4ee6784f6d827c60e76c
This commit is contained in:
jif
2026-09-15 17:09:11 +00:00
committed by copyberry
parent d4e11a9b97
commit eeded5ba1a
22 changed files with 246 additions and 286 deletions
+2 -1
View File
@@ -1600,6 +1600,7 @@ impl Session {
&config.features,
&initial_history,
);
let codex_responses_headers = thread_extension_data.get::<crate::CodexResponsesHeaders>();
let services = SessionServices {
// Start with an empty connection set. The initialized set is
// published after SessionConfigured so MCP events follow it.
@@ -1672,7 +1673,6 @@ impl Session {
attestation_provider,
config.http_client_factory(),
)
.with_free_guardian_enabled(config.free_guardian_enabled())
.with_session_context(
crate::guardian::prompt_cache_key_override_for_review_session(
&session_configuration.session_source,
@@ -1680,6 +1680,7 @@ impl Session {
)
.or(fork_cache_key),
tx_event.clone(),
codex_responses_headers,
),
executed_tool_calls: executed_tool_calls.clone(),
code_mode_service: crate::tools::code_mode::CodeModeService::new(