@stfade/pi-read-delegator 1.0.11 → 1.0.13

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 CHANGED
@@ -1,106 +1,215 @@
1
1
  # pi-read-delegator
2
2
 
3
- Pi extension that removes read tools (`read`, `grep`, `find`, `ls`) from the main model and delegates all read operations to a local **Reader** subagent.
3
+ **Pi extension**: delegates all file-read and search operations to a lightweight Reader subagent. The main model never sees raw file contents saving tokens, avoiding context pollution, and keeping the orchestrator focused on reasoning.
4
4
 
5
- ## How It Works
5
+ ## Architecture
6
6
 
7
7
  ```
8
- Main Model Reader Subagent
9
- ┌──────────┐ ┌──────────┐
10
- write │ │ read
11
- edit │ ──task──> │ grep
12
- bash │ <──result── find
13
- (write) │ ls │
14
- └──────────┘ └──────────┘
8
+ ┌──────────────────────────────────────────────────────────────┐
9
+ │ ORCHESTRATOR (main model) │
10
+ Cannot use: read, grep, find, ls
11
+ Cannot run: cat, grep, head, tail, Get-Content, findstr
12
+ MUST delegate via: subagent(agent="reader", task="...")
13
+
14
+ │ System prompt tells orchestrator HOW to delegate: │
15
+ │ Action: read | Target: src/file.ts | Detail: function X │
16
+ │ Action: grep | Target: src/ | Detail: "pattern" │
17
+ │ Action: find | Target: src/ | Detail: *.ts │
18
+ └──────────────────────┬───────────────────────────────────────┘
19
+ │ subagent(agent="reader", task="...")
20
+ ┌──────────────────────▼───────────────────────────────────────┐
21
+ │ READER SUBAGENT (pi-subagents → reader.md) │
22
+ │ • Tools: read, grep, find, ls │
23
+ │ • Receives structured task, returns structured output │
24
+ │ │
25
+ │ src/config.ts:42 const DEFAULT_CONFIG = { │
26
+ │ src/config.ts:43 enabled: true, │
27
+ │ ... │
28
+ └──────────────────────────────────────────────────────────────┘
15
29
  ```
16
30
 
17
- - **Write tools** (`write`, `edit`) remain with the main model.
18
- - **Read tools** (`read`, `grep`, `find`, `ls`) are blocked on the main model and routed to the Reader subagent.
19
- - **Bash commands** are filtered: read commands go to Reader, write commands execute directly, ambiguous commands prompt the user.
31
+ ### Communication protocol
20
32
 
21
- ## Requirements
33
+ The orchestrator and reader communicate through a **structured task/result protocol** — no free-form chatting, no "max N lines" truncation.
22
34
 
