mirror of
https://github.com/openai/codex.git
synced 2026-10-27 18:48:37 +00:00
Include completed commentary in the /copy picker (#43846)
## Why During an active turn, `/copy` could still offer the previous final response even after a new commentary message had completed. ## What changed Record every completed agent message with non-empty visible Markdown for copying, including commentary. The picker can then offer the latest completed commentary as a whole response and expose its code blocks. ## Testing Add a regression test and picker snapshot covering completed commentary during an active turn after a previous final response. Verify that selecting “Whole response” copies the commentary and that the picker lists its shell code block. GitOrigin-RevId: 0ea1d5e3952ccac21f2ee951d482619de82f28e0
This commit is contained in:
committed by
copyberry
parent
b090e901f8
commit
dd9512c000
@@ -355,9 +355,7 @@ impl ChatWidget {
|
||||
} else {
|
||||
self.finalize_completed_assistant_message(Some(parsed.visible_markdown.as_str()));
|
||||
}
|
||||
if matches!(item.phase, Some(MessagePhase::FinalAnswer) | None)
|
||||
&& !parsed.visible_markdown.is_empty()
|
||||
{
|
||||
if !parsed.visible_markdown.is_empty() {
|
||||
self.transcript
|
||||
.record_agent_markdown(parsed.visible_markdown.clone(), message);
|
||||
}
|
||||
|
||||
@@ -1840,6 +1840,40 @@ async fn slash_copy_state_tracks_turn_complete_final_reply() {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn slash_copy_picker_uses_completed_commentary_during_active_turn() {
|
||||
let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;
|
||||
complete_turn_with_message(&mut chat, "turn-1", Some("Previous final response"));
|
||||
handle_turn_started(&mut chat, "active");
|
||||
let commentary = "Here is the command:\n\n```sh\necho current\n```";
|
||||
let current_thread_id = chat.thread_id.map(|id| id.to_string()).unwrap_or_default();
|
||||
chat.handle_server_notification(
|
||||
ServerNotification::ItemCompleted(ItemCompletedNotification {
|
||||
thread_id: current_thread_id,
|
||||
turn_id: "active".to_string(),
|
||||
completed_at_ms: 0,
|
||||
item: AppServerThreadItem::AgentMessage {
|
||||
id: "active-commentary".to_string(),
|
||||
text: commentary.to_string(),
|
||||
phase: Some(MessagePhase::Commentary),
|
||||
memory_citation: None,
|
||||
delivery: None,
|
||||
questions: None,
|
||||
},
|
||||
}),
|
||||
/*replay_kind*/ None,
|
||||
);
|
||||
while rx.try_recv().is_ok() {}
|
||||
|
||||
chat.dispatch_command(SlashCommand::Copy);
|
||||
insta::assert_snapshot!(render_bottom_popup(&chat, /*width*/ 80));
|
||||
chat.handle_key_event(KeyEvent::new(KeyCode::Char('1'), KeyModifiers::NONE));
|
||||
assert_eq!(
|
||||
next_copy_selection(&mut rx),
|
||||
(commentary.to_string(), "Whole response".to_string(),)
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn slash_copy_state_tracks_plan_item_completion() {
|
||||
let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
---
|
||||
source: tui/src/chatwidget/tests/slash_commands.rs
|
||||
expression: "render_bottom_popup(&chat, 80)"
|
||||
---
|
||||
Copy to clipboard
|
||||
|
||||
› 1. Whole response Here is the command:
|
||||
2. sh code echo current
|
||||
|
||||
Press enter to confirm or esc to go back
|
||||
@@ -38,7 +38,7 @@ pub(super) struct TranscriptState {
|
||||
pub(super) active_cell_revision: u64,
|
||||
/// One bounded entry shared by layout and paint across unchanged active-cell frames.
|
||||
pub(super) active_cell_layout: Cell<Option<ActiveCellLayoutCache>>,
|
||||
/// Markdown of the most recently completed agent response for whole-response copying.
|
||||
/// Markdown of the most recently completed agent message for whole-response copying.
|
||||
pub(super) last_agent_markdown: Option<String>,
|
||||
/// Original source of that response, before display sanitization, for exact block copying.
|
||||
pub(super) last_agent_source: Option<String>,
|
||||
|
||||
Reference in New Issue
Block a user