Render assistant file citations as local links (#42650)

## What changed

- Convert `codex-file-citation` directives in assistant Markdown into local-file links while preserving paths with Markdown-significant characters, Unicode, Windows separators, and location suffixes.
- Apply citation rendering consistently to streaming output, finalized messages and plans, and resume-picker transcript previews.
- Keep directives literal in code, HTML, existing links, reference definitions, escaped text, and generic Markdown rendering.
- Bound repeated parsing work for malformed directive candidates without limiting valid citations.

## Testing

- Add coverage for citation parsing and rendering across finalized, streaming, and resume-preview output, including malformed input and path edge cases.

GitOrigin-RevId: 5a0bfb3fc7ac21b7e8846fd170a349fb2d2d5e85
This commit is contained in:
Ian MacLeod
2026-09-04 01:46:55 +00:00
committed by copyberry
parent 956aa3f637
commit f46671b14a
13 changed files with 635 additions and 22 deletions
@@ -5,6 +5,7 @@
use super::DecodedTextMerge;
use super::Event;
use super::FileCitations;
use super::HyperlinkLine;
use super::Options;
use super::Parser;
@@ -38,10 +39,11 @@ pub(crate) fn render_streaming_markdown_lines_with_width_and_cwd(
let mut options = Options::empty();
options.insert(Options::ENABLE_STRIKETHROUGH);
options.insert(Options::ENABLE_TABLES);
let parser = Parser::new_ext(input, options);
let citations = FileCitations::new(input, options);
let parser = Parser::new_ext(&citations.markdown, options);
let has_reference_link_definition = parser.reference_definitions().iter().next().is_some();
let parser = TopLevelBlockTracker {
iter: DecodedTextMerge::new(parser.into_offset_iter()),
iter: DecodedTextMerge::new(citations.events(parser, cwd)),
depth: 0,
block_count: 0,
last_start: 0,