Files
codex/codex-rs/core/src/session_prefix.rs
pakrym-oai 287587c32c Classify additional generated context fragments (#40275)
## What changed

- Represent compaction summaries and Guardian-approved actions as typed contextual fragments.
- Inject subagent notifications through the same fragment path.
- Annotate the resulting request items with `compaction.summary`, `guardian.approved_action`, and `multi_agent.subagent_notification` content kinds while preserving their existing roles and text.

## Testing

- Verify the content-kind metadata on compacted summaries, approved actions, and subagent notifications.

GitOrigin-RevId: 01c93e7f08b2dc1c1e85ba69e82bfb5f56e6cca5
2026-08-23 20:08:40 +00:00

51 lines
2.0 KiB
Rust

use codex_protocol::AgentPath;
use codex_protocol::protocol::AgentStatus;
use codex_utils_output_truncation::TruncationPolicy;
use codex_utils_output_truncation::truncate_text;
use crate::context::ContextualUserFragment;
use crate::context::InterAgentCompletionMessage;
const COMPLETION_MESSAGE_MAX_TOKENS: usize = 1_000;
const COMPLETION_MESSAGE_ENVELOPE_TOKEN_RESERVE: usize = 100;
const ERROR_MAX_TOKENS: usize =
COMPLETION_MESSAGE_MAX_TOKENS - COMPLETION_MESSAGE_ENVELOPE_TOKEN_RESERVE;
const ERROR_NEXT_ACTION: &str = "This agent's turn failed. If you still need this agent, use the available collaboration tools to give it another task.";
// Helpers for model-visible session state markers that are stored in user-role
// messages but are not user intent.
// TODO(jif) unify with structured schema
pub(crate) fn format_inter_agent_completion_message(
task_name: AgentPath,
sender: AgentPath,
status: &AgentStatus,
) -> Option<String> {
let payload = match status {
AgentStatus::Completed(Some(message)) => message.clone(),
AgentStatus::Completed(None) => String::new(),
AgentStatus::Errored(error) => {
let error = truncate_text(error, TruncationPolicy::Tokens(ERROR_MAX_TOKENS));
format!("Agent errored: {error}\n\n{ERROR_NEXT_ACTION}")
}
AgentStatus::Shutdown => "Agent shut down.".to_string(),
AgentStatus::NotFound => "Agent was not found.".to_string(),
AgentStatus::PendingInit | AgentStatus::Running | AgentStatus::Interrupted => return None,
};
Some(InterAgentCompletionMessage::new(task_name, sender, payload).render())
}
#[cfg(test)]
#[path = "session_prefix_tests.rs"]
mod tests;
pub(crate) fn format_subagent_context_line(
agent_reference: &str,
agent_nickname: Option<&str>,
) -> String {
match agent_nickname.filter(|nickname| !nickname.is_empty()) {
Some(agent_nickname) => format!("- {agent_reference}: {agent_nickname}"),
None => format!("- {agent_reference}"),
}
}