mirror of
https://github.com/openai/codex.git
synced 2026-11-02 19:43:24 +00:00
Render async questions and replies with Markdown in the TUI (#57292)
## Why Async question replies appeared as plain user text, leaving Markdown formatting literal and repeating the full question above each answer. ## What changed - Accent question titles with a `?` prefix while preserving Markdown in titles and suggestions. - Render replies with a `↪ Re:` question caption and a Markdown answer. Limit captions to two rows with an ellipsis on overflow, while keeping answers complete. - Apply the same rendering to live messages and loaded transcripts, preserving inline styles, hyperlinks, and Markdown when copying selections. ## Testing Add snapshots and assertions for matching live and loaded transcript rendering, plus tests for caption clipping, hyperlink bounds, Markdown copying, partial selections, and whitespace-only or nonprinting answers. GitOrigin-RevId: 0290d8a2ebfb42bd5d7374c7037cde5ae8a13b5d
This commit is contained in:
@@ -12,7 +12,6 @@ use crate::history_cell::HistoryCell;
|
||||
use crate::history_cell::PlainHistoryCell;
|
||||
use crate::history_cell::PrefixedWrappedHistoryCell;
|
||||
use crate::history_cell::ReasoningSummaryCell;
|
||||
use crate::history_cell::UserHistoryCell;
|
||||
use crate::history_cell::split_reasoning_summary_parts;
|
||||
use crate::inline_visualization::InlineVisualizationContext;
|
||||
use crate::legacy_core::config::Config;
|
||||
@@ -252,28 +251,36 @@ fn item_to_cells(
|
||||
.collect(),
|
||||
};
|
||||
let message = item.message();
|
||||
let reply_text = crate::async_question_reply::display_text(&message);
|
||||
let text_elements = if reply_text.is_some() {
|
||||
Vec::new()
|
||||
let replies = crate::async_question_reply::parse(&message).unwrap_or_default();
|
||||
let (message, elements) = if replies.is_empty() {
|
||||
(message, item.text_elements())
|
||||
} else {
|
||||
item.text_elements()
|
||||
(
|
||||
crate::async_question_reply::display_replies(&replies),
|
||||
Vec::new(),
|
||||
)
|
||||
};
|
||||
cells.push(Arc::new(UserHistoryCell {
|
||||
presentation: Default::default(),
|
||||
message: reply_text.unwrap_or(message),
|
||||
text_elements,
|
||||
local_image_paths: item.local_image_paths(),
|
||||
remote_image_urls: item.image_urls(),
|
||||
}));
|
||||
let cell = crate::history_cell::new_user_prompt(
|
||||
message,
|
||||
elements,
|
||||
item.local_image_paths(),
|
||||
item.image_urls(),
|
||||
);
|
||||
cells.push(Arc::new(cell.with_async_replies(replies, cwd.as_path())));
|
||||
}
|
||||
ThreadItemPayload::AgentMessage { text, .. } => {
|
||||
ThreadItemPayload::AgentMessage {
|
||||
text, questions, ..
|
||||
} => {
|
||||
let parsed = parse_assistant_markdown(&text, cwd.as_path());
|
||||
if !parsed.visible_markdown.trim().is_empty() {
|
||||
cells.push(Arc::new(AgentMarkdownCell::new_with_inline_visualizations(
|
||||
parsed.visible_markdown,
|
||||
cwd.as_path(),
|
||||
inline_visualization_context,
|
||||
)));
|
||||
cells.push(Arc::new(
|
||||
AgentMarkdownCell::new_with_inline_visualizations(
|
||||
parsed.visible_markdown,
|
||||
cwd.as_path(),
|
||||
inline_visualization_context,
|
||||
)
|
||||
.with_questions(questions.as_deref().unwrap_or_default()),
|
||||
));
|
||||
}
|
||||
}
|
||||
ThreadItemPayload::FunctionCallOutput {
|
||||
|
||||
Reference in New Issue
Block a user