npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

oh-my-tps

v0.3.1

Published

Tiny live TTFT and TPS readouts for the Pi coding agent.

Readme

Oh My TPS

English | 简体中文

安装

npm package

pi install npm:oh-my-tps

Git repository

pi install git:github.com/EnderLiquid/oh-my-tps

功能速览

oh-my-tps 只做一件事: 给 Pi TUI 加一组实时速度读数,测量 LLM 首字延迟和输出速度。

  • τ:TTFT,首个 token 到达前等了多久,单位秒
  • Δ:TPS,每秒输出多少 token

显示效果:

τ0.8 Δ48.6

就这么多。

十个字符的空间,开箱即用的体验。

感兴趣可以继续往下看,但到这里你其实已经会用了。

读数详解

你会在 TUI 底部状态区域看到这样的读数:

τ0.8 Δ48.6
τ1.1 Δ49.7L
τ0.8A Δ52.4A

这里后缀的含义是:

  • A:平均值(Average)。TTFT 和 TPS 分别维护自己的历史样本。
  • L:上一轮有效的最终 TPS(Last),仅用于 Δ

可以这样理解:

  • τ0.8 Δ48.6:响应正在流式传输,TTFT 约为 0.8 秒,并且已经产生了当前有效的实时 TPS。
  • τ1.1 Δ49.7L:请求已经发出,但还没有收到首个 token;TTFT 正在计时,Δ 暂时显示上一轮最终有效 TPS。
  • τ0.8A Δ52.4A:当前处于空闲状态,显示近期 TTFT 和 TPS 的平均值。

流式传输时的 Δ 仍可能显示为上一轮 TPS、平均 TPS 或未知值,直到实时 TPS 满足首次计算条件。响应结束后的 Δ 优先使用服务提供方返回的 usage.output;只有没有可用的 usage.output 时,才使用最后一次有效的实时 TPS。本轮没有有效最终 TPS 时,最终状态回退到本轮开始前的上一轮 TPS,再回退到平均 TPS。

配置

默认开箱即用。要更改读数颜色,创建 ~/.pi/agent/oh-my-tps.json

{
  "builtinRenderer": {
    "color": "muted"
  }
}

同时,插件支持自行绘制并替换内置读数。做法是把状态数据发布到 Pi 的事件总线,实现测量与渲染解耦,内置读数只是其中一个事件订阅者。你可以关闭内置读数,订阅同一份数据并渲染到任何位置。详见 CONFIGURATION.zh-CN.md

原理说明

下面这部分面向希望了解插件原理的用户。

状态机

内部分为四个阶段:

  1. 等待阶段:请求已发出,等待首个 token
  2. 流式输出阶段:首个 token 已到达,响应正在流式输出
  3. 最终阶段:响应结束,已完成本轮 TPS 的结算尝试
  4. 空闲状态:当前没有正在处理的服务提供方请求

示例:

空闲 τ… Δ? (还没有历史样本)
    -> 等待 τ0.2 Δ? (等待首个 token,每200ms更新τ)
    -> 流式输出 τ1.3 Δ? (首个 token 可能来自思考,τ已锁定,实时 TPS 尚未就绪)
    -> 流式输出 τ1.3 Δ51.0 (新的非思考增量到达,实时 TPS 已满足观察条件)
    -> 最终 τ1.3 Δ52.0 (本轮有效最终 TPS 来自 `usage.output` 或实时 TPS 回退值)
    -> 空闲 τ1.3A Δ52.0A
    -> 等待 τ0.2 Δ52.0L (优先显示上一轮有效最终 TPS)

τ 的来源

TTFT 的定义是:从请求发出到首个 token 到达所等待的时间。

插件使用首个携带 token 的非空流式增量作为可观测信号。以下事件在 delta.length > 0 时会触发 TTFT:

  • text_delta
  • thinking_delta
  • toolcall_delta

以下事件不会触发 TTFT:

  • text_start
  • thinking_start
  • toolcall_start
  • 空增量以及其他元数据事件

收到首个有效增量后,插件把它与请求开始时间的差值锁定为本轮 TTFT。

因此:

  • 等待阶段的 τ 会一直增加;
  • 首个正文、思考或工具调用 token 到达后,进入流式输出阶段,τ 就锁定;
  • thinking_start 等元数据不会结束等待,但非空 thinking_delta 会结束等待;
  • 如果服务提供方把思考内容加密并且不传输思考增量,插件只能测量首个可观察 token 的 TTFT,无法获得隐藏思考阶段内部的时间轴。

TTFT 样本与 TPS 样本独立维护。只要首个 token 到达,本轮就可以贡献 TTFT 平均值,即使本轮最终没有有效 TPS。

实时 Δ 的来源

