omp packages

pi-keepwarm0.1.1

Pi extension: manually keep a long session's prompt cache warm while you're idle, so the next message after a long break doesn't pay a full cache rewrite.

GitHub Actions Published 24 days ago MIT ~341 downloads/mo

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.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

pi-keepwarm

English | 中文

一个 pi 扩展:在你空闲时替长 session 保持 prompt cache 不过期。离开 20–60 分钟后发的第一条消息仍然能直接读缓存,不用全价重写。

默认按 session 手动开关:需要时执行 /keepwarm,用完再关。在配置文件里设 autoStart 后,每个 session 都会自动开启。

为什么需要它

没有请求访问时,各家的 prompt cache 很快就会过期:

Provider 默认缓存时长
Anthropic (Claude) 5 分钟(每次命中重新计时;可选 1h 档,写入价为基础输入价的 2×)
OpenAI GPT-5.6 及以后 ≥ 30 分钟
OpenAI 更早的模型 in_memory 约 5–10 分钟;部分模型支持 24h 保留

在一个 15 万 token 的 Claude session 里,离开 10 分钟后发的下一条消息要把整个前缀按基础输入价的 1.25× 重写一遍。而在过期前刷新一次缓存,只需付一次读缓存的费用:大多数 Claude 模型是基础输入价的 0.1×,部分模型更低。

pi 内置的 cacheWarming 只在对话进行中保温,设成 "idle" 后也最多再保温 30 分钟。keepwarm 针对的是更长的空闲:由你手动开启,一直保温到你关闭,或者达到时间、花费上限为止。

安装

pi install npm:pi-keepwarm

或从 git 安装:

pi install git:github.com/cminn10/pi-keepwarm

用法

命令 作用
/keepwarm 开关切换;开启时使用配置文件里的默认值
/keepwarm on 5h $20 开启;命令里给出的参数会覆盖配置文件里的默认值
/keepwarm on forever 不限时长(配置文件里的花费上限仍然有效)
开启状态下 /keepwarm on 5h 只改时限(从现在起算)
开启状态下 /keepwarm on $30 只改花费上限;nocap 表示去掉上限
/keepwarm status 查看状态、TTL、下次刷新时间、刷新次数、花费、失败次数
/keepwarm config 查看配置文件路径和当前生效的默认值
/keepwarm off 关闭

花费上限按本 session 里 keepwarm 的累计花费计算,关掉再开也继续累加。

配置

第一次启动 session 时,keepwarm 会生成 ~/.pi/agent/keepwarm.json(设了 PI_CODING_AGENT_DIR 时放在对应目录下),内容是默认配置:

{
  "autoStart": false,
  "duration": "2h",
  "maxCost": null,
  "maxRetries": 2
}
字段 含义
autoStart true 表示每个 session 启动时自动开启
duration 默认时限:"90m"、"2h"、"forever"
maxCost 每个 session 的 keepwarm 默认花费上限(美元),null 表示不设上限
maxRetries 连续失败多少次后自动关闭(请求出错或没读到缓存都算失败)

示例:总是自动开启,不限时长,每个 session 最多花 $10:

{ "autoStart": true, "duration": "forever", "maxCost": 10, "maxRetries": 2 }

每次 session 启动、每次执行 /keepwarm 或 /keepwarm on 时都会重新读取这个文件,改完不用重新加载 pi。非法的值会退回默认值并提示。以 _ 开头的字段(比如自动生成的 _help)会被忽略。

状态栏:

🔥 keepwarm · ⏳ active · 3× $0.09/$20.00          对话进行中,暂停刷新
🔥 keepwarm · next 10:52 PM · 4× $0.12/$20.00      空闲中,显示下次刷新时间

