mirror of
https://github.com/wu736139669/hapi.git
synced 2026-11-08 01:43:07 +00:00
feat(hub): persist agent turns and report them through hapi usage
Whether a session's agent is thinking lived only in the session cache, so once a turn ended nothing could say how long the agent had worked, and a hub restart forgot even the turn in progress. Tools that track time (Weft, for one) had no way to see when agents on other machines were busy. Schema v28 adds session_turns: a row opens when a session starts thinking (a prompt queued through the hub, the agent reporting it, or a patch) and closes when it stops, the session ends, or its keepalives expire, at the last keepalive. Rows are only written on those transitions, never per keepalive. Turns move with a session when it is merged away. At startup the hub closes turns left open by the previous process at the session's newest message. If the agent carries on thinking within 10 minutes of the restart, the same turn continues, so the work between that message and the restart isn't lost. The deadline counts from the restart, and a keepalive or patch reporting idle, the session ending, or a new prompt ends the chance: those start a new turn. GET /api/activity returns, for the caller's namespace, each session's turns in a window (default 24 h, at most 31 days) with what identifies it (flavor, agent session id, machine, path, title) and the permission prompts and questions it waited on, taken from agent_state. `hapi usage [--since] [--until] [--json]` prints a summary or a hapi.activity.v1 report for other tools, with distinct exit codes for bad arguments (2), missing or refused credentials (3) and a hub too old to answer (4). The summary counts only the part of each turn inside the window and subtracts overlapping waits once. It reuses the peer commands' token exchange. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
b4be7c2d93
commit
23122ccbc0
@@ -1134,3 +1134,43 @@ export type UsageSummaryResponse = {
|
||||
byModel: UsageSummaryBucket[]
|
||||
updatedAt: number
|
||||
}
|
||||
|
||||
/** A stretch an agent was working: from `thinking` turning on to it turning
|
||||
* off. `end` is null while the turn is still going. */
|
||||
export type AgentActivityTurn = {
|
||||
start: number
|
||||
end: number | null
|
||||
endReason: 'idle' | 'session_end' | 'expired' | 'hub_restart' | null
|
||||
startedBy: 'hub_prompt' | 'agent' | 'patch'
|
||||
}
|
||||
|
||||
/** The agent waiting on the user inside a turn: a permission prompt or a
|
||||
* question. `end` is null while it is still waiting. */
|
||||
export type AgentActivityWait = {
|
||||
start: number
|
||||
end: number | null
|
||||
kind: 'permission' | 'input'
|
||||
tool: string
|
||||
}
|
||||
|
||||
export type AgentActivitySession = {
|
||||
id: string
|
||||
flavor: string | null
|
||||
/** The agent's own session id (Claude session, Codex thread, ...). */
|
||||
agentSessionId: string | null
|
||||
machineId: string | null
|
||||
host: string | null
|
||||
machineName: string | null
|
||||
path: string | null
|
||||
title: string | null
|
||||
turns: AgentActivityTurn[]
|
||||
waits: AgentActivityWait[]
|
||||
}
|
||||
|
||||
/** GET /api/activity: when agents in the caller's namespace were working. */
|
||||
export type AgentActivityResponse = {
|
||||
since: number
|
||||
until: number
|
||||
generatedAt: number
|
||||
sessions: AgentActivitySession[]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user