Skip to content

Voice roster reads: sweep, digest, last reply, screen (WI-1268) - #970

Merged
thedancingdeveloper merged 3 commits into
mainfrom
wi-1268-voice-reads
Oct 12, 2026
Merged

thedancingdeveloper merged 3 commits into
mainfrom
wi-1268-voice-reads

Conversation

@thedancingdeveloper

Copy link
Copy Markdown
Contributor

What

The voice assistant can read the session roster. session.sweep is the roster question ("what's going on", "what needs me"); a named session goes to session.digest, session.last_reply, or session.screen. All four are curated reads with no approval. list_sessions stays a bounded name/role lookup (≤32) and spells a non-worker as name (role), so "oversight" resolves. The sweep the assistant actually runs is forced to digest mode with screen_lines clamped to 5.

Why

A spoken "what's going on" was answered from an unbounded session list or a raw tail, and never saw the blocked report, the last reply, or the screen. WI-1268.

Does not reimplement WI-1266 (session.list pagination), which is PR #968. This branch does not depend on it: the curated tools pass ids through to core, and the engine's own lookup still wants a UUID.

Closes nothing on GitHub; the item is WI-1268 in Vogt.

Verification

  • Python core: uv run pytest, uv run mypy, uv run ruff check ., uv run ruff format --check .
  • Docs: uv run python scripts/check_docs.py
  • PWA (web/): pnpm typecheck, pnpm test, pnpm test:browser (Playwright)
  • Engine (engine/): cargo fmt --all -- --check, cargo clippy --workspace --all-targets -- -D warnings, cargo test -p vogt-engine-server --lib assistant::tests
  • Not applicable — this change doesn't touch code these gates cover

Also uv run pytest tests/test_voice_capabilities.py --no-cov (4 passed). Full cargo test --workspace was not run; the assistant lib tests (78) were.

Docs

  • docs/ENGINE.md §6.5.1: the four reads are Voice-readable, and list_sessions is the bounded name/role lookup.
  • Not applicable

thedancingdeveloper and others added 2 commits October 12, 2026 02:18
…n (WI-1268)

Checkpoint of the paused WI-1268 worker; its own commit was refused by the
git guard. Unverified: gates not run on this commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sweep_args borrowed its argument mutably while reassigning it, and the
call site passed a String where the signature takes &str. Clone the
object instead, and assert the loop test against the clamped arguments
so session.sweep is the one read that is rewritten.
@thedancingdeveloper

Copy link
Copy Markdown
Contributor Author

Review — WI-1268 voice roster reads (head 93d73f7)

Reviewed the diff in a detached checkout of that SHA; did not touch the author's worktree or the dirty checkout on wi-1044. uv run pytest tests/test_voice_capabilities.py --no-cov: 4 passed.

What checks out:

  • The four reads are in CURATED_READS, the comment sits above the array so _const no longer invents a quoted operation, and the new regression asserts each is Voice-readable in ENGINE.md §6.5.1, present in CURATED_READS, non-mutating, and on the MCP transport. The §6.5.1 rows and the list_sessions tools row match the code.
  • sweep_args rewrites only session.sweep: it forces mode=digest, leaves every other argument (attention, limit, fields, states) alone, and the existing curated-read loop asserts the rewritten arguments are exactly what the core is called with. Other operations pass through unchanged.
  • list_sessions filters by case-insensitive name and role, caps at MAX_VOCABULARY_SESSIONS (32), and now returns role. vocabulary_session spells a worker as the bare name and anything else as name (role), with the unit test covering worker, oversight and a blank name. Both role variants exist on SessionRole.
  • WI-1266 (session.list pagination) is correctly left out.

Blocker: the screen-lines clamp drops the screen whenever the number is not an integer

let lines = object
    .get("screen_lines")
    .and_then(Value::as_u64)
    .unwrap_or(0)
    .min(5);

Value::as_u64 returns None for any JSON number with a fractional part, and the unwrap_or(0) then stores 0. sweep_sessions treats screen_lines == 0 as "ask for no screen at all" (screen_tail=[]), so the roster the assistant reads back has no screen. Tool-call arguments are model-produced JSON, not the Rust struct the unit test builds: {"screen_lines": 5.0} is the shape that arrives, and it clamps to 0. The prompt makes this worse rather than better — it says "keep screen_lines at 5 or fewer" and never tells the model to pass a positive value, so a compliant model that omits it also gets 0 via the same default. The test only exercises screen_lines: 40 (an integer) and a missing key, so both paths are green.

Use as_u64().or_else(|| as_f64().map(|n| n as u64)), and default the missing key to 5 rather than 0, since this rewrite exists to make the screen speakable, not to suppress it.

blockers (head 93d73f7)

Missing, fractional or negative screen_lines now clamps to the speakable
default of 5 instead of 0, which asked for no screen at all; whole-number
floats are accepted. Fixes the review blocker on #970.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@thedancingdeveloper

Copy link
Copy Markdown
Contributor Author

Re-review — head 199ec23

The blocker from the previous review is fixed. sweep_args now reads screen_lines through as_u64 and falls back to as_f64 for a finite, non-negative whole number, so a model-sent 5.0 clamps to 5 instead of being dropped. Anything else — missing, fractional, negative — defaults to 5 rather than 0, and an explicit integer 0 is still honoured as "no screen". The prompt now says omitting the field still reads five lines. The rewrite still touches only session.sweep and still forces digest mode.

Verified: cargo test -p vogt-engine-server --lib sweep_the_assistant_runs passes, including the new cases for 3.0, 5.0, 2.5, -1, 0 and a missing key. Nothing else in the diff changed since 93d73f7.

no blockers (head 199ec23)

@thedancingdeveloper
thedancingdeveloper enabled auto-merge (rebase) October 12, 2026 03:03
@thedancingdeveloper
thedancingdeveloper merged commit ac363da into main Oct 12, 2026
16 checks passed
@thedancingdeveloper
thedancingdeveloper deleted the wi-1268-voice-reads branch October 12, 2026 03:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant