summaryrefslogtreecommitdiff
path: root/_selfcheck.lua
diff options
context:
space:
mode:
authort <t@tjp.lol>2026-10-30 01:58:33 -0600
committert <t@tjp.lol>2026-10-30 08:17:49 -0600
commit61863eb46d88a69e95c3f748a1e9df2d4b547f2a (patch)
treeaf257d8e46d500327d315c711fe381057ce25cc9 /_selfcheck.lua
parenta139aba0d7426c5961ea26ec8d1ce70de25f12e6 (diff)
Start warming turns with callback-form run_asyncHEADv0.2.0main
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.lua167
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