hive-agent: export ACP-reported cost and context fill over OTLP
An ACP agent's `usage_update` carries `cost.{amount,currency}`, the
session's running total (opencode sums every assistant message in the
session). hive-runtime now reads it and turns the running total into
what each report added: a new session counts from zero, a session loaded
into a freshly started agent only baselines on its first report, and a
falling total adds nothing. The spend is held on the runtime until
`Runtime::take_reported_cost` drains it; claude's runtime reports none,
since the claude binary already exports `claude_code.cost.usage`.
hive-agent's existing turn-metrics meter records three new instruments:
- `hyperhive.agent.cost.usage` (counter, `model` + `currency`), ACP only;
- `hyperhive.agent.context.used` / `.size` (gauges, no attributes), for
every backend: the two numbers the web UI's ctx% divides.
The `hyperhive · agents` dashboard gets ACP cost panels on its cost tab
and a context-fill panel on its health tab.
Refs #4845
This commit is contained in:
parent
5d7042e655
commit
c2bdf30e05
8 changed files with 605 additions and 26 deletions
|
|
@ -1001,6 +1001,7 @@ async fn handle_turn<S: Surface>(
|
|||
let ended_at = chrono::Utc::now().timestamp();
|
||||
let duration_ms = i64::try_from(started_instant.elapsed().as_millis()).unwrap_or(i64::MAX);
|
||||
let (open_threads, open_reminders) = S::post_turn_counts(socket).await;
|
||||
let context_window = bus.effective_context_window(&model_at_start);
|
||||
let row = serve_common::build_row(serve_common::TurnRowArgs {
|
||||
started_at,
|
||||
ended_at,
|
||||
|
|
@ -1014,10 +1015,17 @@ async fn handle_turn<S: Surface>(
|
|||
open_reminders_count: open_reminders,
|
||||
});
|
||||
// Harness-only OTEL metrics (duration/wake_from/result_kind/loose-ends/
|
||||
// session boundaries) — independent of the sqlite sink below, and a
|
||||
// cheap no-op when OTEL isn't configured. See `otel_turn_metrics`'s
|
||||
// module doc for why token/cost/tool-count are deliberately not here.
|
||||
// session boundaries/context fill) — independent of the sqlite sink
|
||||
// below, and a cheap no-op when OTEL isn't configured. See
|
||||
// `otel_turn_metrics`'s module doc for why token/tool-count are
|
||||
// deliberately not here, and why cost is only ever an ACP agent's.
|
||||
otel_turn_metrics::record(&row, fresh_session);
|
||||
if let Some(ctx) = bus.last_ctx_usage() {
|
||||
otel_turn_metrics::record_context(ctx.context_tokens(), context_window);
|
||||
}
|
||||
for cost in hive_runtime::Runtime::take_reported_cost(session) {
|
||||
otel_turn_metrics::record_reported_cost(&row.model, &cost);
|
||||
}
|
||||
if let Some(stats) = stats {
|
||||
stats.record(&row);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue