tanuki-context 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -0
- package/dist/agent.js +1 -1
- package/dist/cli.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -229,6 +229,49 @@ harness that holds the two engines to byte-identical JSON and
|
|
|
229
229
|
pixel-identical PNGs on every knob combination, including distilled
|
|
230
230
|
renders and a full MCP session with error paths.
|
|
231
231
|
|
|
232
|
+
## How it compares
|
|
233
|
+
|
|
234
|
+
Five approaches to the same problem, measured on the same 200 KB journal
|
|
235
|
+
(51,200 tokens raw) on the same machine. They are not five competitors —
|
|
236
|
+
they are different answers to "does the model need to see this at all?",
|
|
237
|
+
and several of them compose.
|
|
238
|
+
|
|
239
|
+
| approach | what enters context | tokens | what the model can still do |
|
|
240
|
+
| --- | --- | ---: | --- |
|
|
241
|
+
| raw text (baseline) | everything, as text | 51,200 | everything, quotable |
|
|
242
|
+
| caveman-style compression (tanuki ladder L4, stays text) | reworded text | 51,198 (-0%) | on a log: nothing changes — the exact-recall guard protects every line, and unguarded caveman would corrupt them. On prose it manages -6% (DESIGN.md). Wrong tool for logs |
|
|
243
|
+
| ponytail strategy (send only the queried slice: `distill` + `query`) | matched + error lines, as text | 22,110 (-57%) | greppable, quotable text of everything important; the unmatched rest is gone |
|
|
244
|
+
| [pxpipe](https://github.com/teamchong/pxpipe) (its own `export` CLI on this corpus) | 8 PNG pages + prompt + factsheet | ~11,965 (-77%) | read everything back; 96 precision-critical strings ride verbatim in the factsheet |
|
|
245
|
+
| tanuki, distill + render | 4 PNG pages | 5,264 (-90%) | read everything that survives distill: repeats collapsed with exact counts, all 310 error/warn lines verbatim |
|
|
246
|
+
| tanuki, + codebook + tiny font | 2 PNG pages | 2,576 (-95%) | same content, lossy glyphs (99.7% read-back) — opt-in |
|
|
247
|
+
| [context-mode](https://www.npmjs.com/package/context-mode) (sandbox pass over the file) | one analysis result | ~270 per question (-99.5%) | only the answer it asked for; the file never enters context at all |
|
|
248
|
+
|
|
249
|
+
Reading that honestly:
|
|
250
|
+
|
|
251
|
+
- **context-mode wins whenever a question suffices.** If the model never
|
|
252
|
+
needs to *see* the log, ~270 tokens per query is unbeatable. The moment it
|
|
253
|
+
needs the material in front of it (debugging an unknown, quoting context,
|
|
254
|
+
"read all of this and tell me what's weird"), retrieval stops being the
|
|
255
|
+
same product. The two compose: keep the file in context-mode's sandbox,
|
|
256
|
+
render it with tanuki the day the model actually has to read it.
|
|
257
|
+
- **pxpipe and tanuki are the same engine**, so the gap between -77% and
|
|
258
|
+
-90% here is not the imaging — it is distill (pxpipe does not de-noise
|
|
259
|
+
logs) plus the sidecar text its export flow pastes alongside. On prose,
|
|
260
|
+
where distill does nothing, the two land in the same place. pxpipe's
|
|
261
|
+
factsheet is a fidelity feature tanuki lacks: guaranteed-verbatim strings
|
|
262
|
+
next to the pages.
|
|
263
|
+
- **Caveman-style prompt compression is the weakest option for logs**, and
|
|
264
|
+
tanuki's own level 4 proves it: the guard that makes it safe also makes
|
|
265
|
+
it a no-op on structured content. It exists for wordy prose.
|
|
266
|
+
- **The ponytail row is a strategy, not a tool**: send only what is needed.
|
|
267
|
+
It beats nothing on this corpus except raw text, but it composes — the
|
|
268
|
+
22,110-token slice drawn as pages is 4,704 tokens, and `estimate` will
|
|
269
|
+
happily price that route for you.
|
|
270
|
+
|
|
271
|
+
Every row is reproducible: rows 1-3 and 5-6 are single `tanuki-context`
|
|
272
|
+
commands, the pxpipe row is `pxpipe export --stdin < your.log` on their
|
|
273
|
+
CLI, the context-mode row is one `ctx_execute_file` call in its sandbox.
|
|
274
|
+
|
|
232
275
|
## Limits, plainly
|
|
233
276
|
|
|
234
277
|
- **Rendering is exact; reading is a model skill.** Pages are pixel-faithful
|
package/dist/agent.js
CHANGED
|
@@ -65,7 +65,7 @@ class ZJ{value;constructor(J){this.value=J}}function nJ(){let J=process.env.TANU
|
|
|
65
65
|
//! tanuki-context estimate <file> [level] [--distill]
|
|
66
66
|
//! tanuki-context render <file> [level] [outdir]
|
|
67
67
|
//! tanuki-context proxy [--port N] [--upstream URL] [knobs] (implicit mode)
|
|
68
|
-
var cJ="0.2.
|
|
68
|
+
var cJ="0.2.3",NJ=6;function JZ(J,Q){let Z=Math.min(J.length,Q.length),$=0;while($<Z&&J.charCodeAt($)===Q.charCodeAt($))$++;if($>=Z)return J.length-Q.length;return J.codePointAt($)-Q.codePointAt($)}function C(J,Q,Z=""){if(J===null||J===void 0)return"null";if(J instanceof ZJ){let z=J.value;return Number.isFinite(z)&&Number.isInteger(z)?z.toFixed(1):String(z)}let $=typeof J;if($==="string")return JSON.stringify(J);if($==="number"||$==="boolean")return String(J);if(Array.isArray(J)){if(J.length===0)return"[]";if(!Q){let q="[";for(let X=0;X<J.length;X++){if(X>0)q+=",";q+=C(J[X],!1)}return q+"]"}let z=Z+" ",K=`[
|
|
69
69
|
`;for(let q=0;q<J.length;q++){if(q>0)K+=`,
|
|
70
70
|
`;K+=z+C(J[q],!0,z)}return K+`
|
|
71
71
|
`+Z+"]"}let V=J,G=Object.keys(V).sort(JZ);if(G.length===0)return"{}";if(!Q){let z="{";for(let K=0;K<G.length;K++){if(K>0)z+=",";z+=JSON.stringify(G[K])+":"+C(V[G[K]],!1)}return z+"}"}let Y=Z+" ",H=`{
|
package/dist/cli.js
CHANGED
|
@@ -71,7 +71,7 @@ var c={level:0,distill:!1,codebook:!1,font:"normal",minChars:4000,ratio:0.75,min
|
|
|
71
71
|
//! tanuki-context estimate <file> [level] [--distill]
|
|
72
72
|
//! tanuki-context render <file> [level] [outdir]
|
|
73
73
|
//! tanuki-context proxy [--port N] [--upstream URL] [knobs] (implicit mode)
|
|
74
|
-
var NZ="0.2.
|
|
74
|
+
var NZ="0.2.3",TJ=6;function jZ(J,Q){let Z=Math.min(J.length,Q.length),$=0;while($<Z&&J.charCodeAt($)===Q.charCodeAt($))$++;if($>=Z)return J.length-Q.length;return J.codePointAt($)-Q.codePointAt($)}function E(J,Q,Z=""){if(J===null||J===void 0)return"null";if(J instanceof e){let H=J.value;return Number.isFinite(H)&&Number.isInteger(H)?H.toFixed(1):String(H)}let $=typeof J;if($==="string")return JSON.stringify(J);if($==="number"||$==="boolean")return String(J);if(Array.isArray(J)){if(J.length===0)return"[]";if(!Q){let B="[";for(let X=0;X<J.length;X++){if(X>0)B+=",";B+=E(J[X],!1)}return B+"]"}let H=Z+" ",K=`[
|
|
75
75
|
`;for(let B=0;B<J.length;B++){if(B>0)K+=`,
|
|
76
76
|
`;K+=H+E(J[B],!0,H)}return K+`
|
|
77
77
|
`+Z+"]"}let V=J,z=Object.keys(V).sort(jZ);if(z.length===0)return"{}";if(!Q){let H="{";for(let K=0;K<z.length;K++){if(K>0)H+=",";H+=JSON.stringify(z[K])+":"+E(V[z[K]],!1)}return H+"}"}let Y=Z+" ",G=`{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tanuki-context",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Token-cutting context pipeline as an MCP server: distill logs, compress text, render dense PNG pages (pxpipe imaging engine). Zero dependencies.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|