Codex Handbook
core/src/context/contextual_user_message.rs 102 lines
use codex_protocol::items::HookPromptItem;use codex_protocol::items::parse_hook_prompt_fragment;use codex_protocol::models::ContentItem;use super::AdditionalContextUserFragment;use super::EnvironmentContext;use super::FragmentRegistration;use super::FragmentRegistrationProxy;use super::InternalModelContextFragment;use super::LegacyApplyPatchExecCommandWarning;use super::LegacyModelMismatchWarning;use super::LegacyUnifiedExecProcessLimitWarning;use super::SkillInstructions;use super::SubagentNotification;use super::TurnAborted;use super::UserInstructions;use super::UserShellCommand;static USER_INSTRUCTIONS_REGISTRATION: FragmentRegistrationProxy<UserInstructions> =    FragmentRegistrationProxy::new();static ENVIRONMENT_CONTEXT_REGISTRATION: FragmentRegistrationProxy<EnvironmentContext> =    FragmentRegistrationProxy::new();static ADDITIONAL_CONTEXT_REGISTRATION: FragmentRegistrationProxy<AdditionalContextUserFragment> =    FragmentRegistrationProxy::new();static SKILL_INSTRUCTIONS_REGISTRATION: FragmentRegistrationProxy<SkillInstructions> =    FragmentRegistrationProxy::new();static USER_SHELL_COMMAND_REGISTRATION: FragmentRegistrationProxy<UserShellCommand> =    FragmentRegistrationProxy::new();static TURN_ABORTED_REGISTRATION: FragmentRegistrationProxy<TurnAborted> =    FragmentRegistrationProxy::new();static SUBAGENT_NOTIFICATION_REGISTRATION: FragmentRegistrationProxy<SubagentNotification> =    FragmentRegistrationProxy::new();static INTERNAL_MODEL_CONTEXT_REGISTRATION: FragmentRegistrationProxy<    InternalModelContextFragment,> = FragmentRegistrationProxy::new();static LEGACY_UNIFIED_EXEC_PROCESS_LIMIT_WARNING_REGISTRATION: FragmentRegistrationProxy<    LegacyUnifiedExecProcessLimitWarning,> = FragmentRegistrationProxy::new();static LEGACY_APPLY_PATCH_EXEC_COMMAND_WARNING_REGISTRATION: FragmentRegistrationProxy<    LegacyApplyPatchExecCommandWarning,> = FragmentRegistrationProxy::new();static LEGACY_MODEL_MISMATCH_WARNING_REGISTRATION: FragmentRegistrationProxy<    LegacyModelMismatchWarning,> = FragmentRegistrationProxy::new();static CONTEXTUAL_USER_FRAGMENTS: &[&dyn FragmentRegistration] = &[    &USER_INSTRUCTIONS_REGISTRATION,    &ENVIRONMENT_CONTEXT_REGISTRATION,    &ADDITIONAL_CONTEXT_REGISTRATION,    &SKILL_INSTRUCTIONS_REGISTRATION,    &USER_SHELL_COMMAND_REGISTRATION,    &TURN_ABORTED_REGISTRATION,    &SUBAGENT_NOTIFICATION_REGISTRATION,    &INTERNAL_MODEL_CONTEXT_REGISTRATION,    &LEGACY_UNIFIED_EXEC_PROCESS_LIMIT_WARNING_REGISTRATION,    &LEGACY_APPLY_PATCH_EXEC_COMMAND_WARNING_REGISTRATION,    &LEGACY_MODEL_MISMATCH_WARNING_REGISTRATION,];fn is_standard_contextual_user_text(text: &str) -> bool {    CONTEXTUAL_USER_FRAGMENTS        .iter()        .any(|fragment| fragment.matches_text(text))}pub(crate) fn is_contextual_user_fragment(content_item: &ContentItem) -> bool {    let ContentItem::InputText { text } = content_item else {        return false;    };    parse_hook_prompt_fragment(text).is_some() || is_standard_contextual_user_text(text)}pub(crate) fn parse_visible_hook_prompt_message(    id: Option<&String>,    content: &[ContentItem],) -> Option<HookPromptItem> {    let mut fragments = Vec::new();    for content_item in content {        let ContentItem::InputText { text } = content_item else {            return None;        };        if let Some(fragment) = parse_hook_prompt_fragment(text) {            fragments.push(fragment);            continue;        }        if is_standard_contextual_user_text(text) {            continue;        }        return None;    }    if fragments.is_empty() {        return None;    }    Some(HookPromptItem::from_fragments(id, fragments))}#[cfg(test)]#[path = "contextual_user_message_tests.rs"]mod tests;