pi-squeeze 0.2.1 → 0.3.0
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 +14 -1
- package/extensions/core/config.ts +4 -0
- package/extensions/core/savings.ts +42 -0
- package/extensions/squeeze.ts +12 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -86,9 +86,22 @@ Safety rules:
|
|
|
86
86
|
| `/squeeze min <chars>` | smallest output worth compacting (default 400) |
|
|
87
87
|
|
|
88
88
|
Settings are remembered in `<pi agent dir>/squeeze.json` (`PI_CODING_AGENT_DIR`, else `~/.pi/agent`); it also holds
|
|
89
|
-
`lineChars`, `perGroup` and `total`, the limits of a compacted result. `PI_SQUEEZE=off` disables it at start.
|
|
89
|
+
`lineChars`, `perGroup` and `total`, the limits of a compacted result, and `logSavings` (below). `PI_SQUEEZE=off` disables it at start.
|
|
90
90
|
The status line shows the tokens saved.
|
|
91
91
|
|
|
92
|
+
## Savings log
|
|
93
|
+
|
|
94
|
+
Each compacted output adds one line to `<pi agent dir>/squeeze-savings.jsonl`, so the savings can be tracked
|
|
95
|
+
over time; the model never sees it:
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
{"ts":"2026-01-02T09:15:00.000Z","session":"…","cwd":"/work/app","tokens":1840,"chars":7360,"kind":"build"}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
[tokenburn](https://github.com/sorinirimies/tokenburn) and [pi-tokenburn](https://github.com/sorinirimies/pi-tokenburn)
|
|
102
|
+
read it as the "pi squeeze" saving. When rtk ran the command, rtk logs its own part; this log holds only what
|
|
103
|
+
pi-squeeze cut after it. `"logSavings": false` in `squeeze.json` turns it off.
|
|
104
|
+
|
|
92
105
|
## Development
|
|
93
106
|
|
|
94
107
|
```bash
|
|
@@ -14,6 +14,8 @@ export interface Config {
|
|
|
14
14
|
enabled: boolean;
|
|
15
15
|
/** Show the savings in the status line. */
|
|
16
16
|
showStatus: boolean;
|
|
17
|
+
/** Append each saving to <agent dir>/squeeze-savings.jsonl for usage trackers. */
|
|
18
|
+
logSavings: boolean;
|
|
17
19
|
/** Which compactors run. */
|
|
18
20
|
kinds: Record<Kind, boolean>;
|
|
19
21
|
/** Rewrite commands to their `rtk` form (git, cargo, docker, …) when the rtk binary is installed. */
|
|
@@ -31,6 +33,7 @@ export interface Config {
|
|
|
31
33
|
export const DEFAULT_CONFIG: Config = {
|
|
32
34
|
enabled: true,
|
|
33
35
|
showStatus: true,
|
|
36
|
+
logSavings: true,
|
|
34
37
|
rtk: true,
|
|
35
38
|
kinds: Object.fromEntries(KINDS.map((k) => [k, true])) as Record<Kind, boolean>,
|
|
36
39
|
minChars: 400,
|
|
@@ -51,6 +54,7 @@ export function sanitizeConfig(raw: unknown): Config {
|
|
|
51
54
|
return {
|
|
52
55
|
enabled: bool(r.enabled, d.enabled),
|
|
53
56
|
showStatus: bool(r.showStatus, d.showStatus),
|
|
57
|
+
logSavings: bool(r.logSavings, d.logSavings),
|
|
54
58
|
rtk: bool(r.rtk, d.rtk),
|
|
55
59
|
kinds: Object.fromEntries(KINDS.map((kind) => [kind, bool(k[kind], d.kinds[kind])])) as Record<Kind, boolean>,
|
|
56
60
|
minChars: clampInt(r.minChars, 100, 1_000_000, d.minChars),
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The savings log: one JSON line per compacted output in <agent dir>/squeeze-savings.jsonl, so usage
|
|
3
|
+
* trackers (tokenburn, pi-tokenburn) can count what pi-squeeze saved over time. The model never sees
|
|
4
|
+
* it. When rtk ran the command, rtk logs its own part; this logs only what pi-squeeze cut after it.
|
|
5
|
+
*/
|
|
6
|
+
import { appendFile, mkdir } from "node:fs/promises";
|
|
7
|
+
import { homedir } from "node:os";
|
|
8
|
+
import { dirname, join } from "node:path";
|
|
9
|
+
import type { Kind } from "./compact.ts";
|
|
10
|
+
import { resolveAgentDir } from "./config.ts";
|
|
11
|
+
|
|
12
|
+
export const SAVINGS_LOG = "squeeze-savings.jsonl";
|
|
13
|
+
|
|
14
|
+
export const savingsLogPath = (env: Record<string, string | undefined> = process.env, home: string = homedir()): string =>
|
|
15
|
+
join(resolveAgentDir(env, home), SAVINGS_LOG);
|
|
16
|
+
|
|
17
|
+
/** One line of the log. `tokens` is estimated from `chars` (4 characters per token). */
|
|
18
|
+
export interface SavingRecord {
|
|
19
|
+
/** When the output was compacted (ISO 8601, UTC). */
|
|
20
|
+
ts: string;
|
|
21
|
+
session: string;
|
|
22
|
+
cwd: string;
|
|
23
|
+
/** Tokens kept out of the context. */
|
|
24
|
+
tokens: number;
|
|
25
|
+
/** Characters kept out of the context. */
|
|
26
|
+
chars: number;
|
|
27
|
+
/** The compactor that did it. */
|
|
28
|
+
kind: Kind;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const savingLine = (r: SavingRecord): string => JSON.stringify(r) + "\n";
|
|
32
|
+
|
|
33
|
+
/** Appends one record. Never throws: a log that cannot be written must not affect the session. */
|
|
34
|
+
export async function appendSaving(record: SavingRecord, path: string = savingsLogPath()): Promise<boolean> {
|
|
35
|
+
try {
|
|
36
|
+
await mkdir(dirname(path), { recursive: true });
|
|
37
|
+
await appendFile(path, savingLine(record), "utf8");
|
|
38
|
+
return true;
|
|
39
|
+
} catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
package/extensions/squeeze.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { completions, parseCommand } from "./command/parse.ts";
|
|
|
11
11
|
import { compact, KINDS } from "./core/compact.ts";
|
|
12
12
|
import { type Config, DEFAULT_CONFIG, optionsOf, readConfig, saveConfig } from "./core/config.ts";
|
|
13
13
|
import { rewrite } from "./core/rtk.ts";
|
|
14
|
+
import { appendSaving } from "./core/savings.ts";
|
|
14
15
|
import { fileIn, readFullOutput } from "./core/files.ts";
|
|
15
16
|
import { saveFull } from "./core/save.ts";
|
|
16
17
|
import { emptyStats, record, saved, summary, tokens } from "./core/stats.ts";
|
|
@@ -68,6 +69,17 @@ export default function (pi: ExtensionAPI) {
|
|
|
68
69
|
// Never more than pi would have shown.
|
|
69
70
|
if (!r || r.text.length >= shown.length) return;
|
|
70
71
|
record(stats, { ...r, before: shown.length });
|
|
72
|
+
if (config.logSavings) {
|
|
73
|
+
const chars = shown.length - r.after;
|
|
74
|
+
void appendSaving({
|
|
75
|
+
ts: new Date(Date.now()).toISOString(),
|
|
76
|
+
session: ctx.sessionManager?.getSessionId?.() ?? "",
|
|
77
|
+
cwd: ctx.cwd ?? "",
|
|
78
|
+
tokens: tokens(chars),
|
|
79
|
+
chars,
|
|
80
|
+
kind: r.kind,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
71
83
|
showStatus(ctx);
|
|
72
84
|
const where = fullPath ?? (r.truncated ? saveFull(original) : undefined);
|
|
73
85
|
const text = where ? `${r.text}\n[squeeze: output shortened; full output: ${where}]` : r.text;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-squeeze",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Shrinks bash output before it reaches the agent's context: native compactors for git, search, listings, tests, builds (cargo, gradle, Maven, javac, Xcode, tsc, docker), Android (adb, lint, detekt), linters, package installs and logs, plus rtk when installed. Full output stays one temp file away.",
|
|
5
5
|
"keywords": ["pi-package", "pi-extension", "pi", "tokens", "context", "compaction", "rtk"],
|
|
6
6
|
"license": "MIT",
|