服务提供方不会持续告诉 Pi “刚刚又生成了多少个 token”,所以实时 TPS 只能在本地估算。当前实现使用非思考增量的滚动队列:

  • 纳入非空的 text_delta
  • 纳入非空的 toolcall_delta
  • 排除所有 thinking_delta,包括思考摘要。

默认窗口是最近 5 秒。每当新的非思考增量到达时,插件会:

  1. 将原始增量和到达时间加入队列;
  2. 移除窗口之外的旧增量;
  3. 按到达顺序拼接窗口内的增量;
  4. 使用 tokenx 估算拼接内容的 token 数;
  5. 用窗口内 token 数除以观察时长,得到新的实时 TPS。

公式可以表示为:

实时 TPS = 最近窗口内的非思考增量估算 token
           /
           min(5秒,首个非思考增量后的观察时长)

从首个非思考增量到第一次计算实时 TPS,至少需要观察 2 秒。这个等待时间用于避免流式刚开始时分母过小,或者服务提供方一次性发送初始积压内容而产生异常高值。

实时 TPS 是最近窗口内正文和工具参数的传输速率,只在新的非思考增量到达时重算,不使用后台定时器。

最终 Δ 的来源

响应结束时,插件按以下顺序结算 TPS。

1. 服务提供方返回的 usage.output

当服务提供方返回有限正数 usage.output,并且从首个非空的正文、思考或工具调用增量到响应结束至少经过 2 秒时,使用:

最终 TPS = usage.output
           /
           (响应结束时间 - 首个有效内容增量时间)

usage.output 通常是服务提供方报告的真实输出 token 数,可能包含推理 token。因此,这个来源的分子可能包含思考 token,分母则从首个可观察的内容增量开始。

对于加密思考模型,隐藏思考可能在首个可观察增量之前已经发生。客户端无法知晓这段隐藏推理时长,因此 usage.output 来源的最终 TPS 可能略高于真实值。

2. 实时 TPS 回退值

只有当服务提供方没有可用的 usage.output 时,才使用本轮最后一次有效的实时 TPS:

最终 TPS = 本轮最后一次有效的实时 TPS

这个来源不包含思考,只反映正文和工具参数在最近窗口中的输出速率。

如果服务提供方返回了可用的 usage.output,但从首个有效内容增量到响应结束的时长不足 2 秒,插件不会改用实时 TPS 回退值;本轮没有有效最终 TPS。

实时值与最终值存在偏差的原因

1. token 估算是启发式的

tokenx 不是精确 tokenizer,而是一个轻量、偏启发式的估算库。它的优势是小而快,适合实时 UI 刷新。代价也很明确:它不是为所有模型都精确对齐而设计的。

tokenx 的设计与基准测试更偏向 GPT tokenizer / 英文文本 场景。当接入其他模型家族的 LLM,或者输出内容包含非英文字符时,偏差往往会更大一些。

2. 流式输出节奏不均匀

模型输出不是严格按“每个 token 匀速到达”展示给 UI 的。实际过程中还会受到这些因素影响:

  • 服务提供方自己的 SSE / chunk 刷新策略;
  • Pi 发布事件的节奏;
  • 思考、工具调用、正文混在一起时的内容结构变化。

3. 两种 TPS 的统计范围不同

实时 TPS 和 usage.output 来源的最终 TPS 的定义本来就不同:

  • 实时 TPS 只统计最近窗口内的非思考正文和工具调用;
  • usage.output 来源的最终 TPS 使用服务提供方报告的输出 token,并统计从首个正文、思考或工具调用增量到响应结束的时长;
  • 实时 TPS 不包含思考,而 usage.output 来源的最终 TPS 可能包含推理 token。

所以二者即使都没有估算误差,也不一定相等。实时值反映当前响应末段的输出节奏,最终值反映本轮可观察流式阶段的整体结果。

平均值 A

当前实现分别维护最近最多 5 条 TTFT 样本和 TPS 样本:

  • 首个 token 到达后,TTFT 就可以写入 TTFT 历史;
  • 只有本轮产生有效最终 TPS,才会写入 TPS 历史;
  • 使用服务提供方 usage.output 计算出的最终 TPS,以及实时 TPS 回退值来源的最终 TPS,都会纳入平均 TPS;
  • 因此一轮请求可能贡献 TTFT,但不贡献 TPS。

A 表示近期有效样本的平均值,不保证 TTFT 平均值和 TPS 平均值来自完全相同的请求集合,也不保证平均 TPS 中每条样本都具有相同的 token 统计范围。

数据参考指导

经验上可以这样看:

  • τ:参考价值很高,适合观察请求延迟;
  • 最终 / 平均 Δ:适合观察近期整体输出速度表现;
  • 实时 Δ:适合观察当前正文或工具参数的实时输出速度;

插件适用范围

  • 适用于为 LLM 速度与延迟提供粗略量化参考
  • 适用于快速发现长会话中某次明显偏慢的请求
  • 不适用于严格的模型性能对比与基准测试

许可证

MIT License