From 80075efd6bfd01df48a9f0e5967d89f7a7467d5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Arrufat?= Date: Tue, 5 May 2026 08:16:01 +0200 Subject: [PATCH] agent: centralize session and node registry resets --- src/agent/Agent.zig | 8 +++++++- src/agent/McpServer.zig | 2 +- src/agent/ToolExecutor.zig | 9 +++++++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/agent/Agent.zig b/src/agent/Agent.zig index d364b92e..36b4cacf 100644 --- a/src/agent/Agent.zig +++ b/src/agent/Agent.zig @@ -878,6 +878,12 @@ fn attemptSelfHeal(self: *Self, arena: std.mem.Allocator, failed_command: []cons return null; } +/// Tear down the browser session and start fresh. Used by the MCP `task` tool +/// when the caller asks for an isolated run. +pub fn resetSession(self: *Self) !void { + return self.tool_executor.resetSession(); +} + /// MCP entry point: run a single user task with a clean LLM context. Browser /// state (URL, cookies, etc.) is preserved by default; pass a fresh session /// upstream if isolation is needed. Returns the assistant text on success @@ -892,7 +898,7 @@ pub fn runOneTask( _ = self.message_arena.reset(.retain_capacity); // Each task gets a fresh LLM context; drop registry entries that point // into the old session so a stray backendNodeId can't survive a navigation. - self.tool_executor.node_registry.reset(); + self.tool_executor.resetNodeRegistry(); self.one_shot_attachments = attachments; return self.processUserMessage(task, null); } diff --git a/src/agent/McpServer.zig b/src/agent/McpServer.zig index 37302c30..75ac0a24 100644 --- a/src/agent/McpServer.zig +++ b/src/agent/McpServer.zig @@ -111,7 +111,7 @@ pub fn handleToolCall(self: *Self, arena: std.mem.Allocator, req: protocol.Reque } if (args.fresh orelse false) { - self.agent.tool_executor.resetSession() catch |err| { + self.agent.resetSession() catch |err| { log.err(.mcp, "fresh session reset failed", .{ .err = err }); return self.sendErrorResult(id, "Failed to start a fresh browser session"); }; diff --git a/src/agent/ToolExecutor.zig b/src/agent/ToolExecutor.zig index f520e605..dc07fe9a 100644 --- a/src/agent/ToolExecutor.zig +++ b/src/agent/ToolExecutor.zig @@ -49,12 +49,17 @@ pub fn deinit(self: *Self) void { } /// Tear down the current `Browser` and `Session` and replace them with -/// fresh ones. Caller is responsible for clearing any registry/cache -/// state that depended on the old session. +/// fresh ones. Also clears the node registry, since backendNodeIds from +/// the old session would dangle into the new one. pub fn resetSession(self: *Self) !void { self.browser.deinit(); try self.browser.init(self.app, .{}, null); self.session = try self.browser.newSession(self.notification); + self.node_registry.reset(); +} + +pub fn resetNodeRegistry(self: *Self) void { + self.node_registry.reset(); } pub const CallError = browser_tools.ToolError || error{InvalidJsonArguments};