@snailuu/pi-token-use

Pi extension: interactive multi-dimensional drill-down of local token usage (time / project / model)

Packages

Package details

extension

Install @snailuu/pi-token-use from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@snailuu/pi-token-use
Package
@snailuu/pi-token-use
Version
0.2.1
Published
Jul 25, 2026
Downloads
442/mo · 442/wk
Author
snailuu
License
MIT
Types
extension
Size
69.3 KB
Dependencies
0 dependencies · 2 peers
Pi manifest JSON
{
  "extensions": [
    "./src/index.ts"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

@snailuu/pi-token-use

npm

pi 扩展:交互式浏览本机 token 用量与花费,按时间 / 项目 / 模型多维钻取。

pi 自带的 /session 只能看当前会话。本扩展扫描本机全部历史会话,用一个可导航的浮层面板回答「哪个项目最花钱」「某段时间内各模型分别用了多少」「这次暴增是哪次对话干的」。

金额默认自动算出:单价优先取 pi 自己维护的模型目录,你也可以在配置文件里为自建中转等渠道指定实际单价。

安装

pi install npm:@snailuu/pi-token-use

本地开发:

pi install /path/to/pi-token-use-npm

使用

/token-use                        打开面板(默认全部时间)
/token-use today                  只看今天
/token-use 7d | 30d | all         预设时间窗
/token-use 2026-07-01..2026-07-24 自定义日期区间(闭区间,本地时区)

面板占满整个终端。顶部三行(时间 / 分组 / 排序)和下方表格都是可聚焦区域:

作用
在表格内移动行;到达表格顶端后继续 依次进入 排序 → 分组 → 时间
在筛选行上:切换该行的选项,立即生效在表格上:展开 / 收起当前行
Enter 在筛选行上:回到表格在表格上:展开 / 收起
Tab 快捷切换分组(不必先把焦点移上去)
t 快捷切换时间窗
s 快捷切换排序列
p 在用量视图和定价视图之间切换
e (定价页)就地编辑当前渠道的单价
d (定价页)清除手工价,回退自动匹配
r (定价页)重读配置文件,同步外部改动
Esc 关闭

面板长这样( 标记当前聚焦的筛选行, 标记表格光标):

╭────────────────────────────────────────────────────────────────────────────╮
│ pi token 用量  [用量] 定价  (p 切换)                                       │
│  时间:  今天  7天  30天 [全部]                                             │
│  分组: [项目] 模型                                                         │
│  排序: [金额] input  output  cacheRead  命中率                             │
├────────────────────────────────────────────────────────────────────────────┤
│ 项目                            input    output cacheRead  命中率      金额│
│ 合计                            8.67M      356K    123.3M   93.4%     $7.11│
│ ▾ team/web-app ●                8.16M      310K    112.4M   93.2%     $6.86│
│▶  ▾ provider-a/model-pro        7.90M      301K    110.1M   93.3%     $4.18│
│       03-14 14:07 · 补结...     4.80M      213K     65.9M   93.2%     $2.56│
│       03-14 14:07 · 重构...     3.10M       88K     44.2M   93.4%     $1.62│
│   ▸ my-relay/model-mini          264K      9.1K     2.30M   89.7%     $2.67│
│ ▸ team/api-server                415K       38K     9.80M   95.9%     $0.26│
├────────────────────────────────────────────────────────────────────────────┤
│ 1 个渠道借用了同名模型的官方价,金额仅供参考:my-relay/model-mini          │
│ 1 个渠道无单价,其 token 未计入金额:provider-x/model-unknown              │
│ ↑↓ 移动 · ←→ 切换/展开 · Tab 分组 · t 时间 · s 排序 · p 定价 · Esc 关闭    │
╰────────────────────────────────────────────────────────────────────────────╯

标记当前所在项目。合计行固定在表头下方,不参与排序也不随滚动。价格来源可疑的渠道不在行内打标记,只在底部集中说明。

p 进入定价页,看每个渠道实际生效的单价及其出处,并直接改价:

╭────────────────────────────────────────────────────────────────────────────╮
│ pi token 用量   用量 [定价] (p 切换)                                       │
├────────────────────────────────────────────────────────────────────────────┤
│ 渠道                                    input    output    cacheR      来源│
│▶provider-a/model-pro                    $0.44     $0.88    $0.004      目录│
│ my-relay/model-mini                      $2.5       $15     $0.25      借用│
│ provider-x/model-unknown                    —         —         —    无单价│
├────────────────────────────────────────────────────────────────────────────┤
│ 单价单位 $/百万 token · 配置文件 ~/.pi/agent/extensions/pi-token-use/con...│
│ ↑↓ 移动 · e 编辑 · d 清除手工价 · r 重读配置 · p 返回用量 · Esc 关闭       │
╰────────────────────────────────────────────────────────────────────────────╯

定价页列出的是全部历史用到过的渠道,与时间窗无关——定价是渠道的固有属性。

e 就地改价,四个字段预填当前生效值,把中转站的数字覆盖上去即可:

│ 渠道                                    input    output    cacheR      来源│
│▶provider-a/model-pro                  [0.44█]      0.88     0.004    编辑中│
│ my-relay/model-mini                      $2.5       $15     $0.25      借用│
├────────────────────────────────────────────────────────────────────────────┤
│ 输入数字 · Tab/←→ 切字段 · Enter 保存 · Esc 取消编辑                       │
╰────────────────────────────────────────────────────────────────────────────╯
  • 只接受数字和小数点,其他按键忽略
  • Enter 写进配置文件的 pricing 段并立即重算金额,切回用量页就是新数字
  • Esc 只取消编辑,不关闭面板
  • d 清除该渠道的手工价,回退到自动匹配
  • 编辑本身带阶梯定价的渠道时,底部会提示保存后阶梯定价将失效(手工价是整条替换的)

为什么四类 token 要分开看

因为它们的单价差着两个数量级。cacheRead(复用的 prompt 前缀)在某些模型上只有 input 的 1/120。一台机器上 90%+ 的 token 是 cacheRead 很常见——此时「总 token」这个数字几乎不携带信息,排行榜会完全被缓存复读主导。

所以本扩展不提供「总计」列,默认按 input 排序,并单独给出命中率。

定价配置

金额默认全自动,多数情况下不用配。只有当某个渠道的实际价格和官方价不同(自建中转常有折扣或加价),才需要改。

改单个渠道直接在定价页按 e;要批量导入整份价格表,就直接写配置文件——两者改的是同一份数据。

配置文件:~/.pi/agent/extensions/pi-token-use/config.json第一次打开面板时自动生成,分两段:

{
  "_note": "catalog 段由插件自动同步为 pi 的官方定价,直接修改它不会生效;要覆盖某个渠道的价格,请写到 pricing 段。",
  "catalog": {
    "provider-a/model-pro": { "input": 0.44, "output": 0.88, "cacheRead": 0.004, "cacheWrite": 0 },
    "my-relay/model-mini": { "input": 2.5, "output": 15, "cacheRead": 0.25, "cacheWrite": 0 }
  },
  "pricing": {
    "my-relay/model-mini": { "input": 3.5, "output": 21, "cacheRead": 0.35, "cacheWrite": 0 },
    "my-relay/*": { "input": 2, "output": 10, "cacheRead": 0.2, "cacheWrite": 0 }
  }
}
谁写 作用
catalog 插件自动写,每次打开面板同步为 pi 最新官方价 只供查阅和复制,改它无效;官方降价会自动反映在这里
pricing 你或 AI 写,插件除了 e 保存外绝不碰 实际生效的覆盖价,优先级最高

要改价,就把 catalog 里那一条复制到 pricing 再改数字。

catalog 段只列四个基础单价,不写阶梯规则(避免文件太长)。但计价时仍会用官方阶梯——某些模型单次请求 prompt 超过阈值后单价会翻倍,这个规则直接来自 pi 的模型目录。一旦你在 pricing 里覆盖了某渠道,它就按你给的单一价计算,不再有阶梯。

  • key 是 provider/modelprovider/* 作为该渠道的兜底默认值
  • 单价单位是 每百万 token 美元,与 pi 自带定价表一致
  • 省略的字段按 0
  • 解析不出官方价的渠道不会写进 catalog——写成 0 等于把「未知」伪装成「免费」
  • 阶梯定价写 "tiers": [{ "inputTokensAbove": 272000, "input": 10, "output": 45, "cacheRead": 1 }]

改完文件重新打开面板即生效,不需要重启 pi;面板正开着的话,在定价页按 r 就能重读。文件是纯 JSON,方便让 AI 读了中转站价格表后批量写入 pricing 段,不必一条条手填。

在定价页按 e 保存时,只会改动那一条,文件里其他内容(AI 批量写入的整份价格表、其他配置段)原样保留。如果文件当前是坏 JSON,保存会被拒绝并提示——宁可不写,也不能把你原有的内容冲掉。

配置写错不会被静默忽略——用量页底部会提示有几处问题,按 p 看具体是哪一条哪个字段。

单价从哪来

按优先级取第一个命中的:

优先级 来源 面板显示
1 配置文件里 provider/model 精确匹配 手工配置
2 配置文件里 provider/* 通配 手工通配
3 pi 模型目录中同 provider 同 model pi 定价表
4 pi 模型目录中其他 provider 下的同名 model 借用同名模型

第 4 种是推测——它假定你的中转按被借用方的官方价计费。这个假设未必成立,所以面板底部会明确列出哪些渠道用的是借来的价。想让数字变准,就在配置里给这些渠道填上真实单价。

四种都不命中时该渠道没有金额,显示 而不是 $0:0 表示免费, 表示不知道,两者不能混。

关于金额的算法

金额是逐条记录算完再相加的,不是把 token 汇总后乘单价。

因为阶梯定价按单次请求的 prompt 量判定档位(且 cacheRead 计入该判定)。若先汇总,总量必然落进最高档,金额会被系统性抬高——在实测数据上这个差距达到 71%

工作方式

数据源是 ~/.pi/agent/sessions/ 下的会话 JSONL,扩展只读不写,不 hook 模型调用,也不建任何缓存或数据库——每次打开面板全量重扫(数十个会话、数千条记录的规模下约 100ms),所以看到的永远是最新数据,包括你刚刚这轮对话产生的用量。

所有数据都留在本地,不发往任何外部服务。

术语定义见 CONTEXT.md

开发

pnpm install
pnpm test        # vitest,覆盖解析与聚合纯函数
pnpm typecheck

License

MIT