perf(console): tail-cap large RPC results without a full copy
A large RPC result was fully split into lines and copied before being handed to the console, even though only the last few lines could survive the model's line cap. - The formatter now takes a line cap and keeps only the last N lines, located by a backward newline scan, so a huge result is never fully split or copied. JSON classification still keys off the first character of the whole result. - It works over a string view and moves line text through, and fold spans are computed over the formatted lines directly instead of a separate vector of copies. - getline semantics are preserved: a trailing newline adds no empty line and an empty result yields no lines. Tests: getline parity for empty, trailing-newline and blank-line inputs, the backward tail cap, and JSON classification and fold spans over a capped result. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2052,15 +2052,15 @@ void ConsoleTab::renderCommandsPopup(ConsoleCommandExecutor& exec)
|
||||
|
||||
void ConsoleTab::addFormattedResult(const std::string& result, bool is_error)
|
||||
{
|
||||
const std::vector<ConsoleResultLine> resultLines = FormatConsoleRpcResultLines(result, is_error);
|
||||
// Only the last maxLines lines can survive the model's cap, so a huge result is tail-capped
|
||||
// up front instead of being fully split and copied.
|
||||
std::vector<ConsoleResultLine> resultLines =
|
||||
FormatConsoleRpcResultLines(result, is_error, model_.maxLines());
|
||||
|
||||
// Precompute JSON fold spans over the whole block so each opener line carries the offset
|
||||
// to its matching closer (the spans are relative, so they stay valid as the model's line
|
||||
// cap evicts from the front). The block is ingested under one lock (ingestBatch).
|
||||
std::vector<std::string> texts;
|
||||
texts.reserve(resultLines.size());
|
||||
for (const auto& rl : resultLines) texts.push_back(rl.text);
|
||||
const std::vector<int> foldSpans = ComputeConsoleFoldSpans(texts);
|
||||
const std::vector<int> foldSpans = ComputeConsoleResultFoldSpans(resultLines);
|
||||
|
||||
std::vector<ConsoleModelLine> block;
|
||||
block.reserve(resultLines.size());
|
||||
@@ -2075,7 +2075,7 @@ void ConsoleTab::addFormattedResult(const std::string& result, bool is_error)
|
||||
case ConsoleResultLineRole::Result: break;
|
||||
}
|
||||
ConsoleModelLine ml;
|
||||
ml.text = resultLines[i].text;
|
||||
ml.text = std::move(resultLines[i].text);
|
||||
ml.channel = channel;
|
||||
ml.foldSpan = foldSpans[i];
|
||||
block.push_back(std::move(ml));
|
||||
|
||||
Reference in New Issue
Block a user