2094 lines · 88.2 KB · Zig
RawDownload
const std = @import("std");const builtin = @import("builtin");const agent_stream_provider = @import("../../stream_provider.zig");const command_admission = @import("../../../permissions/command_admission.zig");const permission_auto_classifier = @import("../../../permissions/auto_classifier.zig");const types = @import("../../../shared/types.zig");const permissions = @import("../../../permissions/permissions.zig");const worker_runtime = @import("../../worker_runtime.zig");const background_runtime = @import("../../../background/background_runtime.zig");const builtin_context = @import("../../../../builtins/context.zig");const builtin_gateway = @import("../../../../builtins/gateway.zig");const gateway_client = @import("../../../../gateway/client.zig");const builtin_tools = @import("../../../../builtins/tools.zig");const session_runtime = @import("../../../session/session.zig");const session_codec = @import("../../../session/session_codec.zig");const command_replay_store = @import("../../../session/command_replay_store.zig");const session_child_store = @import("../../../session/session_child_store.zig");const gateway_json = @import("../../../gateway/gateway_json.zig");const gateway_failure_diagnostics = @import("../../../gateway/gateway_failure_diagnostics.zig");const lifecycle_hooks = @import("../../../hooks/hooks.zig");const model_capabilities = @import("../../../config/model_capabilities.zig");const file_mutation = @import("../../../tooling/file_mutation.zig");const file_mutation_contract = @import("../../../tooling/file_mutation_contract.zig");const context_contract = @import("../../../workspace/context_contract.zig");const io_mod = @import("../../../shared/io.zig");const pathing = @import("../../../workspace/pathing.zig");const tool_dispatch = @import("../../../tooling/tool_dispatch.zig");const tool_runtime = @import("../../../tooling/tool_runtime.zig");const command_output_content = @import("../../../tooling/command_output_content.zig");const testing_write_file = if (builtin.is_test)    @import("../../../../tools/filesystem/write_file.zig")else    struct {};const testing_edit_file = if (builtin.is_test)    @import("../../../../tools/filesystem/edit_file.zig")else    struct {}; const runtime_config = @import("../config.zig");const runtime_deps = @import("../deps.zig");const runtime_lifecycle = @import("../lifecycle.zig");const model_response_recovery = @import("../model_response_recovery.zig");const runtime_orchestrator = @import("../orchestrator.zig");const runtime_tool_contracts = @import("../tool_contracts.zig"); const Allocator = std.mem.Allocator;const ChatMessage = types.ChatMessage;const HistoryTurn = types.HistoryTurn;const PermissionGrant = types.PermissionGrant;const PermissionMode = types.PermissionMode;const ToolCall = types.ToolCall;const ToolPermissionDecision = types.ToolPermissionDecision;const QueuedPrompt = worker_runtime.QueuedPrompt;const WorkerEvent = worker_runtime.WorkerEvent;const AgentRuntimeDeps = runtime_deps.AgentRuntimeDeps;const Config = runtime_config.Config;const ToolExecutionResult = runtime_tool_contracts.ToolExecutionResult;const ToolExecutionRequest = runtime_tool_contracts.ToolExecutionRequest;const SandboxScopeRequired = runtime_tool_contracts.SandboxScopeRequired;const ToolCallValidationResult = runtime_tool_contracts.ToolCallValidationResult;const DiffEntryPayload = runtime_tool_contracts.DiffEntryPayload;const SecondaryPublicationReport = runtime_tool_contracts.SecondaryPublicationReport; pub const vision_agent_test_tools = [_]tool_dispatch.Tool{builtin_tools.vision}; pub const VisionAgentToolRuntime = struct {    alloc: Allocator,    workspace_root: []const u8 = "/tmp/workspace",    session_id: ?[]const u8 = null,    agent_stream_provider: agent_stream_provider.Provider = agent_stream_provider.unavailable_provider,    result_allocator_override: ?Allocator = null,    execution_count: usize = 0,    result_count: usize = 0,    worker: worker_runtime.WorkerRuntime = .{},    background: background_runtime.BackgroundRuntime = .{},    session: session_runtime.SessionRuntime = .{ .max_history_turns = 8 },     pub fn deinit(self: *VisionAgentToolRuntime) void {        self.worker.deinit(self.alloc);        self.background.deinit(self.alloc);        self.session.deinit(self.alloc);    }     pub fn delegate(self: *VisionAgentToolRuntime) ExecuteDelegate {        return .{            .ctx = self,            .run = execute,            .set_agent_stream_provider = setAgentStreamProvider,        };    }     fn setAgentStreamProvider(raw: *anyopaque, provider: agent_stream_provider.Provider) void {        const self: *VisionAgentToolRuntime = @ptrCast(@alignCast(raw));        self.agent_stream_provider = provider;    }     fn execute(raw: *anyopaque, request: ToolExecutionRequest) !ToolExecutionResult {        const self: *VisionAgentToolRuntime = @ptrCast(@alignCast(raw));        self.execution_count += 1;        var effective_request = request;        effective_request.result_allocator = self.result_allocator_override orelse            request.result_allocator;        const result = try tool_runtime.executeToolCallAuthorized(            self.context(),            effective_request,        );        self.result_count += 1;        return result;    }     fn context(self: *VisionAgentToolRuntime) tool_runtime.Context {        return .{            .workspace_root = self.workspace_root,            .ignored_list_entries = &.{},            .max_list_entries = 100,            .max_read_file_bytes = 64 * 1024,            .max_read_file_lines = 400,            .max_read_file_line_len = 2000,            .max_command_output_bytes = 64 * 1024,            .max_tool_result_bytes = 64 * 1024,            .api_key = "key",            .agent_stream_provider = self.agent_stream_provider,            .model = "anthropic/claude-opus-4.6",            .gateway_retry_count = 1,            .gateway_chat_url = "https://example.invalid",            .agent_step_limit = 8,            .tool_registry = .{ .tools = vision_agent_test_tools[0..] },            .permission_mode = .ask,            .permission_grants = &.{},            .permission_rules = .{},            .worker = &self.worker,            .background = &self.background,            .session = &self.session,            .session_allocator = self.alloc,            .context_limits = .{ .image_adapter_output_bytes = .{                .value = .{ .bytes = 64 * 1024 },                .source = .command_line,            } },            .context_registry = .{ .default_provider = builtin_context.provider },            .lifecycle_scope = .{                .kind = .interactive,                .workspace_root = self.workspace_root,                .session_id = self.session_id,            },            .output_chunk_ctx = undefined,            .on_output_chunk = discardVisionToolOutput,            .background_url_ctx = undefined,            .on_background_url_ready = discardVisionBackgroundUrl,        };    }}; fn discardVisionToolOutput(    _: *anyopaque,    _: ?types.ToolLifecycleId,    _: command_output_content.Stream,    _: []const u8,) anyerror!void {} fn discardVisionBackgroundUrl(_: *anyopaque, _: u64, _: []const u8) void {} const test_tools = [_]tool_dispatch.Tool{    builtin_tools.list_files,    builtin_tools.glob_files,    builtin_tools.grep_files,    builtin_tools.read_file,    builtin_tools.write_file,    builtin_tools.edit_file,    builtin_tools.delete_file,    builtin_tools.rename_file,    builtin_tools.copy_file,    builtin_tools.create_folder,    builtin_tools.file_info,    builtin_tools.memory,    builtin_tools.semantic_search,    builtin_tools.open_file,    builtin_tools.web_fetch,    builtin_tools.web_search,    builtin_tools.terminal,    builtin_tools.skill,    builtin_tools.install_skill,    builtin_tools.subagent,    builtin_tools.mcp_search_tools,    builtin_tools.mcp_select_tool,    builtin_tools.ask_user_question,    builtin_tools.read_tool_result,};const test_tool_registry = tool_dispatch.Registry{ .tools = test_tools[0..] }; fn testExecutionAuthority(call: ToolCall) command_admission.ToolExecutionAuthority {    return testExecutionAuthorityWithScope(call, .restricted);} fn testExecutionAuthorityWithScope(    call: ToolCall,    scope: permission_auto_classifier.SandboxScope,) command_admission.ToolExecutionAuthority {    if (!std.mem.eql(u8, call.name, "terminal")) return .ordinary;    return .{ .run_command = .{ .shell_allowed = .{        .fingerprint = .{            .command = call.arguments_json,            .resolved_cwd = "",            .background = false,            .resolved_backend = .none,            .target_os = builtin.os.tag,            .scope = scope,        },        .source = .interactive_once,    } } };} pub const FakeCompletion = struct {    status: std.http.Status = .ok,    err_body: ?[]const u8 = null,    retry_after_seconds: ?u64 = null,    pre_send_error: ?anyerror = null,    stream_error: ?anyerror = null,    stream_error_after_chunks: ?anyerror = null,    stream_error_after_tool_starts: ?anyerror = null,    chunks: []const []const u8 = &.{},    reasoning_chunks: []const []const u8 = &.{},    content: ?[]const u8 = null,    tool_calls: []const ToolCall = &.{},    streamed_tool_starts: []const ToolCall = &.{},    provider_result_identity_failure: ?types.ProviderResultIdentityFailure = null,    provider_failure_detail: ?[]const u8 = null,    finish_reason: ?types.ProviderFinishReason = null,    omit_finish: bool = false,    usage: types.Usage = .{},    delivery_ambiguous: bool = false,    pause_before_output: bool = false,    cancel_before_output: bool = false,    cancel_after_chunks: bool = false,    cancel_during_tool_stream: bool = false,}; pub const FakeGateway = struct {    alloc: Allocator,    completions: []const FakeCompletion,    index: usize = 0,    request_bodies: std.ArrayList([]u8) = .empty,    request_models: std.ArrayList([]u8) = .empty,    request_api_keys: std.ArrayList([]u8) = .empty,    request_session_ids: std.ArrayList(?[]u8) = .empty,    recovery_pause_flag: ?*std.atomic.Value(bool) = null,     pub fn init(alloc: Allocator, completions: []const FakeCompletion) FakeGateway {        return .{ .alloc = alloc, .completions = completions };    }     pub fn deinit(self: *FakeGateway) void {        for (self.request_bodies.items) |body| self.alloc.free(body);        self.request_bodies.deinit(self.alloc);        for (self.request_models.items) |model| self.alloc.free(model);        self.request_models.deinit(self.alloc);        for (self.request_api_keys.items) |api_key| self.alloc.free(api_key);        self.request_api_keys.deinit(self.alloc);        for (self.request_session_ids.items) |session_id| {            if (session_id) |id| self.alloc.free(id);        }        self.request_session_ids.deinit(self.alloc);    }     pub fn provider(self: *FakeGateway) agent_stream_provider.Provider {        var result = builtin_gateway.agent_stream_provider;        result.context = self;        result.stream_fn = fakeGatewayStream;        return result;    }     fn stream(        self: *FakeGateway,        alloc: Allocator,        request: agent_stream_provider.Request,    ) !agent_stream_provider.Result {        try self.request_bodies.append(self.alloc, try self.alloc.dupe(u8, request.payload));        try self.request_models.append(self.alloc, try self.alloc.dupe(u8, request.model));        try self.request_api_keys.append(self.alloc, try self.alloc.dupe(u8, request.api_key));        const session_id = if (request.session_id) |id| try self.alloc.dupe(u8, id) else null;        errdefer if (session_id) |id| self.alloc.free(id);        try self.request_session_ids.append(self.alloc, session_id);        if (self.index >= self.completions.len) return error.TestUnexpectedGatewayRequest;        const completion = self.completions[self.index];        self.index += 1;         if (completion.pre_send_error) |err| {            recordNetworkFailureEvidence(request, err);            return err;        }        request.delivery.markPossiblySent();         if (completion.stream_error) |err| {            recordNetworkFailureEvidence(request, err);            return err;        }         if (completion.pause_before_output) {            if (self.recovery_pause_flag) |flag| flag.store(true, .seq_cst);            request.cancel_flag.store(true, .seq_cst);            return error.Cancelled;        }        if (completion.cancel_before_output) {            request.cancel_flag.store(true, .seq_cst);            return .{ .status = .ok };        }         if (request.on_reasoning_chunk) |reasoning| {            for (completion.reasoning_chunks) |chunk| reasoning(request.callback_ctx, chunk);        }        for (completion.chunks) |chunk| {            request.on_content_chunk(request.callback_ctx, chunk);        }        if (completion.cancel_after_chunks) request.cancel_flag.store(true, .seq_cst);        if (completion.stream_error_after_chunks) |err| {            recordNetworkFailureEvidence(request, err);            return err;        }        if (request.on_tool_start) |start| {            for (completion.streamed_tool_starts) |call| {                start(request.callback_ctx, call.id, call.name, null);            }        }        if (completion.stream_error_after_tool_starts) |err| {            recordNetworkFailureEvidence(request, err);            return err;        }        if (completion.cancel_during_tool_stream) {            request.cancel_flag.store(true, .seq_cst);            return error.Cancelled;        }        if (completion.status != .ok) {            const err_body = if (completion.err_body) |body| try alloc.dupe(u8, body) else null;            const diagnostics = gateway_failure_diagnostics.collect(alloc, request.payload, err_body);            return .{                .status = completion.status,                .err_body = err_body,                .retry_after_seconds = completion.retry_after_seconds,                .failure_schema = diagnostics.schema,                .failure_request_shape = diagnostics.request_shape,                .ownership = .owned,            };        }         return .{            .status = .ok,            .completion = .{                .content = completion.content,                .tool_calls = completion.tool_calls,                .provider_result_identity_failure = completion.provider_result_identity_failure,                .provider_failure_detail = completion.provider_failure_detail,                .delivery_ambiguous = completion.delivery_ambiguous,                .finish_reason = if (completion.omit_finish)                    null                else                    completion.finish_reason orelse if (completion.tool_calls.len > 0) .tool_calls else .stop,                .usage = completion.usage,            },            .generation_origin = "https://ai-gateway.vercel.sh",        };    }     fn recordNetworkFailureEvidence(        request: agent_stream_provider.Request,        err: anyerror,    ) void {        request.attempt_evidence.network_failure = gateway_client.networkFailureEvidence(            err,            request.delivery.load(),        );    }}; pub const ModelCapabilityOverride = struct {    model: []const u8,    capabilities: model_capabilities.Capabilities,}; fn fakeGatewayStream(    context: ?*anyopaque,    alloc: Allocator,    request: agent_stream_provider.Request,) !agent_stream_provider.Result {    const gateway: *FakeGateway = @ptrCast(@alignCast(context.?));    return gateway.stream(alloc, request);} pub const FakeExecPlan = union(enum) {    result: ToolExecutionResult,    err: anyerror,}; pub const ExecuteDelegate = struct {    ctx: *anyopaque,    run: *const fn (*anyopaque, ToolExecutionRequest) anyerror!ToolExecutionResult,    set_agent_stream_provider: ?*const fn (*anyopaque, agent_stream_provider.Provider) void = null,}; pub const PermissionRequestOverride = struct {    context: *anyopaque,    request_fn: *const fn (        *anyopaque,        Allocator,        ToolCall,        permission_auto_classifier.ReviewTurnContext,        PermissionMode,        []const PermissionGrant,        ?runtime_tool_contracts.LiveToolAuthority,        ?runtime_tool_contracts.LivePermissionRevalidation,        []const []const u8,    ) anyerror!command_admission.PermissionOutcome,}; pub const SandboxWideningRequestOverride = struct {    context: *anyopaque,    request_fn: *const fn (        *anyopaque,        Allocator,        ToolCall,        permission_auto_classifier.ReviewTurnContext,        PermissionMode,        []const PermissionGrant,        ?runtime_tool_contracts.LiveToolAuthority,        []const []const u8,        SandboxScopeRequired,    ) anyerror!command_admission.PermissionOutcome,}; pub const ToolExecutionOverride = struct {    context: *anyopaque,    execute_fn: *const fn (        *anyopaque,        ToolExecutionRequest,    ) anyerror!ToolExecutionResult,}; fn captureReviewAuthority(    alloc: Allocator,    review_turn: permission_auto_classifier.ReviewTurnContext,) ![]u8 {    var captured: std.ArrayList(u8) = .empty;    errdefer captured.deinit(alloc);    if (review_turn.current_root_request.len > 0) {        try captured.appendSlice(alloc, review_turn.current_root_request);        try captured.append(alloc, '\n');    }    return captured.toOwnedSlice(alloc);} pub const FakeAgentRuntimeDeps = struct {    alloc: Allocator,    agent_stream_provider: agent_stream_provider.Provider = agent_stream_provider.unavailable_provider,    live_tool_authority: ?runtime_deps.LiveToolAuthorityProvider = null,    tool_activity_recorder: ?runtime_deps.ToolActivityRecorder = null,    tool_registry: tool_dispatch.Registry = test_tool_registry,    context_registry: ?context_contract.Registry = null,    context_enabled: bool = false,    execute_mutex: std.Io.Mutex = .init,    log: std.ArrayList([]u8) = .empty,    texts: std.ArrayList([]u8) = .empty,    system_notices: std.ArrayList([]u8) = .empty,    interactive_notices: std.ArrayList(types.SemanticNotice) = .empty,    context_notices: std.ArrayList([]u8) = .empty,    route_recovery_statuses: std.ArrayList(types.RouteRecoveryStatus) = .empty,    permission_names: std.ArrayList([]u8) = .empty,    permission_call_ids: std.ArrayList([]u8) = .empty,    permission_user_intent_contexts: std.ArrayList([]u8) = .empty,    permission_review_models: std.ArrayList([]u8) = .empty,    permission_review_target_call_ids: std.ArrayList([]u8) = .empty,    permission_review_origins: std.ArrayList(permission_auto_classifier.ReviewOrigin) = .empty,    permission_review_root_authority_counts: std.ArrayList(usize) = .empty,    permission_review_feedback_counts: std.ArrayList(usize) = .empty,    permission_review_pending_call_counts: std.ArrayList(usize) = .empty,    sandbox_widening_user_intent_contexts: std.ArrayList([]u8) = .empty,    executed_names: std.ArrayList([]u8) = .empty,    executed_call_ids: std.ArrayList([]u8) = .empty,    rejected_names: std.ArrayList([]u8) = .empty,    inner_usage_names: std.ArrayList([]u8) = .empty,    inner_usages: std.ArrayList(types.ToolUsage) = .empty,    validated_names: std.ArrayList([]u8) = .empty,    availability_checked_names: std.ArrayList([]u8) = .empty,    execution_classification_complete: std.ArrayList(bool) = .empty,    last_validated_arguments: ?[]u8 = null,    last_permission_arguments: ?[]u8 = null,    last_executed_arguments: ?[]u8 = null,    last_execute_root_user_intent_context: ?[]u8 = null,    last_execute_root_user_messages: std.ArrayList([]u8) = .empty,    last_execute_root_user_evidence_complete: bool = false,    propagated_grants: std.ArrayList(PermissionGrant) = .empty,    event_grants: std.ArrayList(PermissionGrant) = .empty,    last_execute_grants: std.ArrayList(PermissionGrant) = .empty,    last_live_authority_generation: ?u64 = null,    last_live_authority_sandbox: ?types.BackendKind = null,    last_live_authority_tool_count: usize = 0,    last_live_authority_integration_count: usize = 0,    last_live_authority_rule_count: usize = 0,    last_live_authority_grant_count: usize = 0,    last_frozen_file_grants: std.ArrayList(PermissionGrant) = .empty,    permission_decisions: []const ToolPermissionDecision = &.{},    permission_auto_review_results: []const ?permission_auto_classifier.Result = &.{},    permission_denial_reasons: []const types.ToolPermissionDenialReason = &.{},

Lines 1–500 of 2094.