Activity-line vocabulary + plan-progress formatting (plan 188 T2).
Purpose
-------
The loop already knows three things the terminal never showed: which
tool calls were *proposed*, how each gated call was *decided*, and when
a *sub-agent* started and finished. It also holds live plan state in the
planner singleton. Plan 188 T2 surfaces all of it through one small,
non-abstract presenter hook —
:meth:`~oc_ui.presenter_base.Presenter.show_activity` — and this module
owns the shared, framework-free pieces both the plain console and the
Rich presenter render from.
Two seams feed that hook, deliberately kept apart:
- the **bus subscriber** (:mod:`oc_chat.core.presenter_events`) folds the
approval and sub-agent lanes, because those lanes exist *only* as
events and the bus is the substrate's own read side;
- the **plan lane** is presenter-side, because plan state is not on the
bus at all — the REPL holds it in the planner process singleton, and
a planner tool result is the exact moment it changed.
Nothing here publishes an event or adds an event kind: Phase 0 renders
what already exists (synthesis §2 — the bus is observability, not
control).
Responsibilities
----------------
- :data:`TONES` — the tone vocabulary presenters map to styles.
- :data:`PLANNER_TOOLS` — the tool names whose results carry a plan
state change.
- :func:`format_plan_progress` — a live planner status dict → one
compact progress line (or ``None`` when there is no plan).
- :func:`plan_progress_from_result` — the presenter-side entry point:
a planner tool result → the current progress line, read from the
planner singleton at render time.
Diagnostics
-----------
Domain: OC_UI.TERMINAL
Levels:
L2 — lifecycle events
L3 — semantic details
L4 — deep tracing
Contracts
---------
- Framework-free: no ``rich`` import, matching
:mod:`oc_ui.terminal.statusline` and :mod:`oc_ui.terminal.diffview`.
- :func:`plan_progress_from_result` is best-effort and never raises:
an unavailable planner degrades to ``None`` (no line), never to a
broken render.
- No guessing: a planner result carrying an ``error`` produces no
progress line, and a goal is truncated for width rather than
reflowed.
Dependencies
------------
- oc_diagnostics (structured debug logging via _dbg)
- oc_chat.tools.planner (lazy; get_status reads the live plan state at render time)
| str | None oc_ui.terminal.activity.plan_progress_from_result |
( |
str | tool, |
|
|
object | result ) |
Progress line for a planner tool result, read from LIVE planner state.
The result payloads differ per tool (``create_plan`` echoes the plan,
``mark_step`` echoes one step), so rather than reconstructing state
from whichever shape arrived, this reads
:func:`oc_chat.tools.planner.get_status` — the REPL's own current
state — at render time. Best-effort: any failure yields ``None``.
Definition at line 142 of file activity.py.