Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions assets/icon-sources.json
Original file line number Diff line number Diff line change
Expand Up @@ -2552,5 +2552,13 @@
"homepage": "https://www.liblib.tv",
"mimeType": "image/png",
"sha256": "ada9717d540928baec64105056b93e8e8bc6cfbff145f9f3a9eadb6dd9b90689"
},
{
"name": "tokencare",
"icon": "tokencare/icon.png",
"source": "generated original artwork for TokenCare (Pillow script: layered context lines compressing into one bar on an indigo-cyan gradient)",
"matchedBy": "generated-original",
"mimeType": "image/png",
"sha256": "3d567d102826140450531f70e4c683cb0bcf556d5b17b529a4edeb356b085180"
}
]
Binary file added assets/tokencare/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions external_plugins/tokencare/.zcode-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "tokencare",
"version": "0.2.2",
"description": "Layered context compression and token optimization: a reversible vault for large tool outputs, duplicate-read detection, model-driven conversation compression, and per-session token statistics.",
"description_i18n": {
"en": "Layered context compression and token optimization: a reversible vault for large tool outputs, duplicate-read detection, model-driven conversation compression, and per-session token statistics.",
"zh-CN": "分层上下文压缩与省 token 优化:可逆的工具输出保险库、重复读取检测、模型驱动的对话压缩与会话 token 统计。"
},
"author": {
"name": "TokenCare contributors"
},
"license": "MIT",
"keywords": ["context", "compression", "token-optimization", "hooks", "glm"],
"skills": "skills",
"commands": "commands",
"hooks": "hooks/hooks.json"
}
21 changes: 21 additions & 0 deletions external_plugins/tokencare/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 TokenCare contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
42 changes: 42 additions & 0 deletions external_plugins/tokencare/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# TokenCare

