Register hidden context markers from extensions

This commit is contained in:
Eric Traut
2026-05-27 20:41:07 -07:00
parent f690ea0b6a
commit dcf0f74199
12 changed files with 70 additions and 42 deletions
@@ -6,7 +6,6 @@ use super::AdditionalContextUserFragment;
use super::EnvironmentContext;
use super::FragmentRegistration;
use super::FragmentRegistrationProxy;
use super::GoalContext;
use super::LegacyApplyPatchExecCommandWarning;
use super::LegacyModelMismatchWarning;
use super::LegacyUnifiedExecProcessLimitWarning;
@@ -22,8 +21,6 @@ static ENVIRONMENT_CONTEXT_REGISTRATION: FragmentRegistrationProxy<EnvironmentCo
FragmentRegistrationProxy::new();
static ADDITIONAL_CONTEXT_REGISTRATION: FragmentRegistrationProxy<AdditionalContextUserFragment> =
FragmentRegistrationProxy::new();
static GOAL_CONTEXT_REGISTRATION: FragmentRegistrationProxy<GoalContext> =
FragmentRegistrationProxy::new();
static SKILL_INSTRUCTIONS_REGISTRATION: FragmentRegistrationProxy<SkillInstructions> =
FragmentRegistrationProxy::new();
static USER_SHELL_COMMAND_REGISTRATION: FragmentRegistrationProxy<UserShellCommand> =
@@ -46,7 +43,6 @@ static CONTEXTUAL_USER_FRAGMENTS: &[&dyn FragmentRegistration] = &[
&USER_INSTRUCTIONS_REGISTRATION,
&ENVIRONMENT_CONTEXT_REGISTRATION,
&ADDITIONAL_CONTEXT_REGISTRATION,
&GOAL_CONTEXT_REGISTRATION,
&SKILL_INSTRUCTIONS_REGISTRATION,
&USER_SHELL_COMMAND_REGISTRATION,
&TURN_ABORTED_REGISTRATION,
@@ -62,11 +58,17 @@ fn is_standard_contextual_user_text(text: &str) -> bool {
.any(|fragment| fragment.matches_text(text))
}
fn is_registered_extension_context_text(text: &str) -> bool {
codex_extension_api::registered_hidden_context_markers().any(|marker| marker.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)
parse_hook_prompt_fragment(text).is_some()
|| is_standard_contextual_user_text(text)
|| is_registered_extension_context_text(text)
}
pub(crate) fn parse_visible_hook_prompt_message(
@@ -83,7 +85,7 @@ pub(crate) fn parse_visible_hook_prompt_message(
fragments.push(fragment);
continue;
}
if is_standard_contextual_user_text(text) {
if is_standard_contextual_user_text(text) || is_registered_extension_context_text(text) {
continue;
}
return None;
@@ -14,9 +14,10 @@ fn detects_environment_context_fragment() {
}
#[test]
fn detects_legacy_goal_context_fragment() {
assert!(is_contextual_user_fragment(&ContentItem::InputText {
text: "<goal_context>\nlegacy hidden goal prompt\n</goal_context>".to_string(),
fn does_not_hard_code_extension_context_fragments() {
assert!(!is_contextual_user_fragment(&ContentItem::InputText {
text: "<example_extension_context>\nextension-owned hidden prompt\n</example_extension_context>"
.to_string(),
}));
}
-29
View File
@@ -1,29 +0,0 @@
//! Legacy hidden user-context marker for goal steering prompts.
//!
//! The goal implementation now lives in `codex-goal-extension`, but existing
//! rollouts can still contain this marker. Core keeps recognizing it so old
//! hidden goal prompts do not resurface as normal user messages after resume.
use super::ContextualUserFragment;
/// Marker-only registration for hidden goal steering context.
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct GoalContext;
impl ContextualUserFragment for GoalContext {
fn role() -> &'static str {
"user"
}
fn markers(&self) -> (&'static str, &'static str) {
Self::type_markers()
}
fn body(&self) -> String {
String::new()
}
fn type_markers() -> (&'static str, &'static str) {
("<goal_context>", "</goal_context>")
}
}
-2
View File
@@ -9,7 +9,6 @@ mod contextual_user_message;
mod environment_context;
mod fragment;
mod fragments;
mod goal_context;
mod guardian_followup_review_reminder;
mod hook_additional_context;
mod image_generation_instructions;
@@ -43,7 +42,6 @@ pub(crate) use fragment::FragmentRegistration;
pub(crate) use fragment::FragmentRegistrationProxy;
pub(crate) use fragments::AdditionalContextDeveloperFragment;
pub(crate) use fragments::AdditionalContextUserFragment;
pub(crate) use goal_context::GoalContext;
pub(crate) use guardian_followup_review_reminder::GuardianFollowupReviewReminder;
pub(crate) use hook_additional_context::HookAdditionalContext;
pub(crate) use image_generation_instructions::ImageGenerationInstructions;
+2 -2
View File
@@ -252,7 +252,7 @@ mod tests {
let original_len = prompt.len();
let request = ThreadIdleRequest::new(HiddenContext::new(
HiddenContextMarker::new("<goal_context>", "</goal_context>"),
HiddenContextMarker::new("<test_context>", "</test_context>"),
prompt,
));
let TurnInput::ResponseInputItem(ResponseInputItem::Message { content, .. }) =
@@ -264,7 +264,7 @@ mod tests {
panic!("expected one text content item");
};
assert!(text.starts_with("<goal_context>"));
assert!(text.starts_with("<test_context>"));
assert!(text.contains("start"));
assert!(text.contains("end"));
assert!(text.len() < original_len);