mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-10-10 13:22:09 -04:00
agent: pump session during terminal idle
Updates isocline to support idle callbacks and registers a hook to pump the session's curl multi while waiting for user input. This prevents connection timeouts. Also refactors the idle pumping logic into `Session.idleSlice` to share it with the MCP server.
This commit is contained in:
1 parent
30c8bcbdd9
commit
d292f2b342
5 files changed
+28
-14
No files matched your search
+2
-2
@@ -39,8 +39,8 @@
|
||||
.hash = "zenai-0.0.0-iOY_VDVqBAA3mH3_90Lg7Vz3JK8oD0gIhcete_M9c1UC",
|
||||
},
|
||||
.isocline = .{
|
||||
.url = "git+https://github.com/arrufat/isocline?ref=lightpanda#77ff0c32b344a7fcf33f418cb9ccc14531c64997",
|
||||
.hash = "N-V-__8AAMFfEwCVkwwv9MwT6R1vcXwTmJn60QGSz-uPK3b9",
|
||||
.url = "git+https://github.com/arrufat/isocline?ref=lightpanda#832a9fe25f5f4458fcc47b5acc7c21db669c2f47",
|
||||
.hash = "N-V-__8AANtqEwD-jr5LWeksHDYkaQSpLbu6MRHFvlPURIik",
|
||||
},
|
||||
},
|
||||
.paths = .{""},
|
||||
|
||||
@@ -381,6 +381,7 @@ pub fn init(allocator: std.mem.Allocator, app: *App, opts: Config.Agent) !*Agent
|
||||
};
|
||||
// The model-list cache fills lazily on the first `/model` completion,
|
||||
// so startup never blocks on the network.
|
||||
Terminal.setIdleCallback(&idlePump, @ptrCast(self));
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -403,6 +404,12 @@ pub fn deinit(self: *Agent) void {
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
|
||||
/// isocline idle hook; returns the delay in ms before the next invocation.
|
||||
fn idlePump(arg: ?*anyopaque) callconv(.c) c_long {
|
||||
const self: *Agent = @ptrCast(@alignCast(arg.?));
|
||||
return self.session.idleSlice();
|
||||
}
|
||||
|
||||
/// Create a fresh browser session and wire its cancel hook back to this agent
|
||||
/// so Ctrl-C aborts in-flight page work. Startup and `/reset`.
|
||||
fn startSession(self: *Agent) !void {
|
||||
|
||||
@@ -937,6 +937,10 @@ fn highlightSlashArgs(henv: ?*c.ic_highlight_env_t, text: []const u8, start: usi
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setIdleCallback(fun: ?*const c.ic_idle_fun_t, arg: ?*anyopaque) void {
|
||||
c.ic_set_idle_callback(fun, arg);
|
||||
}
|
||||
|
||||
pub fn readLine(prompt: [*:0]const u8) ?[]const u8 {
|
||||
// Kitty-keyboard "disambiguate" (Ctrl+Enter as a distinct CSI-u, not bare
|
||||
// \r) only while isocline reads: while active, Ctrl-C arrives as a CSI-u
|
||||
|
||||
@@ -401,6 +401,20 @@ pub fn runner(self: *Session, opts: Runner.Opts) !Runner {
|
||||
return Runner.init(self, opts);
|
||||
}
|
||||
|
||||
/// Page transfers run on the session thread's curl multi; left unserviced
|
||||
/// while the frontend waits on input they die on curl's wall-clock timeout.
|
||||
/// Returns how long the caller may block before pumping again.
|
||||
pub fn idleSlice(self: *Session) u31 {
|
||||
const quiet_ms = 250;
|
||||
self.processDestroyQueues();
|
||||
var r = self.runner(.{}) catch return quiet_ms;
|
||||
const result = r.tick(.{ .ms = 25 }) catch return quiet_ms;
|
||||
return switch (result) {
|
||||
.done => quiet_ms,
|
||||
.ok => |next_ms| @intCast(@min(next_ms, quiet_ms)),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn scheduleNavigation(self: *Session, frame: *Frame) !void {
|
||||
return self.currentPage().?.scheduleNavigation(frame);
|
||||
}
|
||||
|
||||
+1
-12
@@ -66,19 +66,8 @@ pub fn deinit(self: *Self) void {
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
|
||||
/// Pump the browser session for one short slice while the server waits on
|
||||
/// input. Page transfers live on this thread's curl multi; left unserviced
|
||||
/// between tool calls they die on curl's wall-clock timeout. Returns how
|
||||
/// long the caller may block before pumping again.
|
||||
pub fn idle(self: *Self) u31 {
|
||||
const quiet_ms = 250;
|
||||
self.session.processDestroyQueues();
|
||||
var runner = self.session.runner(.{}) catch return quiet_ms; // no page yet
|
||||
const result = runner.tick(.{ .ms = 25 }) catch return quiet_ms;
|
||||
return switch (result) {
|
||||
.done => quiet_ms,
|
||||
.ok => |next_ms| @intCast(@min(next_ms, quiet_ms)),
|
||||
};
|
||||
return self.session.idleSlice();
|
||||
}
|
||||
|
||||
pub fn sendError(self: *Self, id: std.json.Value, code: protocol.ErrorCode, message: []const u8) !void {
|
||||
|
||||
Reference in new issue
Block a user