Repository navigation
0.15.1
Added
create_chat_router(request_factory=…)accepts an async factory. The
factory may now beasync def(or otherwise return an awaitable); its result
is awaited before the turn runs, e.g. to look up the authenticated user with a
query. The sync form is unchanged.
Fixed
Runtime.astreamleft a pendingqueue.get()/done.wait()task. In the
event/donewait loop the losing future was cancelled but never awaited (and
done.wait()was not cancelled at all when an event won), so closing the
stream early — a dropped SSE client, an app shutdown — left a task pending and
printedTask was destroyed but it is pending!. Both futures are now
cancelled and awaited every iteration, and the runner task is settled in the
generator'sfinally.Runtime.astreamwaited on a cancelled runner without bound. A misbehaving
agent that swallowsCancelledErrorcould hang the caller's disconnect or
shutdown path; the wait is now bounded (_CANCEL_GRACE_SECONDS).A2Amessage/streamleaked its run on client disconnect. The server's
stream generatorcreate_taskd the run but had nofinally, so a dropped
client left the run executing (burning tokens) and pending at loop shutdown
(Task was destroyed but it is pending!). The generator now cancels and
awaits the run when closed early, and the in-process task store is bounded
(_MAX_TASKS, evicting the oldest terminal task).ChatAssistant.streamleaked per-turn resources when opening failed. A
callableresources=builds a fresh instance per turn; if the store failed to
open the session (or the runtime could not be built) it was never closed.
_open/streamnow close it on that failure path.EventHubsubscriber queues were unbounded. A subscriber that never drains
could grow memory without limit; the queue is now bounded and drops the oldest
status hint when full.
Full changelog: https://github.com/bzdvdn/reactifact/blob/master/CHANGELOG.md