-
Notifications
You must be signed in to change notification settings - Fork 12
Description
Parent
Part of #204 (Phase 4: Hardening)
Problem
Agent status updates rely on agents explicitly calling the gt_status tool, which they often forget to do. Meanwhile, the Kilo SDK already has agents writing markdown with H1 headers that describe what they're doing — # Installing packages, # Running tests, # Creating the main UI components. These natural status lines already flow through the event stream but aren't used.
Solution
Parse H1 headers from the agent's text output and use them as status updates automatically. Remove the gt_status tool.
Implementation
Add H1 parsing to broadcastEvent() in container/src/process-manager.ts (line 88). When a message.part.updated event arrives with data.part.type === "text", extract the first H1 line and post it to the existing updateAgentStatusMessage API:
// In broadcastEvent(), after the existing buffer/WS/persist logic:
if (eventType === 'message.part.updated' || eventType === 'message_part.updated') {
const part = data?.part;
if (part?.type === 'text' && typeof part.text === 'string') {
const h1Match = part.text.match(/^# (.+)$/m);
if (h1Match && h1Match[1] !== lastStatusForAgent.get(agentId)) {
lastStatusForAgent.set(agentId, h1Match[1]);
client.updateAgentStatusMessage(h1Match[1]).catch(() => {});
}
}
}The lastStatusForAgent Map deduplicates — message.part.updated fires on every text delta, but the H1 only changes when the agent starts a new response block. Without dedup, we'd spam the status API with identical updates.
What this flows into
The updateAgentStatusMessage API already:
- Updates
agent_metadata.agent_status_messagein TownDO SQLite (agents.ts:482-493) - Broadcasts an
agent_statusWebSocket message to all connected dashboard clients (Town.do.ts:999-1018) - The dashboard's agent cards already render status bubbles from this data (feat(gastown): add agent status bubble UI and gt_status tool #999)
No dashboard changes needed. The status bubbles just start working reliably because they're populated from the agent's natural output instead of an explicit tool call.
Remove gt_status tool
Once H1 parsing is in place:
- Remove
gt_statusfromcontainer/plugin/tools.ts:215-230 - Remove the corresponding client method
updateAgentStatusMessagefromclient.ts:130-135(keep the HTTP endpoint — the container's H1 parser uses it) - Remove
gt_statusreferences from polecat and mayor system prompts - Remove the prompt guidance about calling
gt_statusat "meaningful phase transitions"
Edge cases
- Agent writes multiple H1s in one response: Use the last one — it's the most current status
- Agent writes no H1: No status update — the previous status remains. This is fine; not every response needs a status change.
- H1 is very long: Truncate to 120 characters for the status message
- Non-text parts (tool calls, reasoning): Ignored — only
type: "text"parts are parsed
Acceptance Criteria
- H1 headers parsed from
message.part.updatedevents inbroadcastEvent() - Parsed H1 posted to existing
updateAgentStatusMessageAPI - Deduplication prevents redundant status updates for the same H1
-
gt_statustool removed from plugin tools -
gt_statusreferences removed from system prompts - Agent status bubbles on dashboard update automatically from agent output
- No dashboard changes needed — existing status bubble UI works as-is
Notes
- No data migration needed
- This is a simplification — we're removing a tool and its prompt overhead while getting more reliable status updates
- The H1 convention is already established in the Kilo/OpenCode CLI output format. Agents naturally write these as part of their response structure.
- If we later want richer status metadata (progress percentage, estimated time), we can parse additional markdown conventions (e.g., progress bars, metadata blocks) from the same text stream
- Supersedes the tool-based approach from feat(gastown): add agent status bubble UI and gt_status tool #999 (Agent Status Bubbles)