@kyaulabs/pi-widgets0.4.2
Fast mode, token throughput, and time-to-first-token status widgets for Pi
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
pi-widgets
Status widgets for Pi. The package contains two independent extensions:
fast-mode.tstoggles OpenAI's Fast, Ultrafast, and Flex service tiers and shows the active mode.tps.tsreports request-average output throughput and first-server-event latency (displayed as TTFT) in Pi's footer and working line.
Requirements
- Node.js 22.19.0 or newer
- Pi 0.84.4 or newer
The package is tested against Pi 0.84.4. Pi loads the TypeScript files directly, so there is no build step or generated runtime code.
Install
Install both extensions from npm:
pi install npm:@kyaulabs/pi-widgets
A Git checkout also works:
pi install git:github.com/kyaulabs/pi-widgets
For local development, point Pi at the checkout:
pi install /path/to/pi-widgets
Restart Pi after installation. Use /reload after editing a locally installed checkout.
Load only one extension
Pi package filters can select a single widget. Add the package in object form to ~/.pi/agent/settings.json:
{
"packages": [
{
"source": "npm:@kyaulabs/pi-widgets",
"extensions": ["extensions/fast-mode.ts"]
}
]
}
Replace the extension path with extensions/tps.ts to load only the TPS widget.
If upgrading from the old filenames, update explicit extension paths and package filters to
extensions/fast-mode.ts and extensions/tps.ts. Remove any manually copied old files to avoid
loading duplicate widgets. Commands, settings keys, and shortcuts are unchanged.
GPT Fast mode
Fast mode is disabled by default. Run /fast or press Ctrl+Alt+M to toggle it for the current session. The Fast footer status appears while it is enabled.
When the selected model is supported, the extension sends the API-compatible
priority value for Fast mode in the matching provider request:
{
"service_tier": "priority"
}
Run /ultrafast to request service_tier: "ultrafast" for gpt-6-astra or
gpt-5.6-sol on either provider. The footer shows ⚡ Ultrafast in purple.
GPT-5.6 Sol requires OpenAI preview access. Both tiers cost more than Standard;
see OpenAI's Fast and
Ultrafast guides
for pricing and availability restrictions. Provider authentication and account
access still determine whether a request is accepted.
Run /flex to request service_tier: "flex", with a green Flex footer status.
Flex offers lower costs in exchange for slower responses and occasional resource
unavailability. The extension uses the model list in OpenAI's
Flex pricing table:
gpt-6-astra, gpt-6.1-sol, gpt-6-sol, gpt-6-luna, gpt-5.6-sol,
gpt-5.6-terra, gpt-5.6-luna, gpt-5.5, gpt-5.5-pro, gpt-5.4,
gpt-5.4-mini, gpt-5.4-nano, gpt-5.4-pro, gpt-5.2, gpt-5.1, gpt-5,
gpt-5-mini, gpt-5-nano, o3, and o4-mini, on either provider.
See the Flex guide
for availability and timeout guidance. This command does not change provider
timeouts or retries, or automatically fall back to a higher-cost tier.
All three modes are mutually exclusive: enabling one replaces the other. Running the active mode's command again disables it. The existing shortcut toggles Fast only. Unsupported models and mismatched payloads are left unchanged, with a warning when the selected mode does not support the current model.
Supported models
The extension enables Fast requests on openai and openai-codex for the models
in OpenAI's Fast pricing table:
gpt-6-astra,gpt-6.1-sol,gpt-6-sol,gpt-6-lunagpt-5.6-sol,gpt-5.6-terra,gpt-5.6-lunagpt-5.5,gpt-5.4,gpt-5.4-mini,gpt-5.2,gpt-5.1,gpt-5,gpt-5-minigpt-4.1,gpt-4.1-mini,gpt-4.1-nano,gpt-4o,gpt-4o-2024-05-13,gpt-4o-minio3,o4-mini
The existing gpt-5.6 alias remains supported. Unlisted models are not enabled automatically.
Default state
Set the startup state under pi-gpt-fast-mode in ~/.pi/agent/settings.json:
{
"pi-gpt-fast-mode": {
"enabled": true
}
}
The /fast, /ultrafast, and /flex commands change only the current session.
A new session reloads the configured Fast default; Ultrafast and Flex are never
enabled automatically.
Shortcut
Set one shortcut, several shortcuts, or false in ~/.pi/agent/keybindings.json:
{
"pi-gpt-fast-mode": ["ctrl+alt+m", "alt+f"]
}
{
"pi-gpt-fast-mode": false
}
The default is ctrl+alt+m. The extension ignores ctrl+m, enter, and return because those keys submit input in common terminal configurations. Empty or invalid scalar values restore the default shortcut.
TPS and TTFT status
The TPS widget measures request-average output throughput, not pure decoding speed.
For each response, timing starts at before_provider_request and stops at the assistant's
message_end. The denominator includes the wait before content, hidden reasoning, streaming,
and response finalization, excluding the observable pauses listed below.
Previously, the widget divided the final output count by time after the first content delta.
Pi's OpenAI Responses providers, including openai-codex, copy output_tokens to usage.output
and its reasoning breakdown to usage.reasoning. Output already includes hidden reasoning.
Counting that reasoning over only the later content burst inflated TPS.
For example, a 10-second request wait followed by 100 output tokens in 2 seconds now produces 8.3 tok/s. TTFT is measured independently from the first server event, not from that content burst. A local file read before the request counts toward neither.
The calculation is:
sum of output tokens from measurable responses / sum of their matching timed request seconds
Each response includes its own initial wait. The footer aggregates across the prompt's
responses until agent_settled; it never averages individual rates. It freezes between
requests. The working-line suffix is removed during pauses, leaving Pi's tool, compaction,
and retry indicators alone. A finalized measurement might look like:
32.4 tok/s · TTFT 700ms
The UI labels first-server-event latency as TTFT. It runs from before_provider_request
to the first parsed provider_stream_event, using the same pause-adjusted request clock, and
resets for each response. This is not necessarily time to a generated token, visible prose, or
the first network byte: response.created can establish this measurement without any content.
Text, thinking, and tool-call deltas do not establish TTFT; first-content latency is not displayed.
TTFT is hidden until a raw event is observed, or when the Pi host/provider lacks the necessary
hooks. It never uses a fabricated zero or substitutes content arrival for a missing raw event.
Buffered/nonstreaming responses with a request hook and positive output usage can contribute
throughput while TTFT remains hidden. Without a request hook, neither request
throughput nor latency is inferred from message_start. /tps ttft and showTTFT control this
single latency value.
Live counts use one estimated token per four Unicode code points in text, thinking, and tool-call
argument deltas, rounded up per response. They use the full timed request, not a post-content
window. Partial usage can be stale and is ignored. A positive final usage.output replaces
that response's estimate. Missing, invalid, or zero-placeholder usage retains the estimate.
The display always uses plain tok/s, without average or estimate prefixes; live counts and
aggregates containing fallback counts are still estimates. Hidden reasoning is unobservable in
these estimates, so final usage can change the rate substantially. While waiting without
content, the previous aggregate remains unchanged.
The widget uses each provider's declared output total without adding or subtracting
usage.reasoning. Reasoning metadata can be missing or zero, and subtracting it is not a
provider-independent count of streamed content. Input/cache tokens, tool results, nested
model calls during tools, and compaction/branch-summary usage do not contribute.
Responses without a matching request window, with less than 50 ms of timed request duration,
or without positive usage or an observed output estimate contribute neither tokens nor time.
Throughput and latency exclude:
- Tool execution, including parallel/custom tools, permission gates, and result hooks.
- Manual, automatic, failed, and cancelled compactions, plus branch summarization.
- Prompt/context preparation and authentication before the provider-request hook.
- Blocking extension UI prompts and gaps between requests.
- Observable retry backoff, queued-continuation preparation, and idle time.
Retries within an open response retain the observed attempt time before a non-success HTTP response. Timing pauses at that response and resumes at a repeated request hook, excluding backoff. Final usage replaces the response's estimate once, not once per attempt. Latencies are measured from the initial hook over these accumulated attempt intervals. If success headers, a raw stream event, or content arrive without a new request hook, retry latency cannot be separated from backoff: that response's timing becomes unknown and its throughput sample is excluded. Previous aggregates remain intact. Pi-level retries after a response closes start a new response window; the gap is excluded.
Cancellation stops the timer immediately and retains only a measurable estimate of content observed before cancellation. Late events cannot add finalized usage to that closed window. An interrupted response retains an observed first-server-event TTFT; without that event, TTFT remains hidden.
Accuracy limits: these are client-observed measurements. Chunking, buffering, network delay, and finalization affect them; hidden provider-internal retries/reconnects without observable boundaries remain inside the timed request. Older Pi hosts and custom providers may lack hooks. Historical total response durations are not TTFT measurements. This reporting fix does not eliminate provider latency, establish the cause of reported long stalls, or change transport, authentication, reasoning effort, or service tier.
Commands
| Command | Effect |
|---|---|
/tps or /tps status |
Show the current measurement and display settings. |
/tps on |
Enable all TPS metrics. |
/tps off |
Disable all TPS metrics. |
/tps toggle |
Toggle all TPS metrics. |
/tps bar on|off|toggle |
Control the footer value. |
/tps line on|off|toggle |
Control the working-line suffix. |
/tps ttft on|off|toggle |
Control first-server-event TTFT in the working line. |
/tps help |
Show command help. |
Command changes last for the current session.
Persistent settings
Set defaults under pi-tps-status in ~/.pi/agent/settings.json:
{
"pi-tps-status": {
"enabled": true,
"statusBar": true,
"workingLine": true,
"showTTFT": true,
"refreshMs": 250
}
}
| Setting | Type | Default | Meaning |
|---|---|---|---|
enabled |
boolean | true |
Enable throughput and latency measurement output. |
statusBar |
boolean | true |
Show TPS in Pi's footer. |
workingLine |
boolean | true |
Show live metrics beside Pi's working indicator. |
showTTFT |
boolean | true |
Include first-server-event TTFT in the working line. |
refreshMs |
number | 250 |
Refresh interval, rounded and clamped to 100–2000 ms. |
Invalid values use their defaults. Missing or malformed settings files do not stop the extension from loading.
Colors and Zentui
The footer color moves through these throughput ranges:
- 15 tok/s or less: red
- 15–40 tok/s: red through yellow to green (
#1aaa13) - 40–75 tok/s: green to cyan (
#4dc5dc) - 75–100 tok/s: cyan to purple (
#73488b) - 100 tok/s or more: purple
Standard Pi output uses 24-bit ANSI color.
When pi-zentui advertises working-line segment support, the widget sends throughput and latency as a named tps segment instead of replacing Pi's working message. It also emits the matching status color before each footer update. Without Zentui, it uses Pi's standard status and working-message APIs.
Data handling
Both extensions run inside the Pi process with the permissions granted to Pi.
The Fast mode extension reads settings.json and keybindings.json. It changes only matching provider payloads while Fast mode is enabled. The TPS extension reads settings.json and observes lifecycle, message-usage, and tool-execution events. It does not write settings, session data, prompts, responses, or metrics to disk, and it does not send telemetry.
Development
Install dependencies and activate the tracked Git hooks:
npm install
npm run hooks:install
Run the same checks used by CI:
npm run check
npm pack --dry-run
npm run check lints and type-checks the extensions, then runs coverage with 98 percent minimums for statements, branches, functions, and lines. The pre-commit hook also requires Gitleaks.
See CONTRIBUTING.md for test and pull-request requirements.
License
Copyright © KYAU Labs. Licensed under the GNU Affero General Public License v3.0.