Commit graph

3 commits

Author SHA1 Message Date
Ouroboros
6df27fc33d Release the held reviewer tool on an event, not on a wall-clock timer
tests/test_native_tool_timeout.py::test_abandoned_call_stops_the_episode_crediting_read_extents
failed the macos-latest full-test leg of #1187 ('error' == 'executed'). The
tool bound is 0.3 s, the first call is abandoned at 0.3 s, and a timer freed
the tool at 0.6 s, which put the SECOND call exactly on its own 0.3 s bound:
locally it won by hundredths of a second, a slow runner lost. The tool is now
freed the moment the model is asked a second time, which can only happen
after the abandonment. Test-only; no production code changes.
2026-09-21 15:30:37 +03:00
Anton
4d0101f279 test: stabilize cross-platform CI fixtures
Co-authored-by: Ouroboros <311266734+ouroboros-agent@users.noreply.github.com>
2026-09-21 12:56:53 +03:00
Ouroboros
8678cee2fc Bound a reviewer's inspection tool call with the loop's own timeout policy
`review_native_episode` held the runtime's only bare `registry.execute`: an
omission left behind when the round cap was removed, not a decision. The
episode reads its clock only before a model send, so one wedged tool call kept
a reviewer slot silent for 7 h 16 min while every other bound (owner deadline,
transcript, ledger) stayed unarmed.

The call now resolves its number through the SAME per-tool policy every other
tool call uses and narrows it by whatever calendar/execution bound the reviewer
already inherited — no new number, no floor, no elapsed-time classifier. Past
the bound the call is abandoned on its private worker through the late
settlement mechanics the loop already owns, extracted so both callers share
one: the reviewer hears the host's own TOOL_TIMEOUT sentence, the receipt is an
error carrying `native_tool_abandoned`, and a worker loose on the shared
inspection context retires the episode's read attribution, so a late stamp can
never become this episode's coverage. `compact_context` stays unwrapped: it is
this thread's bookkeeping over the transcript, not a call that can wedge.

Receipts also carry `started_at` and `duration_sec` on one clock domain, so the
next time a reviewer goes quiet the host can say which call it was waiting on.

Co-authored-by: Ouroboros <311266734+ouroboros-agent@users.noreply.github.com>
2026-09-21 04:39:19 +03:00