Layered context compression and token optimization for [ZCode](https://z.ai). One plugin that unifies the ideas of [billion-context](https://github.com/ranxianglei/billion-context) (incremental, reversible context compression) and [dsh-token-optimizer](https://github.com/Zoria-Lind/dsh-token-optimizer) (tool-output triage, read-dedup, monitoring) — with their overlapping parts merged instead of duplicated.

Long sessions accumulate huge tool outputs, re-read the same unchanged files, and blow past context limits. TokenCare cuts that waste in three layers and keeps **everything reversible** through an on-disk vault.

## How it works

| Layer | What it does | Origin |
|---|---|---|
| **L0 — Observe** (automatic) | A `PostToolUse` hook records every tool result's size, hash, and file path to a per-session ledger. Very large outputs (> 30k chars) get a one-line nudge toward `/digest`. After ZCode compacts the session, a `SessionStart(compact)` hook points back at the vault so details are recovered, never guessed. | dsh `monitor` + billion-context session stats & growth nudges, merged into one ledger |
| **L1 — Lossless spill & read-dedup** | `/digest` stores the original verbatim in the vault and emits a structure-aware digest: errors → 300-char excerpt, JSON → shape summary, CSV → header + row count + first/last row, text → head/tail. Duplicate unchanged file reads are detected from the ledger and called out with wasted-token estimates. | dsh `outputLadder` + `fileDiff`, made reversible à la billion-context |
| **L2 — Model-driven compression** | `/compress` writes a structured summary of the settled conversation into the vault, registers it in the index, then anchors ZCode's built-in `/compact` on it. Suggested at ~45% context pressure instead of waiting for an emergency. | billion-context `compress`/`decompress` + dsh `compactionDriver`, unified |
| **Recovery** | `/context-search` greps vault originals and summaries; originals come back whole. | billion-context `search_context` |
| **Statistics** | `/token-status` reports per-tool token estimates, largest outputs, duplicate reads, recoverable savings, vault totals, and MCP-server trimming advice. | dsh `/token-status` + `monitor` + billion-context `acp_status`, unified |

## Commands

- `/token-status` — token statistics and savings opportunities
- `/digest <file | "last output">` — spill a large output, keep only its digest
- `/compress [scope]` — compress settled history into a reversible summary
- `/context-search <query>` — recover details from the vault

## Install / requirements

- ZCode with plugins enabled. Install from a marketplace that lists this plugin.
- **Node.js ≥ 16 on PATH** for the hooks and vault CLI (zero npm dependencies, stdlib only). The skill and commands degrade gracefully without it — only automatic ledger recording and the CLI stop working; no session is ever blocked by a failed hook.

All data lives in `<project>/.zcode/tokencare/` (ledger + vault) and is self-gitignored.

## Design decisions

- **Tuned for GLM-5.3 Max and Flash Max.** Token estimation is GLM-aware (CJK ≈ 1 token/char, ASCII ≈ 4 chars/token) instead of the usual chars÷4, which undercounts Chinese-heavy sessions. A profile system shifts strategy per tier — `TOKENCARE_PROFILE=flash|balanced|max` (auto-detected from `TOKENCARE_MODEL` / `ZCODE_MODEL` / `ANTHROPIC_MODEL` or the hook payload): Flash-class nudges at 20k chars and compresses at ~35–40% pressure; balanced (default) 30k / ~45%; Max-class nudges at 40k chars, defers compression to ~55% and focuses on duplicate reads and giant outputs. `/token-status` shows the active profile and its advice.

- **No proxy.** billion-context works as a stream-rewriting proxy between agent and model API. A marketplace plugin cannot (and should not) intercept model traffic, so TokenCare achieves the same savings with hooks + skills + commands, and deliberately cooperates with ZCode's built-in compaction instead of replacing it.
- **One status surface, one ledger.** Both source projects ship overlapping compaction-drivers and monitors; here they are a single ledger and a single `/token-status`.
- **text2img (dsh) is intentionally not ported.** Rendering text to images to save tokens needs a vision model, an API key, and per-platform text rendering, while `/digest` achieves the same token saving losslessly with no dependencies.
- **toolTrim is advisory.** A plugin cannot remove MCP tool schemas from requests, so `/token-status` surfaces MCP usage and advises disabling unused servers in Settings.

## Credits & license

MIT. Design inspired by and indebted to [billion-context](https://github.com/ranxianglei/billion-context) (MIT + attribution) and [dsh-token-optimizer](https://github.com/Zoria-Lind/dsh-token-optimizer) (MIT). No code was copied; both projects are worth a look in their own right.
46 changes: 46 additions & 0 deletions external_plugins/tokencare/README_CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# TokenCare

面向 [ZCode](https://z.ai) 的分层上下文压缩与省 token 优化插件。将 [billion-context](https://github.com/ranxianglei/billion-context)(增量、可逆的上下文压缩)与 [dsh-token-optimizer](https://github.com/Zoria-Lind/dsh-token-optimizer)(工具输出分级、重复读取消除、用量监控)的理念统一为一个插件——重叠部分合并,不做重复造轮子。

长会话会积累巨大的工具输出、反复读取同一文件、撑爆上下文窗口。TokenCare 用三层策略削减浪费,并通过磁盘上的"保险库(vault)"保证**一切皆可恢复**。

## 工作原理

| 层 | 作用 | 来源 |
|---|---|---|
| **L0 — 观测**(自动) | PostToolUse 钩子把每次工具结果的大小、哈希、文件路径记入会话账本;超过 3 万字符的输出会收到一行提示,引导使用 `/digest`;ZCode 压缩会话后,SessionStart(compact) 钩子提示通过保险库找回细节,绝不凭空猜测。 | dsh `monitor` + billion-context 会话统计与增长提示,合并为单一账本 |
| **L1 — 无损外存与去重** | `/digest` 将原文逐字存入保险库并生成结构感知摘要:错误 → 300 字符摘录,JSON → 结构概要,CSV → 表头 + 行数 + 首末行,文本 → 头尾截取。账本自动检测"同一文件未变更却重复读取"并按 token 估算量化浪费。 | dsh `outputLadder` + `fileDiff`,按 billion-context 思路做成可逆 |
| **L2 — 模型驱动压缩** | `/compress` 把会话中已稳定的部分写成结构化摘要存入保险库并登记索引,再以它为锚点配合 ZCode 内置 `/compact`。建议在约 45% 上下文压力时执行,而非等到 80% 以上才应急。 | billion-context `compress`/`decompress` + dsh `compactionDriver`,统一 |
| **恢复** | `/context-search` 在保险库的原文与摘要中检索;原文可完整取回。 | billion-context `search_context` |
| **统计** | `/token-status` 输出按工具的 token 估算、最大输出、重复读取、可回收空间、保险库总量,以及 MCP 服务裁剪建议。 | dsh `/token-status` + `monitor` + billion-context `acp_status`,统一 |

## 命令

- `/token-status` — token 统计与节省机会
- `/digest <文件 | "last output">` — 大输出外存,仅保留摘要
- `/compress [范围]` — 将已稳定的会话历史压缩为可逆摘要
- `/context-search <关键词>` — 从保险库找回细节

## GLM-5.3 Max / Flash Max 调优

token 估算针对 GLM 系分词器做了中英双语感知(中日韩 ≈ 每字符 1 token,ASCII ≈ 4 字符/token),中文密集会话不再被低估。策略按模型档位自动切换:`TOKENCARE_PROFILE=flash|balanced|max`(也可通过 `TOKENCARE_MODEL` / `ZCODE_MODEL` / `ANTHROPIC_MODEL` 或钩子载荷自动识别):Flash 档 2 万字符即提示、约 35–40% 压力即压缩;balanced(默认)3 万 / 约 45%;Max 档 4 万才提示、约 55% 再压缩,优先消除重复读取与超大输出。`/token-status` 会显示当前档位与建议。

## 安装与依赖

- 启用插件功能的 ZCode。从收录本插件的插件市场安装。
- 钩子与保险库 CLI 需要 **PATH 中有 Node.js ≥ 16**(零 npm 依赖,仅标准库)。缺少 Node 时优雅降级:仅自动记账与 CLI 停止工作,任何会话都不会因此中断。

数据保存在 `<项目>/.zcode/tokencare/`(账本 + 保险库),目录自动自 gitignore。

权限与副作用说明:插件只读写项目内的 `.zcode/tokencare/` 目录;钩子在每次工具调用后本地执行一次 Node 脚本(无网络请求、无外部依赖);不会删除或改写保险库中的任何原文。

## 设计决策

- **不做代理。** billion-context 以流改写代理方式工作;市场插件无法也不应拦截模型流量,TokenCare 改用钩子 + 技能 + 命令达成同样节省,并与 ZCode 内置压缩协作而非取代。
- **一个状态出口、一份账本。** 两个上游项目各有重叠的压缩驱动与监控,这里合并为单一账本与单一 `/token-status`。
- **未移植 text2img(dsh)。** 文本转图片省 token 需要视觉模型、API 密钥与各平台文字渲染,而 `/digest` 以零依赖、无损方式达到同样节省。
- **toolTrim 仅作建议。** 插件无法从请求中移除 MCP 工具 schema,`/token-status` 呈现 MCP 使用情况并建议在设置中停用闲置服务。

## 致谢与许可

MIT。设计受 [billion-context](https://github.com/ranxianglei/billion-context)(MIT + 署名条款)与 [dsh-token-optimizer](https://github.com/Zoria-Lind/dsh-token-optimizer)(MIT)启发并致谢;未复制任何代码,两个项目本身值得一读。
11 changes: 11 additions & 0 deletions external_plugins/tokencare/commands/compress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
description: Compress the settled part of this conversation into a reversible vault summary.
argument-hint: "[scope hint, e.g. 'everything before the last hour']"
skills: tokencare
---

Use the `tokencare` skill (L2) for this request.

Scope: $ARGUMENTS (default: the older, settled part of the conversation — recent turns stay intact).

Follow the skill's L2 protocol exactly: write a structured summary (`summary-<n>.md`) into `.zcode/tokencare/vault/` covering goals/state, decisions and reasons, files touched, key commands and results, open threads, and spill-id pointers; register it in `vault/index.json`; then tell the user the summary is the compaction anchor and suggest running ZCode's built-in `/compact` now. Emphasize that nothing is lost — `/context-search` recovers any detail from the vault afterwards.
17 changes: 17 additions & 0 deletions external_plugins/tokencare/commands/context-search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
description: Search the context vault for details lost to compaction or spilled from context.
argument-hint: "<query>"
skills: tokencare
---

Use the `tokencare` skill (recovery) for this request.

Query: $ARGUMENTS

Run:

```
node "<tokencare skill base dir>/../../scripts/vault.mjs" search "$ARGUMENTS"
```

Report the matches with their vault ids. If a match looks relevant but truncated, fetch the full original with `vault.mjs get <id>` and answer from it. If there are no matches, say so plainly and fall back to normal tools (re-reading the file, re-running the command) — do not guess at vault contents.
17 changes: 17 additions & 0 deletions external_plugins/tokencare/commands/digest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
description: Spill a large tool output or file to the vault and replace it with a compact digest.
argument-hint: "<file path | 'last output'>"
skills: tokencare
---

Use the `tokencare` skill (L1) for this request.

Target: $ARGUMENTS

If the argument is a file path, spill it directly:

```
node "<tokencare skill base dir>/../../scripts/vault.mjs" spill "<file>"
```

If it is "last output" or similar, the most recent large tool output is still in the conversation: save it to a temporary file (or pipe via `--stdin`), then spill that. Use the printed digest block in place of the original from now on, and mention the spill id so the user can recover the original later with `/context-search`.
13 changes: 13 additions & 0 deletions external_plugins/tokencare/commands/token-status.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
description: Show token usage statistics and savings opportunities for this project's sessions.
argument-hint: "[--json]"
skills: tokencare
---

Use the `tokencare` skill for this request. Run the vault statistics tool:

```
node "<tokencare skill base dir>/../../scripts/vault.mjs" stats $ARGUMENTS
```

Present the report to the user in a readable form (per-tool estimated tokens, largest outputs, duplicate unchanged re-reads, oversized outputs, vault totals). Then act on what it flags: offer `/digest` for oversized outputs, point out duplicate reads with the exact wasted-token estimates, and remind about unused MCP servers if MCP tools appear. Token figures are chars÷4 estimates — label them as such.
29 changes: 29 additions & 0 deletions external_plugins/tokencare/hooks/hooks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"hooks": {
"PostToolUse": [
{
"hooks": [
{
"type": "command",
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/vault.mjs\" record posttooluse",
"timeoutMs": 10000,
"statusMessage": "TokenCare: recording tool output stats"
}
]
}
],
"SessionStart": [
{
"matcher": "compact",
"hooks": [
{
"type": "command",
"command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/vault.mjs\" record sessionstart",
"timeoutMs": 10000,
"statusMessage": "TokenCare: checking context vault"
}
]
}
]
}
}
Loading