Merge branch 'summary_op' into compact_cmd

This commit is contained in:
aibrahim-oai
2025-07-14 15:35:07 -07:00
committed by GitHub
3 changed files with 77 additions and 0 deletions

View File

@@ -782,6 +782,36 @@ async fn submission_loop(
}
});
}
Op::SummarizeContext => {
let sess = match sess.as_ref() {
Some(sess) => sess,
None => {
send_no_session_event(sub.id).await;
continue;
}
};
// Create a summarization request as user input
const SUMMARIZATION_PROMPT: &str = r#"
Please provide a summary of our conversation so far, highlighting key points,
decisions made, and any important context that would be useful for future reference.
This summary will be used to replace our conversation history with a more concise
version so choose what details you will need to continue your work.
Provide the summary directly without main title.
"#;
let summarization_prompt = vec![InputItem::Text {
text: SUMMARIZATION_PROMPT.to_string(),
}];
// Attempt to inject input into current task
if let Err(items) = sess.inject_input(summarization_prompt) {
// No current task, spawn a new one
let task = AgentTask::spawn(sess.clone(), sub.id, items);
sess.set_task(task);
}
}
}
}
debug!("Agent loop exited");

View File

@@ -108,6 +108,11 @@ pub enum Op {
/// Request a single history entry identified by `log_id` + `offset`.
GetHistoryEntryRequest { offset: usize, log_id: u64 },
/// Request the agent to summarize the current conversation context.
/// The agent will use its existing context (either conversation history or previous response id)
/// to generate a summary which will be returned as an AgentMessage event.
SummarizeContext,
}
/// Determines the conditions under which the user is consulted to approve

View File

@@ -0,0 +1,42 @@
#![expect(clippy::unwrap_used, clippy::expect_used)]
//! Tests for the `Op::SummarizeContext` operation added to verify that
//! summarization requests are properly handled and injected as user input.
use std::time::Duration;
use codex_core::Codex;
use codex_core::protocol::EventMsg;
use codex_core::protocol::Op;
mod test_support;
use tempfile::TempDir;
use test_support::load_default_config_for_test;
use tokio::time::timeout;
/// Helper function to set up a codex session and wait for it to be configured
async fn setup_configured_codex_session() -> Codex {
let codex_home = TempDir::new().unwrap();
let config = load_default_config_for_test(&codex_home);
let (codex, _, _) = codex_core::codex_wrapper::init_codex(config).await.unwrap();
codex
}
#[tokio::test]
async fn test_summarize_context_spawns_new_agent_task() {
// Test the specific behavior: when there's no current task,
// SummarizeContext should spawn a new AgentTask with the summarization prompt
let codex = setup_configured_codex_session().await;
// At this point, there should be no current task running
let _sub_id = codex.submit(Op::SummarizeContext).await.unwrap();
let event = timeout(Duration::from_secs(5), codex.next_event())
.await
.expect("timeout waiting for task started event")
.expect("codex closed");
assert!(
matches!(event.msg, EventMsg::TaskStarted),
"Expected TaskStarted when no current task exists - should spawn new AgentTask"
);
}