fix(daemon): present a captured engine's stdout as a pseudo-terminal - #245
Merged
Merged
Conversation
added 4 commits
September 25, 2026 04:36
…minal The serve view and the daemon capture the engine's output to a log file, so an engine that gates terminal-only output on stdout being a terminal llama.cpp's model download progress among them produces none of it. The proposal presents the captured engine's stdout as a pseudo-terminal and records redrawing lines as their state.
llama.cpp prints a download's progress only when stdout is a terminal, so under the capture — stdout pointed at the log file — a model download is silent. The pseudo-terminal makes the engine produce the output, and a pump normalises the terminal stream into the log's lines: a redrawing line recorded as its state, first and final always and a further distinct state at most once per two seconds, no escape sequences reaching the log.
An engine that moves onto a line it has already written and writes there without a carriage return rewrites the line the way the terminal shows it; the normaliser was extending the content the line held. The move now settles the state the line draws, and the next write starts a new state of the line. The change also closes the package's remaining coverage gaps: the escape sequences the engines may send, the no-pseudo-terminal fallback, the pump's end-of-stream drain, and the supervisor's refused starts.
The maintainer internals gains the capture's rationale: the normaliser's line model and the rules a 'simplification' would break, the NO_COLOR rule, and the fallback the tests keep alive.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A model download is silent in the engine log, because the engine only draws its progress to a terminal.
Summary
NO_COLOR=1so its log lines do not reach the file coloured through the stderr pathserveandserve --apiforward the engine's output byte-for-byte as before: no pseudo-terminal, no normaliser, noNO_COLORImplementation details
The normaliser (
internal/daemon/ptylog.go) keeps the terminal's lines as a column and records the states of the ones the engine redraws, rather than emulating a screen. The engine's up-down cursor dance is part of each redraw, so a cursor move moves the drawing between the column's lines and never ends one; a state's replacement is deferred to the next text byte; and a half-rate tick records a pending state on every line, because a bar's last state outlives the engine's move off its line. The pump always drains the master so the engine can never wedge on a full terminal, and the log file closes only after the pump's final record.The change is specified in
openspec/changes/engine-pty-log-capture/and its rationale indocs/maintainer/internals.md.Fixes #226