An experimental Markdown renderer#597
Conversation
52c62cc to
f2f1298
Compare
|
Oh yeah it also seems like I'm not getting the fancy table behavior described, it's just showing the markdown table. |
Ah, it seems to work with claude, but not codex, is the thing |
@mplanchard that's because the LLM embedded it in a code block. Ask it to give you the table without a code fences. |
eyyy yeah that does it, although the heading alignment is a bit funky
|
|
Ah thanks. I'll need to see the traffic that generated the Markdown to look into it. https://github.com/xenodium/agent-shell?tab=readme-ov-file#how-do-i-viewget-agent-client-protocol-traffic |
Good to know. I'll see if I can find a more subtle default. Having said that, the new renderer offers faces that can be overriden. |
Roger, here you go traffic output13:14:13.690 → request session/list 13:14:13.692 → request session/prompt 13:14:13.754 ← response result 13:14:15.454 ← notification session/update 13:14:15.455 ← notification session/update 13:14:15.482 ← notification session/update 13:14:15.483 ← notification session/update 13:14:15.514 ← notification session/update 13:14:15.515 ← notification session/update 13:14:15.548 ← notification session/update 13:14:15.572 ← notification session/update 13:14:15.572 ← notification session/update 13:14:15.593 ← notification session/update 13:14:15.594 ← notification session/update 13:14:15.620 ← notification session/update 13:14:15.639 ← notification session/update 13:14:15.658 ← notification session/update 13:14:15.677 ← notification session/update 13:14:15.724 ← notification session/update 13:14:15.748 ← notification session/update 13:14:15.749 ← notification session/update 13:14:15.770 ← notification session/update 13:14:15.770 ← notification session/update 13:14:15.796 ← notification session/update 13:14:15.797 ← notification session/update 13:14:15.838 ← notification session/update 13:14:15.856 ← notification session/update 13:14:15.875 ← notification session/update 13:14:15.876 ← notification session/update 13:14:15.897 ← notification session/update 13:14:15.918 ← notification session/update 13:14:15.938 ← notification session/update 13:14:15.958 ← notification session/update 13:14:15.977 ← notification session/update 13:14:15.996 ← notification session/update 13:14:16.112 ← notification session/update 13:14:16.113 ← notification session/update 13:14:16.115 ← notification session/update 13:14:16.118 ← notification session/update 13:14:16.120 ← notification session/update 13:14:16.123 ← notification session/update 13:14:16.149 ← notification session/update 13:14:16.149 ← notification session/update 13:14:16.182 ← notification session/update 13:14:16.221 ← notification session/update 13:14:16.222 ← notification session/update 13:14:16.224 ← notification session/update 13:14:16.227 ← notification session/update 13:14:16.254 ← notification session/update 13:14:16.328 ← notification session/update 13:14:16.329 ← notification session/update 13:14:16.332 ← notification session/update 13:14:16.334 ← notification session/update 13:14:16.361 ← notification session/update 13:14:16.362 ← notification session/update 13:14:16.365 ← notification session/update 13:14:16.392 ← notification session/update 13:14:16.419 ← notification session/update 13:14:16.420 ← notification session/update 13:14:16.449 ← notification session/update 13:14:16.473 ← notification session/update 13:14:16.474 ← notification session/update 13:14:16.514 ← notification session/update 13:14:16.515 ← notification session/update 13:14:16.551 ← notification session/update 13:14:16.552 ← notification session/update 13:14:16.585 ← notification session/update 13:14:16.587 ← notification session/update 13:14:16.619 ← notification session/update 13:14:16.620 ← notification session/update 13:14:16.657 ← notification session/update 13:14:16.659 ← notification session/update 13:14:16.682 ← notification session/update 13:14:16.683 ← notification session/update 13:14:16.713 ← notification session/update 13:14:16.713 ← notification session/update 13:14:16.748 ← notification session/update 13:14:16.773 ← notification session/update 13:14:16.793 ← notification session/update 13:14:16.935 ← notification session/update 13:14:16.936 ← notification session/update 13:14:16.948 ← notification session/update 13:14:16.952 ← notification session/update 13:14:16.956 ← notification session/update 13:14:16.960 ← notification session/update 13:14:16.963 ← notification session/update 13:14:16.967 ← notification session/update 13:14:16.996 ← notification session/update 13:14:16.997 ← notification session/update 13:14:17.000 ← notification session/update 13:14:17.037 ← notification session/update 13:14:17.037 ← notification session/update 13:14:17.041 ← notification session/update 13:14:17.045 ← notification session/update 13:14:17.068 ← notification session/update 13:14:17.090 ← notification session/update 13:14:17.112 ← notification session/update 13:14:17.114 ← notification session/update 13:14:17.144 ← notification session/update 13:14:17.173 ← notification session/update 13:14:17.175 ← notification session/update 13:14:17.217 ← notification session/update 13:14:17.258 ← notification session/update 13:14:17.286 ← notification session/update 13:14:17.287 ← notification session/update 13:14:17.397 ← notification session/update 13:14:17.403 ← notification session/update 13:14:17.430 ← notification session/update 13:14:17.431 ← notification session/update 13:14:17.435 ← notification session/update 13:14:17.439 ← notification session/update 13:14:17.443 ← notification session/update 13:14:17.447 ← notification session/update 13:14:17.451 ← notification session/update 13:14:17.455 ← notification session/update 13:14:17.491 ← notification session/update 13:14:17.492 ← notification session/update 13:14:17.495 ← notification session/update 13:14:17.526 ← notification session/update 13:14:17.528 ← notification session/update 13:14:17.532 ← notification session/update 13:14:17.557 ← notification session/update 13:14:17.559 ← notification session/update 13:14:17.583 ← notification session/update 13:14:17.715 ← notification session/update 13:14:17.717 ← notification session/update 13:14:17.722 ← notification session/update 13:14:17.725 ← notification session/update 13:14:17.729 ← notification session/update 13:14:17.767 ← notification session/update 13:14:17.768 ← notification session/update 13:14:17.772 ← notification session/update 13:14:17.777 ← notification session/update 13:14:17.781 ← notification session/update 13:14:17.813 ← notification session/update 13:14:17.815 ← notification session/update 13:14:17.840 ← notification session/update 13:14:17.864 ← notification session/update 13:14:17.866 ← notification session/update 13:14:17.870 ← notification session/update 13:14:17.915 ← notification session/update 13:14:17.916 ← notification session/update 13:14:17.947 ← notification session/update 13:14:17.948 ← notification session/update 13:14:18.087 ← notification session/update 13:14:18.089 ← notification session/update 13:14:18.094 ← notification session/update 13:14:18.100 ← notification session/update 13:14:18.105 ← notification session/update 13:14:18.109 ← notification session/update 13:14:18.114 ← notification session/update 13:14:18.119 ← notification session/update 13:14:18.152 ← notification session/update 13:14:18.153 ← notification session/update 13:14:18.156 ← notification session/update 13:14:18.195 ← notification session/update 13:14:18.196 ← notification session/update 13:14:18.224 ← notification session/update 13:14:18.226 ← notification session/update 13:14:18.231 ← notification session/update 13:14:18.384 ← notification session/update 13:14:18.387 ← notification session/update 13:14:18.392 ← notification session/update 13:14:18.398 ← notification session/update 13:14:18.403 ← notification session/update 13:14:18.469 ← response result 13:14:18.475 → request session/list 13:14:18.540 ← response result full shell outputCodex> same output but not in a code block ▼ Notices |
|
thanks! almost there... The buffer that has this: Press C-x C-s (acp-traffic-save-to) to get the actual content of each one of those items |
|
Oh lol, yeah, I thought that output didn't seem very useful. It's okay, one of these days I'll learn to read. weird that GH doesn't let you upload |
|
Thanks that helps. Made some changes. Mind trying it out and see if you still have issues with headers on Codex? |
- avoid-ranges is now a sorted vector; --in-avoid-range-p does binary search and returns the containing range. - --replace-* passes use that return value to jump past avoid-ranges instead of re-matching inside them. - --find-tables skips avoid-ranges in one hop and uses forward-line 1 between non-matches (table regex is bol-anchored).
Skip re-rendering already-processed prefix on each call Streaming use of `agent-shell-markdown-replace-markup' calls the renderer once per chunk, so every pass was re-walking the entire buffer from `point-min' on each call — O(N^2) over N chunks. Track a per-buffer "watermark": the position before which content is fully rendered and stable. Stored as an `agent-shell-markdown-watermark' text property on the first character (so a propertized string returned from `agent-shell-markdown-convert' carries it without a buffer-local variable). Re-stamped at the end of each render to: - start of the last line in the buffer; clamped back to - start of any open fence (so a future closing ``` still matches), - start of any rendered table whose extension is still possible (so streamed continuation rows still fold in). The next call narrows to (watermark, point-max) and every pass runs inside the narrow. `:force' on `agent-shell-markdown-replace-markup' drops the watermark and re-renders the whole buffer.
|
Awesome. Thanks for reporting back! |



Experimenting with inline text properties to render Markdown text into agent-shell buffers.
agent-shell's Markdown renderer today is powered by overlays. While overlays have served us well for some time, they have some limitations, primarily around performance (so far has been good enough-ish) but also with text navigation/selection.
This branch is an experiment to see if we can achieve an improved experience around Markdown rendering using inlined text properties (no overlays).
Two initial areas of focus:
Table navigation and content selection (not currently possible in today's overlay implementaion)
Cell navigation
M-x agent-shell-markdown-table-next-cellM-x agent-shell-markdown-table-previous-cellMore performant code block rendering
Enabling experimental renderer
To try out the experimental renderer in this branch use:
Report bugs
This is fairly experimental, so please do report bugs.