mirror of
https://github.com/openai/codex.git
synced 2026-11-12 22:42:36 +00:00
Enable remote compaction for Amazon Bedrock (#36981)
## What changed - Add provider-owned remote compaction capabilities for unsupported, v1, and v2 protocols. - Mark Amazon Bedrock as v1-only so manual and automatic compaction use `/v1/responses/compact`, even when the v2 feature is enabled. - Preserve v2 support for OpenAI and Azure Responses providers and local compaction for unsupported providers. ## Testing - Cover Amazon Bedrock manual and automatic remote compaction, including endpoint selection, authentication headers, model selection, and reuse of the compacted summary. GitOrigin-RevId: d58093178605d1f8155b93d9a161408177f6ac72
This commit is contained in:
1 parent
e1f39b5f5b
commit
b9ba969f39
10 files changed
+277
-156
No files matched your search
@@ -50,8 +50,6 @@ use codex_utils_output_truncation::truncate_text;
|
||||
use futures::prelude::*;
|
||||
use tracing::error;
|
||||
|
||||
use codex_model_provider_info::ModelProviderInfo;
|
||||
|
||||
pub use codex_prompts::SUMMARIZATION_PROMPT;
|
||||
pub use codex_prompts::SUMMARY_PREFIX;
|
||||
const COMPACT_USER_MESSAGE_MAX_TOKENS: usize = 20_000;
|
||||
@@ -105,10 +103,6 @@ pub(crate) async fn build_compaction_initial_context(
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn should_use_remote_compact_task(provider: &ModelProviderInfo) -> bool {
|
||||
provider.supports_remote_compaction()
|
||||
}
|
||||
|
||||
pub(crate) async fn run_inline_auto_compact_task(
|
||||
sess: Arc<Session>,
|
||||
turn_context: Arc<TurnContext>,
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
use super::*;
|
||||
use codex_model_provider_info::ModelProviderInfo;
|
||||
use codex_model_provider_info::WireApi;
|
||||
use codex_protocol::ResponseItemId;
|
||||
use codex_protocol::models::DEFAULT_IMAGE_DETAIL;
|
||||
use codex_protocol::models::InternalChatMessageMetadataPassthrough;
|
||||
@@ -266,31 +264,6 @@ fn build_compacted_history_preserves_user_message_passthrough_metadata() {
|
||||
assert_eq!(history[1].turn_id(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_use_remote_compact_task_for_azure_provider() {
|
||||
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,
|
||||
aws: 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,
|
||||
supports_standalone_web_search: false,
|
||||
};
|
||||
|
||||
assert!(should_use_remote_compact_task(&provider));
|
||||
}
|
||||
#[tokio::test]
|
||||
async fn process_compacted_history_replaces_developer_messages() {
|
||||
let compacted_history = vec![
|
||||
|
||||
@@ -11,7 +11,6 @@ use crate::client_common::ResponseEvent;
|
||||
use crate::collect_explicit_skill_mentions;
|
||||
use crate::compact::InitialContextInjection;
|
||||
use crate::compact::run_inline_auto_compact_task;
|
||||
use crate::compact::should_use_remote_compact_task;
|
||||
use crate::compact_remote::run_inline_remote_auto_compact_task;
|
||||
use crate::compact_remote_v2::run_inline_remote_auto_compact_task as run_inline_remote_auto_compact_task_v2;
|
||||
use crate::connectors;
|
||||
@@ -81,6 +80,7 @@ use codex_features::Feature;
|
||||
use codex_file_system::FindUpErrorPolicy;
|
||||
use codex_file_system::find_nearest_ancestor_with_markers;
|
||||
use codex_login::CodexAuth;
|
||||
use codex_model_provider::RemoteCompactionSupport;
|
||||
use codex_protocol::ResponseItemId;
|
||||
use codex_protocol::config_types::AutoCompactTokenLimitScope;
|
||||
use codex_protocol::config_types::ModeKind;
|
||||
@@ -1171,11 +1171,12 @@ async fn run_auto_compact(
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if should_use_remote_compact_task(turn_context.provider.info()) {
|
||||
if turn_context
|
||||
.config
|
||||
.features
|
||||
.enabled(Feature::RemoteCompactionV2)
|
||||
match turn_context.provider.capabilities().remote_compaction {
|
||||
RemoteCompactionSupport::V2
|
||||
if turn_context
|
||||
.config
|
||||
.features
|
||||
.enabled(Feature::RemoteCompactionV2) =>
|
||||
{
|
||||
emit_compact_metric(
|
||||
&sess.services.session_telemetry,
|
||||
@@ -1192,37 +1193,39 @@ async fn run_auto_compact(
|
||||
phase,
|
||||
)
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
emit_compact_metric(
|
||||
&sess.services.session_telemetry,
|
||||
"remote",
|
||||
/*manual*/ false,
|
||||
);
|
||||
run_inline_remote_auto_compact_task(
|
||||
Arc::clone(sess),
|
||||
step_context,
|
||||
fallback_step_context,
|
||||
client_session.turn_state(),
|
||||
initial_context_injection,
|
||||
reason,
|
||||
phase,
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
emit_compact_metric(
|
||||
&sess.services.session_telemetry,
|
||||
"local",
|
||||
/*manual*/ false,
|
||||
);
|
||||
run_inline_auto_compact_task(
|
||||
Arc::clone(sess),
|
||||
Arc::clone(turn_context),
|
||||
initial_context_injection,
|
||||
reason,
|
||||
phase,
|
||||
)
|
||||
.await?;
|
||||
RemoteCompactionSupport::V1 | RemoteCompactionSupport::V2 => {
|
||||
emit_compact_metric(
|
||||
&sess.services.session_telemetry,
|
||||
"remote",
|
||||
/*manual*/ false,
|
||||
);
|
||||
run_inline_remote_auto_compact_task(
|
||||
Arc::clone(sess),
|
||||
step_context,
|
||||
fallback_step_context,
|
||||
client_session.turn_state(),
|
||||
initial_context_injection,
|
||||
reason,
|
||||
phase,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
RemoteCompactionSupport::Unsupported => {
|
||||
emit_compact_metric(
|
||||
&sess.services.session_telemetry,
|
||||
"local",
|
||||
/*manual*/ false,
|
||||
);
|
||||
run_inline_auto_compact_task(
|
||||
Arc::clone(sess),
|
||||
Arc::clone(turn_context),
|
||||
initial_context_injection,
|
||||
reason,
|
||||
phase,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ use crate::session::session::Session;
|
||||
use crate::session::turn_context::TurnContext;
|
||||
use crate::state::TaskKind;
|
||||
use codex_features::Feature;
|
||||
use codex_model_provider::RemoteCompactionSupport;
|
||||
use codex_protocol::error::CodexErrorDetails;
|
||||
use codex_protocol::user_input::UserInput;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
@@ -37,11 +38,9 @@ impl SessionTask for CompactTask {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let result = if crate::compact::should_use_remote_compact_task(ctx.provider.info()) {
|
||||
if ctx
|
||||
.config
|
||||
.features
|
||||
.enabled(codex_features::Feature::RemoteCompactionV2)
|
||||
let result = match ctx.provider.capabilities().remote_compaction {
|
||||
RemoteCompactionSupport::V2
|
||||
if ctx.config.features.enabled(Feature::RemoteCompactionV2) =>
|
||||
{
|
||||
emit_compact_metric(
|
||||
&session.services.session_telemetry,
|
||||
@@ -49,7 +48,8 @@ impl SessionTask for CompactTask {
|
||||
/*manual*/ true,
|
||||
);
|
||||
crate::compact_remote_v2::run_remote_compact_task(session.clone(), ctx).await
|
||||
} else {
|
||||
}
|
||||
RemoteCompactionSupport::V1 | RemoteCompactionSupport::V2 => {
|
||||
emit_compact_metric(
|
||||
&session.services.session_telemetry,
|
||||
"remote",
|
||||
@@ -57,23 +57,24 @@ impl SessionTask for CompactTask {
|
||||
);
|
||||
crate::compact_remote::run_remote_compact_task(session.clone(), ctx).await
|
||||
}
|
||||
} else {
|
||||
emit_compact_metric(
|
||||
&session.services.session_telemetry,
|
||||
"local",
|
||||
/*manual*/ true,
|
||||
);
|
||||
let input = vec![UserInput::Text {
|
||||
text: ctx
|
||||
.config
|
||||
.compact_prompt
|
||||
.as_deref()
|
||||
.unwrap_or(crate::compact::SUMMARIZATION_PROMPT)
|
||||
.to_string(),
|
||||
// Compaction prompt is synthesized; no UI element ranges to preserve.
|
||||
text_elements: Vec::new(),
|
||||
}];
|
||||
crate::compact::run_compact_task(session.clone(), ctx, input).await
|
||||
RemoteCompactionSupport::Unsupported => {
|
||||
emit_compact_metric(
|
||||
&session.services.session_telemetry,
|
||||
"local",
|
||||
/*manual*/ true,
|
||||
);
|
||||
let input = vec![UserInput::Text {
|
||||
text: ctx
|
||||
.config
|
||||
.compact_prompt
|
||||
.as_deref()
|
||||
.unwrap_or(crate::compact::SUMMARIZATION_PROMPT)
|
||||
.to_string(),
|
||||
// Compaction prompt is synthesized; no UI element ranges to preserve.
|
||||
text_elements: Vec::new(),
|
||||
}];
|
||||
crate::compact::run_compact_task(session.clone(), ctx, input).await
|
||||
}
|
||||
};
|
||||
if let Err(err) = result
|
||||
&& matches!(err.details(), CodexErrorDetails::TurnAborted)
|
||||
|
||||
Reference in new issue
Block a user