Add TokenScope Open List build (Word selection rewrite with a live token counter) - #201
Open
AbhinayYendoti wants to merge 2 commits into
Open
Add TokenScope Open List build (Word selection rewrite with a live token counter)#201AbhinayYendoti wants to merge 2 commits into
AbhinayYendoti wants to merge 2 commits into
Conversation
TokenScope is a Word add-in for the Open Task List card "Word selection rewrite with a live token counter" (S1). Select a paragraph, give a rewrite instruction, and see what the surgical edit actually cost next to what regenerating the whole document would have cost. The card's bar is that the counter is measured, not asserted, so both sides of the comparison are real SuperDocs jobs: chat/async in ask_every_time mode, compact job polling, and approve only when the user presses Apply. The whole-document figure is not modelled - it is the same instruction run as a genuine regeneration in a throwaway session on a copy of the document. Two measurements are reported side by side, because one turned out not to be enough. metadata.cumulative_tokens is SuperDocs' own figure and is never computed here, but it proved unstable across runs and is sometimes absent, so it is nullable and renders as "Not reported" rather than zero. Alongside it: the tokens of text each job actually returned, counted from its own pending_changes, which is available on every job at every size. Includes a reproducible benchmark at 3/10/50/100/300 pages whose results are generated, never typed by hand. Four sizes came back clean and monotone; the 300-page regeneration never completed across three attempts and is recorded as such rather than converted into a percentage. Built by Abhinay Yendoti for the SuperDocs engineering task. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
package-lock.json is 6,759 of the 12,828 lines in this pull request. More than half the review surface was a lockfile, which buries the work a maintainer is actually here to read. Marking it and bench/results.json linguist-generated collapses both in the diff view and drops them from language statistics. Nothing is removed: both stay committed, so `npm ci` still installs the exact tree that was tested, and either file can still be expanded and diffed on demand. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What I built
TokenScope — a Word add-in that rewrites the paragraph you selected, then shows what that surgical edit actually cost next to what regenerating the whole document would have cost.
Built for the Open Task List card "Word selection rewrite with a live token counter" (Band S1 — surfaces: chat, API).
Path:
extensions/AbhinayYendoti/tokenscope/Problem
An AI document editor that regenerates the whole document on every turn pays for the whole document on every turn. The cost of a one-paragraph change scales with the size of the file it happens to live in, which is backwards — the edit did not get bigger, the document did.
Surgical editing breaks that coupling. The claim is easy to make and easy to hand-wave, so TokenScope makes it falsifiable: it runs both operations against the live API, on the same document, on the same day, and reports what each one actually did.
How it works
The selection is delimited in the message rather than described, so the model matches an exact string instead of interpreting "the second paragraph". Every figure on screen carries a badge saying whether it was Measured, Tokenized or Estimated.
SuperDocs integration
Live REST API throughout — no mock, no offline fallback. Without a key the app starts, says the key is missing, and refuses to rewrite rather than show invented numbers.
POST /v1/chat/async/v1/chat, which returns before a job record exists — and the job record is the only place a token count appears.GET /v1/jobs/{job_id}compact=truewhile running, one full read once settled), and the source of the measured token count.POST /v1/chat/{session_id}/approveGET /v1/agents/whoamiapproval_mode: "ask_every_time"on every request;approve_allis never sent.The token counter is measured, not asserted. It reads
metadata.cumulative_tokensoff the job record — SuperDocs' own figure, never computed here. The whole-document side is not modelled either: it is the same instruction run as a genuine regeneration in a throwaway session on a copy of the document.That field turned out to be unstable across runs and is sometimes absent entirely, so it is nullable and renders as "Not reported" rather than zero. A second measurement sits beside it — the tokens of text each job actually returned, counted from its own
pending_changes— which is available on every job at every size.Scope is verified. SuperDocs mints its own chunk ids, so returned changes are mapped back to the selection on their original text. A change that cannot be mapped is out of scope: shown to the user, never offered for apply.
How to run
Everything runs from the project folder; no command needs the repository root. Word is optional — without it the right-hand column is a live document surface using the browser's own Selection API, and every SuperDocs call is identical. Word instructions (HTTPS cert, sideloading) are in the project README.
Testing
Run from
extensions/AbhinayYendoti/tokenscope/after a cleannpm ci:npm test— 93 tests passing, no API key requirednpm run typecheck— clean (strict,exactOptionalPropertyTypes)npm run lint— cleannpm run build— cleannpx office-addin-manifest validate manifest.xml— validThe client tests stub
fetchrather than the client, so the real request is built, the real zod schemas parse the response, and the real error mapping runs; fixtures are trimmed copies of bodies the live API actually returned.Manual end-to-end against the live API, from this folder:
whoamireturned tier and quota; a real rewrite completed in 9.4s producing one change, in scope, zero out of scope, with a measured cost of 86,702 tokens; the apply path was exercised separately in the browser.npm run benchregenerates the benchmark. Results inbench/RESULTS.mdare generated, never typed by hand, and every row carries its job ids and timestamp.The surgical column does not move. That is the entire argument.
Limitations
metadata.cumulative_tokensis not fully dependable. Not a running total despite the name; across runs the same 3-page rewrite reported 181,978 once and ~90,500 three times, and one 300-page run finished carrying no count at all. That is why the second measurement exists.core, not a claim about the platform.o200k_baseis probably not SuperDocs' tokenizer. Local counts measure text volume reproducibly and are only ever compared against each other, never presented as billing.src/host/word.tsare unverified.AI disclosure
AI coding assistance (Claude) was used throughout, as CONTRIBUTING invites. The measurement design, the decision to stop trusting the provider's counter after the benchmark contradicted it, and every number reported here came out of running the live API and reading what came back.
Candidate
Abhinay Yendoti