@tduyng/pi-context 0.0.3 → 0.0.4
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 +35 -49
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,82 +1,62 @@
|
|
|
1
1
|
# @tduyng/pi-context
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Four things for the context window: see what fills it, compact from the warm cache instead of a cold one, retire a finished turn, and read back what compaction dropped.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
When the window fills, pi compacts and a summariser reads the conversation again, from cold. That request costs the conversation it summarises. `/context` shows where the window went, and the other three make a compaction cheaper or smaller.
|
|
6
6
|
|
|
7
|
-
`history` is
|
|
7
|
+
`history` is 134 tokens and only in sessions that load it. `/context`, `/collapse` and `/context-cache` are commands, so they cost nothing until typed. The dedupe is an event hook and adds no schema.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## Where the window went
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
`/context` opens a TUI panel with a colored pixel map and a category list. Every consumer gets a row: system prompt, tools, user messages, assistant text, tool results, bash executions, compacted history, extension entries, free space. Categories break down by tool or custom type, sorted by token weight, and children are capped at 30 shown with a `+N more` line carrying their combined count.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
The panel fits the window it opens in. Its body takes at most 70% of the rows, each line is truncated to the column width instead of wrapping, and a list too tall for the window keeps every category it can before spending the rest on child rows. The map is hidden below six rows or 86 columns.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
## Compacting from the warm prefix
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
The capture is the full transcript of the last request, including the leading system message that carries the prompt and the tool declarations. The summary request replays it unchanged with one instruction appended, so almost all of the input is a cache read, and the summariser sees full tool output rather than pi's 2,000-character head cuts.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
The fallback is narrow on purpose. The branch is projected through pi's own entry conversion and the captured conversation must still be its prefix. A kept region that moved, a model change, a cold cache, a truncated reply or a provider error all fall back to pi's own compaction. Nothing is cancelled, since a compaction pi asked for always runs, on the cached path when it can and on pi's path otherwise.
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
`/context-cache` shows the declared lifetime, the last refresh and the warm capture. Each decision lands in `<agent-dir>/cached-compaction.jsonl` with its reason, which is where to look when a compaction took the slow path.
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
Every decision lands in `~/.pi/agent/cached-compaction.jsonl` with the reason it took.
|
|
26
|
-
|
|
27
|
-
## history
|
|
28
|
-
|
|
29
|
-
Search or read earlier conversation that left the window: pruned results, compacted spans, or earlier sessions of the project.
|
|
30
|
-
|
|
31
|
-
`search` walks the current branch newest first. With `all: true` it searches every session file of the project, newest file first. Multi-word queries OR-match. Echoes (compaction summaries, verbatim input records, prior history results) rank below originals, so a copy never displaces what it copied. The default limit is 10, the maximum 50, and the ranking is lexical.
|
|
32
|
-
|
|
33
|
-
`read` returns one entry in full, sliced to fit the remaining context. Page size is min 2,000, max 20,000 characters, sized to leave room for the reply. `offset` pages through.
|
|
34
|
-
|
|
35
|
-
Session files are append-only JSONL, streamed line by line, so a large transcript never lands in memory.
|
|
36
|
-
|
|
37
|
-
## /collapse
|
|
23
|
+
## A finished turn, retired
|
|
38
24
|
|
|
39
25
|
`/collapse [turns]` replaces finished turns with one branch summary, one turn by default. The anchor is the entry before the oldest user prompt in the span, so nothing before the task moves.
|
|
40
26
|
|
|
41
|
-
|
|
27
|
+
It builds the summary from the entries themselves: modified files, read-only files, command count, validation runs, the failures with the command that failed, and the last assistant text as the outcome. No model reads the span and no request goes out, which is where this differs from a compaction. It costs nothing and leaves the cache alone.
|
|
42
28
|
|
|
43
29
|
Two cases refuse. Nothing sits before the first prompt of a session, so there is no anchor, and a prompt with no assistant turn after it is work in flight rather than a finished turn.
|
|
44
30
|
|
|
45
|
-
What it drops is real
|
|
31
|
+
What it drops is real: the reasoning inside a turn goes, the summary keeps one text block, and the file list caps at twelve with the remainder counted. The raw entries stay in the session file, so `history` recovers any of them and `/tree` walks back to them. The collapsed messages' usage rides along on the branch summary entry, which is where pi reads totals, so `/cost` still counts what those turns cost.
|
|
46
32
|
|
|
47
|
-
|
|
33
|
+
## Reading back what compaction dropped
|
|
48
34
|
|
|
49
|
-
|
|
35
|
+
`history` searches or reads earlier conversation that left the window: pruned results, compacted spans, or earlier sessions of the project.
|
|
50
36
|
|
|
51
|
-
|
|
37
|
+
`search` walks the current branch newest first, or every session file of the project with `all: true`, newest file first. Multi-word queries OR-match. Echoes (compaction summaries, verbatim input records, prior history results) rank below originals, so a copy never displaces what it copied. The default limit is 10, the maximum 50, and the ranking is lexical.
|
|
52
38
|
|
|
53
|
-
|
|
39
|
+
`read` returns one entry in full, sliced to fit the remaining context. Page size is 2,000 to 20,000 characters, sized to leave room for the reply, and `offset` pages through. Session files are append-only JSONL, streamed line by line, so a large transcript never lands in memory.
|
|
54
40
|
|
|
55
|
-
##
|
|
41
|
+
## A record of what was said
|
|
56
42
|
|
|
57
|
-
|
|
43
|
+
After automatic compaction, not manual `/compact`, a hidden custom message lists the compacted span's verbatim user inputs, `ask_question` answers, and visible custom messages. The cap is 20,000 characters, and the first ask, the latest ask and the latest input always survive.
|
|
58
44
|
|
|
59
|
-
|
|
45
|
+
A summary paraphrases a request, and the exact wording of an ask is often the requirement.
|
|
60
46
|
|
|
61
|
-
|
|
47
|
+
## Two defects it fixes
|
|
62
48
|
|
|
63
|
-
|
|
49
|
+
When the agent directory and the working directory resolve to the same file through different paths, from a hardlink, a bind mount or a symlinked ancestor, pi adds the same `<project_instructions>` block twice. A `before_agent_start` handler strips the second copy by content, so two identical blocks are always redundant and blocks with different content stay.
|
|
64
50
|
|
|
65
|
-
|
|
51
|
+
The other is a stale read. A `read` puts a file's bytes in the transcript, and a later `edit` makes them wrong. Over the recorded sessions, 66 percent of read bytes are stale by this rule. An earlier version marked them in place, and the measurement removed it: replacing a tool result rewrites the cached prefix from that point, so on a 300k-token session one marker re-bills 200k to 300k tokens to reclaim 8 KB, and it recurs on every later edit to a path already read. Compaction rewrites the whole prefix once and pays for it once.
|
|
66
52
|
|
|
67
|
-
##
|
|
53
|
+
## Three ideas that measured to nothing
|
|
68
54
|
|
|
69
|
-
|
|
55
|
+
Kept because the numbers are the argument against rebuilding them:
|
|
70
56
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
This one is kept because it closes the question rather than deferring it.
|
|
76
|
-
|
|
77
|
-
A large tool result is rarely needed whole, so the idea was to build small views of one (`full`, `head`, `tail`, `signals`, `outline`) and ask the local model which to keep. It ran on a `tool_execution_end` handler over every result past 2,000 characters, cost 839 calls and 740,402 tokens, 43 percent of everything this suite sent to the local model, and changed nothing: the handler returned no hint, nothing was rewritten, and the log entry held a `stateHash` rather than the result, so nothing could be scored afterwards. Asking the model directly returns near-uniform distributions over the five views.
|
|
78
|
-
|
|
79
|
-
The offline fallback scored each view against the lines a later message quoted from the result, and that label cannot fire: across 1,045 replayed cases, not one tool-result line was ever quoted verbatim, at every bar from 4 to 80 characters. The model reads a result and acts on it rather than repeating it, so these sessions hold no signal to score a view against. The views and the benchmark are deleted.
|
|
57
|
+
- A tool-result view selector, where a local model picked `full`, `head`, `tail`, `signals` or `outline` for every result over 2,000 characters. It cost 839 calls and 740k tokens and changed nothing, because not one tool-result line was ever quoted verbatim by a later message. With no label, there was nothing to score a view against.
|
|
58
|
+
- A compaction deferral hook. It opened at `contextWindow - reserveTokens`, a line a real session request never reaches, and recorded one firing in the whole history.
|
|
59
|
+
- A history rerank, which promoted twice in 17 searches and scored 0.612 to 0.659 AUC against a lexical floor at 0.707.
|
|
80
60
|
|
|
81
61
|
## Install
|
|
82
62
|
|
|
@@ -86,4 +66,10 @@ pi install npm:@tduyng/pi-context
|
|
|
86
66
|
|
|
87
67
|
Local checkout: `pi install /path/to/dotfiles/pi/agent/extensions/pi-context`
|
|
88
68
|
|
|
89
|
-
|
|
69
|
+
Set `PI_CACHE_RETENTION=long` so cached compaction has a cache to read. Pi's default is 5 minutes, and a pause longer than that turns the warm path into a cold one. Nothing else is configurable.
|
|
70
|
+
|
|
71
|
+
## Limits
|
|
72
|
+
|
|
73
|
+
- Cached compaction falls back to pi's own path on any change to the prefix, so it helps a long stable session most.
|
|
74
|
+
- `/collapse` drops the reasoning inside a turn, keeps one text block, and caps the file list at twelve.
|
|
75
|
+
- `history` ranks lexically. It is recall over a transcript, not a search engine.
|
package/package.json
CHANGED