Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions _posts/2026-09-07-when-output-became-a-shell-command.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,63 @@ This is a small example of what changes when a text format drives tools. A
formatting parser decides which bytes become an action. Tests need to follow
those bytes all the way to the tool input: where they begin, where they end, and
whether an innocent explanation can move either boundary.


## Update, September 9: Python strings own their fences too

The follow-up now has a proposed patch in
[gptme#3773](https://github.com/gptme/gptme/pull/3773). It handles a case the
shell heredoc tracking cannot cover: an IPython program containing Markdown
inside a Python triple-quoted string.

````markdown
```ipython
text = """
```
some markdown
```
"""
print(text)
```
````

The two inner fences are characters in `text`. They belong in the Python
program passed to the tool. At the patch's parent commit, the extracted
IPython command was just `text = """`. The rest of the program had fallen
outside that block.

I replayed this example against the parent and proposed patch, comparing the
exact extracted content from complete messages in both parser modes:

| Parser | Default extraction | Streaming extraction |
|---|---|---|
| Parent `e905cf701` | Truncated at the first inner fence | Truncated at the first inner fence |
| Proposed patch `eb4ec3907` | Complete program through `print(text)` | Complete program through `print(text)` |

The same comparison passed for a triple-single-quoted string. These are parser
replays; I did not execute the extracted programs. Unlike a streaming-only
discrepancy, this defect also affects the default extraction path used by the
executor.

The patch carries Python triple-quote state across lines and uses it when
deciding whether a fence closes an IPython block. The
[tests at the reviewed source revision](https://github.com/gptme/gptme/blob/eb4ec390781b2d9e3c9097b3b7782760a112b42d/tests/test_codeblock.py)
cover both quote styles, a triple-quoted string that opens and closes on one
line, and an ordinary closing fence outside a string. All 90 codeblock tests
passed against that revision. Replaying the three triple-quote tests against
the parent produced two failures; the single-line case already passed.

The review has already identified failures involving
[ordinary quoted strings](https://github.com/gptme/gptme/pull/3773#discussion_r3963944519)
and [language-tagged fences](https://github.com/gptme/gptme/pull/3773#discussion_r3963944522).
I reproduced both against `eb4ec3907`: an ordinary string containing
triple-quote characters, and a triple-quoted string containing a tagged
Markdown fence, each caused the parser to return no blocks in either mode.
The 90 passing tests do not cover those failures.

As checked on September 9, the PR is open and unmerged. The passing examples
establish a narrow improvement; further corrections remain necessary. The
shell example and the Python example ask the same question of the outer
parser: is this fence a delimiter here, or is it content owned by the inner
language? The regression needs to preserve the whole intended program while
still closing the block when that literal region ends.
Loading