agent page: inbox view of last 30 messages addressed to this agent
new wire request AgentRequest::Recent { limit } / ManagerRequest::Recent
(plus matching responses with Vec<InboxRow>). InboxRow moved to
hive-sh4re so it lives on both surfaces without an internal-to-wire
conversion. host-side dispatch in agent_server / manager_server
calls broker.recent_for(name, limit).
per-agent web_ui /api/state grew an inbox: Vec<InboxRow> populated
via the same per-agent socket (best-effort; transport failure
returns empty). frontend renders as a collapsible <details> section
between the state row and the terminal — fmt timestamp / from /
body in a tight grid, capped at 16em scrollable. only visible when
there are rows.
This commit is contained in:
parent
bd7d2d4860
commit
538e0446d7
13 changed files with 151 additions and 20 deletions
|
|
@ -121,5 +121,11 @@ async fn dispatch(req: &AgentRequest, agent: &str, broker: &Broker) -> AgentResp
|
|||
message: format!("{e:#}"),
|
||||
},
|
||||
},
|
||||
AgentRequest::Recent { limit } => match broker.recent_for(agent, *limit) {
|
||||
Ok(rows) => AgentResponse::Recent { rows },
|
||||
Err(e) => AgentResponse::Err {
|
||||
message: format!("{e:#}"),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use std::sync::Mutex;
|
|||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use hive_sh4re::Message;
|
||||
use hive_sh4re::{InboxRow, Message};
|
||||
use rusqlite::{Connection, OptionalExtension, params};
|
||||
use serde::Serialize;
|
||||
use tokio::sync::broadcast;
|
||||
|
|
@ -28,16 +28,6 @@ CREATE INDEX IF NOT EXISTS idx_messages_undelivered
|
|||
/// may drop events past this; we send a `lagged` notice in their stream.
|
||||
const EVENT_CHANNEL: usize = 256;
|
||||
|
||||
/// One row in a `recent_for()` query — the broker's flat view of a
|
||||
/// message addressed to a given recipient.
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct InboxRow {
|
||||
pub id: i64,
|
||||
pub from: String,
|
||||
pub body: String,
|
||||
pub at: i64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
#[serde(rename_all = "snake_case", tag = "kind")]
|
||||
pub enum MessageEvent {
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ struct StateSnapshot {
|
|||
/// Latest messages addressed to `operator` — surfaces agent replies
|
||||
/// asynchronously so the operator can see them without watching the
|
||||
/// live panel during a turn.
|
||||
operator_inbox: Vec<crate::broker::InboxRow>,
|
||||
operator_inbox: Vec<hive_sh4re::InboxRow>,
|
||||
/// Pending operator questions (currently only from the manager).
|
||||
/// `ask_operator` returns immediately with the id; on `/answer-question`
|
||||
/// we mark the row answered and fire `HelperEvent::OperatorAnswered`
|
||||
|
|
|
|||
|
|
@ -100,6 +100,12 @@ async fn dispatch(req: &ManagerRequest, coord: &Coordinator) -> ManagerResponse
|
|||
message: format!("{e:#}"),
|
||||
},
|
||||
},
|
||||
ManagerRequest::Recent { limit } => match coord.broker.recent_for(MANAGER_AGENT, *limit) {
|
||||
Ok(rows) => ManagerResponse::Recent { rows },
|
||||
Err(e) => ManagerResponse::Err {
|
||||
message: format!("{e:#}"),
|
||||
},
|
||||
},
|
||||
ManagerRequest::Recv => match coord
|
||||
.broker
|
||||
.recv_blocking(MANAGER_AGENT, MANAGER_RECV_LONG_POLL)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue