Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added
- `tole doctor` (#378): tiered provider diagnostics — `offline` (wiring) and `catalog` (live `/models`, the model must be served); each blocker carries its fix command, the exit code is non-zero when the requested tier is not reached, and keys / URL credentials are never printed.
- Per-user-turn token stats (#379): `tole status` lists input / output / cache-read / cache-write / reasoning tokens per turn and the status JSON (`GET /sessions/{id}/status`, `tole_session_status`) gains an additive `usage_report.turns` array. Derived from the durable usage ledger, so old sessions read the same way and nothing is stored twice; a value no step reported is `n/a` / `null`, never 0, and no elapsed time is invented.

### Changed
- Memory loop injection hygiene (#384): the recalled batch is hard-capped at 24 items / 64 KiB and deduplicated; a malformed recall payload (non-array, or a hit without content) now fails the whole batch visibly instead of silently injecting fewer items; `tole serve`/MCP sessions report recall failures on stderr like the CLI does.
Expand All @@ -30,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `read_file` rejects an empty `path` with a clear message instead of a confusing "is a directory" error.

### Added
- Per-user-turn token stats (#379): `tole status` lists input / output / cache-read / cache-write / reasoning tokens per turn and the status JSON (`GET /sessions/{id}/status`, `tole_session_status`) gains an additive `usage_report.turns` array. Derived from the durable usage ledger, so old sessions read the same way and nothing is stored twice; a value no step reported is `n/a` / `null`, never 0, and no elapsed time is invented.
- `tole status` and the serve status JSON now report token usage, cache-hit rate and a per-step request-size split (system+tools vs history, stored per step under `tole_wire` in the usage record); `fact/mission` gains `cached_tokens`. Instrumentation only: the wire, budgets and durable entry shapes are unchanged (#211, part 1 of 3).

### Changed
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,10 @@ the usage derived from the ledger for any session: prompt / completion /
reasoning / cached tokens, the cache-hit rate, and the request size in
characters split into system+tools vs history at the first and last step
(#211; recorded per step under `tole_wire`; sessions recorded before it read
`n/a`). Reported only — `--max-tokens` accounting is unchanged.
`n/a`). It also lists per-user-turn stats (#379: input / output / cache-read /
cache-write / reasoning tokens, `turns` in the status JSON), summed from the same
ledger so they survive restarts; a value no step reported is `n/a` / `null`,
never 0. Reported only — `--max-tokens` accounting is unchanged.

## Approval gates

Expand Down
4 changes: 4 additions & 0 deletions crates/tole-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2145,6 +2145,10 @@ fn status_command(sessions_dir: &Path, id: &str) -> Result<()> {
for line in tole_cli::usage_report::usage_report(usage).render_lines() {
println!("{line}");
}
// Issue #379: per user-turn stats from the same ledger.
for line in tole_cli::usage_report::turn_lines(storage.entries(), usage) {
println!("{line}");
}
Ok(())
}

Expand Down
2 changes: 1 addition & 1 deletion crates/tole-cli/src/serve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,7 @@ fn route(state: &State, method: &str, path: &str, body: &str) -> (u16, serde_jso
Ok(guard) => (
Some(guard.entries().len()),
// Issue #211: additive usage report.
tole_cli::usage_report::usage_report(guard.usages()).to_json(),
tole_cli::usage_report::usage_json(guard.entries(), guard.usages()),
),
// turn in flight — skip the count and report
Err(_) => (None, json!(null)),
Expand Down
2 changes: 1 addition & 1 deletion crates/tole-cli/src/session_tools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ impl Tool for SessionStatusTool {
json!(guard.entries().len()),
// Issue #211: additive usage report (same object as the
// serve status JSON).
crate::usage_report::usage_report(guard.usages()).to_json(),
crate::usage_report::usage_json(guard.entries(), guard.usages()),
),
Err(_) => (json!(null), json!(null)), // turn in flight
};
Expand Down
Loading
Loading