ask_operator: multi-select + free-text fallback
ask_operator now accepts a multi: bool. when true and options is
non-empty, the dashboard renders the choices as checkboxes — operator
picks any subset, answer comes back as a ', '-joined string. when
false (default), options are radio buttons.
independent of multi, a free-text input ('or type your own…') is
always rendered alongside options so the operator is never trapped
by an incomplete list. submit merges checked options + free text into
the single 'answer' field.
schema migration: operator_questions grows a multi INTEGER column
with a one-shot ALTER TABLE on open. backward compatible — old rows
default to 0 (not multi).
prompt + mcp tool description updated; existing dashboard css for
.qform was rewritten around the new vertical layout.
This commit is contained in:
parent
c337cc06f8
commit
8344dd9ab7
7 changed files with 130 additions and 35 deletions
|
|
@ -9,7 +9,7 @@ Tools (hyperhive surface):
|
|||
- `mcp__hyperhive__start(name)` — start a stopped sub-agent. No approval required.
|
||||
- `mcp__hyperhive__restart(name)` — stop + start a sub-agent. No approval required.
|
||||
- `mcp__hyperhive__request_apply_commit(agent, commit_ref)` — submit a config change for any agent (`hm1nd` for self) for operator approval.
|
||||
- `mcp__hyperhive__ask_operator(question, options?)` — surface a question on the dashboard. Returns immediately with a question id; the operator's answer arrives later as a system `operator_answered` event in your inbox. Do not poll inside the same turn — finish the current work and react when the event lands.
|
||||
- `mcp__hyperhive__ask_operator(question, options?, multi?)` — surface a question on the dashboard. Returns immediately with a question id; the operator's answer arrives later as a system `operator_answered` 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. Do not poll inside the same turn — finish the current work and react when the event lands.
|
||||
|
||||
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.
|
||||
|
||||
|
|
|
|||
|
|
@ -227,10 +227,16 @@ pub struct RestartArgs {
|
|||
pub struct AskOperatorArgs {
|
||||
/// The question to surface on the dashboard.
|
||||
pub question: String,
|
||||
/// Optional fixed-choice answers. If empty, the dashboard renders a
|
||||
/// free-text input. Otherwise renders a select list of these options.
|
||||
/// Optional fixed-choice answers. The dashboard always renders a
|
||||
/// free-text fallback ("Other…") so the operator is never trapped
|
||||
/// by an incomplete list.
|
||||
#[serde(default)]
|
||||
pub options: Vec<String>,
|
||||
/// When true, options are rendered as checkboxes — operator can pick
|
||||
/// any subset. The answer comes back as a single string with
|
||||
/// selections joined by ", ". Ignored when `options` is empty.
|
||||
#[serde(default)]
|
||||
pub multi: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
|
||||
|
|
@ -369,7 +375,9 @@ impl ManagerServer {
|
|||
with event `operator_answered { id, question, answer }` lands in your inbox; handle it \
|
||||
on a future turn. Use this when a decision needs human signal (ambiguous sub-agent \
|
||||
request, policy call, scope clarification). `options` is advisory: pass a short \
|
||||
fixed-choice list when applicable, otherwise leave empty for free text."
|
||||
fixed-choice list when applicable, otherwise leave empty for free text. Set \
|
||||
`multi: true` to let the operator pick multiple options (checkboxes); the answer \
|
||||
comes back as a comma-separated string."
|
||||
)]
|
||||
async fn ask_operator(&self, Parameters(args): Parameters<AskOperatorArgs>) -> String {
|
||||
let log = format!("{args:?}");
|
||||
|
|
@ -378,6 +386,7 @@ impl ManagerServer {
|
|||
.dispatch(hive_sh4re::ManagerRequest::AskOperator {
|
||||
question: args.question,
|
||||
options: args.options,
|
||||
multi: args.multi,
|
||||
})
|
||||
.await;
|
||||
match resp {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue