ask: rename ask_operator → ask + optional 'to' for agent-to-agent Q&A
This commit is contained in:
parent
87f8f8a123
commit
82b0877c47
21 changed files with 640 additions and 266 deletions
|
|
@ -221,11 +221,17 @@ pub enum AgentRequest {
|
|||
/// Non-mutating — pulls from the broker without delivering. The
|
||||
/// per-agent web UI uses this to render its own inbox section.
|
||||
Recent { limit: u64 },
|
||||
/// Surface a question to the operator on the dashboard. Same
|
||||
/// shape as `ManagerRequest::AskOperator` — any agent can ask;
|
||||
/// the answer routes back to the asker's inbox as a
|
||||
/// `HelperEvent::OperatorAnswered`.
|
||||
AskOperator {
|
||||
/// Surface a question to either the operator or another agent.
|
||||
/// `to = None` (or `Some("operator")`) routes the question to the
|
||||
/// dashboard's operator-question queue (legacy `AskOperator`
|
||||
/// behaviour). `to = Some(<agent>)` routes it to that agent's
|
||||
/// inbox as a `HelperEvent::QuestionAsked` so the recipient can
|
||||
/// answer back via `AgentRequest::Answer` (or
|
||||
/// `ManagerRequest::Answer`); the answer threads back to the asker
|
||||
/// as a `HelperEvent::QuestionAnswered` event. Either way the
|
||||
/// response shape is `QuestionQueued { id }` — the asker uses the
|
||||
/// id to correlate the asynchronous answer event.
|
||||
Ask {
|
||||
question: String,
|
||||
#[serde(default)]
|
||||
options: Vec<String>,
|
||||
|
|
@ -233,7 +239,18 @@ pub enum AgentRequest {
|
|||
multi: bool,
|
||||
#[serde(default)]
|
||||
ttl_seconds: Option<u64>,
|
||||
/// Recipient of the question. `None` or `Some("operator")` =
|
||||
/// the human operator (dashboard); `Some(<agent_name>)` = a
|
||||
/// peer agent (their inbox).
|
||||
#[serde(default)]
|
||||
to: Option<String>,
|
||||
},
|
||||
/// Answer a question previously routed to this agent via
|
||||
/// `HelperEvent::QuestionAsked`. The caller is implicitly the
|
||||
/// answerer; only the question's `target` agent (or the operator,
|
||||
/// via the dashboard) is authorised. Wires through to
|
||||
/// `HelperEvent::QuestionAnswered` in the asker's inbox.
|
||||
Answer { id: i64, answer: String },
|
||||
/// Schedule a reminder message to be delivered to this agent at a
|
||||
/// future time. The reminder lands in the agent's inbox as an auto-sent
|
||||
/// message from `"reminder"`. Use for agent follow-ups (e.g. check task
|
||||
|
|
@ -264,8 +281,8 @@ pub enum AgentResponse {
|
|||
Status { unread: u64 },
|
||||
/// `Recent` result: newest-first inbox rows.
|
||||
Recent { rows: Vec<InboxRow> },
|
||||
/// `AskOperator` result: the queued question id. The answer lands
|
||||
/// later as `HelperEvent::OperatorAnswered` in this agent's inbox.
|
||||
/// `Ask` result: the queued question id. The answer lands later
|
||||
/// as `HelperEvent::QuestionAnswered` in this agent's inbox.
|
||||
QuestionQueued { id: i64 },
|
||||
}
|
||||
|
||||
|
|
@ -375,14 +392,32 @@ pub enum HelperEvent {
|
|||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
note: Option<String>,
|
||||
},
|
||||
/// The operator answered a question that was queued via
|
||||
/// `AskOperator`. `id` matches the `QuestionQueued.id` returned to the
|
||||
/// asker; `question` echoes the original prompt so the manager can
|
||||
/// stitch the answer back to context across compactions.
|
||||
OperatorAnswered {
|
||||
/// A question queued via `Ask` was answered (by the operator via
|
||||
/// the dashboard, or by another agent via `Answer`). `id` matches
|
||||
/// the `QuestionQueued.id` returned to the asker; `question`
|
||||
/// echoes the original prompt so the asker can stitch the answer
|
||||
/// back to context across compactions; `answerer` is who answered
|
||||
/// (`"operator"` or a peer agent name).
|
||||
QuestionAnswered {
|
||||
id: i64,
|
||||
question: String,
|
||||
answer: String,
|
||||
answerer: String,
|
||||
},
|
||||
/// A peer (or the manager) asked this agent a question via
|
||||
/// `Ask { to: Some(<this-agent>), ... }`. The recipient should
|
||||
/// answer via `Answer { id, answer }` on their socket; the answer
|
||||
/// will route back to the asker as a `QuestionAnswered` event.
|
||||
/// `options` + `multi` mirror the original `Ask` args so the
|
||||
/// answerer knows what shape of reply is expected.
|
||||
QuestionAsked {
|
||||
id: i64,
|
||||
asker: String,
|
||||
question: String,
|
||||
#[serde(default)]
|
||||
options: Vec<String>,
|
||||
#[serde(default)]
|
||||
multi: bool,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -452,9 +487,10 @@ pub enum ManagerRequest {
|
|||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
description: Option<String>,
|
||||
},
|
||||
/// Ask the operator a question. Returns immediately with the queued
|
||||
/// question id; the operator's answer arrives later as a
|
||||
/// `HelperEvent::OperatorAnswered` in the manager inbox.
|
||||
/// Surface a question to either the operator or another agent.
|
||||
/// Mirrors `AgentRequest::Ask` exactly — see that doc for the
|
||||
/// routing semantics (operator = dashboard queue; agent = the
|
||||
/// peer's inbox via `HelperEvent::QuestionAsked`).
|
||||
///
|
||||
/// - `options` is advisory: empty = free-text only; non-empty = the
|
||||
/// dashboard renders the choices alongside a free-text fallback
|
||||
|
|
@ -464,9 +500,11 @@ pub enum ManagerRequest {
|
|||
/// selections joined by ", ".
|
||||
/// - `ttl_seconds`: optional auto-cancel after that many seconds. On
|
||||
/// expiry the question is resolved with answer `[expired]` and the
|
||||
/// manager gets the usual `OperatorAnswered` event. None = wait
|
||||
/// forever for an operator answer (or manual cancel).
|
||||
AskOperator {
|
||||
/// asker gets the usual `QuestionAnswered` event. None = wait
|
||||
/// forever for an answer (or manual cancel).
|
||||
/// - `to`: recipient (None / `Some("operator")` = operator;
|
||||
/// `Some(<agent>)` = peer agent).
|
||||
Ask {
|
||||
question: String,
|
||||
#[serde(default)]
|
||||
options: Vec<String>,
|
||||
|
|
@ -474,7 +512,13 @@ pub enum ManagerRequest {
|
|||
multi: bool,
|
||||
#[serde(default)]
|
||||
ttl_seconds: Option<u64>,
|
||||
#[serde(default)]
|
||||
to: Option<String>,
|
||||
},
|
||||
/// Answer a question previously routed to the manager via
|
||||
/// `HelperEvent::QuestionAsked` (i.e. an agent asked the manager
|
||||
/// for input). Mirror of `AgentRequest::Answer`.
|
||||
Answer { id: i64, answer: String },
|
||||
/// Fetch recent journal lines for a sub-agent container. hive-c0re
|
||||
/// runs `journalctl -M <agent> -n <lines> --no-pager` and returns
|
||||
/// the output as a string. Useful for diagnosing MCP registration
|
||||
|
|
@ -514,9 +558,10 @@ pub enum ManagerResponse {
|
|||
Status {
|
||||
unread: u64,
|
||||
},
|
||||
/// Result of `AskOperator`: the queued question id. The actual answer
|
||||
/// arrives later as a `HelperEvent::OperatorAnswered` in the manager
|
||||
/// inbox, so this returns immediately rather than blocking the turn.
|
||||
/// Result of `Ask`: the queued question id. The actual answer
|
||||
/// arrives later as a `HelperEvent::QuestionAnswered` in the
|
||||
/// asker's inbox, so this returns immediately rather than blocking
|
||||
/// the turn.
|
||||
QuestionQueued {
|
||||
id: i64,
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue