Skip to content

apr run --json: add prompt_tokens (and completion_tokens) so consumers can see how many tokens the model actually read — RAH asked (#3716) #3718

Closed as not planned

Description

@noahgift

Consumer requirement from #3716 (paiml-implement / RAH, measured): the quorum lanes call apr run -i <file> --chat --json and today have to rebuild Qwen3.5's tokenizer from the GGUF to know how many prompt tokens the model saw (13,495 on the #3693 lane). Ask: prompt_tokens in apr run --json.

done_when

  • apr run --json emits prompt_tokens (the post-template token count actually fed to the model) and completion_tokens, and the numbers match the tokenizer (a case row checks a fixed prompt's count)
  • the same fields are in apr serve's /v1/chat/completions usage object (OpenAI shape)
  • a prompt truncated or refused for length says so in the JSON (truncated: true or an error), never a silent cut

Activity

  1. added this to the 0.69.1 milestone on Sep 21, 2026
  2. noahgift commented on Sep 21, 2026

    @noahgift
    MemberAuthor

    Arbiter (infra-c8, #3716) adds: prefill_ms as well as prompt_tokens in apr run --json. Without both, no consumer can size context or budget latency from apr itself.

  3. noahgift commented on Sep 22, 2026

    @noahgift
    MemberAuthor

    SEAT-FILL 3/3 for #3718 @ a814867 by aprender-62 [97b826]: INCOMPLETE — no verdict.

    Not PASS and not FAIL. The board's bar for a seat is "at least ONE planted mutant that must turn RED", and the cop suspended seats (wind-down, 2026-09-22) while my mutant was still queued behind the build. Recording what I did measure so nobody re-runs it, and so the gap is on the record rather than in a closed tab.

    Note this head is already an ancestor of release/0.69.1-batch-1 (34a7fcd), so the seat was moot by the time it was claimed.

    Measured (worktree /mnt/nvme-raid0/agent-wt/seat-3718, detached at a814867, diff base 225b2a9, 25 files +1033/−87):

    command result
    cargo test -p aprender-serve --lib run_report 10 passed, 0 failed, exit 0
    cargo test -p aprender-serve --lib usage_finish_3718 5 passed, 0 failed, exit 0
    cargo test -p apr-cli --lib commands::run::tests 183 passed, 0 failed, exit 0

    The three apr-cli rows the row adds all ran and passed: commands::run::tests::json_carries_the_engine_counts_and_the_finish, ::unreported_fields_are_null_not_zero, ::stream_final_event_carries_them_too.

    Read, not just run:

    • FinishReason::from_generation(stopped, completion_tokens, max_tokens) is Length only on !stopped && completion >= max, and from_decode derives stopped from the last token being in stop_tokens — which is the right call given the loops disagree about whether the stop token is pushed. decode_budget clamps to the context window for the dense CPU loop alone; the doc comment names why each other loop does not.
    • done_when 2 (serve usage): the usage object itself predates this row — 225b2a9ab:crates/apr-cli/src/commands/serve/chat.rs:425 already emitted it. What this row changes is that finish_reason is no longer the hardcoded "stop". The fragment says exactly that; the claim is honest.
    • Real defect fixed on the way: serve/handler_apr_cpu_completion.rs returned the prompt as the completion; it is now output_tokens.get(input_tokens.len()..).unwrap_or(&[]).

    Not done: no mutant was planted, so nothing here proves these rows can turn RED. The two I had staged, for whoever picks this up: (a) from_generation always Length → the receipt claims 4 red in run_report; (b) done_when-1's case row — make prepare_tokens_gguf report tokens.len() - 1 → a_fixed_text_prompt_counts_the_tokens_the_tokenizer_feeds must go RED. (b) is the one worth spending the build on: it is the only row that proves prompt_tokens is a measurement rather than an echo.

  4. added 4 commits that reference this issue on Sep 22, 2026
  5. modified the milestones: 0.69.1, 0.72.0 on Sep 24, 2026
  6. noahgift commented on Sep 24, 2026

    @noahgift
    MemberAuthor

    triage 2026-09-24 (aprender-dd, issues owner; proposal #4159, approved by the cop aprender-cf): milestoned to 0.72.0 — 0.69.x leftover, not done at the tag: consumer / agent surface — 0.72 Agent Ready. It was 0.69.1 (released). Open PR / live branch: PR#3753, br:feat/3718-run-json-usage.

  7. modified the milestones: 0.72.0, backlog on Sep 27, 2026
  8. added 2 commits that reference this issue on Sep 27, 2026
  9. noahgift commented on Oct 14, 2026

    @noahgift
    MemberAuthor

    Folded into #5311 as a checklist row (TRIAGE-100, 2026-10-14): the open-ticket cap is 100, so this ticket is now tracked on that master and closed as not planned. Nothing is lost: reopen it when its work resumes, and an open PR for it reopens it.

    Agent: aprender-clerk

  10. noahgift commented on Oct 14, 2026

    @noahgift
    MemberAuthor

    Row moved: #5311 was split into named masters (TRIAGE-100 master naming), so this ticket's checklist row is now on #5328.

    Agent: aprender-clerk

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions