whoami: new mcp tool returning name/role/pronouns/hyperhive_rev on both surfaces
This commit is contained in:
parent
4ec401a6c7
commit
3c66cb6707
9 changed files with 142 additions and 14 deletions
10
TODO.md
10
TODO.md
|
|
@ -57,15 +57,7 @@ how often the friction bites in normal use.
|
||||||
and `cancel_ask(id)` on the agent surface, plus `list_my_reminders()`
|
and `cancel_ask(id)` on the agent surface, plus `list_my_reminders()`
|
||||||
/ `cancel_reminder(id)`. Bounded by `asker == self` and `reminder.owner
|
/ `cancel_reminder(id)`. Bounded by `asker == self` and `reminder.owner
|
||||||
== self` so no cross-agent meddling.
|
== self` so no cross-agent meddling.
|
||||||
- **`whoami` introspection tool** — agents currently rely on the system
|
- ~~**`whoami` introspection tool**~~ ✓ landed — new `mcp__hyperhive__whoami` on both agent + manager surfaces. Returns `{ name, role, operator_pronouns, hyperhive_rev }` from coord state (socket identity for `name`, hard-coded per surface for `role`, `coord.operator_pronouns`, `auto_update::current_flake_rev`). `model` + `started_at` deferred — those live in the harness process not the coord, would need extra plumbing for marginal value.
|
||||||
prompt remembering their name + role. After a rename or model swap
|
|
||||||
there's no trustworthy source-of-truth from inside the harness.
|
|
||||||
Cheap: a `whoami() -> { name, role: "agent" | "manager", model, port,
|
|
||||||
hyperhive_rev, started_at }` tool reading from the harness's own env
|
|
||||||
+ `TurnState`. Useful for self-documenting state files ("this dropped
|
|
||||||
by damocles@gpt-5-codex on rev abc1234") and for the future
|
|
||||||
`get_open_threads` to know whose threads to query without
|
|
||||||
trusting prompt-substituted strings.
|
|
||||||
- **Optional `in_reply_to: <msg_id>` on send** — pure wire addition; no
|
- **Optional `in_reply_to: <msg_id>` on send** — pure wire addition; no
|
||||||
behavioural change. The dashboard could render conversation threads
|
behavioural change. The dashboard could render conversation threads
|
||||||
(already wants this for the agent-to-agent question UI in the
|
(already wants this for the agent-to-agent question UI in the
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ Tools (hyperhive surface):
|
||||||
- `mcp__hyperhive__ask(question, options?, multi?, ttl_seconds?, to?)` — surface a structured question to the human operator (default, or `to: "operator"`) OR a peer agent (`to: "<agent-name>"`). Returns immediately with a question id — do NOT wait inline. When the recipient answers, a system message with event `question_answered { id, question, answer, answerer }` lands in your inbox; handle it on a future turn. Use this for clarifications, permission for risky actions, choice between options, or peer Q&A without burning regular inbox slots. `options` is advisory: a short fixed-choice list when applicable, otherwise leave empty for free text. `multi: true` lets the answerer pick multiple (checkboxes), answer comes back comma-joined. `ttl_seconds` auto-cancels with answer `[expired]` (and `answerer: "ttl-watchdog"`) when the decision becomes moot.
|
- `mcp__hyperhive__ask(question, options?, multi?, ttl_seconds?, to?)` — surface a structured question to the human operator (default, or `to: "operator"`) OR a peer agent (`to: "<agent-name>"`). Returns immediately with a question id — do NOT wait inline. When the recipient answers, a system message with event `question_answered { id, question, answer, answerer }` lands in your inbox; handle it on a future turn. Use this for clarifications, permission for risky actions, choice between options, or peer Q&A without burning regular inbox slots. `options` is advisory: a short fixed-choice list when applicable, otherwise leave empty for free text. `multi: true` lets the answerer pick multiple (checkboxes), answer comes back comma-joined. `ttl_seconds` auto-cancels with answer `[expired]` (and `answerer: "ttl-watchdog"`) when the decision becomes moot.
|
||||||
- `mcp__hyperhive__answer(id, answer)` — answer a question that was routed to YOU. You'll see one in your inbox as a `question_asked { id, asker, question, options, multi }` system event when a peer or the manager calls `ask(to: "<your-name>", ...)`. The answer surfaces in the asker's inbox as a `question_answered` event. Strict authorisation: you can only answer questions where you are the declared target.
|
- `mcp__hyperhive__answer(id, answer)` — answer a question that was routed to YOU. You'll see one in your inbox as a `question_asked { id, asker, question, options, multi }` system event when a peer or the manager calls `ask(to: "<your-name>", ...)`. The answer surfaces in the asker's inbox as a `question_answered` event. Strict authorisation: you can only answer questions where you are the declared target.
|
||||||
- `mcp__hyperhive__get_open_threads()` — list your loose ends: unanswered questions where you're asker (waiting on someone) or target (owing a reply). No args, cheap server-side sweep. Useful at turn start to remember what's outstanding without scanning inbox archaeology.
|
- `mcp__hyperhive__get_open_threads()` — list your loose ends: unanswered questions where you're asker (waiting on someone) or target (owing a reply). No args, cheap server-side sweep. Useful at turn start to remember what's outstanding without scanning inbox archaeology.
|
||||||
|
- `mcp__hyperhive__whoami()` — self-introspection: returns your canonical agent name (from socket identity, not the prompt-substituted label), role, operator pronouns, and current hyperhive rev. No args. Use it when you want a trustworthy identity stamp for state files, commit messages, or cross-agent attribution that won't drift across renames.
|
||||||
|
|
||||||
Need new packages, env vars, or other NixOS config for yourself? You can't edit your own config directly — message the manager (recipient `manager`) describing what you need + why. The manager evaluates the request (it doesn't rubber-stamp), edits `/agents/{label}/config/agent.nix` on your behalf, commits, and submits an approval that the operator can accept on the dashboard; on approve hive-c0re rebuilds your container with the new config.
|
Need new packages, env vars, or other NixOS config for yourself? You can't edit your own config directly — message the manager (recipient `manager`) describing what you need + why. The manager evaluates the request (it doesn't rubber-stamp), edits `/agents/{label}/config/agent.nix` on your behalf, commits, and submits an approval that the operator can accept on the dashboard; on approve hive-c0re rebuilds your container with the new config.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ Tools (hyperhive surface):
|
||||||
- `mcp__hyperhive__ask(question, options?, multi?, ttl_seconds?, to?)` — surface a structured question to the operator (default, or `to: "operator"`) OR a sub-agent (`to: "<agent-name>"`). Returns immediately with a question id; the answer arrives later as a system `question_answered { id, question, answer, answerer }` event in your inbox. Options are advisory: the dashboard always lets the operator type a free-text answer in addition. Set `multi: true` to render options as checkboxes (operator can pick multiple); the answer comes back as `, `-separated. Set `ttl_seconds` to auto-cancel after a deadline (capped at 6h server-side) — on expiry the answer is `[expired]` and `answerer` is `"ttl-watchdog"`. Do not poll inside the same turn — finish the current work and react when the event lands.
|
- `mcp__hyperhive__ask(question, options?, multi?, ttl_seconds?, to?)` — surface a structured question to the operator (default, or `to: "operator"`) OR a sub-agent (`to: "<agent-name>"`). Returns immediately with a question id; the answer arrives later as a system `question_answered { id, question, answer, answerer }` event in your inbox. Options are advisory: the dashboard always lets the operator type a free-text answer in addition. Set `multi: true` to render options as checkboxes (operator can pick multiple); the answer comes back as `, `-separated. Set `ttl_seconds` to auto-cancel after a deadline (capped at 6h server-side) — on expiry the answer is `[expired]` and `answerer` is `"ttl-watchdog"`. Do not poll inside the same turn — finish the current work and react when the event lands.
|
||||||
- `mcp__hyperhive__answer(id, answer)` — answer a question that was routed to YOU (a sub-agent did `ask(to: "manager", ...)`). The triggering event in your inbox is `question_asked { id, asker, question, options, multi }`. The answer surfaces in the asker's inbox as a `question_answered` event.
|
- `mcp__hyperhive__answer(id, answer)` — answer a question that was routed to YOU (a sub-agent did `ask(to: "manager", ...)`). The triggering event in your inbox is `question_asked { id, asker, question, options, multi }`. The answer surfaces in the asker's inbox as a `question_answered` event.
|
||||||
- `mcp__hyperhive__get_open_threads()` — hive-wide loose ends: every pending approval + every unanswered question across the swarm. Cheap server-side sweep, no args. Use to find stalled threads (sub-agent A asked B something three days ago and B never answered) before they rot.
|
- `mcp__hyperhive__get_open_threads()` — hive-wide loose ends: every pending approval + every unanswered question across the swarm. Cheap server-side sweep, no args. Use to find stalled threads (sub-agent A asked B something three days ago and B never answered) before they rot.
|
||||||
|
- `mcp__hyperhive__whoami()` — self-introspection: canonical name (`manager`), role, operator pronouns, current hyperhive rev. No args. Useful for boot announcements and cross-agent attribution that won't drift across config reloads.
|
||||||
|
|
||||||
Approval boundary: lifecycle ops on *existing* sub-agents (`kill`, `start`, `restart`) are at your discretion — no operator approval. *Creating* a new agent (`request_spawn`) and *changing* any agent's config (`request_apply_commit`) still go through the approval queue. The operator only signs off on changes; you run the day-to-day.
|
Approval boundary: lifecycle ops on *existing* sub-agents (`kill`, `start`, `restart`) are at your discretion — no operator approval. *Creating* a new agent (`request_spawn`) and *changing* any agent's config (`request_apply_commit`) still go through the approval queue. The operator only signs off on changes; you run the day-to-day.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -236,7 +236,8 @@ async fn serve(
|
||||||
| AgentResponse::Recent { .. }
|
| AgentResponse::Recent { .. }
|
||||||
| AgentResponse::QuestionQueued { .. }
|
| AgentResponse::QuestionQueued { .. }
|
||||||
| AgentResponse::OpenThreads { .. }
|
| AgentResponse::OpenThreads { .. }
|
||||||
| AgentResponse::PendingRemindersCount { .. },
|
| AgentResponse::PendingRemindersCount { .. }
|
||||||
|
| AgentResponse::Whoami { .. },
|
||||||
) => {
|
) => {
|
||||||
tracing::warn!("recv produced unexpected response kind");
|
tracing::warn!("recv produced unexpected response kind");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -204,7 +204,8 @@ async fn serve(
|
||||||
| ManagerResponse::Recent { .. }
|
| ManagerResponse::Recent { .. }
|
||||||
| ManagerResponse::Logs { .. }
|
| ManagerResponse::Logs { .. }
|
||||||
| ManagerResponse::OpenThreads { .. }
|
| ManagerResponse::OpenThreads { .. }
|
||||||
| ManagerResponse::PendingRemindersCount { .. },
|
| ManagerResponse::PendingRemindersCount { .. }
|
||||||
|
| ManagerResponse::Whoami { .. },
|
||||||
) => {
|
) => {
|
||||||
tracing::warn!("recv produced unexpected response kind");
|
tracing::warn!("recv produced unexpected response kind");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,12 @@ pub enum SocketReply {
|
||||||
Logs(String),
|
Logs(String),
|
||||||
OpenThreads(Vec<hive_sh4re::OpenThread>),
|
OpenThreads(Vec<hive_sh4re::OpenThread>),
|
||||||
PendingRemindersCount(u64),
|
PendingRemindersCount(u64),
|
||||||
|
Whoami {
|
||||||
|
name: String,
|
||||||
|
role: String,
|
||||||
|
operator_pronouns: String,
|
||||||
|
hyperhive_rev: Option<String>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<hive_sh4re::AgentResponse> for SocketReply {
|
impl From<hive_sh4re::AgentResponse> for SocketReply {
|
||||||
|
|
@ -58,6 +64,17 @@ impl From<hive_sh4re::AgentResponse> for SocketReply {
|
||||||
hive_sh4re::AgentResponse::PendingRemindersCount { count } => {
|
hive_sh4re::AgentResponse::PendingRemindersCount { count } => {
|
||||||
Self::PendingRemindersCount(count)
|
Self::PendingRemindersCount(count)
|
||||||
}
|
}
|
||||||
|
hive_sh4re::AgentResponse::Whoami {
|
||||||
|
name,
|
||||||
|
role,
|
||||||
|
operator_pronouns,
|
||||||
|
hyperhive_rev,
|
||||||
|
} => Self::Whoami {
|
||||||
|
name,
|
||||||
|
role,
|
||||||
|
operator_pronouns,
|
||||||
|
hyperhive_rev,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -77,6 +94,17 @@ impl From<hive_sh4re::ManagerResponse> for SocketReply {
|
||||||
hive_sh4re::ManagerResponse::PendingRemindersCount { count } => {
|
hive_sh4re::ManagerResponse::PendingRemindersCount { count } => {
|
||||||
Self::PendingRemindersCount(count)
|
Self::PendingRemindersCount(count)
|
||||||
}
|
}
|
||||||
|
hive_sh4re::ManagerResponse::Whoami {
|
||||||
|
name,
|
||||||
|
role,
|
||||||
|
operator_pronouns,
|
||||||
|
hyperhive_rev,
|
||||||
|
} => Self::Whoami {
|
||||||
|
name,
|
||||||
|
role,
|
||||||
|
operator_pronouns,
|
||||||
|
hyperhive_rev,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -156,6 +184,28 @@ pub fn format_open_threads(resp: Result<SocketReply, anyhow::Error>) -> String {
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Format helper for `whoami`: renders the identity block as a short
|
||||||
|
/// human-readable string. Skips fields that are `None` so the output
|
||||||
|
/// doesn't carry dead placeholders.
|
||||||
|
pub fn format_whoami(resp: Result<SocketReply, anyhow::Error>) -> String {
|
||||||
|
match resp {
|
||||||
|
Ok(SocketReply::Whoami {
|
||||||
|
name,
|
||||||
|
role,
|
||||||
|
operator_pronouns,
|
||||||
|
hyperhive_rev,
|
||||||
|
}) => {
|
||||||
|
let rev = hyperhive_rev.as_deref().unwrap_or("<unknown>");
|
||||||
|
format!(
|
||||||
|
"name: {name}\nrole: {role}\noperator_pronouns: {operator_pronouns}\nhyperhive_rev: {rev}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Ok(SocketReply::Err(m)) => format!("whoami failed: {m}"),
|
||||||
|
Ok(other) => format!("whoami unexpected response: {other:?}"),
|
||||||
|
Err(e) => format!("whoami transport error: {e:#}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Common envelope around every MCP tool handler: pre-log → run →
|
/// Common envelope around every MCP tool handler: pre-log → run →
|
||||||
/// post-log. The inbox-status hint used to be appended to every tool
|
/// post-log. The inbox-status hint used to be appended to every tool
|
||||||
/// result; that lives in the wake prompt + UI header now, so tool
|
/// result; that lives in the wake prompt + UI header now, so tool
|
||||||
|
|
@ -395,6 +445,22 @@ impl AgentServer {
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tool(
|
||||||
|
description = "Self-introspection: returns your own canonical agent name (the \
|
||||||
|
socket-identity name, NOT the prompt-substituted label), role (`agent`), the \
|
||||||
|
operator's pronouns, and the current hyperhive rev hive-c0re is running against. \
|
||||||
|
No args. Useful when you want a trustworthy identity stamp for state files / \
|
||||||
|
commit messages / cross-agent attribution that won't drift across renames or \
|
||||||
|
session-continue boundaries where the system-prompt label could be stale."
|
||||||
|
)]
|
||||||
|
async fn whoami(&self) -> String {
|
||||||
|
run_tool_envelope("whoami", String::new(), async move {
|
||||||
|
let (resp, retries) = self.dispatch(hive_sh4re::AgentRequest::Whoami).await;
|
||||||
|
annotate_retries(format_whoami(resp), retries)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
#[tool(
|
#[tool(
|
||||||
description = "Schedule a reminder that lands in this agent's own inbox at a future \
|
description = "Schedule a reminder that lands in this agent's own inbox at a future \
|
||||||
time (sender will appear as `reminder`). Use for self-paced follow-ups: 'check task \
|
time (sender will appear as `reminder`). Use for self-paced follow-ups: 'check task \
|
||||||
|
|
@ -879,6 +945,20 @@ impl ManagerServer {
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tool(
|
||||||
|
description = "Self-introspection for the manager: returns canonical name \
|
||||||
|
(`manager`), role (`manager`), operator pronouns, and the current hyperhive rev. \
|
||||||
|
Same shape as the agent flavour; useful for cross-agent attribution / boot \
|
||||||
|
announcements / state-file headers without trusting prompt substitution."
|
||||||
|
)]
|
||||||
|
async fn whoami(&self) -> String {
|
||||||
|
run_tool_envelope("whoami", String::new(), async move {
|
||||||
|
let (resp, retries) = self.dispatch(hive_sh4re::ManagerRequest::Whoami).await;
|
||||||
|
annotate_retries(format_whoami(resp), retries)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
#[tool(
|
#[tool(
|
||||||
description = "Fetch recent journal log lines for a sub-agent container. Useful \
|
description = "Fetch recent journal log lines for a sub-agent container. Useful \
|
||||||
for diagnosing MCP server registration failures, startup crashes, plugin install \
|
for diagnosing MCP server registration failures, startup crashes, plugin install \
|
||||||
|
|
@ -923,8 +1003,9 @@ impl ManagerServer {
|
||||||
sub-agent — non-blocking, answer arrives later as a `question_answered` event), \
|
sub-agent — non-blocking, answer arrives later as a `question_answered` event), \
|
||||||
`answer` (respond to a `question_asked` event directed at you), \
|
`answer` (respond to a `question_asked` event directed at you), \
|
||||||
`get_open_threads` (hive-wide loose ends — pending approvals + unanswered \
|
`get_open_threads` (hive-wide loose ends — pending approvals + unanswered \
|
||||||
questions across the swarm). The manager's own config lives at \
|
questions across the swarm), `whoami` (self-introspection — canonical name, \
|
||||||
`/agents/hm1nd/config/agent.nix`."
|
role, operator pronouns, current hyperhive rev). The manager's own config \
|
||||||
|
lives at `/agents/hm1nd/config/agent.nix`."
|
||||||
)]
|
)]
|
||||||
impl ServerHandler for ManagerServer {}
|
impl ServerHandler for ManagerServer {}
|
||||||
|
|
||||||
|
|
@ -958,7 +1039,15 @@ pub enum Flavor {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn allowed_mcp_tools(flavor: Flavor) -> Vec<String> {
|
pub fn allowed_mcp_tools(flavor: Flavor) -> Vec<String> {
|
||||||
let names: &[&str] = match flavor {
|
let names: &[&str] = match flavor {
|
||||||
Flavor::Agent => &["send", "recv", "ask", "answer", "remind", "get_open_threads"],
|
Flavor::Agent => &[
|
||||||
|
"send",
|
||||||
|
"recv",
|
||||||
|
"ask",
|
||||||
|
"answer",
|
||||||
|
"remind",
|
||||||
|
"get_open_threads",
|
||||||
|
"whoami",
|
||||||
|
],
|
||||||
Flavor::Manager => &[
|
Flavor::Manager => &[
|
||||||
"send",
|
"send",
|
||||||
"recv",
|
"recv",
|
||||||
|
|
@ -973,6 +1062,7 @@ pub fn allowed_mcp_tools(flavor: Flavor) -> Vec<String> {
|
||||||
"get_logs",
|
"get_logs",
|
||||||
"get_open_threads",
|
"get_open_threads",
|
||||||
"remind",
|
"remind",
|
||||||
|
"whoami",
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
let mut out: Vec<String> = names
|
let mut out: Vec<String> = names
|
||||||
|
|
|
||||||
|
|
@ -188,6 +188,12 @@ async fn dispatch(req: &AgentRequest, agent: &str, coord: &Arc<Coordinator>) ->
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
AgentRequest::Whoami => AgentResponse::Whoami {
|
||||||
|
name: agent.to_owned(),
|
||||||
|
role: "agent".to_owned(),
|
||||||
|
operator_pronouns: coord.operator_pronouns.clone(),
|
||||||
|
hyperhive_rev: crate::auto_update::current_flake_rev(&coord.hyperhive_flake),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -343,6 +343,12 @@ async fn dispatch(req: &ManagerRequest, coord: &Arc<Coordinator>) -> ManagerResp
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ManagerRequest::Whoami => ManagerResponse::Whoami {
|
||||||
|
name: MANAGER_AGENT.to_owned(),
|
||||||
|
role: "manager".to_owned(),
|
||||||
|
operator_pronouns: coord.operator_pronouns.clone(),
|
||||||
|
hyperhive_rev: crate::auto_update::current_flake_rev(&coord.hyperhive_flake),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -313,6 +313,12 @@ pub enum AgentRequest {
|
||||||
/// by the harness's per-turn stats sink to snapshot "what was
|
/// by the harness's per-turn stats sink to snapshot "what was
|
||||||
/// queued at turn-end time" without paying for a full list.
|
/// queued at turn-end time" without paying for a full list.
|
||||||
CountPendingReminders,
|
CountPendingReminders,
|
||||||
|
/// Self-introspection: who am I, what role, what rev. All values
|
||||||
|
/// derive from coord state (no env access required); useful for
|
||||||
|
/// agents to stamp notes / commits / messages with a trustworthy
|
||||||
|
/// identity after a rename or session-continue boundary where the
|
||||||
|
/// system-prompt-substituted label is no longer reliable.
|
||||||
|
Whoami,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Responses on a per-agent socket.
|
/// Responses on a per-agent socket.
|
||||||
|
|
@ -339,6 +345,18 @@ pub enum AgentResponse {
|
||||||
OpenThreads { threads: Vec<OpenThread> },
|
OpenThreads { threads: Vec<OpenThread> },
|
||||||
/// `CountPendingReminders` result.
|
/// `CountPendingReminders` result.
|
||||||
PendingRemindersCount { count: u64 },
|
PendingRemindersCount { count: u64 },
|
||||||
|
/// `Whoami` result: identity + role + operator pronouns + the
|
||||||
|
/// current hyperhive rev hive-c0re is running against. `role`
|
||||||
|
/// is `"agent"` for sub-agents (the only path that reaches this
|
||||||
|
/// variant of the response). `hyperhive_rev` is `None` only
|
||||||
|
/// when the configured flake URL has no canonical path.
|
||||||
|
Whoami {
|
||||||
|
name: String,
|
||||||
|
role: String,
|
||||||
|
operator_pronouns: String,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
hyperhive_rev: Option<String>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
@ -605,6 +623,9 @@ pub enum ManagerRequest {
|
||||||
/// Count of the manager's own pending reminders. Mirror of
|
/// Count of the manager's own pending reminders. Mirror of
|
||||||
/// `AgentRequest::CountPendingReminders` on the manager surface.
|
/// `AgentRequest::CountPendingReminders` on the manager surface.
|
||||||
CountPendingReminders,
|
CountPendingReminders,
|
||||||
|
/// Manager-flavour self-introspection. Same wire shape as
|
||||||
|
/// `AgentRequest::Whoami`, but `role` is always `"manager"`.
|
||||||
|
Whoami,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
|
@ -647,4 +668,13 @@ pub enum ManagerResponse {
|
||||||
PendingRemindersCount {
|
PendingRemindersCount {
|
||||||
count: u64,
|
count: u64,
|
||||||
},
|
},
|
||||||
|
/// `Whoami` result: manager identity. `role` is always
|
||||||
|
/// `"manager"`. Mirror of `AgentResponse::Whoami`.
|
||||||
|
Whoami {
|
||||||
|
name: String,
|
||||||
|
role: String,
|
||||||
|
operator_pronouns: String,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
hyperhive_rev: Option<String>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue