@runminton/pi-context-usage-refine
v1.0.0
Published
Pi extension for visualizing and analyzing current session context usage.
Maintainers
Readme
pi-context-usage-refine
一个 pi 扩展,提供 /context 命令及其子命令,用于可视化和分析当前会话的上下文(context)使用情况。
从原仓库精简而来,只保留 context 可视化和 details 细分视图,去掉了 /release、skills、发布辅助等能力。
快速上手
加载扩展:
pi -e ./pi-context-usage-refine/index.ts进入会话后,试试这几个命令:
| 命令 | 作用 |
|---|---|
| /context | 显示点阵图 + token 概要 |
| /context details | 展开 system prompt / tools / conversation 细分视图 |
| /context web | 生成离线 HTML 报告并用默认浏览器打开 |
| /ctx | /context details 的快捷方式 |
| /ctxw | /context web 的快捷方式 |
其中 /context details 和 /context web 会在当前会话运行一次本地 probe 来捕获实时 system prompt 和状态(见下文"Probe 机制")。probe 不经过模型推理、不消耗模型额度,完成后立即展示。
目录结构
pi-context-usage-refine/
├── index.ts # 扩展入口,注册 /context /ctx /ctxw 命令
├── README.md
├── context/
│ ├── index.ts # 主逻辑:命令路由、completions、流程编排
│ ├── breakdown.ts # 对话轮次分析、工具细分、system prompt 量化
│ ├── grid.ts # 11×8 点阵图渲染
│ ├── tokens.ts # token 计算、缓存读取、格子分配、符号定义
│ ├── web.ts # 离线 HTML 生成 + 跨平台浏览器打开
│ ├── in-process-probe.ts # 本地 probe,不经过模型推理/不访问网络
│ └── terminal-compat.ts # Windows 终端兼容适配
└── tests/
├── mock-context.ts # 纯内存 mock 测试
├── context-web.ts # HTML 转义 / CSP / 离线验证
├── in-process-probe.ts # 集成测试:启动真实 pi 进程验证 probe
├── platform-launch.ts # 跨平台浏览器打开命令测试
├── terminal-compat.ts # Windows 字形替换测试
└── fixtures/
├── arm-in-process-probe.ts # 在真实 pi 进程中挂载 probe
└── state-marker.ts # 模拟其他扩展修改 system prompt命令详解
概要模式 (/context)
在终端直接输出一个 11×8 的点阵图,每个格子代表总量的大约 1.14%,用五种符号区分不同类型的占用量:
| 符号 | 含义 | 颜色 |
|---|---|---|
| ◍ | System Prompt | accent |
| ⚙ | Tools (参数 schema) | muted |
| ● | Messages (对话消息) | success |
| · | Free (剩余可用) | dim |
| ○ | Buffer (模型输出预留) | warning |
图下方附带精确的 token 数和占比明细。
详细模式 (/context details)
在终端内展开一个完整的会话分析视图,包含三个区块:
System Prompt 区块
- 完整文本,支持终端分页滚动
- 显示 token 估算值(按字符数/4 估算)
Tools 区块
- 当前所有活跃工具的名称、描述、参数 schema 各自的 token 数
- 按总 token 数降序排列,方便识别"最占 context"的工具
- 报告 system prompt + tools 的合计 token 数,并在跟 provider 返回的缓存 token 数不一致时给出说明(因为 provider 端还有无法自省的开销)
Conversation 区块
- 每一轮对话(turn)的 token 估算值与累计值
- 通过颜色标记工具密集轮次(warning)与纯文本轮次(success)
- compaction 轮次用
Σ前缀区分 - 显示每条消息的角色和截断预览
Web 报告模式 (/context web)
生成完全离线的 HTML 文件,通过默认浏览器打开,不启动 Web 服务、不加载 CDN、字体或远程资源。
HTML 特性:
- Content-Security-Policy:
default-src 'none';同时放开style-src 'unsafe-inline'和script-src 'unsafe-inline'以支持搜索高亮和复制功能(仍不加载任何外部资源) - System Prompt 搜索:输入关键词即时高亮匹配段落
- 复制按钮:一键复制完整 system prompt 到剪贴板
- Context 概览:显示 system prompt、活跃工具 schema、对话和工具结果的 token 估算
- Tools 折叠:默认只显示工具名和 token 数,可展开查看完整 JSON schema
- 工具调用统计:按当前会话分支中的工具分组,显示调用次数以及参数和结果的 token 估算
- Conversation 表格:显示轮次编号、时间、摘要、token 数
- 暗色主题:原生暗色样式,不依赖任何外部样式库
跨平台浏览器启动逻辑:
| 环境 | 命令 |
|---|---|
| macOS | open <path> |
| Windows (原生) | cmd.exe /c start "" <path> |
| WSL | 通过 wslpath 转换为 Windows 路径后调用 Windows 的 cmd.exe |
| Linux | xdg-open <path> |
Probe 机制(核心设计)
details 和 web 模式依赖一个本地 probe 来捕获当前会话的 system prompt 和运行时状态。probe 不发起网络请求、不消耗模型额度,全程在当前进程内完成。
为什么需要 probe?
pi 的 system prompt 并不是一个静态字符串——它在会话启动后会经过多个插件的 before_agent_start 钩子追加内容。扩展加载的顺序、其他扩展的状态、当前 agent 所处的阶段都会影响最终生效的 system prompt。根据实际观察,当前 pi 版本中 ctx.getSystemPrompt() 返回的是钩子触发前的初始值,无法反映其他扩展通过 before_agent_start 追加的动态部分。
Probe 利用当前进程中的插件实例运行,因此能读取其他扩展的内存开关状态,生成与其他扩展视角一致的 system prompt 快照。
工作流程
- 用户触发
details/web - 等待 agent 空闲
- 包装当前活跃 provider 的
stream/streamSimple实现 - 通过
pi.sendUserMessage()发送一条 probe 消息(deliverAs: "followUp") - 当 pi 组装请求、调用当前 provider 时,包装器被触发
- 包装器不发起网络请求,直接从参数中读取
context.systemPrompt、model.provider、model.id - 将捕获的数据传给回调;所有非 probe 请求保持委托给原始 provider
- 返回一个假的
AssistantMessage(usage 全部为零,不消耗模型额度,stop reason 为 "stop") agent_settled事件触发,消费捕获的数据并渲染展示
边界与限制
- Probe 会真实创建一轮用户/助手消息。但不需要担心——连续按两次 ESC(在会话树中回退一个分支点)或者在会话历史树中直接删掉 probe 的那两条消息即可,对会话没有任何实质影响。它的用途就是获取实时快照,用完回退掉就好。
- 运行期间不要从其他入口同时提交消息,避免并发请求被错误捕获。
- 不会切换 provider 或 model,也不会访问网络。
- 捕获后能读取到其他插件通过
before_agent_start追加的内容(因为同进程的插件实例已注册)。
安全保障
agent_settled回调、session_shutdown事件和 probe 启动异常时都会清除待处理 probe- provider 包装器在当前会话持续存在,但所有非 probe 请求都会原样委托给原始 provider
- 多次调用
restore()是幂等的
Token 计算方法
system prompt
按 Math.ceil(text.length / 4) 估算,即平均每 4 个字符约 1 个 token。
tools
对每个工具的 name + description + JSON.stringify(parameters) 的总字符数做同样的 /4 估算。
对话消息
依赖 pi SDK 提供的 estimateTokens(message) 函数,该函数会考虑 JSON 结构化表示和内容字符串的混合。
工具调用
网页报告只统计当前会话分支中的工具调用。调用参数按工具名和序列化参数估算,工具结果使用
estimateTokens(message) 估算。provider 返回的 usage 面向整次模型请求,不能精确归因到某一个工具。
缓存 token
通过查找最后一条非中止、非出错的 assistant 消息的 usage.cacheRead + usage.cacheWrite 来获取 provider 端的缓存 token 数。
点阵格子分配
按各类 token 占总 context window 的比例,四舍五入分配到 88 个格子。为了防止小数值被舍去后完全消失,如果某类 >0 但分配结果为 0,则强制给 1 格。最后通过补齐/截断确保总格数固定为 88。
Windows 终端兼容
原生 Windows 终端对 Unicode 的特殊字符(如 ╭╮╰╯──│▾▸)存在渲染问题——某些字形的实际显示宽度不等于 1,导致差分重绘时出现残影或错位。
该扩展在 process.platform === "win32" 时做两件事:
- 字形替换:将所有 Unicode 装饰字符替换为等义的 ASCII 字符(如
╭→+,◍→S,⚙→T) - 禁用 overlay:不使用差分叠加重绘,改用独占的 custom view 模式,彻底消除残影
在 Linux/macOS 上则保持原生 Unicode 渲染和 overlay 模式。
测试
本地运行
# 独立 fork 首次运行时,先安装 peer dependencies
npm install
# 基础 mock 测试(无需 pi 进程)
node --experimental-transform-types ./tests/mock-context.ts
# Web 报告生成与转义验证
node --experimental-strip-types ./tests/context-web.ts
# 平台浏览器启动命令验证
node --experimental-strip-types ./tests/platform-launch.ts
# Windows 终端兼容验证
node --experimental-strip-types ./tests/terminal-compat.ts
# In-process probe 集成测试(需要 pi 在 PATH 中)
node --experimental-strip-types ./tests/in-process-probe.ts测试覆盖
mock-context.ts:验证context命令被注册、release命令不被注册、token 计算与 turn 分解的数学一致性context-web.ts:验证 HTML 转义(<secret>→<secret>)、CSP header 正确、无远程资源引入、文件写入与清理in-process-probe.ts:启动真实 pi 进程,加载一个指向回环地址的原生 Codex API fixture provider,验证 probe 能捕获其他扩展注入的内容,且不会访问该 providerplatform-launch.ts:验证 Windows/WSL/Linux 下buildBrowserOpenCommand返回正确的命令结构terminal-compat.ts:验证 Windows 下 Unicode 到 ASCII 的映射正确、overlay 状态开关正确
