const std = @import("std");const command_admission = @import("../../permissions/command_admission.zig");const permission_auto_classifier = @import("../../permissions/auto_classifier.zig");const types = @import("../../shared/types.zig");const text_utils = @import("../../shared/text_utils.zig");const tool_dispatch = @import("../../tooling/tool_dispatch.zig");const tool_specs = @import("../../tooling/tool_specs.zig");const tooling_presentation = @import("../../tooling/tool_presentation.zig");const debug_trace = @import("../../shared/debug_trace.zig");const diff = @import("../../output/diff.zig");const file_mutation_contract = @import("../../tooling/file_mutation_contract.zig");const tool_result_errors = @import("../../tooling/tool_result_errors.zig");const test_builtin_tools = if (@import("builtin").is_test) @import("../../../builtins/tools.zig")else struct {}; const runtime_deps = @import("deps.zig");const runtime_tool_contracts = @import("tool_contracts.zig"); const Allocator = std.mem.Allocator;const ToolCall = types.ToolCall;const AgentRuntimeDeps = runtime_deps.AgentRuntimeDeps;const DiffEntryPayload = runtime_tool_contracts.DiffEntryPayload;const ToolExecutionResult = runtime_tool_contracts.ToolExecutionResult; pub fn isProviderSearchAlias(tool_name: []const u8) bool { return tooling_presentation.isProviderSearchAlias(tool_name);} pub fn streamStartMayHaveExecutedAtProvider( registry: tool_dispatch.Registry, tool_name: []const u8,) bool { if (isProviderSearchAlias(tool_name)) return true; const spec = registry.lookup(tool_name) orelse return false; return spec.provider_executed;} pub const ProvisionalToolStatuses = struct { const TrackedStatus = struct { id: []u8, tool_name: []u8, label_value: ?[]u8, fn deinit(self: *TrackedStatus, alloc: Allocator) void { alloc.free(self.id); alloc.free(self.tool_name); if (self.label_value) |value| alloc.free(value); self.* = undefined; } }; tracked: std.ArrayList(TrackedStatus) = .empty, terminal_ids: std.ArrayList([]u8) = .empty, presentation_group_id: ?types.ToolPresentationGroupId = null, pub const StartPreflight = union(enum) { ineligible, eligible: struct { action_label: []const u8, activity_kind: types.ToolActivityKind, }, }; pub fn deinit(self: *ProvisionalToolStatuses, alloc: Allocator) void { for (self.tracked.items) |*status| status.deinit(alloc); self.tracked.deinit(alloc); for (self.terminal_ids.items) |id| alloc.free(id); self.terminal_ids.deinit(alloc); } pub fn preflight(registry: tool_dispatch.Registry, tool_name: []const u8) ?StartPreflight { if (tooling_presentation.isProviderSearchAlias(tool_name)) { return .{ .eligible = .{ .action_label = "Searching", .activity_kind = .read, } }; } const lookup_name = if (std.mem.eql(u8, tool_name, "run_command")) "terminal" else tool_name; const spec = registry.lookup(lookup_name) orelse return null; return switch (spec.activity_kind) { .ask, .write, .edit => .ineligible, else => .{ .eligible = .{ .action_label = spec.action_label, .activity_kind = spec.activity_kind, } }, }; } pub fn publish( self: *ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, alloc: Allocator, turn_id: u64, tool_id: []const u8, tool_name: []const u8, activity_kind: types.ToolActivityKind, action_label: []const u8, label_value: ?[]const u8, ) !void { if (tool_id.len == 0) { debug_trace.logf( "ui_activity", "suppressed provisional lifecycle with missing identity turn_id={d}", .{turn_id}, ); return; } var buf: [512]u8 = undefined; const label = try formatProvisionalProgressLabel(&buf, tool_name, action_label, label_value); const recorded = try self.recordTracked( alloc, tool_id, tool_name, label_value, ); hooks.push_tool_lifecycle(hooks.ctx, .{ .provisional = .{ .id = .{ .turn_id = turn_id, .call_id = tool_id }, .presentation_group_id = self.presentation_group_id, .tool_name = tool_name, .activity_kind = activity_kind, }, }) catch |err| { if (recorded) self.forget(alloc, tool_id); return err; }; hooks.push_tool_lifecycle(hooks.ctx, .{ .progress = .{ .id = .{ .turn_id = turn_id, .call_id = tool_id }, .text = label, }, }) catch {}; } pub fn finishMalformedToolArguments( self: *const ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, arena: Allocator, turn_id: u64, call: ToolCall, ) !void { const call_id = self.visibleId(call) orelse return; const summary = try std.fmt.allocPrint( arena, "{s} failed: invalid JSON arguments", .{call.name}, ); try hooks.push_tool_lifecycle(hooks.ctx, .{ .terminal = .{ .id = .{ .turn_id = turn_id, .call_id = call_id }, .outcome = .{ .kind = .failed, .summary = summary }, }, }); } pub fn finishMalformedProviderToolArguments( self: *const ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, arena: Allocator, turn_id: u64, calls: []const ToolCall, ) !void { for (calls) |call| { if (call.provenance != .provider_executed or call.argument_integrity != .malformed_json) continue; try self.finishMalformedToolArguments(hooks, arena, turn_id, call); } } pub fn finishRejectedCompletions( self: *const ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, arena: Allocator, turn_id: u64, calls: []const ToolCall, advertised_dynamic_tool_names: []const []const u8, ) !void { for (calls) |call| { if (!self.has(call.id)) continue; try finishDeniedToolStatus( hooks, arena, turn_id, call, true, null, "Failed", advertised_dynamic_tool_names, ); } } /// Settles one admitted call against its tracked final or provisional id. /// The tracked id is consumed only after terminal publication succeeds. pub fn settleAdmittedCall( self: *ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, alloc: Allocator, arena: Allocator, turn_id: u64, call: ToolCall, label: []const u8, advertised_dynamic_tool_names: []const []const u8, ) !bool { return self.finishDeniedCall( hooks, alloc, arena, turn_id, call, false, null, label, advertised_dynamic_tool_names, ); } pub fn settleDeferredCall( self: *ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, alloc: Allocator, arena: Allocator, turn_id: u64, call: ToolCall, advertised_dynamic_tool_names: []const []const u8, ) !bool { const recorded_terminal = try self.recordTerminal(alloc, call.id); if (!recorded_terminal) return false; errdefer self.forgetTerminal(alloc, call.id); const target = try self.ensureTerminalTarget( hooks, arena, turn_id, call, false, null, advertised_dynamic_tool_names, ) orelse { self.forgetTerminal(alloc, call.id); return false; }; try finishDeferredToolStatus( hooks, arena, turn_id, target.call, advertised_dynamic_tool_names, ); if (target.tracked_id) |tracked_id| self.forget(alloc, tracked_id); return true; } pub fn finishDeniedCall( self: *ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, alloc: Allocator, arena: Allocator, turn_id: u64, call: ToolCall, authoritative_started: bool, file_display_path: ?[]const u8, label: []const u8, advertised_dynamic_tool_names: []const []const u8, ) !bool { const recorded_terminal = try self.recordTerminal(alloc, call.id); if (!recorded_terminal) return false; errdefer self.forgetTerminal(alloc, call.id); const target = try self.ensureTerminalTarget( hooks, arena, turn_id, call, authoritative_started, file_display_path, advertised_dynamic_tool_names, ) orelse { self.forgetTerminal(alloc, call.id); return false; }; try finishDeniedToolStatus( hooks, arena, turn_id, target.call, true, file_display_path, label, advertised_dynamic_tool_names, ); if (target.tracked_id) |tracked_id| self.forget(alloc, tracked_id); return true; } pub fn finishExecutedCall( self: *ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, alloc: Allocator, arena: Allocator, turn_id: u64, call: ToolCall, authoritative_started: bool, file_display_path: ?[]const u8, result: ToolExecutionResult, safe_result: []const u8, result_memory: types.ToolResultMemory, diff_entry: ?DiffEntryPayload, advertised_dynamic_tool_names: []const []const u8, ) !bool { const recorded_terminal = try self.recordTerminal(alloc, call.id); if (!recorded_terminal) return false; errdefer self.forgetTerminal(alloc, call.id); const target = try self.ensureTerminalTarget( hooks, arena, turn_id, call, authoritative_started, file_display_path, advertised_dynamic_tool_names, ) orelse { self.forgetTerminal(alloc, call.id); return false; }; try finishExecutedToolStatus( hooks, arena, turn_id, target.call, true, file_display_path, result, safe_result, result_memory, diff_entry, advertised_dynamic_tool_names, ); if (target.tracked_id) |tracked_id| self.forget(alloc, tracked_id); return true; } pub fn finishCancelledCall( self: *ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, alloc: Allocator, arena: Allocator, turn_id: u64, call: ToolCall, authoritative_started: bool, file_display_path: ?[]const u8, result: ToolExecutionResult, advertised_dynamic_tool_names: []const []const u8, ) !bool { const recorded_terminal = try self.recordTerminal(alloc, call.id); if (!recorded_terminal) return false; errdefer self.forgetTerminal(alloc, call.id); const target = try self.ensureTerminalTarget( hooks, arena, turn_id, call, authoritative_started, file_display_path, advertised_dynamic_tool_names, ) orelse { self.forgetTerminal(alloc, call.id); return false; }; try finishCancelledToolStatus( hooks, arena, turn_id, target.call, true, file_display_path, result, advertised_dynamic_tool_names, ); if (target.tracked_id) |tracked_id| self.forget(alloc, tracked_id); return true; } pub fn finishTrackedCancelled( self: *ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, alloc: Allocator, arena: Allocator, turn_id: u64, ) !void { while (self.tracked.items.len > 0) { const status = &self.tracked.items[self.tracked.items.len - 1]; if (self.hasTerminal(status.id)) { self.forget(alloc, status.id); continue; } const recorded_terminal = try self.recordTerminal(alloc, status.id); if (!recorded_terminal) { self.forget(alloc, status.id); continue; } errdefer self.forgetTerminal(alloc, status.id); const detail = status.label_value orelse status.tool_name; const encoded = try text_utils.encodeTerminalSafe( arena, detail, diff.max_encoded_label_bytes, ); const summary = try std.fmt.allocPrint(arena, "Cancelled {s}", .{encoded.bytes}); try hooks.push_tool_lifecycle(hooks.ctx, .{ .terminal = .{ .id = .{ .turn_id = turn_id, .call_id = status.id }, .outcome = .{ .kind = .cancelled, .summary = summary }, } }); self.forget(alloc, status.id); } } /// Settles provisional starts from an interrupted, proven-unexecuted /// stream unless the recovered completion retained their identity. pub fn finishUnmatchedRecoveryStarts( self: *ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, alloc: Allocator, arena: Allocator, turn_id: u64, recovered_calls: []const ToolCall, ) !void { var index = self.tracked.items.len; while (index > 0) { index -= 1; const status = &self.tracked.items[index]; if (trackedStatusMatchesCalls(status.*, recovered_calls)) continue; if (streamStartMayHaveExecutedAtProvider( hooks.tool_registry, status.tool_name, )) continue; if (self.hasTerminal(status.id)) { self.forget(alloc, status.id); continue; } const recorded_terminal = try self.recordTerminal(alloc, status.id); if (!recorded_terminal) { self.forget(alloc, status.id); continue; } errdefer self.forgetTerminal(alloc, status.id); const detail = status.label_value orelse status.tool_name; const encoded = try text_utils.encodeTerminalSafe( arena, detail, diff.max_encoded_label_bytes, ); const summary = try std.fmt.allocPrint( arena, "Connection interrupted before {s} ran", .{encoded.bytes}, ); try hooks.push_tool_lifecycle(hooks.ctx, .{ .terminal = .{ .id = .{ .turn_id = turn_id, .call_id = status.id }, .outcome = .{ .kind = .failed, .summary = summary }, } }); self.forget(alloc, status.id); } } pub fn visibleId(self: *const ProvisionalToolStatuses, call: ToolCall) ?[]const u8 { if (self.has(call.id)) return call.id; if (call.provisional_id) |provisional_id| { if (self.has(provisional_id)) return provisional_id; } return null; } fn record(self: *ProvisionalToolStatuses, alloc: Allocator, id: []const u8) !bool { return self.recordTracked(alloc, id, "", null); } fn recordTracked( self: *ProvisionalToolStatuses, alloc: Allocator, id: []const u8, tool_name: []const u8, label_value: ?[]const u8, ) !bool { if (id.len == 0) return false; if (self.findTracked(id)) |index| { const status = &self.tracked.items[index]; if (label_value) |value| { const owned_value = try alloc.dupe(u8, value); if (status.label_value) |prior| alloc.free(prior); status.label_value = owned_value; } return false; } const owned_id = try alloc.dupe(u8, id); errdefer alloc.free(owned_id); const owned_tool_name = try alloc.dupe(u8, tool_name);Lines 1–500 of 2164. Load more
const std = @import("std"); const command_admission = @import("../../permissions/command_admission.zig"); const permission_auto_classifier = @import("../../permissions/auto_classifier.zig"); const types = @import("../../shared/types.zig"); const text_utils = @import("../../shared/text_utils.zig"); const tool_dispatch = @import("../../tooling/tool_dispatch.zig"); const tool_specs = @import("../../tooling/tool_specs.zig"); const tooling_presentation = @import("../../tooling/tool_presentation.zig"); const debug_trace = @import("../../shared/debug_trace.zig"); const diff = @import("../../output/diff.zig"); const file_mutation_contract = @import("../../tooling/file_mutation_contract.zig"); const tool_result_errors = @import("../../tooling/tool_result_errors.zig"); const test_builtin_tools = if (@import("builtin").is_test) @import("../../../builtins/tools.zig") else struct {}; const runtime_deps = @import("deps.zig"); const runtime_tool_contracts = @import("tool_contracts.zig"); const Allocator = std.mem.Allocator; const ToolCall = types.ToolCall; const AgentRuntimeDeps = runtime_deps.AgentRuntimeDeps; const DiffEntryPayload = runtime_tool_contracts.DiffEntryPayload; const ToolExecutionResult = runtime_tool_contracts.ToolExecutionResult; pub fn isProviderSearchAlias(tool_name: []const u8) bool { return tooling_presentation.isProviderSearchAlias(tool_name); } pub fn streamStartMayHaveExecutedAtProvider( registry: tool_dispatch.Registry, tool_name: []const u8, ) bool { if (isProviderSearchAlias(tool_name)) return true; const spec = registry.lookup(tool_name) orelse return false; return spec.provider_executed; } pub const ProvisionalToolStatuses = struct { const TrackedStatus = struct { id: []u8, tool_name: []u8, label_value: ?[]u8, fn deinit(self: *TrackedStatus, alloc: Allocator) void { alloc.free(self.id); alloc.free(self.tool_name); if (self.label_value) |value| alloc.free(value); self.* = undefined; } }; tracked: std.ArrayList(TrackedStatus) = .empty, terminal_ids: std.ArrayList([]u8) = .empty, presentation_group_id: ?types.ToolPresentationGroupId = null, pub const StartPreflight = union(enum) { ineligible, eligible: struct { action_label: []const u8, activity_kind: types.ToolActivityKind, }, }; pub fn deinit(self: *ProvisionalToolStatuses, alloc: Allocator) void { for (self.tracked.items) |*status| status.deinit(alloc); self.tracked.deinit(alloc); for (self.terminal_ids.items) |id| alloc.free(id); self.terminal_ids.deinit(alloc); } pub fn preflight(registry: tool_dispatch.Registry, tool_name: []const u8) ?StartPreflight { if (tooling_presentation.isProviderSearchAlias(tool_name)) { return .{ .eligible = .{ .action_label = "Searching", .activity_kind = .read, } }; } const lookup_name = if (std.mem.eql(u8, tool_name, "run_command")) "terminal" else tool_name; const spec = registry.lookup(lookup_name) orelse return null; return switch (spec.activity_kind) { .ask, .write, .edit => .ineligible, else => .{ .eligible = .{ .action_label = spec.action_label, .activity_kind = spec.activity_kind, } }, }; } pub fn publish( self: *ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, alloc: Allocator, turn_id: u64, tool_id: []const u8, tool_name: []const u8, activity_kind: types.ToolActivityKind, action_label: []const u8, label_value: ?[]const u8, ) !void { if (tool_id.len == 0) { debug_trace.logf( "ui_activity", "suppressed provisional lifecycle with missing identity turn_id={d}", .{turn_id}, ); return; } var buf: [512]u8 = undefined; const label = try formatProvisionalProgressLabel(&buf, tool_name, action_label, label_value); const recorded = try self.recordTracked( alloc, tool_id, tool_name, label_value, ); hooks.push_tool_lifecycle(hooks.ctx, .{ .provisional = .{ .id = .{ .turn_id = turn_id, .call_id = tool_id }, .presentation_group_id = self.presentation_group_id, .tool_name = tool_name, .activity_kind = activity_kind, }, }) catch |err| { if (recorded) self.forget(alloc, tool_id); return err; }; hooks.push_tool_lifecycle(hooks.ctx, .{ .progress = .{ .id = .{ .turn_id = turn_id, .call_id = tool_id }, .text = label, }, }) catch {}; } pub fn finishMalformedToolArguments( self: *const ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, arena: Allocator, turn_id: u64, call: ToolCall, ) !void { const call_id = self.visibleId(call) orelse return; const summary = try std.fmt.allocPrint( arena, "{s} failed: invalid JSON arguments", .{call.name}, ); try hooks.push_tool_lifecycle(hooks.ctx, .{ .terminal = .{ .id = .{ .turn_id = turn_id, .call_id = call_id }, .outcome = .{ .kind = .failed, .summary = summary }, }, }); } pub fn finishMalformedProviderToolArguments( self: *const ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, arena: Allocator, turn_id: u64, calls: []const ToolCall, ) !void { for (calls) |call| { if (call.provenance != .provider_executed or call.argument_integrity != .malformed_json) continue; try self.finishMalformedToolArguments(hooks, arena, turn_id, call); } } pub fn finishRejectedCompletions( self: *const ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, arena: Allocator, turn_id: u64, calls: []const ToolCall, advertised_dynamic_tool_names: []const []const u8, ) !void { for (calls) |call| { if (!self.has(call.id)) continue; try finishDeniedToolStatus( hooks, arena, turn_id, call, true, null, "Failed", advertised_dynamic_tool_names, ); } } /// Settles one admitted call against its tracked final or provisional id. /// The tracked id is consumed only after terminal publication succeeds. pub fn settleAdmittedCall( self: *ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, alloc: Allocator, arena: Allocator, turn_id: u64, call: ToolCall, label: []const u8, advertised_dynamic_tool_names: []const []const u8, ) !bool { return self.finishDeniedCall( hooks, alloc, arena, turn_id, call, false, null, label, advertised_dynamic_tool_names, ); } pub fn settleDeferredCall( self: *ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, alloc: Allocator, arena: Allocator, turn_id: u64, call: ToolCall, advertised_dynamic_tool_names: []const []const u8, ) !bool { const recorded_terminal = try self.recordTerminal(alloc, call.id); if (!recorded_terminal) return false; errdefer self.forgetTerminal(alloc, call.id); const target = try self.ensureTerminalTarget( hooks, arena, turn_id, call, false, null, advertised_dynamic_tool_names, ) orelse { self.forgetTerminal(alloc, call.id); return false; }; try finishDeferredToolStatus( hooks, arena, turn_id, target.call, advertised_dynamic_tool_names, ); if (target.tracked_id) |tracked_id| self.forget(alloc, tracked_id); return true; } pub fn finishDeniedCall( self: *ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, alloc: Allocator, arena: Allocator, turn_id: u64, call: ToolCall, authoritative_started: bool, file_display_path: ?[]const u8, label: []const u8, advertised_dynamic_tool_names: []const []const u8, ) !bool { const recorded_terminal = try self.recordTerminal(alloc, call.id); if (!recorded_terminal) return false; errdefer self.forgetTerminal(alloc, call.id); const target = try self.ensureTerminalTarget( hooks, arena, turn_id, call, authoritative_started, file_display_path, advertised_dynamic_tool_names, ) orelse { self.forgetTerminal(alloc, call.id); return false; }; try finishDeniedToolStatus( hooks, arena, turn_id, target.call, true, file_display_path, label, advertised_dynamic_tool_names, ); if (target.tracked_id) |tracked_id| self.forget(alloc, tracked_id); return true; } pub fn finishExecutedCall( self: *ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, alloc: Allocator, arena: Allocator, turn_id: u64, call: ToolCall, authoritative_started: bool, file_display_path: ?[]const u8, result: ToolExecutionResult, safe_result: []const u8, result_memory: types.ToolResultMemory, diff_entry: ?DiffEntryPayload, advertised_dynamic_tool_names: []const []const u8, ) !bool { const recorded_terminal = try self.recordTerminal(alloc, call.id); if (!recorded_terminal) return false; errdefer self.forgetTerminal(alloc, call.id); const target = try self.ensureTerminalTarget( hooks, arena, turn_id, call, authoritative_started, file_display_path, advertised_dynamic_tool_names, ) orelse { self.forgetTerminal(alloc, call.id); return false; }; try finishExecutedToolStatus( hooks, arena, turn_id, target.call, true, file_display_path, result, safe_result, result_memory, diff_entry, advertised_dynamic_tool_names, ); if (target.tracked_id) |tracked_id| self.forget(alloc, tracked_id); return true; } pub fn finishCancelledCall( self: *ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, alloc: Allocator, arena: Allocator, turn_id: u64, call: ToolCall, authoritative_started: bool, file_display_path: ?[]const u8, result: ToolExecutionResult, advertised_dynamic_tool_names: []const []const u8, ) !bool { const recorded_terminal = try self.recordTerminal(alloc, call.id); if (!recorded_terminal) return false; errdefer self.forgetTerminal(alloc, call.id); const target = try self.ensureTerminalTarget( hooks, arena, turn_id, call, authoritative_started, file_display_path, advertised_dynamic_tool_names, ) orelse { self.forgetTerminal(alloc, call.id); return false; }; try finishCancelledToolStatus( hooks, arena, turn_id, target.call, true, file_display_path, result, advertised_dynamic_tool_names, ); if (target.tracked_id) |tracked_id| self.forget(alloc, tracked_id); return true; } pub fn finishTrackedCancelled( self: *ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, alloc: Allocator, arena: Allocator, turn_id: u64, ) !void { while (self.tracked.items.len > 0) { const status = &self.tracked.items[self.tracked.items.len - 1]; if (self.hasTerminal(status.id)) { self.forget(alloc, status.id); continue; } const recorded_terminal = try self.recordTerminal(alloc, status.id); if (!recorded_terminal) { self.forget(alloc, status.id); continue; } errdefer self.forgetTerminal(alloc, status.id); const detail = status.label_value orelse status.tool_name; const encoded = try text_utils.encodeTerminalSafe( arena, detail, diff.max_encoded_label_bytes, ); const summary = try std.fmt.allocPrint(arena, "Cancelled {s}", .{encoded.bytes}); try hooks.push_tool_lifecycle(hooks.ctx, .{ .terminal = .{ .id = .{ .turn_id = turn_id, .call_id = status.id }, .outcome = .{ .kind = .cancelled, .summary = summary }, } }); self.forget(alloc, status.id); } } /// Settles provisional starts from an interrupted, proven-unexecuted /// stream unless the recovered completion retained their identity. pub fn finishUnmatchedRecoveryStarts( self: *ProvisionalToolStatuses, hooks: *const AgentRuntimeDeps, alloc: Allocator, arena: Allocator, turn_id: u64, recovered_calls: []const ToolCall, ) !void { var index = self.tracked.items.len; while (index > 0) { index -= 1; const status = &self.tracked.items[index]; if (trackedStatusMatchesCalls(status.*, recovered_calls)) continue; if (streamStartMayHaveExecutedAtProvider( hooks.tool_registry, status.tool_name, )) continue; if (self.hasTerminal(status.id)) { self.forget(alloc, status.id); continue; } const recorded_terminal = try self.recordTerminal(alloc, status.id); if (!recorded_terminal) { self.forget(alloc, status.id); continue; } errdefer self.forgetTerminal(alloc, status.id); const detail = status.label_value orelse status.tool_name; const encoded = try text_utils.encodeTerminalSafe( arena, detail, diff.max_encoded_label_bytes, ); const summary = try std.fmt.allocPrint( arena, "Connection interrupted before {s} ran", .{encoded.bytes}, ); try hooks.push_tool_lifecycle(hooks.ctx, .{ .terminal = .{ .id = .{ .turn_id = turn_id, .call_id = status.id }, .outcome = .{ .kind = .failed, .summary = summary }, } }); self.forget(alloc, status.id); } } pub fn visibleId(self: *const ProvisionalToolStatuses, call: ToolCall) ?[]const u8 { if (self.has(call.id)) return call.id; if (call.provisional_id) |provisional_id| { if (self.has(provisional_id)) return provisional_id; } return null; } fn record(self: *ProvisionalToolStatuses, alloc: Allocator, id: []const u8) !bool { return self.recordTracked(alloc, id, "", null); } fn recordTracked( self: *ProvisionalToolStatuses, alloc: Allocator, id: []const u8, tool_name: []const u8, label_value: ?[]const u8, ) !bool { if (id.len == 0) return false; if (self.findTracked(id)) |index| { const status = &self.tracked.items[index]; if (label_value) |value| { const owned_value = try alloc.dupe(u8, value); if (status.label_value) |prior| alloc.free(prior); status.label_value = owned_value; } return false; } const owned_id = try alloc.dupe(u8, id); errdefer alloc.free(owned_id); const owned_tool_name = try alloc.dupe(u8, tool_name);