Skip to content

feat(cli): document pages/s in gw chat stats; rename tokens to toks - #217

Merged
jeremyipark merged 10 commits into
mainfrom
cursor/gw-chat-pages-metrics-bece
Sep 2, 2026
Merged

feat(cli): document pages/s in gw chat stats; rename tokens to toks#217
jeremyipark merged 10 commits into
mainfrom
cursor/gw-chat-pages-metrics-bece

Conversation

@spillai

@spillai spillai commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add pages and pages/s to vlmrun gw chat stats footer (stream, --no-stream, and --json).
  • Parse page counts only from gateway OCR output — not local PDF inspection.
  • Support glm-ocr document URL responses: num_pages, single-quoted attributes, streaming-split tags, and <page> tag fallback when no count attribute is present.
  • Lighten stats line styling (dim not bold) and show whole-second latency.

Testing

  • pytest -sv tests/test_gateway.py (120 tests)
  • Live: vlmrun gw chat https://storage.googleapis.com/vlm-data-public-prod/hub/examples/finance.sec-filings/tsla-8k.pdf -m glm-ocr shows pages: 5 · pages/s: … in footer

Note

Earlier commits only matched pages="N" or used pypdfium2 for local files. glm-ocr URL-backed PDFs emit num_pages="N", so document URLs showed token stats without page metrics until this fix.

Open in Web Open in Cursor 

Report pages and pages/s in the gw chat summary footer for document
inputs, parsing gateway OCR wrappers or counting local PDF pages when
pypdfium2 is available. Rename the token count label from tokens to toks
to match the existing toks/s throughput metric.

Co-authored-by: sudeep <sudeep@vlm.run>
Remove pypdfium2 fallback for page counts. Pages and pages_per_sec are
parsed from <document pages="N"> in gateway output for stream,
--no-stream, and --json modes.

Co-authored-by: sudeep <sudeep@vlm.run>
@spillai
spillai marked this pull request as ready for review September 2, 2026 19:08

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

Devin Review

Comment thread vlmrun/cli/_cli/gateway.py Outdated

def _parse_document_pages_from_content(content: str) -> Optional[int]:
"""Sum ``pages`` attributes from ``<document pages="N">`` wrappers in OCR output."""
matches = _DOCUMENT_PAGES_RE.findall(content)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Document-like OCR text inflates page metrics

When OCR text contains <document pages="N">, _parse_document_pages_from_content counts it as another wrapper. The footer and JSON then overstate pages and throughput.

Prompt for agents
The page parser in vlmrun/cli/_cli/gateway.py uses findall across the complete model-generated response. OCR page bodies can themselves contain text matching <document pages="N">, so those matches are summed with the gateway's real document wrappers. Parse only wrapper elements that occur at valid document boundaries, while preserving support for multiple top-level wrappers and avoiding matches inside page content. Add a regression test containing one real wrapper and a document-like tag in its OCR text.
Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Use dim not-bold Rich styling instead of dim white for the stats footer.
Round elapsed time to integer seconds (e.g. 15s) for a cleaner total.

Co-authored-by: sudeep <sudeep@vlm.run>
glm-ocr wraps OCR output in <document num_pages="N"> rather than
pages="N". Accept both attribute names when reporting pages/s.

Co-authored-by: sudeep <sudeep@vlm.run>
glm-ocr wraps URL-backed PDFs with num_pages (not pages) and optional
<page> blocks. Broaden the OCR output parser for single quotes, attributes
split across streaming chunks, and page-tag fallback. Add gw chat tests
that assert pages metrics for http(s) document inputs.

Co-authored-by: sudeep <sudeep@vlm.run>
Restore dim white (not bold) for the stats footer and panel subtitle.
Drop the blue rule style on the streaming stats line so the summary
stays neutral.

Co-authored-by: sudeep <sudeep@vlm.run>
Display page metrics as `5 pages · 2.00 pages/s` instead of
`pages: 5 · pages/s: 2.00` to match other throughput labels.

Co-authored-by: sudeep <sudeep@vlm.run>
Co-authored-by: sudeep <sudeep@vlm.run>
@jeremyipark
jeremyipark merged commit 59e0716 into main Sep 2, 2026
4 checks passed
jeremyipark pushed a commit that referenced this pull request Sep 2, 2026
<!-- CURSOR_AGENT_PR_BODY_BEGIN -->
## Summary

Fixes `toks/s` to measure from first streamed token (excluding TTFT),
rebased onto main so PR #217's `pages` / `pages/s` stats are preserved.

- `_drain_stream` returns `generation_s` (first token → stream end)
- `_stats_parts` uses `generation_s` for `toks/s`, total `latency_s` for
`pages/s` and the `Xs` footer
- Page stats from #217 (`_parse_document_pages_from_content`, footer +
`--json`) unchanged

## Why pages might not appear

Page metrics are **parsed from OCR response text**, not from the local
PDF:
- Needs `<document pages="N">` / `num_pages="N"` or countable `<page>`
tags (glm-ocr markdown)
- Raw JSON OCR output (`--method detect` / `ocr`) has no document
wrapper → no pages in footer

## Test plan

- [x] `pytest -sv tests/test_gateway.py` (120 passed; 1 streaming footer
test can flake on narrow terminals when `toks/s` is huge)
<!-- CURSOR_AGENT_PR_BODY_END -->

<div><a
href="https://cursor.com/agents/bc-58c0d343-1ef3-46d2-8ce5-e2704dc70d00?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-web-light.png"><img
alt="Open in Web" width="114" height="28"
src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>&nbsp;<a
href="https://cursor.com/background-agent?bcId=bc-58c0d343-1ef3-46d2-8ce5-e2704dc70d00&cursor_ref=pr_footer&cursor_cta=open_in_cursor"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img
alt="Open in Cursor" width="131" height="28"
src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;</div>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants