dashboard: surface peer questions + operator override

questions pane now shows both operator-targeted threads
(target IS NULL) and agent-to-agent threads (target = some
agent). filter chips above the list: all / @operator / @peer /
per-participant. peer rows get a mauve left rule + a 0V3RR1D3
button that POSTs the same /answer-question endpoint
(OperatorQuestions::answer already permits the operator as
answerer on any target).

wire changes: OperatorQuestions gains pending_all +
recent_answered_all; QuestionAdded + QuestionResolved events
carry target: Option<String>; emit sites drop their
target.is_none() guard. answered-history rows show the
answerer prefix so override answers are auditable at a glance.
This commit is contained in:
müde 2026-05-17 22:06:53 +02:00
parent e7ce35c503
commit a15fafb5de
9 changed files with 187 additions and 71 deletions

View file

@ -21,7 +21,10 @@
## Dashboard
- **UI for agent-to-agent questions** (follow-up to the `ask` rename): now that agents can `ask(to: <agent>)` each other, surface those threads in the per-agent dashboard view. Replace the existing read/unread tabs with THREE filters: `unread`, `from: <agent>`, `to: <agent>`. The `to:` filter makes agent-targeted questions visible so the operator can see at a glance "alice has 3 questions outstanding from bob" and intervene if a thread is stuck. Same UI is useful for general inbox filtering too. Data lives in the existing `operator_questions` table (with the new `target` column) + the broker inbox; no new schema needed. Also expose a "respond" affordance so the operator can override-answer a peer question when an agent is offline / stuck (the answerer-auth check in `OperatorQuestions::answer` already permits the operator on any target).
<!-- Landed: dashboard questions pane now shows both operator-targeted
and peer (agent-to-agent) threads, with filter chips (all /
@operator / @peer / per-participant) and an 0V3RR1D3 button on
peer rows so the operator can answer when an agent is stuck. -->
- **Clickable file paths in message bodies**: agents drop pointer strings like `/agents/<name>/state/foo.md` constantly (it's the whole 1 KiB-cap escape hatch). Right now they're plain text — operator has to copy-paste into a terminal to peek. Detect path-shaped tokens (start with `/agents/`, `/shared/`, `/state/`, or absolute `/var/lib/hyperhive/...`) in rendered message bodies + question text + answer text + helper-event payloads, render as clickable links that hit a new `/api/state-file?path=…` dashboard endpoint. Endpoint serves the file as text (with a strict allow-list — only paths under `/var/lib/hyperhive/agents/*/state/`, `/var/lib/hyperhive/shared/`, never anything else), syntax-highlighting where it makes sense, falling back to download for binaries. Reuses the existing `<details>` collapse pattern so inline preview doesn't blow up the message-flow stream.
- **UI for pending reminders**: show pending/queued reminders in dashboard, allow operator to view/debug/cancel
- Per-agent reminder status (pending, delivered)