mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
feat(core) RequestRule (#9489)
## Summary Instead of trying to derive the prefix_rule for a command mechanically, let's let the model decide for us. ## Testing - [x] tested locally
This commit is contained in:
committed by
GitHub
Unverified
parent
9f79365691
commit
996e09ca24
+61
-10
@@ -190,6 +190,7 @@ use codex_protocol::models::ContentItem;
|
||||
use codex_protocol::models::DeveloperInstructions;
|
||||
use codex_protocol::models::ResponseInputItem;
|
||||
use codex_protocol::models::ResponseItem;
|
||||
use codex_protocol::models::render_command_prefix_list;
|
||||
use codex_protocol::protocol::CodexErrorInfo;
|
||||
use codex_protocol::protocol::InitialHistory;
|
||||
use codex_protocol::user_input::UserInput;
|
||||
@@ -1226,6 +1227,8 @@ impl Session {
|
||||
DeveloperInstructions::from_policy(
|
||||
&next.sandbox_policy,
|
||||
next.approval_policy,
|
||||
self.services.exec_policy.current().as_ref(),
|
||||
self.features.enabled(Feature::RequestRule),
|
||||
&next.cwd,
|
||||
)
|
||||
.into(),
|
||||
@@ -1416,6 +1419,44 @@ impl Session {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn turn_context_for_sub_id(&self, sub_id: &str) -> Option<Arc<TurnContext>> {
|
||||
let active = self.active_turn.lock().await;
|
||||
active
|
||||
.as_ref()
|
||||
.and_then(|turn| turn.tasks.get(sub_id))
|
||||
.map(|task| Arc::clone(&task.turn_context))
|
||||
}
|
||||
|
||||
pub(crate) async fn record_execpolicy_amendment_message(
|
||||
&self,
|
||||
sub_id: &str,
|
||||
amendment: &ExecPolicyAmendment,
|
||||
) {
|
||||
let Some(prefixes) = render_command_prefix_list([amendment.command.as_slice()]) else {
|
||||
warn!("execpolicy amendment for {sub_id} had no command prefix");
|
||||
return;
|
||||
};
|
||||
let text = format!("Approved command prefix saved:\n{prefixes}");
|
||||
let message: ResponseItem = DeveloperInstructions::new(text.clone()).into();
|
||||
|
||||
if let Some(turn_context) = self.turn_context_for_sub_id(sub_id).await {
|
||||
self.record_conversation_items(&turn_context, std::slice::from_ref(&message))
|
||||
.await;
|
||||
return;
|
||||
}
|
||||
|
||||
if self
|
||||
.inject_response_items(vec![ResponseInputItem::Message {
|
||||
role: "developer".to_string(),
|
||||
content: vec![ContentItem::InputText { text }],
|
||||
}])
|
||||
.await
|
||||
.is_err()
|
||||
{
|
||||
warn!("no active turn found to record execpolicy amendment message for {sub_id}");
|
||||
}
|
||||
}
|
||||
|
||||
/// Emit an exec approval request event and await the user's decision.
|
||||
///
|
||||
/// The request is keyed by `sub_id`/`call_id` so matching responses are delivered
|
||||
@@ -1749,6 +1790,8 @@ impl Session {
|
||||
DeveloperInstructions::from_policy(
|
||||
&turn_context.sandbox_policy,
|
||||
turn_context.approval_policy,
|
||||
self.services.exec_policy.current().as_ref(),
|
||||
self.features.enabled(Feature::RequestRule),
|
||||
&turn_context.cwd,
|
||||
)
|
||||
.into(),
|
||||
@@ -2595,18 +2638,26 @@ mod handlers {
|
||||
if let ReviewDecision::ApprovedExecpolicyAmendment {
|
||||
proposed_execpolicy_amendment,
|
||||
} = &decision
|
||||
&& let Err(err) = sess
|
||||
{
|
||||
match sess
|
||||
.persist_execpolicy_amendment(proposed_execpolicy_amendment)
|
||||
.await
|
||||
{
|
||||
let message = format!("Failed to apply execpolicy amendment: {err}");
|
||||
tracing::warn!("{message}");
|
||||
let warning = EventMsg::Warning(WarningEvent { message });
|
||||
sess.send_event_raw(Event {
|
||||
id: id.clone(),
|
||||
msg: warning,
|
||||
})
|
||||
.await;
|
||||
{
|
||||
Ok(()) => {
|
||||
sess.record_execpolicy_amendment_message(&id, proposed_execpolicy_amendment)
|
||||
.await;
|
||||
}
|
||||
Err(err) => {
|
||||
let message = format!("Failed to apply execpolicy amendment: {err}");
|
||||
tracing::warn!("{message}");
|
||||
let warning = EventMsg::Warning(WarningEvent { message });
|
||||
sess.send_event_raw(Event {
|
||||
id: id.clone(),
|
||||
msg: warning,
|
||||
})
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
match decision {
|
||||
ReviewDecision::Abort => {
|
||||
|
||||
Reference in New Issue
Block a user