Support remote compaction for Azure responses providers (#17958)

Azure Responses providers were still falling back to local compaction
because the compaction gate only checked
`ModelProviderInfo::is_openai()`.

Move the capability check onto `ModelProviderInfo` with
`supports_remote_compaction()`, backed by the existing Azure Responses
endpoint detection used in `codex-api`, and have `core::compact`
delegate to that helper.

Add regression coverage for:
- OpenAI providers using remote compaction
- Azure providers using remote compaction
- non-OpenAI/non-Azure providers staying on the local path

resolves #17773

---------

Co-authored-by: Michael Bolin <mbolin@openai.com>
This commit is contained in:
Ivan MurashkoandMichael Bolin authored and GitHub committed 2026-04-15 13:05:11 -07:00
1 parent 6696e0bbc3
commit f2a4925f63
4 files changed
+87 -1

No files matched your search

+5
View File
@@ -7,6 +7,7 @@
use codex_api::Provider as ApiProvider;
use codex_api::RetryConfig as ApiRetryConfig;
use codex_api::is_azure_responses_provider;
use codex_app_server_protocol::AuthMode;
use codex_protocol::config_types::ModelProviderAuthInfo;
use codex_protocol::error::CodexErr;
@@ -300,6 +301,10 @@ impl ModelProviderInfo {
self.name == OPENAI_PROVIDER_NAME
}
pub fn supports_remote_compaction(&self) -> bool {
self.is_openai() || is_azure_responses_provider(&self.name, self.base_url.as_deref())
}
pub fn has_command_auth(&self) -> bool {
self.auth.is_some()
}
@@ -129,6 +129,61 @@ supports_websockets = true
assert_eq!(provider.websocket_connect_timeout_ms, Some(15_000));
}
#[test]
fn test_supports_remote_compaction_for_openai() {
let provider = ModelProviderInfo::create_openai_provider(/*base_url*/ None);
assert!(provider.supports_remote_compaction());
}
#[test]
fn test_supports_remote_compaction_for_azure_name() {
let provider = ModelProviderInfo {
name: "Azure".into(),
base_url: Some("https://example.com/openai".into()),
env_key: Some("AZURE_OPENAI_API_KEY".into()),
env_key_instructions: None,
experimental_bearer_token: None,
auth: None,
wire_api: WireApi::Responses,
query_params: None,
http_headers: None,
env_http_headers: None,
request_max_retries: None,
stream_max_retries: None,
stream_idle_timeout_ms: None,
websocket_connect_timeout_ms: None,
requires_openai_auth: false,
supports_websockets: false,
};
assert!(provider.supports_remote_compaction());
}
#[test]
fn test_supports_remote_compaction_for_non_openai_non_azure_provider() {
let provider = ModelProviderInfo {
name: "Example".into(),
base_url: Some("https://example.com/v1".into()),
env_key: Some("API_KEY".into()),
env_key_instructions: None,
experimental_bearer_token: None,
auth: None,
wire_api: WireApi::Responses,
query_params: None,
http_headers: None,
env_http_headers: None,
request_max_retries: None,
stream_max_retries: None,
stream_idle_timeout_ms: None,
websocket_connect_timeout_ms: None,
requires_openai_auth: false,
supports_websockets: false,
};
assert!(!provider.supports_remote_compaction());
}
#[test]
fn test_deserialize_provider_auth_config_defaults() {
let base_dir = tempdir().unwrap();