diff options
| author | t <t@tjp.lol> | 2026-10-30 01:58:33 -0600 |
|---|---|---|
| committer | t <t@tjp.lol> | 2026-10-30 08:17:49 -0600 |
| commit | 61863eb46d88a69e95c3f748a1e9df2d4b547f2a (patch) | |
| tree | af257d8e46d500327d315c711fe381057ce25cc9 /_selfcheck.lua | |
| parent | a139aba0d7426c5961ea26ec8d1ce70de25f12e6 (diff) | |
Drive the warm turn from the luv timer with callback run_async, caching
only its termination, and abandon with a nonjoining close. Removes native
job polling. Adds binding-check.lua, a real-binding check against local HTTP
fixtures, to mise run check.
Requires a Pantograph host with callback-form run_async.
Diffstat (limited to '_selfcheck.lua')
| -rw-r--r-- | _selfcheck.lua | 167 |
1 files changed, 149 insertions, 18 deletions
diff --git a/_selfcheck.lua b/_selfcheck.lua index 6cc3e4a..3231646 100644 --- a/_selfcheck.lua +++ b/_selfcheck.lua @@ -184,37 +184,168 @@ do local previous_warm = package.loaded["warming.warm"] package.loaded["warming.config"] = { default_io = function() return {} end, - read = function() return { enabled = true, interval_ms = MIN, duration_ms = MIN, prompt = "OK" } end, + read = function() return { enabled = true, interval_ms = 1, duration_ms = 100, prompt = "OK" } end, } - package.loaded["warming.policy"] = { - new = function() - return { - activity = function(self, now) self.activity_at = now end, - turn_started = function() end, turn_ended = function() end, - expired = function() return false end, due = function() return false end, - attempted = function() end, + package.loaded["warming.policy"] = policy + local real_warm = require("warming.warm") + local handles = {} + package.loaded["warming.warm"] = { + start = function(...) + local handle, err = real_warm.start(...) + if handle then handles[#handles + 1] = handle end + return handle, err + end, + poll = real_warm.poll, + abandon = real_warm.abandon, + } + local starts, callback_queue, forbidden_calls = {}, {}, 0 + local transcript, no_store = {}, {} + local declarations = { { name = "tool", parameters = {} } } + local session_store = { + load = function(_, id) + assert(id == "session-1", "warm request loads the active transcript") + return transcript + end, + } + local warm_agent = { + set_tools = function(_, tools) + assert(tools == declarations, "session tool declarations are copied") + end, + run_async = function(_, request, on_delivery) + assert(type(on_delivery) == "function", "callback form is used") + assert(request.prompt == "OK" and request.dispatch_tools == false, + "the transient request preserves tool isolation") + local stream = { + close = function(self) self.close_calls = (self.close_calls or 0) + 1 end, } + for _, name in ipairs({ "next_event", "result", "request_cancel", "join" }) do + stream[name] = function() + forbidden_calls = forbidden_calls + 1 + error("legacy native-job method used: " .. name) + end + end + starts[#starts + 1] = { request = request, callback = on_delivery, stream = stream } + return stream end, } - package.loaded["warming.warm"] = { start = function() end, poll = function() end, abandon = function() end } - package.loaded.panto = { agent = function() end, ext = { - on = function(name, handler) handlers[name] = handler end, - resolve_model = function() end, - style = function() return { dim = "", reset = "" } end, - } } + local current_time, timer + package.loaded.panto = { + file_system_jsonl_store = function(options) + assert(options.dir == "/sessions", "the active session store is reused") + return session_store + end, + null_store = function() return no_store end, + agent = function(options) + assert(options.conversation == transcript and options.store == no_store, + "the warm agent is isolated over the replayed transcript") + return warm_agent + end, + ext = { + on = function(name, handler) handlers[name] = handler end, + session_info = function() + return { session_dir = "/sessions", session_id = "session-1", model = "model", reasoning = "low" } + end, + resolve_model = function(options) + assert(options.model == "model" and options.reasoning == "low", "session model is retained") + return { resolved = true } + end, + agent = { tools = function() return declarations end }, + style = function() return { dim = "", reset = "" } end, + }, + } package.loaded.luv = { - now = function() return 123 end, + now = function() return current_time end, new_timer = function() - return { start = function(self) self.active = true end, is_active = function(self) return self.active end, - is_closing = function() return false end, stop = function(self) self.active = false end, - close = function() end } + timer = { + start = function(self, _, _, callback) + self.callback = callback + self.active = true + end, + is_active = function(self) return self.active end, + is_closing = function(self) return self.closing or false end, + stop = function(self) self.active = false end, + close = function(self) self.closing = true end, + } + return timer end, } local active_entry = assert(loadfile(here .. "/init.lua"))() active_entry.activate() assert(handlers.render_header and handlers.session_ready, "new event subscriptions are installed") assert(handlers.session_start == nil, "old session_start subscription is absent") + current_time = 0 handlers.session_ready() + assert(timer and timer.active, "session readiness starts the timer") + + local function tick(at) + current_time = at + timer.callback() + end + local function queue_delivery(index, delivery) + callback_queue[#callback_queue + 1] = { index = index, delivery = delivery } + end + local function advance_delivery() + local queued = table.remove(callback_queue, 1) + assert(queued ~= nil, "callback queue has a delivery to advance") + starts[queued.index].callback(queued.delivery) + end + + tick(0) + assert(#starts == 0, "the interval prevents an immediate turn") + tick(1) + assert(#starts == 1 and #callback_queue == 0 and handles[1].result == nil, + "installation returns before any callback is queued or delivered") + assert(handles[1].agent == warm_agent and handles[1].store == session_store + and handles[1].conv == transcript, "owners stay rooted while the turn is live") + queue_delivery(1, { kind = "result", result = { type = "message_start" } }) + assert(handles[1].result == nil, "queued values do not settle before delivery") + advance_delivery() + tick(2) + assert(#starts == 1 and handles[1].result == nil, "result events are discarded, not settled") + queue_delivery(1, { kind = "termination", status = "completed" }) + advance_delivery() + assert(handles[1].result.status == "completed", "completed termination is cached") + tick(3) + assert(#starts == 1, "the completion tick only settles the previous attempt") + + tick(4) + assert(#starts == 2, "the next timer turn starts after the interval") + queue_delivery(1, { kind = "termination", status = "cancelled" }) + advance_delivery() + assert(handles[1].result.status == "completed", "a stale callback cannot rewrite a prior terminal") + tick(4.5) + assert(#starts == 2 and handles[2].result == nil, + "a stale callback cannot settle or replace the current handle") + queue_delivery(2, { kind = "termination", status = "failed", error = { message = "provider failure" } }) + advance_delivery() + tick(5) + assert(handles[2].result.status == "failed" and handles[2].result.err == "provider failure", + "failure termination and its diagnostic are cached") + + tick(6) + assert(#starts == 3, "a failed attempt retries after the interval") + queue_delivery(3, { kind = "termination", status = "cancelled" }) + advance_delivery() + tick(7) + assert(handles[3].result.status == "cancelled", "cancel termination settles the attempt") + + tick(8) + assert(#starts == 4, "a cancelled attempt also follows the retry policy") + local abandoned = handles[4] + handlers.session_end() + assert(timer.closing and not timer.active, "session teardown stops and closes its timer") + assert(abandoned.stream.close_calls == 1 and abandoned.abandoned, + "teardown closes the live subscription without joining") + assert(abandoned.agent == warm_agent and abandoned.store == session_store + and abandoned.conv == transcript, "teardown retains owners through state retirement") + queue_delivery(4, { kind = "termination", status = "completed" }) + advance_delivery() + assert(real_warm.poll(abandoned) == nil, "a stale post-close delivery cannot settle an abandoned turn") + tick(9) + handlers.session_ready() + assert(#starts == 4, "stale timer/session callbacks cannot start work after teardown") + assert(forbidden_calls == 0, "no next_event, native result, cancel-join, or join API was used") + local inner = { render = function() return { "header" } end } local event = { get_component = function() return inner end } event.set_component = function(_, component) event.component = component end |
