mirror of
https://github.com/openai/codex.git
synced 2026-11-13 06:45:07 +00:00
Represent Guardian policy as a contextual fragment (#40420)
## What changed - Add a `GuardianPolicy` contextual fragment that renders as a standalone developer message with the `guardian.policy` content kind. - Use the fragment when rebuilding Guardian context and verify that its content kind remains attached after history compaction. GitOrigin-RevId: f7028fb29a48ad2453437f3d3a4405fcab7a2fd7
This commit is contained in:
1 parent
a25e986323
commit
60821c5043
4 files changed
+62
-11
No files matched your search
@@ -0,0 +1,42 @@
|
|||||||
|
use super::ContextualUserFragment;
|
||||||
|
use codex_protocol::models::ContentItemKind;
|
||||||
|
|
||||||
|
/// The isolated developer policy provided to a Guardian reviewer.
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub(crate) struct GuardianPolicy {
|
||||||
|
policy: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GuardianPolicy {
|
||||||
|
pub(crate) fn new(policy: impl Into<String>) -> Self {
|
||||||
|
Self {
|
||||||
|
policy: policy.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ContextualUserFragment for GuardianPolicy {
|
||||||
|
fn content_kind(&self) -> ContentItemKind {
|
||||||
|
ContentItemKind("guardian.policy".to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn role(&self) -> &'static str {
|
||||||
|
"developer"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn requires_separate_message(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn markers(&self) -> (&'static str, &'static str) {
|
||||||
|
Self::type_markers()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_markers() -> (&'static str, &'static str) {
|
||||||
|
("", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn body(&self) -> String {
|
||||||
|
self.policy.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ mod environments_instructions;
|
|||||||
mod guardian_approved_action;
|
mod guardian_approved_action;
|
||||||
mod guardian_followup_review_reminder;
|
mod guardian_followup_review_reminder;
|
||||||
mod guardian_node_repl_policy;
|
mod guardian_node_repl_policy;
|
||||||
|
mod guardian_policy;
|
||||||
mod guardian_review_evidence;
|
mod guardian_review_evidence;
|
||||||
mod hook_additional_context;
|
mod hook_additional_context;
|
||||||
mod image_resize_notice;
|
mod image_resize_notice;
|
||||||
@@ -62,6 +63,7 @@ pub(crate) use environments_instructions::EnvironmentsInstructions;
|
|||||||
pub(crate) use guardian_approved_action::GuardianApprovedAction;
|
pub(crate) use guardian_approved_action::GuardianApprovedAction;
|
||||||
pub(crate) use guardian_followup_review_reminder::GuardianFollowupReviewReminder;
|
pub(crate) use guardian_followup_review_reminder::GuardianFollowupReviewReminder;
|
||||||
pub(crate) use guardian_node_repl_policy::GuardianNodeReplPolicy;
|
pub(crate) use guardian_node_repl_policy::GuardianNodeReplPolicy;
|
||||||
|
pub(crate) use guardian_policy::GuardianPolicy;
|
||||||
pub use guardian_review_evidence::GuardianReviewEvidence;
|
pub use guardian_review_evidence::GuardianReviewEvidence;
|
||||||
pub use guardian_review_evidence::GuardianReviewEvidenceFragment;
|
pub use guardian_review_evidence::GuardianReviewEvidenceFragment;
|
||||||
pub(crate) use hook_additional_context::HookAdditionalContext;
|
pub(crate) use hook_additional_context::HookAdditionalContext;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ use crate::config::ManagedFeatures;
|
|||||||
use crate::config::resolve_tool_suggest_config_from_layer_stack;
|
use crate::config::resolve_tool_suggest_config_from_layer_stack;
|
||||||
use crate::context::ContextualUserFragment;
|
use crate::context::ContextualUserFragment;
|
||||||
use crate::context::DeveloperInstructions;
|
use crate::context::DeveloperInstructions;
|
||||||
|
use crate::context::GuardianPolicy;
|
||||||
use crate::context::ManagedDeveloperInstructions;
|
use crate::context::ManagedDeveloperInstructions;
|
||||||
use crate::context::ModelSwitchInstructions;
|
use crate::context::ModelSwitchInstructions;
|
||||||
use crate::context::MultiAgentRoleInstructions;
|
use crate::context::MultiAgentRoleInstructions;
|
||||||
@@ -57,7 +58,6 @@ use codex_analytics::SubAgentThreadStartedInput;
|
|||||||
use codex_analytics::TurnCodexErrorFact;
|
use codex_analytics::TurnCodexErrorFact;
|
||||||
use codex_async_utils::OrCancelExt;
|
use codex_async_utils::OrCancelExt;
|
||||||
use codex_connectors::connector_runtime_context_key;
|
use codex_connectors::connector_runtime_context_key;
|
||||||
use codex_context_fragments::AnnotatedContent;
|
|
||||||
use codex_context_fragments::RenderedFragment;
|
use codex_context_fragments::RenderedFragment;
|
||||||
use codex_exec_server::Environment;
|
use codex_exec_server::Environment;
|
||||||
use codex_exec_server::EnvironmentManager;
|
use codex_exec_server::EnvironmentManager;
|
||||||
@@ -3719,13 +3719,7 @@ impl Session {
|
|||||||
&& !developer_instructions.is_empty()
|
&& !developer_instructions.is_empty()
|
||||||
&& let Some(guardian_developer_message) =
|
&& let Some(guardian_developer_message) =
|
||||||
crate::context_manager::updates::build_rendered_message(vec![
|
crate::context_manager::updates::build_rendered_message(vec![
|
||||||
RenderedFragment::new(
|
GuardianPolicy::new(developer_instructions).render_fragment(),
|
||||||
"developer",
|
|
||||||
AnnotatedContent::input_text(
|
|
||||||
developer_instructions,
|
|
||||||
ContentItemKind("guardian.policy".to_string()),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
])
|
])
|
||||||
{
|
{
|
||||||
items.push(guardian_developer_message);
|
items.push(guardian_developer_message);
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ use codex_model_provider::create_model_provider;
|
|||||||
use codex_protocol::config_types::ApprovalsReviewer;
|
use codex_protocol::config_types::ApprovalsReviewer;
|
||||||
use codex_protocol::models::AdditionalPermissionProfile as PermissionProfile;
|
use codex_protocol::models::AdditionalPermissionProfile as PermissionProfile;
|
||||||
use codex_protocol::models::ContentItem;
|
use codex_protocol::models::ContentItem;
|
||||||
|
use codex_protocol::models::ContentItemKind;
|
||||||
use codex_protocol::models::NetworkPermissions;
|
use codex_protocol::models::NetworkPermissions;
|
||||||
use codex_protocol::models::ResponseInputItem;
|
use codex_protocol::models::ResponseInputItem;
|
||||||
use codex_protocol::models::ResponseItem;
|
use codex_protocol::models::ResponseItem;
|
||||||
@@ -640,7 +641,13 @@ async fn process_compacted_history_preserves_separate_guardian_developer_message
|
|||||||
.iter()
|
.iter()
|
||||||
.filter_map(|item| match item {
|
.filter_map(|item| match item {
|
||||||
ResponseItem::Message { role, content, .. } if role == "developer" => {
|
ResponseItem::Message { role, content, .. } if role == "developer" => {
|
||||||
crate::content_items_to_text(content)
|
crate::content_items_to_text(content).map(|text| {
|
||||||
|
(
|
||||||
|
text,
|
||||||
|
item.executed_tool_call_metadata()
|
||||||
|
.and_then(|metadata| metadata.content_item_kinds.clone()),
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
@@ -649,10 +656,16 @@ async fn process_compacted_history_preserves_separate_guardian_developer_message
|
|||||||
assert!(
|
assert!(
|
||||||
!developer_messages
|
!developer_messages
|
||||||
.iter()
|
.iter()
|
||||||
.any(|message| message.contains("stale developer message"))
|
.any(|(message, _)| message.contains("stale developer message"))
|
||||||
);
|
);
|
||||||
assert!(developer_messages.len() >= 2);
|
assert!(developer_messages.len() >= 2);
|
||||||
assert_eq!(developer_messages.last(), Some(&guardian_policy));
|
assert_eq!(
|
||||||
|
developer_messages.last(),
|
||||||
|
Some(&(
|
||||||
|
guardian_policy,
|
||||||
|
Some(vec![ContentItemKind("guardian.policy".to_string())]),
|
||||||
|
))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|||||||
Reference in new issue
Block a user