mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
[codex] Steer budget-limited goal extension turns (#23718)
## What - Add a small extension capability for injecting model-visible response items into the active turn - Have the goal extension inject hidden goal-context steering when tool-finish accounting reaches `BudgetLimited` - Cover the extension backend path with an assertion on the injected steering item ## Why PR #23696 persists and emits the budget-limited goal update from tool-finish accounting, but it leaves the model unaware of that transition. The existing core runtime steers the model to wrap up in this case; the extension path should do the same through an explicit host capability. ## Testing - `just fmt` - `cargo test -p codex-goal-extension` - `cargo test -p codex-extension-api`
This commit is contained in:
@@ -31,10 +31,7 @@ fn detects_subagent_notification_fragment_case_insensitively() {
|
||||
|
||||
#[test]
|
||||
fn detects_goal_context_fragment() {
|
||||
let text = GoalContext {
|
||||
prompt: "Continue working toward the active thread goal.".to_string(),
|
||||
}
|
||||
.render();
|
||||
let text = GoalContext::new("Continue working toward the active thread goal.").render();
|
||||
|
||||
assert!(is_contextual_user_fragment(&ContentItem::InputText {
|
||||
text
|
||||
@@ -43,9 +40,9 @@ fn detects_goal_context_fragment() {
|
||||
|
||||
#[test]
|
||||
fn contextual_user_fragment_is_dyn_compatible() {
|
||||
let fragment: Box<dyn ContextualUserFragment> = Box::new(GoalContext {
|
||||
prompt: "Continue working toward the active thread goal.".to_string(),
|
||||
});
|
||||
let fragment: Box<dyn ContextualUserFragment> = Box::new(GoalContext::new(
|
||||
"Continue working toward the active thread goal.",
|
||||
));
|
||||
|
||||
assert_eq!(
|
||||
fragment.render(),
|
||||
|
||||
@@ -1,10 +1,33 @@
|
||||
//! Hidden user-context fragment for runtime-owned goal steering prompts.
|
||||
|
||||
use super::ContextualUserFragment;
|
||||
use codex_protocol::models::ContentItem;
|
||||
use codex_protocol::models::ResponseInputItem;
|
||||
|
||||
/// Hidden runtime-owned goal steering context injected into model input.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub(crate) struct GoalContext {
|
||||
pub(crate) prompt: String,
|
||||
pub struct GoalContext {
|
||||
prompt: String,
|
||||
}
|
||||
|
||||
impl GoalContext {
|
||||
/// Creates goal context around an already-rendered steering prompt.
|
||||
pub fn new(prompt: impl Into<String>) -> Self {
|
||||
Self {
|
||||
prompt: prompt.into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts the registered fragment into an active-turn injectable item.
|
||||
pub fn into_response_input_item(self) -> ResponseInputItem {
|
||||
ResponseInputItem::Message {
|
||||
role: <Self as ContextualUserFragment>::role().to_string(),
|
||||
content: vec![ContentItem::InputText {
|
||||
text: self.render(),
|
||||
}],
|
||||
phase: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ContextualUserFragment for GoalContext {
|
||||
|
||||
@@ -40,7 +40,7 @@ pub(crate) use environment_context::EnvironmentContext;
|
||||
pub use fragment::ContextualUserFragment;
|
||||
pub(crate) use fragment::FragmentRegistration;
|
||||
pub(crate) use fragment::FragmentRegistrationProxy;
|
||||
pub(crate) use goal_context::GoalContext;
|
||||
pub 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;
|
||||
|
||||
Reference in New Issue
Block a user