Files
Teknium 433046b399 refactor(gateway): move the owner's server-request registry out of session_sudo_prompt
The registry behind sudo, secret, batch clarify and the Desktop UI
requests (_Pending, _open, _ask, resolve, lock_answer, may_settle,
owned_by, ask_viewer, ask_viewer_result) lived in session_sudo_prompt.py
because sudo was its first user. It now has its own module,
gateway/session_server_requests.py, the owner-side counterpart of the
sidecar's tui_gateway/server_requests.py. session_sudo_prompt.py keeps
only ask_sudo and sudo_prompt_scope. Every caller and test imports from
the new module directly, with no re-export shim. No behaviour change.

Review finding by @alt-glitch on #140472
Refs #134889 (TUI-18)
Refs #140337
2026-10-17 08:03:51 -07:00

32 lines
1.9 KiB
Python

"""The terminal result of a batch clarify, shared by every registry that holds one.
A batch (``clarify`` server request with question ids) is answered per question with ``clarify.lock``
and ends one of four ways: the last lock, a closing response frame, a timeout, or an interrupt/cancel.
Main's TUI sidecar (``tui_gateway/server_requests.py``) and the session owner
(``gateway/session_server_requests.py``) both settle batches; each used to compute ``{answers, outcome}``
itself and they drifted. Both call :func:`settle_batch`, so the model is told the same thing on every
surface.
"""
from __future__ import annotations
OUTCOMES = ("submitted", "timed_out", "cancelled")
def settle_batch(locked: dict, frame_result=None, *, ended: str | None = None) -> dict:
"""``{answers, outcome}`` for a batch whose locks so far are *locked*.
- ``ended`` (``"timed_out"`` / ``"cancelled"``): the wait ended with no frame (timeout, interrupt,
a ``cancel()``), or ``"submitted"`` for the last lock. The locked answers stand.
- Otherwise *frame_result* is the closing frame's ``result``. A dict with an ``answers`` dict lays
those answers over the locks (the frame wins per question) and keeps the frame's own outcome when it
names a known one (main's classic CLI reports ``timed_out``), else ``submitted``. Anything else (Ink
Esc / Desktop Skip send ``{}``; an error frame gives ``None``) is a cancel-all: locks kept, ``cancelled``.
"""
if ended is not None:
return {"answers": dict(locked), "outcome": ended if ended in OUTCOMES else "cancelled"}
if isinstance(frame_result, dict) and isinstance(frame_result.get("answers"), dict):
outcome = frame_result.get("outcome")
return {**frame_result, "answers": {**locked, **frame_result["answers"]},
"outcome": outcome if outcome in OUTCOMES else "submitted"}
return {"answers": dict(locked), "outcome": "cancelled"}