工作原理

  • 在 before_provider_request 里抓取 session 中每一次真实请求。
  • 在 agent 空闲期间、缓存快过期时,把最后一次真实请求一字不差地重发一遍,只把输出上限改成最小(Anthropic 用 max_tokens: 1,OpenAI Responses 用 max_output_tokens: 16)。前缀完全一样,provider 就会直接读缓存并重新计时。这些请求不会进入对话上下文。
  • 下次刷新安排在 TTL 的 90%,且至少提前 15 秒,从最后一次访问缓存的请求开始的时间算起,因为 provider 的缓存寿命是从请求发出时开始计算的。
  • 对话进行中不刷新。 在 agent_start 时暂停,在 agent_settled 时恢复。对话中跑得很久的工具调用,由 pi 内置的 cacheWarming: "streaming"(默认开启)负责保温。空闲期间 keepwarm 会让内置保温停手,避免重复刷新。
  • TTL 从请求内容里识别:Anthropic 看 cache_control.ttl: "1h",OpenAI 看 prompt_cache_retention / prompt_cache_options。如果 models.json 里给模型声明了 promptCache,以它为准。
  • 以下情况会暂停保温,等下一条真实消息后再开始:切换模型、compaction、/tree 跳转,或者定时器触发时缓存已经过期(比如电脑休眠过)。这时再刷新就是一次全价写入。
  • 每次刷新都会在 session 文件里写一条 keepwarm 记录,包含 provider 返回的用量和花费。
  • 刷新失败时,只要缓存还没过期,就在 15 秒后重试。连续失败 maxRetries 次后 keepwarm 自动关闭。如果刷新返回的是写缓存而不是读缓存,说明重放的内容和真实请求对不上了,也算一次失败。一次成功的刷新或一次新的真实请求会把失败计数清零。

什么时候划算

设上下文有 P 个 token,基础输入价为 B,使用 Anthropic 的 5 分钟缓存(每 4.5 分钟刷新一次):

费用
一次刷新(读缓存) P × B × 读缓存倍率(大多数 Claude 模型为 0.1×)
开着 keepwarm 空闲 T 分钟 约 T / 4.5 次刷新
缓存过期后重写一次 P × B × 1.25

空闲时间不超过约 4.5 × 1.25 / 读缓存倍率 分钟时,保温比过期后重写一次便宜:读缓存倍率为 0.1× 时约 55 分钟,0.05× 时约 110 分钟。超过这个时间,直接让缓存过期反而更省。可以根据自己通常离开多久来设置 duration / maxCost。

支持的 API

anthropic-messages、openai-responses、azure-openai-responses、openai-codex-responses、openai-completions。

注意事项与限制

  • 运行状态(开关、花费、抓取到的请求)按 session 保存在内存里。/reload 或重新打开 session 后会从头开始:如果设了 autoStart 就自动开启,否则需要再执行一次 /keepwarm。之后从下一条消息开始保温。
  • 如果有别的扩展在 keepwarm 抓取之后又修改了请求内容,重放就对不上,变成一次写缓存。keepwarm 会把这类刷新报告为 cache miss,并计入 maxRetries。
  • 刷新的花费记录在 session 文件里,但不计入 pi 自己统计的 session 总花费。
  • 在 pi 0.87.1 上测试过。

测试用的环境变量

PI_KEEPWARM_EVERY_SEC 强制指定刷新间隔。PI_KEEPWARM_TTL_SEC 强制指定 TTL。PI_KEEPWARM_TEST_FAIL=1 让刷新请求失败(非法的 max_tokens),用来测试重试逻辑。

开发

bun install
bun run check      # 类型检查 + 测试 + npm pack --dry-run
pi install .       # 在 pi 中加载本地工作副本

发布通过手动触发的 GitHub Actions Release workflow 完成(Actions → Release → Run workflow)。它会依次执行:跑 CI、升版本号(patch / minor / major,或 none)、推送版本提交和 tag、通过 npm trusted publishing 发布(OIDC,附带 provenance)、创建 GitHub Release。勾选 dry run 时只跑 CI 和 npm publish --dry-run。

许可证

MIT