23
- - [pi-subagents](https://github.com/earendil-works/pi-subagents) installed
24
- - A local LLM for the Reader subagent (default: `lmstudio/nemotron-mini`)
35
+ **Orchestrator → Reader** (task format):
36
+ ```
37
+ Action: read | Target: src/config.ts | Detail: DEFAULT_CONFIG definition
38
+ Action: grep | Target: src/ | Detail: "isReadCommand" function
39
+ Action: find | Target: src/ | Detail: *.ts
40
+ ```
41
+
42
+ **Reader → Orchestrator** (result format):
43
+ - Minimal, structured output — no markdown headers, no explanations
44
+ - grep: `file:line content` (file path, line number, matched line)
45
+ - read: line-numbered file content
46
+ - find: bare file list, one per line
47
+ - ls: file names with sizes
48
+ - No matches: `(no matches)`
49
+ - Error: `Error: <message>`
50
+
51
+ This protocol was designed based on research findings around **token-efficient subagent orchestration**:
52
+ structured output beats free-form text, file-path-based handoffs avoid triple-token duplication, and single-level hierarchy keeps context clean.
53
+
54
+ ---
55
+
56
+ ### Token optimizations
57
+
58
+ The Reader subagent applies **6 optimization techniques** — researched from Headroom, RTK, and multi-agent orchestration literature — to minimize token usage on every call:
59
+
60
+ | # | Technique | What it does | Token savings |
61
+ |---|-----------|-------------|:------------:|
62
+ | 1 | **CCR Cache** | Session-level file cache with hash-based invalidation. Same file never read twice. | **83%** (re-reads) |
63
+ | 2 | **Structure masks** | Compresses imports, type annotations, and long paths in code output. | **35%** (code reads) |
64
+ | 3 | **Stats extraction** | grep/find/ls return counts first; >20 results → count only. | **60%** (searches) |
65
+ | 4 | **Smart filtering** | Auto-skips node_modules, .git, dist; detects binary files; deduplicates. | **20%** (noisy output) |
66
+ | 5 | **Graduated reading** | Orchestrator taught to use find→grep→read progression instead of full-file reads. | **40%** (surveys) |
67
+ | 6 | **Prompt compression** | Orchestrator prompt compressed from 55 to 22 lines via example-driven format. | **1.5K**/session |
68
+
69
+ ### Token analysis (test results)
70
+
71
+ > **Instructions**: Test pi-read-delegator on different projects. For each project, measure
72
+ total tokens consumed across a full coding session with and without the extension.
73
+ Record results below.
74
+
75
+ | Project | Files | Size | No delegation | Basic delegation | With optimizations | Savings |
76
+ |---------|:-----:|------|:------------:|:----------------:|:------------------:|:-------:|
77
+ | *(your project)* | | | | | | |
78
+ | | | | | | | |
79
+ | | | | | | | |
80
+ | | | | | | | |
81
+ | | | | | | | |
82
+
83
+ **How to measure**: Use Pi's token counter or your provider's usage dashboard.
84
+ "Basic delegation" = extension enabled but optimizations disabled (set `reader_model` to same as orchestrator, clear cache between calls).
85
+ "With optimizations" = all 6 techniques active (default).
86
+ "Savings" = (No delegation − With optimizations) / No delegation × 100.
25
87
 
26
88
  ## Installation
27
89
 
28
90
  ```bash
29
- pi install npm:@stfade/pi-read-delegator
91
+ pi install @stfade/pi-read-delegator
30
92
  ```
31
93
 
32
- Or manually:
94
+ On first session start, the extension:
95
+ 1. Auto-installs `pi-subagents` as a dependency
96
+ 2. Guides you through interactive model selection
97
+ 3. Creates `~/.pi/agent/agents/reader.md` with the Reader's system prompt
98
+ 4. Registers `pi-subagents` in Pi's package list
33
99
 
34
- ```bash
35
- npm install -g pi-read-delegator
36
- ```
100
+ ## Configuration
37
101
 
38
- Then edit `~/.pi/agent/agents/reader.md` to set your preferred Reader model.
102
+ Config file: `~/.pi/agent/read-delegator.json`
103
+
104
+ | Field | Default | Description |
105
+ |-------|---------|-------------|
106
+ | `enabled` | `true` | Enable/disable read delegation |
107
+ | `blocked_tools` | `["read","grep","find","ls"]` | Tools blocked from main model |
108
+ | `reader_subagent_name` | `"reader"` | Subagent name (must match `reader.md`) |
109
+ | `reader_model` | `"lmstudio/nvidia/nemotron-3-nano-4b"` | Model for the Reader (`provider/model`) |
110
+ | `orchestrator_prompt` | *(system prompt)* | Injected into main model's system prompt |
111
+ | `language` | `"auto"` | UI language: `"auto"`, `"en"`, `"tr"` |
112
+
113
+ The subagent template lives at `~/.pi/agent/agents/reader.md` and is auto-managed on every config change.
39
114
 
40
115
  ## Commands
41
116
 
42
- | Command | Description |
43
- |---|---|
44
- | `/read-delegator on` | Enable read delegation |
45
- | `/read-delegator off` | Disable read delegation |
46
- | `/read-delegator status` | Show current status |
117
+ | Command | Action |
118
+ |---------|--------|
119
+ | `/read-delegator` | Show current status |
120
+ | `/read-delegator-status` | Show current status |
121
+ | `/read-delegator-on` | Enable read delegation (blocks read tools) |
122
+ | `/read-delegator-off` | Disable read delegation (restores all tools) |
123
+ | `/read-delegator-model` | Interactive model picker |
124
+ | `/read-delegator-model lmstudio/mistral` | Set a specific model directly |
47
125
 
48
- ## Configuration
126
+ ## Blocked commands
49
127
 
50
- Edit `~/.pi/agent/read-delegator.json`:
51
-
52
- ```json
53
- {
54
- "enabled": true,
55
- "reader_subagent_name": "reader",
56
- "blocked_tools": ["read", "grep", "find", "ls"],
57
- "allowed_bash_write_commands": ["mkdir", "echo", "touch", "sed", "rm", "mv", "cp"],
58
- "orchestrator_prompt": "You are an orchestrator. For any file reading... use the subagent tool...",
59
- "language": "auto"
60
- }
61
- ```
128
+ The extension intercepts read-like shell commands across **three shells** and redirects them to the Reader subagent:
62
129
 
63
- | Field | Description |
64
- |---|---|
65
- | `enabled` | Enable/disable the extension |
66
- | `reader_subagent_name` | Name of the Reader subagent (must match `reader.md`) |
67
- | `blocked_tools` | Tools to block from the main model |
68
- | `language` | `"auto"`, `"tr"`, or `"en"` |
130
+ ### bash / sh (Linux, macOS, WSL, Git Bash)
131
+ `cat`, `grep`, `find`, `ls`, `head`, `tail`, `less`, `wc`, `nl`, `more`, `bat`, `rg`, `fd`, `awk`, `du`, `df`, `stat`, `file`, `which`, `where`, `type`, `dir`, `sort`, `uniq`, `cut`, `tr`, `diff`, `cmp`, `comm`, `od`, `hexdump`, `xxd`
69
132
 
70
- ## Reader Subagent
133
+ ### PowerShell (Windows)
134
+ `Get-Content`, `Select-String`, `Get-ChildItem`, `Get-ItemProperty`, `Get-Item`, `Test-Path`, `Get-Alias`, `Get-Command`, `Measure-Object`, `Compare-Object`, `Where-Object`, `Select-Object`, `Format-List`, `Format-Table`
71
135
 
72
- The Reader template is created at `~/.pi/agent/agents/reader.md` on first run. Edit the `model:` line to use your preferred provider:
136
+ ### cmd.exe (Windows)
137
+ `type`, `findstr`, `find`, `dir`, `more`, `comp`, `fc`, `tree`
73
138
 
74
- ```yaml
75
- model: lmstudio/nemotron-mini # LM Studio
76
- # model: ollama/phi3 # Ollama
77
- # model: openai/gpt-4o-mini # OpenAI
78
- # model: anthropic/claude-haiku # Anthropic
79
- ```
139
+ > **Pipe and chain detection**: `echo hello && cat file | grep x` — each segment is inspected independently. A single read command in any segment blocks the entire chain.
140
+
141
+ ## Picking a Reader model
142
+
143
+ > **Critical requirement:** The Reader model **MUST support tool usage** (function calling).
144
+ > It uses `read`, `grep`, `find`, and `ls` via Pi's tool system to fulfill tasks.
145
+ > Models without tool-use capability **will not work** as a Reader.
146
+
147
+ A small, local model is ideal — the Reader executes precise file operations and returns structured results:
80
148
 
81
- ## Error Handling
149
+ | Provider | Recommended models |
150
+ |----------|-------------------|
151
+ | **LM Studio** | `lmstudio/nemotron-mini`, `lmstudio/qwen2.5-7b-instruct` |
152
+ | **Ollama** | `ollama/qwen2.5:7b`, `ollama/llama3.2:3b` |
153
+ | **llama.cpp** | Any model with tool-use support |
154
+ | **OpenAI** | `openai/gpt-4o-mini` |
155
+ | **Anthropic** | `anthropic/claude-3.5-haiku` |
156
+ | **Gemini** | `gemini/gemini-2.0-flash` |
82
157
 
83
- When the Reader fails:
158
+ ## Troubleshooting
84
159
 
85
- - **[R]etry** resend the same task to Reader
86
- - **[A]llow once** — temporarily unblock tools for one operation
87
- - **[C]ancel** report the failure
160
+ | Problem | Fix |
161
+ |---------|-----|
162
+ | "pi-subagents not installed" | Restart Pi; the extension auto-installs it on session start |
163
+ | Reader doesn't respond | Check `reader_model` in config; ensure the model supports tool usage |
164
+ | Reader returns incomplete data | The Reader returns minimal, structured output; check reader.md template |
165
+ | Tools not blocked | Run `/read-delegator on` |
166
+ | PowerShell commands bypass filter | Update to latest version; all three shells are covered |
167
+ | Model picker doesn't appear | Check `ctx.modelRegistry` is available in your Pi version |
88
168
 
89
- ## Bash Filter
169
+ ## Project token breakdown
90
170
 
91
- | Read commands Reader | Write commands Direct |
92
- |---|---|
93
- | `cat`, `grep`, `find`, `ls` | `mkdir`, `touch`, `rm`, `mv` |
94
- | `head`, `tail`, `less`, `wc` | `cp`, `chmod`, `chown` |
95
- | `bat`, `rg`, `fd`, `awk` | `npm`, `git`, `docker` |
96
- | `sed` (without `-i`) | `sed -i` (in-place edit) |
171
+ > Measured 2026-06-14. Token estimates use ~3.5 chars/token (code-heavy ratio).
97
172
 
98
- ## Supported Languages
173
+ | File type | Count | Size | Est. tokens |
174
+ |-----------|:-----:|------|:-----------:|
175
+ | TypeScript (`.ts`) | 6 | 66 KB | ~19,300 |
176
+ | JavaScript (`.js`) | 6 | 55 KB | ~16,100 |
177
+ | JSON (`.json`) | 3 | 81 KB | ~23,600 |
178
+ | Source maps (`.map`) | 12 | 42 KB | ~12,200 |
179
+ | Markdown (`.md`) | 3 | 12 KB | ~3,400 |
180
+ | **Total** | **36** | **255 KB** | **~74,700** |
181
+ | **Source only** (`.ts` + `.md`) | **9** | **78 KB** | **~22,700** |
99
182
 
100
- - **English** (`en`)
101
- - **Turkish** (`tr`)
183
+ > Source maps and compiled `.js`/`.d.ts` in `dist/` are build artifacts.
184
+ `package-lock.json` accounts for ~78 KB of the JSON total.
102
185
 
103
- Language is auto-detected from Pi's settings or the OS locale.
186
+ ## Development
187
+
188
+ ```bash
189
+ git clone <repo>
190
+ cd pi-read-delegator
191
+ npm install
192
+ npm run build # compiles TypeScript to dist/
193
+ ```
194
+
195
+ ### Project structure
196
+
197
+ ```
198
+ pi-read-delegator/
199
+ ├── src/
200
+ │ ├── index.ts # Entry point — events, commands, tool blocking
201
+ │ ├── config.ts # Config load/save with defaults
202
+ │ ├── tool-blocker.ts # Tool removal/restoration
203
+ │ ├── bash-filter.ts # Cross-platform command classification
204
+ │ ├── reader-manager.ts # Subagent health, dependency install, async exec
205
+ │ ├── ui.ts # Localization (tr/en), status bar, log wrappers
206
+ │ └── templates/
207
+ │ └── reader.md # Default Reader subagent template
208
+ ├── dist/ # Compiled output (gitignored)
209
+ ├── package.json
210
+ ├── tsconfig.json
211
+ └── README.md
212
+ ```
104
213
 
105
214
  ## License
106
215
 
@@ -4,23 +4,33 @@
4
4
  * Classifies shell commands as read-only (delegate to Reader subagent),
5
5
  * write (execute directly), or ambiguous (prompt user).
6
6
  */
7
+ /**
8
+ * Split a command string by shell separators (&&, ||, ;, |, &) and return
9
+ * the list of segment strings. Respects quoting so separators inside quotes
10
+ * are not treated as actual shell separators.
11
+ */
12
+ export declare function splitShellSegments(command: string): string[];
7
13
  /**
8
14
  * Determine if a bash command is read-only and should be forwarded to Reader.
9
15
  *
10
- * Rules:
11
- * - If the first word is in READ_COMMANDS true
12
- * - sed without -i flag → true (read-only stream edit)
13
- * - sed with -i → false (in-place edit = write)
16
+ * Splits on shell separators (&&, ||, ;, |, &) and checks EACH segment.
17
+ * If ANY segment starts with a read command, the full command is blocked.
18
+ *
19
+ * Examples:
20
+ * isReadCommand("cat file") → true
21
+ * isReadCommand("echo hello && cat file") → true (cat in chain)
22
+ * isReadCommand("npm test") → false
23
+ * isReadCommand("grep x | head -5") → true (pipeline)
14
24
  */
15
25
  export declare function isReadCommand(command: string): boolean;
16
26
  /**
17
27
  * Determine if a bash command modifies the filesystem and should run directly.
18
28
  *
19
29
  * Rules:
20
- * - If the first word is in WRITE_COMMANDS → true
30
+ * - If any segment's first word is in WRITE_COMMANDS → true
21
31
  * - sed with -i flag → true (in-place edit)
22
32
  * - Command contains > or >> redirect → true (writes to file)
23
- * - Command contains tee without -a flag → true (writes to file)
33
+ * - Command contains tee → true (writes to file)
24
34
  */
25
35
  export declare function isWriteCommand(command: string): boolean;
26
36
  /**