Repository navigation
v0.5.1
context-guru v0.5.1
This release fixes how the proxy follows the main agent through a Claude Code compaction. It also shows money per agent on the status line, and it stops keep-alive pings when a session ends or compacts.
Items marked [Notice] change something you will see, or need an action from you.
New and changed
The status line shows money for the main agent and its subagents (#525)
- [Notice] The first line now shows 2 figures:
saved $x of $y sessionfor the main agent, andsaved $x of $y subagentsfor all other threads added together. The second figure appears only when the session has other threads. $yis what the requests would have cost without context-guru.$xis the saving after context-guru's own model calls and keep-alive pings. So$xis never larger than$y. Estimates are not in either figure.- The keep-alive saving counts only when you came back after the cache lifetime, a ping kept the cache warm, and your next request read it.
- Each subagent and teammate in the agents list shows its own cache clock and its own
saved $z of $q. Two agents of the same type get a number, for exampleExplore 2. - While the keep-alive holds a cache, its clock runs to the last planned ping plus the cache lifetime.
- [Notice] The status line no longer shows a lifetime total. It was slow in long sessions (#510).
Keep-alive stops when a session ends or compacts (#520, #524)
- [Notice] The plugin now tells the proxy when you leave Claude Code (
/exit, Ctrl-C twice, Ctrl-D, closing the terminal,/clear, logout) or when the conversation compacts. The proxy then stops pinging caches that no request will read again. This is on by default whenever the keep-alive runs. - On a compaction, only the main agent's cache stops. A subagent's or teammate's cache keeps its keep-alive.
- To turn it off, set the plugin option
client_signalstooff, or setCONTEXT_GURU_CLIENT_SIGNALS=offfor the proxy. - [Notice, Codex] Codex runs plugin hooks only after you trust them in
/hooks. Closing the terminal sends nothing in Codex.
Predictive keep-alive campaigns (opt-in) (#521, #534)
- A campaign decides per idle gap whether a ping is worth it. Shadow mode scores the decisions and changes nothing.
- An operator builds a campaign through a new build endpoint, or lets an automatic builder make one per tenant.
- Off by default: with no campaign built, nothing runs and nothing is spent.
Fixed
- [Notice] After a Claude Code compaction, the status line froze (#518, #519). Claude Code 2.1.296 changed the shape of its compaction request. v0.5.0 then moved the rest of the session to a new thread. The status line kept showing the old main thread: for example ctx 98% when the real figure was 7%, "cold" during an active conversation, and a hint to pay for a rewrite that would not happen. Keep-alive also pinged the dead thread. The main thread now keeps its identity across a compaction.
- The main thread could also move between turns (#518, #519). In auto mode, the proxy could move the main thread onto the thread of Claude Code's safety classifier. The status line and the keep-alive then followed the wrong thread. The main thread now stays in place.
- The proxy changed Claude Code's compaction request (#518, #519). The proxy did not detect the request, and it ran its components on it. Content it replaced with a marker was then missing from Claude Code's summary for good. The proxy now sends that request unchanged.
- A slow request on one thread delayed other threads' pings (#527). A due ping now waits only for an open request on its own thread.
- Keep-alive pings that fail are handled better (#527).
- A 429 or 5xx is temporary: the ping is retried at the next slot.
- A real cache miss counts as a missed ping, not as a failure.
- A 401 or 403 stops pings with that credential only, not for the whole account.
- Repeated failures turn off pings on that route for a while, per tenant, so one tenant cannot switch off another.
How to upgrade
Run /context-guru:update, then update the plugin and run /context-guru:statusline once. Without that step, the status line keeps running the previous version's script (#551). The update restarts the proxy, and the restarted proxy assigns the main thread again on the next request. So a session that already compacted on v0.5.0 gets a correct status line from its next turn.
Known limits
- On a slow gateway, a keep-alive ping for a large prompt can time out after 60 s. The proxy then counts it as failed, although it probably still kept the cache warm (#532).
- Claude Code's auto-mode classifier, and an ordinary turn whose tool output quotes the compaction prompt, can be taken for a compaction. That request is then forwarded unchanged, without context-guru's changes. Since this release, it can no longer move the main thread (#533).
Changelog
- 0ea12b6: Merge pull request #516 from rossoctl/feat/plugin-bump-050 (@amiddavid)
- 06c09ac: Merge pull request #519 from rossoctl/feat/compaction-thread (@amiddavid)
- 6d34ce1: Merge pull request #520 from rossoctl/port/lifecycle-signals (@amiddavid)
- 0e2a540: Merge pull request #524 from rossoctl/lc-default/public (@amiddavid)
- 68748ea: Merge pull request #525 from rossoctl/feat/statusline-per-agent (@amiddavid)
- 83d33ea: Merge pull request #527 from rossoctl/lc-default/ka-fixes (@amiddavid)
- 46c46d5: Merge pull request #534 from rossoctl/feat/predictive-campaigns (@amiddavid)
- de80a93: chore(plugin): bump Claude plugin to 0.5.0 and Codex plugin to 0.2.0 (@amiddavid)
- a9abb3a: docs(cache): say why a client signal's session id is the campaign's key ( <>)
- 26a8c15: docs(plugin): render time for the per-agent status line ( <>)
- ee7b7f1: docs(plugin): render time with the money split and bounded name reads ( <>)
- 47ea647: feat(cache): predictive keep-alive campaigns with shadow mode, a build endpoint and an automatic per-tenant builder ( <>)
- 9e79dfe: feat(dash): keep-alive plan and session ping count for the status line ( <>)
- 26b21e3: feat(keepalive): client lifecycle signals on by default whenever the keep-alive runs ( <>)
- ae84df7: feat(keepalive): client lifecycle signals retire a session's cache on exit and compaction ( <>)
- 0686297: feat(plugin): each listed agent shows its own saved $z of $q ( <>)
- dd0743d: feat(plugin): mark active sub-agents, most recent first, at most five ( <>)
- bfeea75: feat(plugin): saved $x of $y for the session and its subagents, on one basis ( <>)
- d67a003: feat(plugin): status line shows per-agent caches, saved of total, keep-alive hold ( <>)
- d737bc4: fix(cache): a compact signal resolves the main thread's campaign decisions only ( <>)
- ddd44ff: fix(dash): held_until counts only pings that refreshed the cache ( <>)
- d60abed: fix(dash): the hosted signal hook sends only session id, event and reason ( <>)
- ba46c77: fix(keepalive): 429 and 5xx pings are skipped and retried; the name check applies to relays only ( <>)
- 468a6eb: fix(keepalive): a 401/403 stops pinging with that credential only, not the account's route ( <>)
- aa79460: fix(keepalive): a 403 blocks the key on that model only; a 401 on every model ( <>)
- 62954fe: fix(keepalive): a 5xx ping is transient again; the model-name check is for the Anthropic route only ( <>)
- d221800: fix(keepalive): a compact signal retires the main thread only; /signal takes JSON only ( <>)
- 78534e5: fix(keepalive): a real cache miss is a missed ping, not a failure; model aliases from the environment ( <>)
- 43d0fe9: fix(keepalive): a request leaves the in-flight count only after its hold is stored ( <>)
- ac45348: fix(keepalive): identify a credential by an HMAC of the full auth value under a per-process key ( <>)
- 4578f01: fix(keepalive): keep the hosted token out of argv; unknown SessionEnd reasons count as other ( <>)
- 2032d5f: fix(keepalive): key the route breaker by tenant so one tenant cannot switch off another ( <>)
- 105f78e: fix(keepalive): no ping while the session has a request in flight; failed pings stop and trip the route ( <>)
- 693192b: fix(keepalive): pause a ping only for its own thread's open request ( <>)
- b4ffaa0: fix(thread): accept agent-team teammate ids (name@team) from the agent header ( <>)
- e489e09: fix(thread): break thread ties by model (@amiddavid)
- bddd7dc: fix(thread): keep the main thread across a Claude Code compaction (@amiddavid)
- 6c9e03f: fix(thread): keep the main thread when Claude Code rewrites its tail (@amiddavid)
- 48312d5: fix(thread): never join a header-less request to a named thread (@amiddavid)
- 9ed9685: style(dash): gofmt the cachestate money test ( <>)
- 07aaccb: test(cache): pin the tree evaluator's tie direction; drop internal engine names from the calibration ( <>)
- f2ba1ab: test(keepalive): cover a 4xx toward the breaker, forget clearing a trip, the OpenAI double miss, a look-alike host ( <>)
- 4ee0750: test(keepalive): the hosted setup snippet's raw payload authenticates by the token header ( <>)
- 5345956: test(keepalive): the in-flight test sets no per-ping dollar ceiling, so another test's price table cannot skip its hold ( <>)
- ba8cd68: test(keepalive): the raw payload and the Codex alias keep an idle subagent on compact ( <>)
- 8c95e89: test(plugin): an agent with no money in its row shows no figure ( <>)
- 30b9993: test(proxy): a ping that read nothing does not count as a refresh ( <>)
Install
No Go toolchain and no C compiler are needed — the binary is statically linked.
Download the tarball for your platform, untar it, and put context-guru-proxy on your
PATH. The archive unpacks into its own directory, so this is safe to run anywhere:
tar xzf context-guru_*_darwin_arm64.tar.gz
install -m 755 context-guru_*/context-guru-proxy ~/.local/bin/
Then see docs/get-started/quickstart-proxy.md.