Something went wrong. Try again.
My version of https://github.com/vercel-labs/fx
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509const std = @import("std");const builtin = @import("builtin");const command_policy = @import("command_policy.zig");const managed_execution = @import("../execution/managed_execution.zig");const file_mutation_contract = @import("file_mutation_contract.zig");const mem_utils = @import("../shared/mem_utils.zig");const text_utils = @import("../shared/text_utils.zig");const tool_args = @import("tool_args.zig");const tool_dispatch = @import("tool_dispatch.zig");const terminal_contracts = @import("../terminal/contracts.zig");const terminal_client_runtime = @import("../terminal/client.zig");const terminal_ui_projection = @import("../terminal/ui_projection.zig");const types = @import("../shared/types.zig");const test_builtin_tools = if (builtin.is_test) @import("../../builtins/tools.zig")else struct {};
const Allocator = std.mem.Allocator;const ToolCall = types.ToolCall;const max_run_command_activity_bytes = 120;const max_run_command_activity_source_bytes = max_run_command_activity_bytes * max_run_command_activity_bytes;pub const max_run_command_reflow_bytes = max_run_command_activity_source_bytes;
pub const ToolActionInput = struct { tool_registry: tool_dispatch.Registry, call: ToolCall, workspace_root: []const u8 = "", display_target: ?[]const u8 = null, is_available_dynamic_mcp_tool: bool = false,};
pub const SubagentActionState = union(enum) { identity, active, pending, completed, feedback: types.SteeringDelivery, stopped: []const u8,};
pub const SubagentAction = struct { label: []u8, detail: []u8,
pub fn deinit(self: SubagentAction, alloc: Allocator) void { alloc.free(self.label); alloc.free(self.detail); }};
/// The caller owns the returned label and detail. Invalid requests have no projection.pub fn subagentAction( alloc: Allocator, call: ToolCall, state: SubagentActionState,) Allocator.Error!?SubagentAction { if (!std.mem.eql(u8, call.name, "subagent")) return null; var scratch_state = std.heap.ArenaAllocator.init(alloc); defer mem_utils.deinit_arena(scratch_state); const scratch = scratch_state.allocator(); const outer = tool_args.parseToolArgsObject(scratch, call.arguments_json) catch |err| return switch (err) { error.OutOfMemory => error.OutOfMemory, else => null, }; const args = if (outer.get("request")) |request| switch (request) { .object => |object| object, else => return null, } else outer; const action = tool_args.optionalStringArg(args, "action") orelse return null; const named = std.mem.eql(u8, action, "message"); if (!named and !std.mem.eql(u8, action, "run")) return null; if (state == .feedback and !named) return null; const raw_name = if (named) tool_args.optionalStringArg(args, "agent") orelse return null else "Subagent"; const raw_preview = tool_args.optionalStringArg(args, if (named) "message" else "task") orelse return null; const name = try text_utils.encodeTerminalSafe(scratch, raw_name, 64); const preview = try subagentPreview(scratch, raw_preview); const label = switch (state) { .identity => try alloc.dupe(u8, name.bytes), .active => try std.fmt.allocPrint(alloc, "{s} working", .{name.bytes}), .pending => try std.fmt.allocPrint(alloc, "{s} still running", .{name.bytes}), .completed => try std.fmt.allocPrint(alloc, "{s} {s}", .{ name.bytes, if (named) "replied" else "finished" }), .feedback => |delivery| try std.fmt.allocPrint(alloc, "{s} feedback {s}", .{ name.bytes, switch (delivery) { .queued => "queued", .applied => "applied", .not_applied => "not applied", } }), .stopped => |reason| if (std.mem.eql(u8, reason, "Failed")) try std.fmt.allocPrint(alloc, "{s} failed", .{name.bytes}) else if (std.mem.eql(u8, reason, "Busy")) try std.fmt.allocPrint(alloc, "{s} busy; message not sent", .{name.bytes}) else if (std.mem.eql(u8, reason, "Cancelled") or std.mem.eql(u8, reason, "Interrupted")) try std.fmt.allocPrint(alloc, "{s} interrupted", .{name.bytes}) else try std.fmt.allocPrint(alloc, "{s} {s}", .{ reason, name.bytes }), }; errdefer alloc.free(label); const detail = if (preview.len == 0) try alloc.dupe(u8, "") else try std.fmt.allocPrint(alloc, "· {s}", .{preview}); return .{ .label = label, .detail = detail };}
fn subagentPreview(alloc: Allocator, raw: []const u8) Allocator.Error![]u8 { var buffer: [124]u8 = undefined; var len: usize = 0; var pending_space = false; // Bound scanning even when a large request contains only whitespace. const source = raw[0..text_utils.utf8BackwardBoundary(raw, @min(raw.len, 16 * 1024))]; for (source) |byte| { if (std.ascii.isWhitespace(byte)) { pending_space = len > 0; continue; } if (pending_space) { buffer[len] = ' '; len += 1; pending_space = false; } if (len == buffer.len) break; buffer[len] = byte; len += 1; if (len == buffer.len) break; } const encoded = try text_utils.encodeTerminalSafe(alloc, buffer[0..len], 120); return encoded.bytes;}
pub fn subagentStatusLine(alloc: Allocator, call: ToolCall, output: []const u8) Allocator.Error!?[]u8 { if (!std.mem.eql(u8, call.name, "subagent")) return null; var parsed = std.json.parseFromSlice(std.json.Value, alloc, output, .{}) catch |err| return switch (err) { error.OutOfMemory => error.OutOfMemory, else => null, }; defer parsed.deinit(); if (parsed.value != .object) return null; if (tool_args.optionalStringArg(parsed.value.object, "delivery")) |value| { const delivery = std.meta.stringToEnum(types.SteeringDelivery, value) orelse return null; const ok = parsed.value.object.get("ok") orelse return null; if (ok != .bool or ok.bool != (delivery != .not_applied)) return null; return formatSubagentPlainAction(alloc, call, .{ .feedback = delivery }); } const pending = parsed.value.object.get("pending") orelse return null; if (pending != .bool or !pending.bool) return null; const ok = parsed.value.object.get("ok") orelse return null; if (ok != .bool or !ok.bool) return null; return formatSubagentPlainAction(alloc, call, .pending);}
/// Only structured child terminal failures change the failure label.pub fn subagentFailureLabel(alloc: Allocator, call: ToolCall, output: []const u8) Allocator.Error![]const u8 { if (!std.mem.eql(u8, call.name, "subagent")) return "Failed"; var parsed = std.json.parseFromSlice(std.json.Value, alloc, output, .{}) catch |err| return switch (err) { error.OutOfMemory => error.OutOfMemory, else => "Failed", }; defer parsed.deinit(); if (parsed.value != .object) return "Failed"; const ok = parsed.value.object.get("ok") orelse return "Failed"; if (ok != .bool or ok.bool) return "Failed"; const code = tool_args.optionalStringArg(parsed.value.object, "error_code") orelse return "Failed"; if (std.mem.eql(u8, code, "child_busy")) return "Busy"; for ([_][]const u8{ "feedback_capacity", "operation_conflict", "override_after_create" }) |rejection| { if (std.mem.eql(u8, code, rejection)) return "Message not sent to"; } return if (std.mem.eql(u8, code, "child_cancelled") or std.mem.eql(u8, code, "child_interrupted")) "Interrupted" else "Failed";}
test "subagent pending result does not claim completion" { const alloc = std.testing.allocator; const call = ToolCall{ .id = "call", .name = "subagent", .arguments_json = "{\"action\":\"run\",\"task\":\"work\"}" }; const line = (try subagentStatusLine(alloc, call, "{\"ok\":true,\"pending\":true}")).?; defer alloc.free(line); try std.testing.expectEqualStrings("Subagent still running · work", line); try std.testing.expect((try subagentStatusLine(alloc, call, "{\"ok\":true,\"result\":\"done\"}")) == null);}
test "subagent rows project request identity state and bounded safe previews" { const alloc = std.testing.allocator; const cases = [_]struct { args: []const u8, state: SubagentActionState, label: []const u8, detail: []const u8 }{ .{ .args = "{\"request\":{\"action\":\"run\",\"task\":\" Check\\n cancellation\\tcleanup \"}}", .state = .active, .label = "Subagent working", .detail = "· Check cancellation cleanup" }, .{ .args = "{\"action\":\"run\",\"task\":\"Check cleanup\"}", .state = .completed, .label = "Subagent finished", .detail = "· Check cleanup" }, .{ .args = "{\"request\":{\"action\":\"message\",\"agent\":\"reviewer\",\"message\":\"Check replay\",\"instructions\":\"Never display this\"}}", .state = .completed, .label = "reviewer replied", .detail = "· Check replay" }, .{ .args = "{\"action\":\"message\",\"agent\":\"reviewer\",\"message\":\"Check again\"}", .state = .{ .stopped = "Failed" }, .label = "reviewer failed", .detail = "· Check again" }, .{ .args = "{\"action\":\"message\",\"agent\":\"reviewer\",\"message\":\"Check again\"}", .state = .{ .stopped = "Cancelled" }, .label = "reviewer interrupted", .detail = "· Check again" }, .{ .args = "{\"action\":\"run\",\"task\":\"Check again\"}", .state = .{ .stopped = "Denied" }, .label = "Denied Subagent", .detail = "· Check again" }, }; for (cases) |case| { const action = (try subagentAction(alloc, .{ .id = "child", .name = "subagent", .arguments_json = case.args }, case.state)).?; defer action.deinit(alloc); try std.testing.expectEqualStrings(case.label, action.label); try std.testing.expectEqualStrings(case.detail, action.detail); } for ([_][]const u8{ "{", "[]", "{\"request\":null}", "{\"action\":\"inspect\"}", "{\"action\":\"message\",\"message\":\"hello\"}" }) |args| { try std.testing.expectEqual(@as(?SubagentAction, null), try subagentAction(alloc, .{ .id = "child", .name = "subagent", .arguments_json = args }, .active)); } const unsafe = (try subagentAction(alloc, .{ .id = "child", .name = "subagent", .arguments_json = "{\"action\":\"message\",\"agent\":\"a\\u001b[2J\",\"message\":\"Check 日本語\\u001b[31m\"}" }, .active)).?; defer unsafe.deinit(alloc); try std.testing.expect(text_utils.isTerminalSafe(unsafe.label)); try std.testing.expect(text_utils.isTerminalSafe(unsafe.detail)); try std.testing.expect(std.mem.find(u8, unsafe.detail, "日本語") != null); const long = try subagentPreview(alloc, "日本語" ** 100); defer alloc.free(long); try std.testing.expect(long.len <= 120); try std.testing.expect(text_utils.isTerminalSafe(long)); try std.testing.expect(std.mem.endsWith(u8, long, "..."));}
test "subagent failure labels trust structured terminal codes only" { const alloc = std.testing.allocator; const call: ToolCall = .{ .id = "child", .name = "subagent", .arguments_json = "{}" }; try std.testing.expectEqualStrings("Interrupted", try subagentFailureLabel(alloc, call, "{\"ok\":false,\"error_code\":\"child_interrupted\"}")); try std.testing.expectEqualStrings("Interrupted", try subagentFailureLabel(alloc, call, "{\"ok\":false,\"error_code\":\"child_cancelled\"}")); for ([_][]const u8{ "child_interrupted", "{", "<tool_result_preview>child_interrupted</tool_result_preview>", "{\"ok\":true,\"error_code\":\"child_interrupted\"}", "{\"ok\":false,\"error_code\":\"child_failed\"}" }) |output| { try std.testing.expectEqualStrings("Failed", try subagentFailureLabel(alloc, call, output)); }}
test "subagent receipts describe message delivery rather than child completion" { const alloc = std.testing.allocator; const call: ToolCall = .{ .id = "feedback", .name = "subagent", .arguments_json = "{\"request\":{\"action\":\"message\",\"agent\":\"reviewer\",\"message\":\"check this\"}}" }; for ([_]struct { output: []const u8, label: []const u8 }{ .{ .output = "{\"ok\":true,\"delivery\":\"queued\"}", .label = "reviewer feedback queued · check this" }, .{ .output = "{\"ok\":true,\"delivery\":\"applied\"}", .label = "reviewer feedback applied · check this" }, .{ .output = "{\"ok\":false,\"delivery\":\"not_applied\"}", .label = "reviewer feedback not applied · check this" }, }) |case| { const line = (try subagentStatusLine(alloc, call, case.output)).?; defer alloc.free(line); try std.testing.expectEqualStrings(case.label, line); } try std.testing.expect((try subagentStatusLine(alloc, call, "{\"ok\":false,\"delivery\":\"queued\"}")) == null); try std.testing.expect((try subagentStatusLine(alloc, call, "{\"ok\":false,\"pending\":true}")) == null); try std.testing.expectEqualStrings("Busy", try subagentFailureLabel(alloc, call, "{\"ok\":false,\"error_code\":\"child_busy\"}"));}
/// The caller owns the returned plain subagent row.pub fn formatSubagentPlainAction(alloc: Allocator, call: ToolCall, state: SubagentActionState) Allocator.Error!?[]u8 { const action = try subagentAction(alloc, call, state) orelse return null; defer action.deinit(alloc); return try std.fmt.allocPrint(alloc, "{s}{s}{s}", .{ action.label, if (action.detail.len == 0) "" else " ", action.detail });}
pub const RunCommandActivity = struct { detail: []const u8, compatibility_tool: ?*const tool_dispatch.Tool,};
pub fn isProviderSearchAlias(name: []const u8) bool { return std.mem.eql(u8, name, "exa_search") or std.mem.eql(u8, name, "perplexity_search") or std.mem.eql(u8, name, "parallel_search");}
fn projectRunCommandActivitySource( command: []const u8, workspace_root_input: []const u8, storage: []u8,) []const u8 { const display_command = stripNoopCurrentDirectoryPrefix(command); var workspace_root_end = workspace_root_input.len; while (workspace_root_end > 1 and workspace_root_input[workspace_root_end - 1] == '/') { workspace_root_end -= 1; } const workspace_root = workspace_root_input[0..workspace_root_end]; const can_abbreviate_workspace = workspace_root.len > 1 and workspace_root[0] == '/'; const source_limit = @min(display_command.len, max_run_command_activity_source_bytes); var source_index: usize = 0; var projected_len: usize = 0; var line_boundary_pending = false;
while (source_index < source_limit) { const byte = display_command[source_index]; if (byte == '\r' or byte == '\n') { line_boundary_pending = true; source_index += 1; continue; } if (line_boundary_pending and (byte == ' ' or byte == '\t')) { source_index += 1; continue; } if (line_boundary_pending) { line_boundary_pending = false; if (projected_len > 0) { storage[projected_len] = ' '; projected_len += 1; if (projected_len == storage.len) break; } }
if (can_abbreviate_workspace and workspace_root.len <= source_limit - source_index and workspaceRootMatchesAt(display_command, workspace_root, source_index)) { storage[projected_len] = '.'; projected_len += 1; if (projected_len == storage.len) break; source_index += workspace_root.len; continue; }
storage[projected_len] = byte; projected_len += 1; if (projected_len == storage.len) break; source_index += 1; }
return storage[0..projected_len];}
fn stripNoopCurrentDirectoryPrefix(command: []const u8) []const u8 { const prefix = "cd . &&"; if (!std.mem.startsWith(u8, command, prefix)) return command; if (command.len == prefix.len or !std.ascii.isWhitespace(command[prefix.len])) return command;
const remainder = std.mem.trimStart(u8, command[prefix.len..], " \t\r\n"); return if (remainder.len > 0) remainder else command;}
fn workspaceRootMatchesAt(command: []const u8, workspace_root: []const u8, index: usize) bool { if (!std.mem.startsWith(u8, command[index..], workspace_root)) return false; if (index > 0 and isPathTokenByte(command[index - 1])) return false;
const next_index = index + workspace_root.len; if (next_index == command.len) return true; return command[next_index] == '/' or !isPathTokenByte(command[next_index]);}
fn containsUnresolvedAbsolutePath(command: []const u8) bool { for (command, 0..) |byte, index| { if (byte != '/' or (index > 0 and isPathTokenByte(command[index - 1]))) continue; const suffix = command[index..]; if (std.mem.startsWith(u8, suffix, "/dev/null") and (suffix.len == "/dev/null".len or !isPathTokenByte(suffix["/dev/null".len]))) { continue; } return true; } return false;}
fn isPathTokenByte(byte: u8) bool { return std.ascii.isAlphanumeric(byte) or switch (byte) { '/', '-', '.', '_', '~' => true, else => false, };}
/// The caller owns the returned allocation and must free it with `alloc`.pub fn formatRunCommandPermissionLabel( alloc: Allocator, command: []const u8,) ![]const u8 { var scratch_state = std.heap.ArenaAllocator.init(alloc); defer mem_utils.deinit_arena(scratch_state); const scratch = scratch_state.allocator(); const encoded = try text_utils.encodeTerminalSafe( scratch, command, max_run_command_activity_bytes, ); const suffix = try commandApprovalLabelSuffix(scratch, "shell", command); return std.fmt.allocPrint(alloc, "shell.run {s}{s}", .{ encoded.bytes, suffix });}
pub fn isAdvertisedDynamicMcpName(registry: tool_dispatch.Registry, name: []const u8, advertised: []const []const u8) bool { if (registry.lookup(name) != null) return false; for (advertised) |advertised_name| { if (std.mem.eql(u8, advertised_name, name)) return true; } return false;}
/// Returns a borrowed static label when the call is a captured command.pub fn runCommandCompletedActionLabel( alloc: Allocator, registry: tool_dispatch.Registry, call: ToolCall,) !?[]const u8 { var parsed = try std.json.parseFromSlice(std.json.Value, alloc, call.arguments_json, .{}); defer parsed.deinit(); if (parsed.value != .object or !isCapturedCommandCall(registry, call, parsed.value.object)) return null; const command = tool_args.optionalStringArg(parsed.value.object, "command") orelse return null; return if (try tool_dispatch.matchRunCommandCompatibility(registry, command)) |matched| matched.tool.completed_action_label else "Ran";}
pub fn formatRunCommandActivity( alloc: Allocator, registry: tool_dispatch.Registry, workspace_root: []const u8, call: ToolCall,) !?RunCommandActivity { var scratch_state = std.heap.ArenaAllocator.init(std.heap.c_allocator); defer mem_utils.deinit_arena(scratch_state); const scratch = scratch_state.allocator();
const args = tool_args.parseToolArgsObject(scratch, call.arguments_json) catch return null; if (!isCapturedCommandCall(registry, call, args)) return null; const command = tool_args.optionalStringArg(args, "command") orelse return null; const detail = (try formatRunCommandDetailBounded( alloc, command, workspace_root, max_run_command_activity_bytes, )) orelse return null; return .{ .detail = detail, .compatibility_tool = if (try tool_dispatch.matchRunCommandCompatibility(registry, command)) |matched| matched.tool else null, };}
/// Formats a session launch command with the live terminal display target/// projection's 120-byte budget, for replayed history where the live session/// rows no longer exist. Returns null when `workspace_root` is empty and the/// command contains an unresolved absolute path, matching the historical/// command display guard; the caller falls back to the raw session id./// The caller owns the returned allocation.pub fn formatHistoricalTerminalDisplayTarget( alloc: Allocator, command: []const u8, workspace_root: []const u8,) !?[]u8 { return formatRunCommandDetailBounded(alloc, command, workspace_root, max_run_command_activity_bytes);}
pub fn formatRunCommandDetailBounded( alloc: Allocator, command: []const u8, workspace_root: []const u8, max_encoded_bytes: usize,) !?[]u8 { if (max_encoded_bytes == 0) return try alloc.dupe(u8, ""); if (workspace_root.len == 0 and containsUnresolvedAbsolutePath(command)) return null;
const effective_max = @min(max_encoded_bytes, max_run_command_activity_source_bytes - 1); const projected_storage = try alloc.alloc(u8, effective_max + 1); defer alloc.free(projected_storage); const projected = projectRunCommandActivitySource(command, workspace_root, projected_storage); const encoded = try text_utils.encodeTerminalSafe(alloc, projected, effective_max); return encoded.bytes;}
/// The caller owns the returned allocation and must free it with `alloc`.fn resolveTerminalDisplayTargetFromRows( alloc: Allocator, registry: tool_dispatch.Registry, workspace_root: []const u8, call: ToolCall, rows: []const terminal_ui_projection.Row, max_encoded_bytes: usize,) !?[]const u8 { var scratch_state = std.heap.ArenaAllocator.init(alloc); defer mem_utils.deinit_arena(scratch_state); const session_id = terminalDisplayTargetSessionId( scratch_state.allocator(), registry, call, ) orelse return null; return @as(?[]const u8, try resolveTerminalSessionTargetFromRows( alloc, workspace_root, session_id, rows, max_encoded_bytes, ));}
fn terminalDisplayTargetSessionId( scratch: Allocator, registry: tool_dispatch.Registry, call: ToolCall,) ?[]const u8 { const spec = registry.lookup(call.name) orelse return null; if (spec.executor_kind != .terminal) return null; const args = tool_args.parseToolArgsObject( scratch, call.arguments_json, ) catch return null; const presentation = tool_dispatch.presentationForArgs(spec.*, args); if (presentation.label_arg_kind != .session_id) return null; return tool_args.optionalStringArg(args, "session_id");}
/// The caller owns the returned allocation and must free it with `alloc`.fn resolveTerminalSessionTargetFromRows( alloc: Allocator, workspace_root: []const u8, session_id: []const u8, rows: []const terminal_ui_projection.Row, max_encoded_bytes: usize,) ![]const u8 { for (rows) |row| { if (!std.mem.eql(u8, row.session_id, session_id)) continue; if (row.label.len == 0 or std.mem.eql(u8, row.label, session_id)) break; return try formatTerminalDisplayTarget( alloc, workspace_root, row.label, max_encoded_bytes, ); }
var encoded = try text_utils.encodeTerminalSafe( alloc, session_id, max_encoded_bytes -| "session ".len, ); defer encoded.deinit(alloc); return try std.fmt.allocPrint(alloc, "session {s}", .{encoded.bytes});}
/// The caller owns the returned allocation and must free it with `alloc`.pub fn resolveTerminalDisplayTarget( alloc: Allocator, registry: tool_dispatch.Registry, workspace_root: []const u8, terminal_client: ?*terminal_client_runtime.Runtime, managed_executions: ?*managed_execution.Runtime, call: ToolCall,) !?[]const u8 { return resolveTerminalDisplayTargetBounded( alloc, registry, workspace_root, terminal_client, managed_executions, call, max_run_command_activity_bytes, );}
/// Resolves the session launch command at a caller-chosen storage bound. The/// status line keeps the compact activity bound; the transcript stores the/// reflow-bound variant so group projection can reclip to the live width./// The caller owns the returned allocation and must free it with `alloc`.pub fn resolveTerminalDisplayTargetBounded( alloc: Allocator, registry: tool_dispatch.Registry, workspace_root: []const u8, terminal_client: ?*terminal_client_runtime.Runtime, managed_executions: ?*managed_execution.Runtime, call: ToolCall, max_encoded_bytes: usize,) !?[]const u8 { var scratch_state = std.heap.ArenaAllocator.init(std.heap.c_allocator); defer mem_utils.deinit_arena(scratch_state); const session_id = terminalDisplayTargetSessionId( scratch_state.allocator(), registry, call, ) orelse return null; if (managed_executions) |executions| { if (try executions.captured_command_alloc(alloc, session_id)) |command| { defer alloc.free(command); if (command.len != 0) return try formatTerminalDisplayTarget(alloc, workspace_root, command, max_encoded_bytes); } } const runtime = terminal_client orelse return @as(?[]const u8, try resolveTerminalSessionTargetFromRows( alloc, workspace_root, session_id, &.{}, max_encoded_bytes, )); var snapshot = try runtime.terminalProjection(std.heap.c_allocator); defer snapshot.deinit(); return @as(?[]const u8, try resolveTerminalSessionTargetFromRows( alloc, workspace_root, session_id, snapshot.rows, max_encoded_bytes, ));}
/// Returns the completed-action label a terminal-session call (interact,/// stop) will use on its settled status line, or null when the call does not/// present a session target. Borrows registry storage; no free needed.pub fn terminalSessionCompletedActionLabel( alloc: Allocator, registry: tool_dispatch.Registry, call: ToolCall,) !?[]const u8 { const spec = registry.lookup(call.name) orelse return null; if (spec.executor_kind != .terminal) return null; var scratch_state = std.heap.ArenaAllocator.init(alloc); defer mem_utils.deinit_arena(scratch_state); const args = tool_args.parseToolArgsObject(scratch_state.allocator(), call.arguments_json) catch return null; const presentation = tool_dispatch.presentationForArgs(spec.*, args); if (presentation.label_arg_kind != .session_id) return null; return presentation.completed_action_label;}
/// The caller owns the returned allocation and must free it with `alloc`.fn formatTerminalDisplayTarget( alloc: Allocator, workspace_root: []const u8, raw: []const u8, max_encoded_bytes: usize,) ![]u8 { if (max_encoded_bytes == 0) return try alloc.dupe(u8, ""); const effective_max = @min(max_encoded_bytes, max_run_command_activity_source_bytes - 1); const projected_storage = try alloc.alloc(u8, effective_max + 1); defer alloc.free(projected_storage); const projected = projectRunCommandActivitySource( raw, workspace_root, projected_storage, ); const encoded = try text_utils.encodeTerminalSafe( alloc, projected, effective_max, ); return encoded.bytes;}
/// Borrows the name from the prepared action without replacing resource labels.pub fn resolvedSkillName(call: ToolCall, presentation: tool_dispatch.CallPresentation) ?[]const u8 { if (presentation.label_arg_kind != .name) return null; const selected = call.resolved_skill orelse return null; return selected.skill.name;}
/// The caller owns the returned allocation and must free it with `alloc`.pub fn formatPlainAction(alloc: Allocator, input: ToolActionInput) ![]const u8 { const call = input.call; if (input.tool_registry.lookup(call.name) != null) { if (try formatSubagentPlainAction(alloc, call, .active)) |line| return line; } if (file_mutation_contract.isToolName(call.name)) { const spec = input.tool_registry.lookup(call.name) orelse return std.fmt.allocPrint(alloc, "Working: {s}", .{call.name}); return std.fmt.allocPrint( alloc, "{s} {s}", .{ spec.action_label, input.display_target orelse spec.label_arg_default }, ); }
if (try formatRunCommandActivity(alloc, input.tool_registry, input.workspace_root, call)) |activity| { defer alloc.free(activity.detail); const action_label = if (activity.compatibility_tool) |tool| tool.action_label else "Running"; return std.fmt.allocPrint(alloc, "{s} {s}", .{ action_label, activity.detail }); }
var scratch_state = std.heap.ArenaAllocator.init(alloc); defer mem_utils.deinit_arena(scratch_state); const scratch = scratch_state.allocator();
const spec = input.tool_registry.lookup(call.name) orelse { if (isProviderSearchAlias(call.name)) { const args = tool_args.parseToolArgsObject(scratch, call.arguments_json) catch { return std.fmt.allocPrint(alloc, "Searching web", .{}); }; return std.fmt.allocPrint(alloc, "Searching {s}", .{try formatWebSearchActionDetail(scratch, args)}); } if (input.is_available_dynamic_mcp_tool) return std.fmt.allocPrint(alloc, "MCP: {s}", .{call.name}); return std.fmt.allocPrint(alloc, "Working: {s}", .{call.name}); }; const args = tool_args.parseToolArgsObject(scratch, call.arguments_json) catch { return std.fmt.allocPrint(alloc, "Working: {s}", .{call.name}); };
const presentation = tool_dispatch.presentationForArgs(spec.*, args); if (spec.executor_kind == .web_search) { return std.fmt.allocPrint(alloc, "{s} {s}", .{ presentation.action_label, try formatWebSearchActionDetail(scratch, args) }); } const value = input.display_target orelse resolvedSkillName(call, presentation) orelse tool_dispatch.presentationLabelValue(presentation, args) orelse presentation.label_arg_default; return std.fmt.allocPrint(alloc, "{s} {s}", .{ presentation.action_label, value });}
/// The caller owns the returned allocation and must free it with `alloc`.pub fn formatPermissionLabel(alloc: Allocator, registry: tool_dispatch.Registry, call: ToolCall) ![]const u8 { var scratch_state = std.heap.ArenaAllocator.init(alloc); defer mem_utils.deinit_arena(scratch_state); const scratch = scratch_state.allocator();
if (try runCommandCompatibilitySource(scratch, registry, call)) |source| { return std.fmt.allocPrint(alloc, "{s} {s}", .{ source.tool.name, source.command }); } const args = tool_args.parseToolArgsObject(scratch, call.arguments_json) catch { return try alloc.dupe(u8, call.name); }; if (isCapturedCommandCall(registry, call, args)) { const command = tool_args.optionalStringArg(args, "command") orelse return try alloc.dupe(u8, call.name); return formatRunCommandPermissionLabel(alloc, command); } const spec = registry.lookup(call.name) orelse return try alloc.dupe(u8, call.name); if (file_mutation_contract.isToolName(call.name)) { return std.fmt.allocPrint( alloc, "{s} {s}", .{ call.name, spec.label_arg_default }, ); } const value = tool_dispatch.toolLabelValue(spec.*, args) orelse return try alloc.dupe(u8, call.name);
if (spec.label_arg_kind == .command) { const suffix = try commandApprovalLabelSuffix(scratch, call.name, value); if (tool_args.optionalStringArg(args, "cwd")) |cwd| { return std.fmt.allocPrint(alloc, "{s} {s} @ {s}{s}", .{ call.name, value, cwd, suffix }); } return std.fmt.allocPrint(alloc, "{s} {s}{s}", .{ call.name, value, suffix }); }
return std.fmt.allocPrint(alloc, "{s} {s}", .{ call.name, value });}
/// The caller owns the returned allocation and must free it with `alloc`.pub fn formatWebSearchActionDetail(alloc: Allocator, args: std.json.ObjectMap) ![]const u8 { var out: std.Io.Writer.Allocating = .init(alloc); errdefer out.deinit(); var label_buf: [160]u8 = undefined; const query = tool_args.optionalStringArg(args, "query") orelse "web"; try out.writer.writeAll(text_utils.clippedLabel(&label_buf, query, 120)); try appendWebSearchDomains(&out.writer, "allowed", args.get("allowed_domains")); try appendWebSearchDomains(&out.writer, "blocked", args.get("blocked_domains")); return try out.toOwnedSlice();}
/// The caller owns the returned allocation and must free it with `alloc`.pub fn formatWebSearchProgressPlain(alloc: Allocator, progress: types.WebSearchProgress) ![]u8 { var query_buf: [160]u8 = undefined; return switch (progress) { .query_started => |query| std.fmt.allocPrint( alloc, "Searching {s}", .{text_utils.clippedLabel(&query_buf, query, 120)}, ), .results_received => |entry| std.fmt.allocPrint( alloc, "Found {d} result{s} for {s}", .{ entry.result_count, if (entry.result_count == 1) "" else "s", text_utils.clippedLabel(&query_buf, entry.query, 120) }, ), };}
/// The caller owns the returned allocation and must free it with `alloc`.pub fn formatWebFetchProgressPlain(alloc: Allocator, progress: types.WebFetchProgress) ![]u8 { var url_buf: [types.WebFetchCompletion.max_url_len]u8 = undefined; return switch (progress) { .fetching => |url| std.fmt.allocPrint(alloc, "Fetching {s}", .{text_utils.clippedLabel(&url_buf, url, 96)}), .converting => |url| std.fmt.allocPrint(alloc, "Converting {s}", .{text_utils.clippedLabel(&url_buf, url, 96)}), };}
fn appendWebSearchDomains(writer: *std.Io.Writer, label: []const u8, value: ?std.json.Value) !void { const array = value orelse return; if (array != .array or array.array.items.len == 0) return; try writer.print(" | {s}: ", .{label}); var domain_buf: [64]u8 = undefined; const shown = @min(array.array.items.len, 3); for (array.array.items[0..shown], 0..) |item, index| { if (index > 0) try writer.writeAll(", "); if (item != .string) { try writer.writeAll("?"); continue; } try writer.writeAll(text_utils.clippedLabel(&domain_buf, item.string, 48)); } if (array.array.items.len > shown) try writer.print(" +{d}", .{array.array.items.len - shown});}
fn commandApprovalLabelSuffix(alloc: Allocator, tool_name: []const u8, command: []const u8) ![]const u8 { if (!std.mem.eql(u8, tool_name, "run_command") and !std.mem.eql(u8, tool_name, "terminal") and !std.mem.eql(u8, tool_name, "shell")) return ""; const risk = command_policy.command_risk_note_for(command); const safer = command_policy.command_safer_alternative_for(command); if (risk == null and safer == null) return ""; const risk_text = if (risk) |note| stripNotePrefix(note) else null; if (risk_text) |note| { if (safer) |alternative| { return std.fmt.allocPrint(alloc, " (risk: {s}; {s})", .{ note, alternative }); } return std.fmt.allocPrint(alloc, " (risk: {s})", .{note}); } if (safer) |alternative| { return std.fmt.allocPrint(alloc, " ({s})", .{alternative}); } return "";}
fn stripNotePrefix(note: []const u8) []const u8 { const prefix = "note: "; if (std.mem.startsWith(u8, note, prefix)) return note[prefix.len..]; return note;}
const RunCommandCompatibilitySource = struct { tool: *const tool_dispatch.Tool, command: []const u8,};
fn runCommandCompatibilitySource( alloc: Allocator, registry: tool_dispatch.Registry, call: ToolCall,) !?RunCommandCompatibilitySource { const args = tool_args.parseToolArgsObject(alloc, call.arguments_json) catch return null; if (!isCapturedCommandCall(registry, call, args)) return null; const command = tool_args.optionalStringArg(args, "command") orelse return null; const matched = (try tool_dispatch.matchRunCommandCompatibility(registry, command)) orelse return null; return .{ .tool = matched.tool, .command = command };}
fn isCapturedCommandCall( registry: tool_dispatch.Registry, call: ToolCall, args: std.json.ObjectMap,) bool { // Historical sessions retain their original tool name. Presentation may // interpret those records, but execution remains unavailable because the // registry no longer contains a `run_command` tool. if (std.mem.eql(u8, call.name, "run_command")) return true; const tool = registry.lookup(call.name) orelse return false; if (tool.executor_kind == .run_command) return true; const expected = tool.captured_command_action orelse return false; const action = tool_args.optionalStringArg(args, "action") orelse return false; return std.mem.eql(u8, action, expected);}
fn matchesTestSkillInstall(command: []const u8) bool { return std.mem.startsWith(u8, command, "npx skills add ");}
fn executeTestSkillInstall( ctx: tool_dispatch.DispatchContext, _: []const u8,) tool_dispatch.DispatchError!tool_dispatch.ToolResult { return .{ .success = try ctx.allocator.dupe(u8, "installed") };}
const test_install_skill = blk: { var tool = test_builtin_tools.skill; tool.name = "install_skill"; tool.model_schema.name = "install_skill"; tool.executor_kind = .install_skill; tool.activity_kind = .write; tool.requires_approval = true; tool.action_label = "Installing skill"; tool.completed_action_label = "Installed skill"; tool.label_arg_kind = .source; tool.label_arg_default = "skill"; tool.run_command_compatibility = .{ .matches = matchesTestSkillInstall, .execute = executeTestSkillInstall, }; break :blk tool;};
const test_web_search = blk: { var tool = test_builtin_tools.read_file; tool.name = "web_search"; tool.model_schema.name = "web_search"; tool.executor_kind = .web_search; tool.action_label = "Searching"; tool.completed_action_label = "Searched"; tool.label_arg_kind = .query; tool.label_arg_default = "web"; break :blk tool;};
const test_tools = [_]tool_dispatch.Tool{ test_builtin_tools.read_file, test_builtin_tools.write_file, test_builtin_tools.edit_file, test_web_search, test_builtin_tools.shell, test_builtin_tools.skill, test_install_skill, test_builtin_tools.ask_user_question,};const test_tool_registry = tool_dispatch.Registry{ .tools = test_tools[0..] };const custom_presentation_tool = blk: { var tool = test_builtin_tools.read_file; tool.name = "custom_presentation"; tool.action_label = "Inspecting"; tool.label_arg_kind = .name; tool.label_arg_default = "custom fallback"; break :blk tool;};const custom_presentation_registry = tool_dispatch.Registry{ .tools = &.{custom_presentation_tool} };
test "tool presentation formats dynamic MCP availability distinctly" { const alloc = std.testing.allocator; const call: ToolCall = .{ .id = "dynamic", .name = "mcp_lookup", .arguments_json = "{}", };
const available = try formatPlainAction(alloc, .{ .tool_registry = test_tool_registry, .call = call, .is_available_dynamic_mcp_tool = true, }); defer alloc.free(available); try std.testing.expectEqualStrings("MCP: mcp_lookup", available);
const unavailable = try formatPlainAction(alloc, .{ .tool_registry = test_tool_registry, .call = call }); defer alloc.free(unavailable); try std.testing.expectEqualStrings("Working: mcp_lookup", unavailable);}
test "tool presentation reads labels from the supplied registry" { const alloc = std.testing.allocator; const label = try formatPlainAction(alloc, .{ .tool_registry = custom_presentation_registry, .call = .{ .id = "custom", .name = "custom_presentation", .arguments_json = "{\"name\":\"registry metadata\"}", }, }); defer alloc.free(label);
try std.testing.expectEqualStrings("Inspecting registry metadata", label);}
test "tool presentation formats plain web progress variants" { const alloc = std.testing.allocator; const cases = [_]struct { text: []const u8, progress: union(enum) { search: types.WebSearchProgress, fetch: types.WebFetchProgress, }, }{ .{ .text = "Searching current Zig release", .progress = .{ .search = .{ .query_started = "current Zig release" } } }, .{ .text = "Found 1 result for current Zig release", .progress = .{ .search = .{ .results_received = .{ .query = "current Zig release", .result_count = 1 } } } }, .{ .text = "Fetching https://ziglang.org", .progress = .{ .fetch = .{ .fetching = "https://ziglang.org" } } }, .{ .text = "Converting https://ziglang.org", .progress = .{ .fetch = .{ .converting = "https://ziglang.org" } } }, };
for (cases) |case| { const text = switch (case.progress) { .search => |progress| try formatWebSearchProgressPlain(alloc, progress), .fetch => |progress| try formatWebFetchProgressPlain(alloc, progress), }; defer alloc.free(text); try std.testing.expectEqualStrings(case.text, text); }}
test "run command presentation resolves registered compatibility" { const alloc = std.testing.allocator; const call = ToolCall{ .id = "install", .name = "run_command", .arguments_json = "{\"command\":\"npx skills add vercel-labs/agent-skills -g -y\"}", }; const activity = (try formatRunCommandActivity(alloc, test_tool_registry, "", call)) orelse return error.TestExpectedEqual; defer alloc.free(activity.detail);
const compatibility_tool = activity.compatibility_tool orelse return error.TestExpectedEqual; try std.testing.expectEqualStrings("install_skill", compatibility_tool.name);
const action = try formatPlainAction(alloc, .{ .tool_registry = test_tool_registry, .call = call }); defer alloc.free(action); try std.testing.expectEqualStrings("Installing skill npx skills add vercel-labs/agent-skills -g -y", action);
const permission = try formatPermissionLabel(alloc, test_tool_registry, call); defer alloc.free(permission); try std.testing.expectEqualStrings("install_skill npx skills add vercel-labs/agent-skills -g -y", permission);}
test "run command activity projects line boundaries without changing other bytes" { const alloc = std.testing.allocator; const cases = [_]struct { arguments_json: []const u8, expected: []const u8, }{ .{ .arguments_json = "{\"command\":\"cat <<'EOF'\\nline one\\nEOF\"}", .expected = "cat <<'EOF' line one EOF", }, .{ .arguments_json = "{\"command\":\"\\r\\n\\tprintf first\\r\\n printf second\\r\\t\\n\"}", .expected = "printf first printf second", }, .{ .arguments_json = "{\"command\":\"printf 'literal \\\\x0a'\"}", .expected = "printf 'literal \\x0a'", }, .{ .arguments_json = "{\"command\":\"printf \\u0007\"}", .expected = "printf \\x07", }, };
for (cases) |case| { const activity = (try formatRunCommandActivity(alloc, test_tool_registry, "", .{ .id = "projected_command", .name = "run_command", .arguments_json = case.arguments_json, })) orelse return error.TestExpectedEqual; defer alloc.free(activity.detail);
try std.testing.expectEqualStrings(case.expected, activity.detail); }}
test "run command detail uses the caller bound without changing activity labels" { const alloc = std.testing.allocator; const command = "printf " ++ ("alpha-beta-gamma-delta-" ** 8); const arguments_json = try std.fmt.allocPrint( alloc, "{{\"command\":{f}}}", .{std.json.fmt(command, .{})}, ); defer alloc.free(arguments_json);
const detail = (try formatRunCommandDetailBounded( alloc, command, "", max_run_command_reflow_bytes, )) orelse return error.TestExpectedEqual; defer alloc.free(detail); try std.testing.expectEqualStrings(command, detail);
const bounded = (try formatRunCommandDetailBounded(alloc, command, "", 80)) orelse return error.TestExpectedEqual; defer alloc.free(bounded); try std.testing.expect(bounded.len <= 80); try std.testing.expect(std.mem.endsWith(u8, bounded, "..."));
const activity = (try formatRunCommandActivity(alloc, test_tool_registry, "", .{ .id = "bounded_activity", .name = "run_command", .arguments_json = arguments_json, })) orelse return error.TestExpectedEqual; defer alloc.free(activity.detail); try std.testing.expect(activity.detail.len <= max_run_command_activity_bytes); try std.testing.expect(std.mem.endsWith(u8, activity.detail, "..."));
const hidden_workspace_path = "printf " ++ ("prefix-" ** 20) ++ " /Users/example/workspace/file"; try std.testing.expectEqual( @as(?[]u8, null), try formatRunCommandDetailBounded( alloc, hidden_workspace_path, "", max_run_command_reflow_bytes, ), );}
test "run command activity abbreviates only active workspace paths" { const alloc = std.testing.allocator; const workspace_root = "/Users/example/workspace"; const cases = [_]struct { arguments_json: []const u8, expected: []const u8, }{ .{ .arguments_json = "{\"command\":\"cd /Users/example/workspace/packages/cli && pwd\"}", .expected = "cd ./packages/cli && pwd", }, .{ .arguments_json = "{\"command\":\"printf '/Users/example/workspace'\"}", .expected = "printf '.'", }, .{ .arguments_json = "{\"command\":\"printf \\\"/Users/example/workspace/src/main.zig\\\"\"}", .expected = "printf \"./src/main.zig\"", }, .{ .arguments_json = "{\"command\":\"printf /Users/example/workspace /Users/example/workspace/src\"}", .expected = "printf . ./src", }, .{ .arguments_json = "{\"command\":\"cd /Users/example/workspace-other && pwd\"}", .expected = "cd /Users/example/workspace-other && pwd", }, .{ .arguments_json = "{\"command\":\"cd /Users/example/other && pwd\"}", .expected = "cd /Users/example/other && pwd", }, .{ .arguments_json = "{\"command\":\"cd /prefix/Users/example/workspace && pwd\"}", .expected = "cd /prefix/Users/example/workspace && pwd", }, };
for (cases) |case| { const call: ToolCall = .{ .id = "workspace_command", .name = "run_command", .arguments_json = case.arguments_json, }; const activity = (try formatRunCommandActivity( alloc, test_tool_registry, workspace_root ++ "/", call, )) orelse return error.TestExpectedEqual; defer alloc.free(activity.detail); try std.testing.expectEqualStrings(case.expected, activity.detail); }
const permission = try formatPermissionLabel(alloc, test_tool_registry, .{ .id = "raw_workspace_command", .name = "run_command", .arguments_json = "{\"command\":\"cd /Users/example/workspace/packages/cli && pwd\"}", }); defer alloc.free(permission); try std.testing.expectEqualStrings( "shell.run cd /Users/example/workspace/packages/cli && pwd", permission, );}
test "run command activity hides only a leading no-op current directory prefix" { const alloc = std.testing.allocator; const cases = [_]struct { command: []const u8, expected: []const u8, }{ .{ .command = "cd . && zig build", .expected = "zig build" }, .{ .command = "cd . &&\n zig build test", .expected = "zig build test" }, .{ .command = "cd ./packages && pwd", .expected = "cd ./packages && pwd" }, .{ .command = "cd .. && pwd", .expected = "cd .. && pwd" }, .{ .command = "cd . || pwd", .expected = "cd . || pwd" }, .{ .command = "printf 'cd . && pwd'", .expected = "printf 'cd . && pwd'" }, .{ .command = "cd . &&", .expected = "cd . &&" }, };
for (cases) |case| { const arguments_json = try std.fmt.allocPrint(alloc, "{{\"command\":{f}}}", .{std.json.fmt(case.command, .{})}); defer alloc.free(arguments_json); const activity = (try formatRunCommandActivity(alloc, test_tool_registry, "", .{ .id = "current_directory_command", .name = "run_command", .arguments_json = arguments_json, })) orelse return error.TestExpectedEqual; defer alloc.free(activity.detail);
try std.testing.expectEqualStrings(case.expected, activity.detail); }
const permission = try formatPermissionLabel(alloc, test_tool_registry, .{ .id = "raw_current_directory_command", .name = "run_command", .arguments_json = "{\"command\":\"cd . && zig build\"}", }); defer alloc.free(permission); try std.testing.expectEqualStrings("shell.run cd . && zig build", permission);}
test "tool presentation formats bounded web search action detail" { const alloc = std.testing.allocator; const label = try formatPlainAction(alloc, .{ .tool_registry = test_tool_registry, .call = .{ .id = "call_search", .name = "web_search", .arguments_json = "{\"query\":\"current Zig release\",\"blocked_domains\":[\"spam.example\",\"ads.example\"]}", }, }); defer alloc.free(label); try std.testing.expectEqualStrings("Searching current Zig release | blocked: spam.example, ads.example", label);}
test "tool presentation bounds a large multiline run command activity" { const alloc = std.testing.allocator; const arguments_json = "{\"command\":\"" ++ ("é\\r\\n" ** 20_000) ++ "\"}"; const label = try formatPlainAction(alloc, .{ .tool_registry = test_tool_registry, .call = .{ .id = "large_command", .name = "run_command", .arguments_json = arguments_json, }, }); defer alloc.free(label);
try std.testing.expect(label.len <= 128); try std.testing.expect(std.mem.findScalar(u8, label, '\r') == null); try std.testing.expect(std.mem.findScalar(u8, label, '\n') == null); try std.testing.expect(std.mem.find(u8, label, "\\x0a") == null); try std.testing.expect(std.mem.find(u8, label, "\\x0d") == null); try std.testing.expect(std.unicode.utf8ValidateSlice(label)); try std.testing.expect(std.mem.endsWith(u8, label, "..."));}
test "tool presentation formats permission labels" { const alloc = std.testing.allocator; const cwd = try formatPermissionLabel(alloc, test_tool_registry, .{ .id = "command", .name = "run_command", .arguments_json = "{\"command\":\"npm test\",\"cwd\":\"/tmp/fx\"}", }); defer alloc.free(cwd); try std.testing.expectEqualStrings("shell.run npm test", cwd);
const risk = try formatPermissionLabel(alloc, test_tool_registry, .{ .id = "risk", .name = "run_command", .arguments_json = "{\"command\":\"git reset --hard\"}", }); defer alloc.free(risk); try expectContains(risk, "risk: command may discard version-control state"); try expectContains(risk, "safer: inspect git status first");}
test "tool presentation preserves plain action fallbacks" { const alloc = std.testing.allocator; const cases = [_]struct { call: ToolCall, expected: []const u8, }{ .{ .call = .{ .id = "read", .name = "read_file", .arguments_json = "{\"path\":\"src/main.zig\"}" }, .expected = "Reading src/main.zig" }, .{ .call = .{ .id = "command", .name = "run_command", .arguments_json = "{\"command\":\"zig build\"}" }, .expected = "Running zig build" }, .{ .call = .{ .id = "ask", .name = "ask_user_question", .arguments_json = "{}" }, .expected = "Asking " }, .{ .call = .{ .id = "skill", .name = "skill", .arguments_json = "{\"name\":\"workflow\"}" }, .expected = "Loading skill workflow" }, .{ .call = .{ .id = "skill-resource", .name = "skill", .arguments_json = "{\"name\":\"workflow\",\"resource\":\"references/contract-design.md\"}" }, .expected = "Reading skill resource references/contract-design.md" }, .{ .call = .{ .id = "install", .name = "install_skill", .arguments_json = "{\"source\":\"vercel-labs/agent-skills\",\"skill\":\"workflow\"}" }, .expected = "Installing skill vercel-labs/agent-skills" }, .{ .call = .{ .id = "unknown", .name = "unknown_tool", .arguments_json = "{}" }, .expected = "Working: unknown_tool" }, };
for (cases) |case| { const label = try formatPlainAction(alloc, .{ .tool_registry = test_tool_registry, .call = case.call }); defer alloc.free(label); try std.testing.expectEqualStrings(case.expected, label); }}
test "tool presentation uses the resolved skill name for location calls" { const alloc = std.testing.allocator; const selected: @import("../skills/skill_contract.zig").PreparedSkill = .{ .skill = .{ .name = "workflow", .description = "", .path = "/skills/different-directory", .source = .workspace_fx, } }; const cases = [_]struct { args: []const u8, expected: []const u8 }{ .{ .args = "{\"location\":\"skill:0000000000000001:0/different-directory\"}", .expected = "Loading skill workflow" }, .{ .args = "{\"location\":\"/skills/different-directory\",\"resource\":\"SKILL.md\"}", .expected = "Loading skill workflow" }, .{ .args = "{\"location\":\"/skills/different-directory\",\"resource\":\"references/rules.md\"}", .expected = "Reading skill resource references/rules.md" }, }; for (cases) |case| { const label = try formatPlainAction(alloc, .{ .tool_registry = test_tool_registry, .call = .{ .id = "load", .name = "skill", .arguments_json = case.args, .resolved_skill = &selected }, }); defer alloc.free(label); try std.testing.expectEqualStrings(case.expected, label); }}
test "captured display target uses retained command without consuming output" { if (comptime builtin.os.tag == .wasi) return; const alloc = std.testing.allocator; var executions = managed_execution.Runtime.init(alloc); defer executions.deinit(); const command = "printf LABEL"; const admission = @import("../permissions/command_admission.zig"); var started = try executions.startCaptured(alloc, .{ .execution_id = "shell-label", .command = command, .cwd = "/tmp", .environment = .legacy, .authority = .{ .shell_allowed = .{ .fingerprint = .init(admission.CommandContext{ .command = command, .resolved_cwd = "/tmp", .target_os = builtin.os.tag, .environment = .legacy, }), .source = .yolo, } }, .max_output_bytes = 4096, .timeout_ms = 2_000, .command_artifact_dir = null, .yield_time_ms = 0, }); defer started.deinit(alloc); try executions.commitDelivery(started.snapshot.execution_id, started.reservation_id); const call = ToolCall{ .id = "observe", .name = "shell", .arguments_json = "{\"action\":\"interact\",\"session_id\":\"shell-label\"}", }; const target = (try resolveTerminalDisplayTarget(alloc, test_tool_registry, "/tmp", null, &executions, call)).?; defer alloc.free(target); try std.testing.expectEqualStrings(command, target); const label = try formatPlainAction(alloc, .{ .tool_registry = test_tool_registry, .call = call, .display_target = target, }); defer alloc.free(label); try std.testing.expectEqualStrings("Waiting for printf LABEL", label);
var completed = try executions.wait(alloc, "shell-label", 2_000, null); defer completed.deinit(alloc); try std.testing.expectEqualStrings("LABEL", completed.snapshot.output_delta); try executions.commitDelivery(completed.snapshot.execution_id, completed.reservation_id); const retained = (try resolveTerminalDisplayTarget(alloc, test_tool_registry, "/tmp", null, &executions, call)).?; defer alloc.free(retained); try std.testing.expectEqualStrings(command, retained); try std.testing.expectEqualStrings(command, target);
const missing = (try resolveTerminalDisplayTarget(alloc, test_tool_registry, "/tmp", null, &executions, .{ .id = "missing", .name = "shell", .arguments_json = "{\"action\":\"stop\",\"session_id\":\"shell-missing\"}", })).?; defer alloc.free(missing); try std.testing.expectEqualStrings("session shell-missing", missing);}
test "terminal display target bounds and sanitizes command metadata" { const alloc = std.testing.allocator; const target = try formatTerminalDisplayTarget(alloc, "/tmp/workspace", "/tmp/workspace/build\n\x1b[31m" ++ ("é" ** 120), max_run_command_activity_bytes); defer alloc.free(target); try std.testing.expect(std.mem.startsWith(u8, target, "./build ")); try std.testing.expect(target.len <= max_run_command_activity_bytes); try std.testing.expect(std.mem.findScalar(u8, target, '\x1b') == null); try std.testing.expect(std.mem.findScalar(u8, target, '\n') == null); try std.testing.expect(std.unicode.utf8ValidateSlice(target)); try std.testing.expect(std.mem.endsWith(u8, target, "..."));}
test "terminal display target bounded variant keeps the launch command up to the caller bound" { const alloc = std.testing.allocator; const command = "bun run " ++ ("pipeline-stage-" ** 30); const compact = try formatTerminalDisplayTarget(alloc, "", command, max_run_command_activity_bytes); defer alloc.free(compact); try std.testing.expect(compact.len <= max_run_command_activity_bytes); try std.testing.expect(std.mem.endsWith(u8, compact, "..."));
const reflow = try formatTerminalDisplayTarget(alloc, "", command, max_run_command_reflow_bytes); defer alloc.free(reflow); try std.testing.expectEqualStrings(command, reflow);}
test "terminal session completed action label matches the interact and stop presentations" { const alloc = std.testing.allocator; const observe = ToolCall{ .id = "observe", .name = "shell", .arguments_json = "{\"action\":\"interact\",\"session_id\":\"shell-1\"}", }; try std.testing.expectEqualStrings( "Observed", (try terminalSessionCompletedActionLabel(alloc, test_tool_registry, observe)).?, );
const send = ToolCall{ .id = "send", .name = "shell", .arguments_json = "{\"action\":\"interact\",\"session_id\":\"shell-1\",\"chars\":\"ls\\n\"}", }; try std.testing.expectEqualStrings( "Sent input to", (try terminalSessionCompletedActionLabel(alloc, test_tool_registry, send)).?, );
const stop = ToolCall{ .id = "stop", .name = "shell", .arguments_json = "{\"action\":\"stop\",\"session_id\":\"shell-1\"}", }; try std.testing.expectEqualStrings( "Stopped", (try terminalSessionCompletedActionLabel(alloc, test_tool_registry, stop)).?, );
const run = ToolCall{ .id = "run", .name = "shell", .arguments_json = "{\"action\":\"run\",\"command\":\"printf ok\"}", }; try std.testing.expect(try terminalSessionCompletedActionLabel(alloc, test_tool_registry, run) == null);
const read = ToolCall{ .id = "read", .name = "read_file", .arguments_json = "{\"path\":\"note.txt\"}", }; try std.testing.expect(try terminalSessionCompletedActionLabel(alloc, test_tool_registry, read) == null);}
test "terminal display target is call-local across a cold inspect projection update" { const alloc = std.testing.allocator; const session_id = "terminal-cold-session"; const facts = terminal_contracts.SessionFacts{ .session_id = session_id, .lifecycle = .running, .attention = .{}, .backend = .native, .output_cursor = .{ .segment = 1, .offset = 0 }, .screen_recovery = .{ .unavailable = .missing }, }; var projection: terminal_ui_projection.Store = .{}; defer projection.deinit(alloc); try projection.observe( alloc, .{ .list = .{} }, .{ .success = .{ .list = .{ .sessions = &.{facts} } } }, );
const inspect_call = ToolCall{ .id = "interact", .name = "shell", .arguments_json = "{\"action\":\"interact\",\"session_id\":\"terminal-cold-session\"}", }; var cold_snapshot = try projection.snapshot(alloc); const current_target = try resolveTerminalDisplayTargetFromRows( alloc, test_tool_registry, "/tmp/workspace", inspect_call, cold_snapshot.rows, max_run_command_activity_bytes, ) orelse return error.TestExpectedEqual; cold_snapshot.deinit(); defer alloc.free(current_target); try std.testing.expectEqualStrings("session terminal-cold-session", current_target);
try projection.observe( alloc, .{ .inspect = .{ .session_id = session_id } }, .{ .success = .{ .inspect = .{ .session = facts, .shell = "/bin/zsh", .cwd = "/tmp/workspace", .command = "npm run dev", } } }, ); try std.testing.expectEqualStrings("session terminal-cold-session", current_target);
var learned_snapshot = try projection.snapshot(alloc); defer learned_snapshot.deinit(); const next_target = try resolveTerminalDisplayTargetFromRows( alloc, test_tool_registry, "/tmp/workspace", .{ .id = "interact-next", .name = "shell", .arguments_json = "{\"action\":\"interact\",\"session_id\":\"terminal-cold-session\"}", }, learned_snapshot.rows, max_run_command_activity_bytes, ) orelse return error.TestExpectedEqual; defer alloc.free(next_target); try std.testing.expectEqualStrings("npm run dev", next_target);}
test "tool presentation frees all formatted output with a normal allocator" { const alloc = std.testing.allocator;
const search = try formatPlainAction(alloc, .{ .tool_registry = test_tool_registry, .call = .{ .id = "search", .name = "web_search", .arguments_json = "{\"query\":\"current Zig release\",\"allowed_domains\":[\"ziglang.org\"]}", }, }); defer alloc.free(search); try std.testing.expectEqualStrings("Searching current Zig release | allowed: ziglang.org", search);
const provider_search = try formatPlainAction(alloc, .{ .tool_registry = test_tool_registry, .call = .{ .id = "provider_search", .name = "exa_search", .arguments_json = "{}", .provenance = .provider_executed, }, }); defer alloc.free(provider_search); try std.testing.expectEqualStrings("Searching web", provider_search);
const command = try formatPermissionLabel(alloc, test_tool_registry, .{ .id = "command", .name = "run_command", .arguments_json = "{\"command\":\"git reset --hard\"}", }); defer alloc.free(command); try expectContains(command, "risk: command may discard version-control state");
var parsed = try std.json.parseFromSlice(std.json.Value, alloc, "{\"query\":\"current Zig release\",\"blocked_domains\":[\"spam.example\"]}", .{}); defer parsed.deinit(); const detail = try formatWebSearchActionDetail(alloc, parsed.value.object); defer alloc.free(detail); try std.testing.expectEqualStrings("current Zig release | blocked: spam.example", detail);}
fn expectContains(text: []const u8, needle: []const u8) !void { try std.testing.expect(std.mem.find(u8, text, needle) != null);}