agent/terminal: inline answer form under ask → operator rows (#666)
When an agent calls mcp__hyperhive__ask with to==operator (the default), the rich tool-use renderer now mounts an empty ask-answer-inline-slot inside the expanded ask row and enqueues a loose-ends refresh. A new reconcileAskBinds() walks waiting slots on every loose-ends update, matches each against pending operator-bound questions by question text, and injects the same inline answer form the side panel uses (buildAnswerForm → POST to the host dashboard answer-question endpoint). When a question resolves, the form gets replaced by a struck-through [answered ✓] tag so the scrollback reflects the closed state. Lets the operator respond to agent questions inline in the live terminal without context-switching to the loose-ends side panel or the dashboard Y3R C4LL tab. Refreshes loose-ends both on tool_use render (best-effort, may miss the question before the broker persists it) and on the matching tool_result (the right moment — MCP has just returned the assigned id). Slots are pruned on /clear and defensively filtered for isConnected on each reconcile. closes #666
This commit is contained in:
parent
4d64f253c8
commit
e056e82d6d
3 changed files with 194 additions and 1 deletions
|
|
@ -552,6 +552,67 @@ pre.diff {
|
|||
.agent-inbox .answer-form button:disabled { opacity: 0.5; cursor: default; }
|
||||
.agent-inbox .answer-status { color: var(--muted); align-self: center; }
|
||||
|
||||
/* #666: inline answer slot mounted under each `ask → operator` row
|
||||
in the live terminal stream. Mirrors the side-panel `.answer-form`
|
||||
look-and-feel — same textarea, same send button — so the operator
|
||||
doesn't have to context-switch between "answering in the panel" and
|
||||
"answering inline". Empty slot collapses to nothing (no margin) so
|
||||
pre-bind rows stay tidy; populated slot gets a thin top divider to
|
||||
separate the question body from the form. Resolved tag (the
|
||||
struck-through `[answered ✓]`) replaces the form once the
|
||||
question's been answered. */
|
||||
.live .ask-answer-inline-slot:empty { display: none; }
|
||||
.live .ask-answer-inline-slot {
|
||||
margin-top: 0.5em;
|
||||
padding-top: 0.5em;
|
||||
border-top: 1px dashed var(--border);
|
||||
}
|
||||
.live .ask-answer-inline-slot .answer-form {
|
||||
display: flex;
|
||||
gap: 0.4em;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.live .ask-answer-inline-slot .answer-form textarea {
|
||||
flex: 1;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
background: var(--bg);
|
||||
color: var(--fg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 3px;
|
||||
padding: 0.3em;
|
||||
resize: vertical;
|
||||
}
|
||||
.live .ask-answer-inline-slot .answer-form button {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
background: var(--bg-elev);
|
||||
color: var(--fg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 3px;
|
||||
padding: 0.3em 0.7em;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.live .ask-answer-inline-slot .answer-form button:hover:not(:disabled) {
|
||||
border-color: var(--purple);
|
||||
color: var(--purple);
|
||||
}
|
||||
.live .ask-answer-inline-slot .answer-form button:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: default;
|
||||
}
|
||||
.live .ask-answer-inline-slot .answer-status {
|
||||
color: var(--muted);
|
||||
align-self: center;
|
||||
}
|
||||
.live .ask-answer-inline-slot .ask-answered-tag {
|
||||
color: var(--muted);
|
||||
font-style: italic;
|
||||
text-decoration: line-through;
|
||||
text-decoration-color: var(--muted);
|
||||
}
|
||||
|
||||
/* #559: "mark all read" header row sits above the recent-messages
|
||||
list in the inbox side-panel flyout. Same look as the answer-form
|
||||
button (mauve hover, bg-elev background) so they read as part of
|
||||
|
|
|
|||
Loading…
Reference in a new issue