Skip to content

wait_for_text: expose risk_band_warned: bool in WaitForTextResult for clients that don't subscribe to log notifications #54

@tony

Description

@tony

Type: enhancement · Tier: deferred · Tool: `wait_for_text`

Problem

When `wait_for_text` polls a pane near `history-limit`, it emits a one-shot `ctx.warning` notification — "wait_for_text correctness is best-effort here. For deterministic synchronization use wait_for_channel." That signal routes only to MCP `notifications/message`. Clients that don't subscribe to log notifications (minimal stdio transports, agent loops that drop log messages, programmatic callers) receive a normal `WaitForTextResult` with `found`/`timed_out` populated but no structured indication that matching was best-effort.

The result: an agent gets back `found=True` or `found=False` and has no way to distinguish "polling was reliable" from "we were in the trim-risk band and the answer might be wrong" — exactly the information the runtime warning was designed to surface.

Proposed fix

Add a structured field to `WaitForTextResult`:

```python
class WaitForTextResult(BaseModel):
found: bool = ...
matched_lines: list[str] = ...
pane_id: str = ...
elapsed_seconds: float = ...
timed_out: bool = ...
risk_band_warned: bool = Field(
default=False,
description=(
"True if polling entered the history-limit trim-risk band "
"(top 10% of history_limit) at any point during the wait. "
"Indicates wait_for_text's match result is best-effort; "
"compose tmux wait-for -S with wait_for_channel for "
"deterministic completion."
),
)
```

The flag is already tracked inside `wait_for_text` as the local `warned_risk_band` bool used to gate the one-shot warning. Surface it on the returned model.

Trade-offs

  • API shape addition to `WaitForTextResult`. Project is pre-alpha (`0.1.x`) so additive fields are not breaking, but the surface should be agreed on before shipping — once a field is in a public response model, removing it is a breaking change.
  • Tests: extend the existing trim-risk-band tests (`test_wait_for_text_warns_in_history_limit_risk_band`, `test_wait_for_text_warns_when_already_in_risk_band`) to assert `result.risk_band_warned is True`. The non-risk-band tests should assert `result.risk_band_warned is False` to lock the default.
  • Docs: the breaking-changes CHANGES entry already says "the tool emits a notifications/message warning when polling approaches history-limit". Add a sentence noting the structured-field equivalent for clients that don't subscribe to logs.

Why this is non-duplicative

Cross-checked against the existing deferred issues:

None of those touch the structured-result-vs-notification ergonomic split for `wait_for_text`. This issue is the standalone tracking point.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions