mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-10-09 04:42:30 -04:00
agent: don't drop REPL tool lines or cut result text mid-codepoint
In a REPL whose stderr isn't a tty the spinner is disabled, so `agentToolDone`'s `emitAbove` returned false and the `● [tool: …]` line was discarded. `printToolOutcome` already fell back to a raw stderr write in that case; share that fallback through `emitStderr`. The non-REPL result line sliced `text` at a byte offset, which could split a multi-byte codepoint and emit garbage. Truncate on a UTF-8 boundary instead.
This commit is contained in:
1 parent
dbe6271479
commit
9b7225b580
1 file changed
+11
-5
+11
-5
@@ -18,6 +18,7 @@
|
||||
|
||||
const std = @import("std");
|
||||
const lp = @import("lightpanda");
|
||||
const string = @import("../string.zig");
|
||||
const Config = lp.Config;
|
||||
const Schema = lp.Schema;
|
||||
const SlashCommand = @import("SlashCommand.zig");
|
||||
@@ -117,7 +118,7 @@ pub fn agentToolDone(self: *Terminal, name: []const u8, args: []const u8, ok: bo
|
||||
const a = if (self.repl_arena) |*ra| ra else return;
|
||||
defer _ = a.reset(.retain_capacity);
|
||||
const bytes = formatBulletLine(a.allocator(), name, args, ok) catch return;
|
||||
_ = self.spinner.emitAbove(bytes);
|
||||
self.emitStderr(bytes);
|
||||
return;
|
||||
}
|
||||
if (self.stderr_is_tty) {
|
||||
@@ -131,6 +132,13 @@ pub fn agentToolDone(self: *Terminal, name: []const u8, args: []const u8, ok: bo
|
||||
}
|
||||
}
|
||||
|
||||
/// Commit a finished line above the spinner, or straight to stderr when the
|
||||
/// spinner isn't running (non-tty REPL) so the line isn't silently dropped.
|
||||
fn emitStderr(self: *Terminal, bytes: []const u8) void {
|
||||
if (self.spinner.emitAbove(bytes)) return;
|
||||
_ = std.c.write(std.posix.STDERR_FILENO, bytes.ptr, bytes.len);
|
||||
}
|
||||
|
||||
fn formatBulletLine(arena: std.mem.Allocator, name: []const u8, args: []const u8, ok: bool) ![]const u8 {
|
||||
var aw: std.Io.Writer.Allocating = .init(arena);
|
||||
const w = &aw.writer;
|
||||
@@ -286,12 +294,10 @@ pub fn printToolOutcome(self: *Terminal, name: []const u8, text: []const u8, is_
|
||||
if (self.repl_arena) |*a| {
|
||||
defer _ = a.reset(.retain_capacity);
|
||||
const bytes = formatReplOutcome(a.allocator(), text, is_error) catch return;
|
||||
if (self.spinner.emitAbove(bytes)) return;
|
||||
_ = std.c.write(std.posix.STDERR_FILENO, (bytes).ptr, (bytes).len);
|
||||
return;
|
||||
return self.emitStderr(bytes);
|
||||
}
|
||||
if (!is_error and !self.verbosity.atLeast(.medium)) return;
|
||||
const truncated = text[0..@min(text.len, max_result_display_len)];
|
||||
const truncated = string.truncateUtf8(text, max_result_display_len);
|
||||
const ellipsis: []const u8 = if (text.len > max_result_display_len) "..." else "";
|
||||
const color: []const u8 = if (is_error) ansi.red else ansi.green;
|
||||
std.debug.print("{s}{s}[result: {s}]{s} {s}{s}\n", .{ ansi.dim, color, name, ansi.reset, truncated, ellipsis });
|
||||
|
||||
Reference in new issue
Block a user