mirror of
https://github.com/openai/codex.git
synced 2026-05-16 01:02:48 +00:00
Merge remote-tracking branch 'origin/main' into ee/pause-queue-sends-core
This commit is contained in:
@@ -7012,7 +7012,9 @@ async fn handle_output_item_done_records_image_save_history_message() {
|
||||
let mut ctx = HandleOutputCtx {
|
||||
sess: Arc::clone(&session),
|
||||
turn_context: Arc::clone(&turn_context),
|
||||
turn_store: Arc::new(codex_extension_api::ExtensionData::new()),
|
||||
turn_store: Arc::new(codex_extension_api::ExtensionData::new(
|
||||
turn_context.sub_id.clone(),
|
||||
)),
|
||||
tool_runtime: test_tool_runtime(Arc::clone(&session), Arc::clone(&turn_context)),
|
||||
cancellation_token: CancellationToken::new(),
|
||||
};
|
||||
@@ -7065,7 +7067,9 @@ async fn handle_output_item_done_skips_image_save_message_when_save_fails() {
|
||||
let mut ctx = HandleOutputCtx {
|
||||
sess: Arc::clone(&session),
|
||||
turn_context: Arc::clone(&turn_context),
|
||||
turn_store: Arc::new(codex_extension_api::ExtensionData::new()),
|
||||
turn_store: Arc::new(codex_extension_api::ExtensionData::new(
|
||||
turn_context.sub_id.clone(),
|
||||
)),
|
||||
tool_runtime: test_tool_runtime(Arc::clone(&session), Arc::clone(&turn_context)),
|
||||
cancellation_token: CancellationToken::new(),
|
||||
};
|
||||
@@ -9092,7 +9096,7 @@ async fn tool_calls_reopen_mailbox_delivery_for_current_turn() {
|
||||
let mut ctx = HandleOutputCtx {
|
||||
sess: Arc::clone(&sess),
|
||||
turn_context: Arc::clone(&tc),
|
||||
turn_store: Arc::new(codex_extension_api::ExtensionData::new()),
|
||||
turn_store: Arc::new(codex_extension_api::ExtensionData::new(tc.sub_id.clone())),
|
||||
tool_runtime: test_tool_runtime(Arc::clone(&sess), Arc::clone(&tc)),
|
||||
cancellation_token: CancellationToken::new(),
|
||||
};
|
||||
|
||||
@@ -43,7 +43,7 @@ async fn plan_mode_uses_contributed_turn_item_for_last_agent_message() {
|
||||
let mut builder = codex_extension_api::ExtensionRegistryBuilder::new();
|
||||
builder.turn_item_contributor(Arc::new(RewriteAgentMessageContributor));
|
||||
session.services.extensions = Arc::new(builder.build());
|
||||
let turn_store = ExtensionData::new();
|
||||
let turn_store = ExtensionData::new(turn_context.sub_id.clone());
|
||||
let mut state = PlanModeStreamState::new(&turn_context.sub_id);
|
||||
let mut last_agent_message = None;
|
||||
let item = assistant_output_text("original assistant text");
|
||||
|
||||
@@ -9,6 +9,7 @@ use tokio::sync::Notify;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tokio_util::task::AbortOnDropHandle;
|
||||
|
||||
use codex_extension_api::ExtensionData;
|
||||
use codex_protocol::dynamic_tools::DynamicToolResponse;
|
||||
use codex_protocol::models::ResponseInputItem;
|
||||
use codex_protocol::request_permissions::RequestPermissionProfile;
|
||||
@@ -101,6 +102,7 @@ pub(crate) struct RunningTask {
|
||||
pub(crate) cancellation_token: CancellationToken,
|
||||
pub(crate) handle: AbortOnDropHandle<()>,
|
||||
pub(crate) turn_context: Arc<TurnContext>,
|
||||
pub(crate) turn_extension_data: Arc<ExtensionData>,
|
||||
// Timer recorded when the task drops to capture the full turn duration.
|
||||
pub(crate) _timer: Option<codex_otel::Timer>,
|
||||
}
|
||||
|
||||
@@ -214,7 +214,7 @@ async fn handle_non_tool_response_item_runs_turn_item_contributors_only_when_req
|
||||
let mut builder = codex_extension_api::ExtensionRegistryBuilder::new();
|
||||
builder.turn_item_contributor(Arc::new(TestTurnItemContributor));
|
||||
session.services.extensions = Arc::new(builder.build());
|
||||
let turn_store = ExtensionData::new();
|
||||
let turn_store = ExtensionData::new(turn_context.sub_id.clone());
|
||||
let item = assistant_output_text(
|
||||
"hello<oai-mem-citation>ignored by memory parser</oai-mem-citation> world",
|
||||
);
|
||||
@@ -288,8 +288,8 @@ async fn handle_output_item_done_returns_contributed_last_agent_message() {
|
||||
let item = assistant_output_text("original assistant text");
|
||||
let mut ctx = HandleOutputCtx {
|
||||
sess: session,
|
||||
turn_context,
|
||||
turn_store: Arc::new(ExtensionData::new()),
|
||||
turn_context: Arc::clone(&turn_context),
|
||||
turn_store: Arc::new(ExtensionData::new(turn_context.sub_id.clone())),
|
||||
tool_runtime,
|
||||
cancellation_token: CancellationToken::new(),
|
||||
};
|
||||
@@ -310,7 +310,7 @@ async fn finalized_turn_item_defers_mailbox_for_contributed_visible_text() {
|
||||
let mut builder = codex_extension_api::ExtensionRegistryBuilder::new();
|
||||
builder.turn_item_contributor(Arc::new(RewriteAgentMessageContributor));
|
||||
session.services.extensions = Arc::new(builder.build());
|
||||
let turn_store = ExtensionData::new();
|
||||
let turn_store = ExtensionData::new(turn_context.sub_id.clone());
|
||||
let item = assistant_output_text("<oai-mem-citation>hidden only</oai-mem-citation>");
|
||||
|
||||
let finalized = finalize_non_tool_response_item(
|
||||
@@ -336,7 +336,7 @@ async fn finalized_turn_item_keeps_mailbox_open_for_commentary_text() {
|
||||
let mut builder = codex_extension_api::ExtensionRegistryBuilder::new();
|
||||
builder.turn_item_contributor(Arc::new(RewriteAgentMessageContributor));
|
||||
session.services.extensions = Arc::new(builder.build());
|
||||
let turn_store = ExtensionData::new();
|
||||
let turn_store = ExtensionData::new(turn_context.sub_id.clone());
|
||||
let item = assistant_output_text_with_phase("still working", Some(MessagePhase::Commentary));
|
||||
|
||||
let finalized = finalize_non_tool_response_item(
|
||||
|
||||
@@ -367,6 +367,7 @@ impl Session {
|
||||
}
|
||||
self.emit_turn_start_lifecycle(turn_context.extension_data.as_ref());
|
||||
|
||||
let turn_extension_data = Arc::clone(&turn_context.extension_data);
|
||||
let mut active = self.active_turn.lock().await;
|
||||
let turn = active.get_or_insert_with(ActiveTurn::default);
|
||||
debug_assert!(turn.tasks.is_empty());
|
||||
@@ -439,6 +440,7 @@ impl Session {
|
||||
task,
|
||||
cancellation_token,
|
||||
turn_context: Arc::clone(&turn_context),
|
||||
turn_extension_data,
|
||||
_timer: timer,
|
||||
};
|
||||
turn.add_task(running_task);
|
||||
|
||||
@@ -42,6 +42,15 @@ function Invoke-ParseRequest {
|
||||
return @{ id = $RequestId; status = 'parse_errors' }
|
||||
}
|
||||
|
||||
# PowerShell's stop-parsing marker hands the remaining source text to native
|
||||
# commands with runtime argument handling that does not match the AST shape we
|
||||
# flatten below. Keep that form out of the argv-like lowering path entirely.
|
||||
foreach ($token in $tokens) {
|
||||
if ($token.Text -eq '--%') {
|
||||
return @{ id = $RequestId; status = 'unsupported' }
|
||||
}
|
||||
}
|
||||
|
||||
# Only accept AST shapes we can flatten into a list of argv-like command words.
|
||||
# Anything more dynamic than that becomes "unsupported" instead of being guessed at.
|
||||
$commands = [System.Collections.ArrayList]::new()
|
||||
|
||||
@@ -296,4 +296,18 @@ mod tests {
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parser_process_rejects_stop_parsing_forms() {
|
||||
let Some(powershell) = try_find_powershell_executable_blocking() else {
|
||||
return;
|
||||
};
|
||||
let powershell = powershell.as_path().to_str().unwrap();
|
||||
let mut parser = PowershellParserProcess::spawn(powershell).unwrap();
|
||||
|
||||
let parsed = parser
|
||||
.parse("git log --% HEAD --output=codex_poc.txt")
|
||||
.unwrap();
|
||||
assert_eq!(parsed, PowershellParseOutcome::Unsupported);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,6 +402,16 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_stop_parsing_git_forms() {
|
||||
assert!(!is_safe_command_windows(&vec_str(&[
|
||||
"powershell.exe",
|
||||
"-NoProfile",
|
||||
"-Command",
|
||||
"git log --% HEAD --output=codex_poc.txt",
|
||||
])));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_powershell_commands_with_side_effects() {
|
||||
assert!(!is_safe_command_windows(&vec_str(&[
|
||||
|
||||
Reference in New Issue
Block a user