2164 lines · 76.6 KB · Zig
RawDownload
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.