Watch
0
0
Fork
You've already forked hyperhive
0

swarm-ui: move the terminal preview's state badges into a state row of the agent details table

The small preview in the detail panel keeps only the connection badge and
expand, and no longer follows the agent's state stream; the full terminal
tab keeps all its badges. The table gets a state row with the turn state, a
paused badge, and the context and billed tokens (not the model, which the
inference row shows). The preview's top padding drops to one badge row, and
the showHeaderBadges prop goes since the full-tab mount is now the only one
with badges.
This commit is contained in:
iris 2026-10-25 14:52:57 +01:00
commit 705160c0fd
3 changed files with 94 additions and 33 deletions

View file

@ -14,6 +14,7 @@ import { AgentInference } from "./AgentInference.js";
import { AgentInstructions } from "./AgentInstructions.js";
import { AgentLimits } from "./AgentLimits.js";
import { AgentPermissions } from "./AgentPermissions.js";
import { AgentStateRow } from "./AgentStateRow.js";
import { AgentTermPreview } from "../terminal/AgentTermPreview.js";
import { FRESHNESS, type AgentRow } from "../AgentTypes.js";
import { LinkAccountMenu } from "./LinkAccountMenu.js";
@ -76,6 +77,10 @@ export function AgentDetail({
/>
) : null}
</dd>
<dt>state</dt>
<dd>
<AgentStateRow key={row.name} agent={row.name} />
</dd>
<dt>hive</dt>
<dd>{row.hive ?? "—"}</dd>
<dt>config PR</dt>

View file

@ -0,0 +1,11 @@
/* The badges of the details table's state row, wrapping rather than clipping
in a narrow panel. */
.ui-agent-state-row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.25em;
}
.ui-agent-state-waiting {
opacity: 0.7;
}

View file

@ -0,0 +1,37 @@
// <AgentStateRow> — an agent's turn state, whether it is paused, and the
// tokens in its context and billed, as the details table's "state" row. The
// terminal preview below the table carries no badges of its own (the full
// terminal tab does), so this is where the panel says what the agent is doing.
// Follows the agent's state stream, which announces on a change and once a
// minute, so the row reads "waiting" until the first report lands.
import {
StateBadges,
termPaths,
tokenTotal,
} from "../terminal/AgentTermPreview.js";
import { useSwarmAgentStateStream } from "../terminal/useSwarmAgentStateStream.js";
import "./AgentStateRow.css";
export function AgentStateRow({ agent }: { agent: string }) {
const { header } = useSwarmAgentStateStream(termPaths(agent).state);
if (!header) {
return (
<span
class="ui-agent-state-waiting"
title="the agent reports its state when it changes, and once a minute"
>
waiting for the agent's report…
</span>
);
}
return (
<div class="ui-agent-state-row">
<StateBadges
header={header}
ctx={tokenTotal(header.ctx_usage)}
cost={tokenTotal(header.cost_usage)}
withModel={false}
/>
</div>
);
}