@madgagarin/pi-agentrouter 1.3.0 β 1.4.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 +22 -12
- package/index.ts +52 -20
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -3,8 +3,13 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@madgagarin/pi-agentrouter)
|
|
4
4
|
[](LICENSE)
|
|
5
5
|
[](https://pi.dev)
|
|
6
|
+
**`pi-agentrouter`** seamlessly connects 4 powerful flagship AI coding models (**GPT-5.6 Sol**, **Claude Opus 4.8**, **Claude Opus 5**, and **DeepSeek V4F**) to your [Pi Coding Agent](https://pi.dev) using a single, unified API key from [AgentRouter](https://agentrouter.org).
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
### π‘ Why use this plugin?
|
|
9
|
+
* π **All 4 Top Models in One Place:** Instantly switch between GPT-5.6 Sol, Claude Opus 4.8, Claude Opus 5, and DeepSeek V4F without managing separate subscriptions or multiple API keys.
|
|
10
|
+
* π° **Save up to 80% on Tokens:** Smart prompt caching and session affinity drastically cut token usage and speed up responses.
|
|
11
|
+
* β‘ **Zero-Config Setup:** Installs in seconds β all models are automatically registered with native reasoning, tool calling, and thinking support.
|
|
12
|
+
* π‘οΈ **Built-in Stability:** Automatic cross-process pacing and authentication guards eliminate 401 and 429 errors during long coding sessions and multi-agent tasks.
|
|
8
13
|
|
|
9
14
|
---
|
|
10
15
|
|
|
@@ -12,7 +17,7 @@ A native, zero-config extension for the [Pi Coding Agent](https://pi.dev) that c
|
|
|
12
17
|
|
|
13
18
|
AgentRouter is a non-profit AI API gateway providing unified access to cutting-edge models:
|
|
14
19
|
|
|
15
|
-
* **Increased Trial Credits:** By signing up through the referral link below, you unlock **increased trial credits (up to $175 / extra +$50 bonus)** to explore GPT-5.6 Sol
|
|
20
|
+
* **Increased Trial Credits:** By signing up through the referral link below, you unlock **increased trial credits (up to $175 / extra +$50 bonus)** to explore GPT-5.6 Sol, Claude Opus, and DeepSeek models.
|
|
16
21
|
* **Support the Author:** Using this link directly supports the author and the ongoing maintenance of this open-source plugin!
|
|
17
22
|
|
|
18
23
|
π **[Sign up on AgentRouter (Referral Link with Bonus)](https://agentrouter.org/register?aff=34dc)** π
|
|
@@ -23,15 +28,18 @@ AgentRouter is a non-profit AI API gateway providing unified access to cutting-e
|
|
|
23
28
|
|
|
24
29
|
## β¨ Features
|
|
25
30
|
|
|
26
|
-
- π **Unified API Key**: Use a single `sk-...` (or custom token) for all modelsβboth OpenAI GPT and Anthropic Claude endpoints are authenticated seamlessly.
|
|
31
|
+
- π **Unified API Key**: Use a single `sk-...` (or custom token) for all modelsβboth OpenAI GPT, DeepSeek, and Anthropic Claude endpoints are authenticated seamlessly.
|
|
27
32
|
- π **Zero-Config Model Auto-Registration**: Automatically registers:
|
|
28
33
|
- `agentrouter-openai/gpt-5.6-sol` (1M Context Window, Native Reasoning, Session Affinity).
|
|
29
|
-
- `agentrouter-
|
|
30
|
-
- `agentrouter-clode/claude-opus-
|
|
31
|
-
-
|
|
32
|
-
- π‘οΈ **
|
|
34
|
+
- `agentrouter-openai/deepseek-v4f` (128K Context Window, Reasoning Support, Session Affinity).
|
|
35
|
+
- `agentrouter-clode/claude-opus-4-8` (512K Context Window, Adaptive Thinking, Empty Signature Compat).
|
|
36
|
+
- `agentrouter-clode/claude-opus-5` (1M Context Window, Adaptive Thinking, Empty Signature Compat).
|
|
37
|
+
- π‘οΈ **Cross-Process Request Pacing**: Shared file-based rate limiter (`~/.pi/agent/.agentrouter-pacing`) synchronizing delays across concurrent subagents, background workers, and the main Pi process to prevent WAF burst blocks.
|
|
38
|
+
- π **Transport-Level Root Prompt Guard**: Enforces canonical `pi-code` harness header at `index: 0` on every outbound request (`before_provider_request`), preventing 401 unauthorized client errors across multi-turn tool executions.
|
|
39
|
+
- β‘ **Optimized Prompt Caching & Dynamic Bypass**: Automatically disables aggressive prompt rewriting on AgentRouter routes (`PI_CACHE_OPTIMIZER_NO_PROMPT_REWRITE=1`) while preserving session affinity headers, achieving **>80% cache hit rates** on consecutive turns.
|
|
40
|
+
- π **Package Priority Guard & Auto-Fix**: Automatically checks package order in `settings.json` on startup and offers interactive one-click placement directly above `pi-cache-optimizer`.
|
|
33
41
|
- π¦ **Seamless Compaction (Fixes 401)**: Solves the `401 unauthorized client` error during `/compact` by ensuring valid Pi client fingerprint headers are passed during summarization.
|
|
34
|
-
- β¨οΈ **Interactive Terminal Controls**: Change API keys, adjust throttle pacing, and cycle through models or thinking depths directly in the TUI.
|
|
42
|
+
- β¨οΈ **Interactive Terminal Controls**: Change API keys, adjust throttle pacing, fix package priority, and cycle through models or thinking depths directly in the TUI.
|
|
35
43
|
|
|
36
44
|
---
|
|
37
45
|
|
|
@@ -83,6 +91,7 @@ To enable quick model cycling with `Ctrl+P` and set default thinking levels, add
|
|
|
83
91
|
"defaultThinkingLevel": "medium",
|
|
84
92
|
"enabledModels": [
|
|
85
93
|
"agentrouter-openai/gpt-5.6-sol",
|
|
94
|
+
"agentrouter-openai/deepseek-v4f",
|
|
86
95
|
"agentrouter-clode/claude-opus-4-8",
|
|
87
96
|
"agentrouter-clode/claude-opus-5"
|
|
88
97
|
]
|
|
@@ -95,7 +104,7 @@ To enable quick model cycling with `Ctrl+P` and set default thinking levels, add
|
|
|
95
104
|
|
|
96
105
|
| Shortcut | Action | Description |
|
|
97
106
|
| :--- | :--- | :--- |
|
|
98
|
-
| `Ctrl + P` | π **Next Model** | Cycles to the next model (`gpt-5.6-sol` β `claude-opus-4-8` β `claude-opus-5`). |
|
|
107
|
+
| `Ctrl + P` | π **Next Model** | Cycles to the next model (`gpt-5.6-sol` β `deepseek-v4f` β `claude-opus-4-8` β `claude-opus-5`). |
|
|
99
108
|
| `Shift + Ctrl + P` | π **Previous Model** | Cycles to the previous model. |
|
|
100
109
|
| `Shift + Tab` | π§ **Cycle Thinking Level** | Toggles reasoning depth: `off` β `minimal` β `low` β `medium` β `high`. |
|
|
101
110
|
| `Ctrl + T` | π **Toggle Thinking Visibility** | Collapses or expands thinking/reasoning blocks on screen. |
|
|
@@ -105,9 +114,10 @@ To enable quick model cycling with `Ctrl+P` and set default thinking levels, add
|
|
|
105
114
|
|
|
106
115
|
## π οΈ In-Chat Commands
|
|
107
116
|
|
|
108
|
-
* `/agentrouter` β View current plugin status, active model, masked key, and pacing interval.
|
|
117
|
+
* `/agentrouter` β View current plugin status, active model, priority position, masked key, and pacing interval.
|
|
109
118
|
* `/agentrouter key <your-key>` β Update API key for all AgentRouter models on the fly.
|
|
110
|
-
* `/agentrouter pacing <ms>` β Adjust the minimum delay between consecutive requests (default: `
|
|
119
|
+
* `/agentrouter pacing <ms>` β Adjust the minimum delay between consecutive requests (default: `3500` ms).
|
|
120
|
+
* `/agentrouter fix-order` β Automatically reorder `settings.json` packages to place this plugin directly before `pi-cache-optimizer`.
|
|
111
121
|
* `/compact` β Compress conversation history safely without 401 authorization errors.
|
|
112
122
|
|
|
113
123
|
---
|
|
@@ -117,7 +127,7 @@ To enable quick model cycling with `Ctrl+P` and set default thinking levels, add
|
|
|
117
127
|
#### Q: Why does `/compact` fail on raw proxy configurations?
|
|
118
128
|
AgentRouter performs client fingerprint verification. Raw summarization requests without Pi's standard prompt signatures get rejected with `401 unauthorized client`. This plugin intercepts the `session_before_compact` event and automatically injects proper authentication signatures.
|
|
119
129
|
|
|
120
|
-
#### Q: Does the
|
|
130
|
+
#### Q: Does the 3.5s pacing delay affect local or other cloud models?
|
|
121
131
|
No. The pacing logic specifically filters for AgentRouter endpoints (`isAgentRouter`). Native OpenAI, Anthropic, Gemini, or local models run at full speed without delay.
|
|
122
132
|
|
|
123
133
|
#### Q: How to use custom subagents with AgentRouter?
|
package/index.ts
CHANGED
|
@@ -89,7 +89,7 @@ export function fixPackagePriorityInSettings(): boolean {
|
|
|
89
89
|
|
|
90
90
|
const initialConfig = loadConfig();
|
|
91
91
|
let currentApiKey = normalizeApiKey(process.env.AGENTROUTER_API_KEY || initialConfig.apiKey || "");
|
|
92
|
-
let minIntervalMs = initialConfig.minIntervalMs ??
|
|
92
|
+
let minIntervalMs = initialConfig.minIntervalMs ?? 3500;
|
|
93
93
|
const PACING_FILE = path.join(process.env.HOME || "", ".pi/agent/.agentrouter-pacing");
|
|
94
94
|
|
|
95
95
|
export function getLastRequestEndTime(): number {
|
|
@@ -188,6 +188,18 @@ export default function (pi: ExtensionAPI) {
|
|
|
188
188
|
sendSessionAffinityHeaders: true,
|
|
189
189
|
},
|
|
190
190
|
},
|
|
191
|
+
{
|
|
192
|
+
id: "deepseek-v4f",
|
|
193
|
+
name: "deepseek-v4f",
|
|
194
|
+
reasoning: true,
|
|
195
|
+
input: ["text"],
|
|
196
|
+
contextWindow: 131072,
|
|
197
|
+
maxTokens: 65536,
|
|
198
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
199
|
+
compat: {
|
|
200
|
+
sendSessionAffinityHeaders: true,
|
|
201
|
+
},
|
|
202
|
+
},
|
|
191
203
|
],
|
|
192
204
|
});
|
|
193
205
|
|
|
@@ -196,10 +208,11 @@ export default function (pi: ExtensionAPI) {
|
|
|
196
208
|
baseUrl: "https://agentrouter.org",
|
|
197
209
|
apiKey,
|
|
198
210
|
api: "anthropic-messages",
|
|
199
|
-
|
|
200
211
|
compat: {
|
|
201
212
|
forceAdaptiveThinking: true,
|
|
213
|
+
allowEmptySignature: true,
|
|
202
214
|
sendSessionAffinityHeaders: true,
|
|
215
|
+
supportsEagerToolInputStreaming: false,
|
|
203
216
|
},
|
|
204
217
|
models: [
|
|
205
218
|
{
|
|
@@ -212,7 +225,9 @@ export default function (pi: ExtensionAPI) {
|
|
|
212
225
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
213
226
|
compat: {
|
|
214
227
|
forceAdaptiveThinking: true,
|
|
228
|
+
allowEmptySignature: true,
|
|
215
229
|
sendSessionAffinityHeaders: true,
|
|
230
|
+
supportsEagerToolInputStreaming: false,
|
|
216
231
|
},
|
|
217
232
|
},
|
|
218
233
|
{
|
|
@@ -225,7 +240,9 @@ export default function (pi: ExtensionAPI) {
|
|
|
225
240
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
226
241
|
compat: {
|
|
227
242
|
forceAdaptiveThinking: true,
|
|
243
|
+
allowEmptySignature: true,
|
|
228
244
|
sendSessionAffinityHeaders: true,
|
|
245
|
+
supportsEagerToolInputStreaming: false,
|
|
229
246
|
},
|
|
230
247
|
},
|
|
231
248
|
],
|
|
@@ -242,20 +259,27 @@ export default function (pi: ExtensionAPI) {
|
|
|
242
259
|
}
|
|
243
260
|
}
|
|
244
261
|
|
|
245
|
-
|
|
262
|
+
// Inter-request pacing to respect AgentRouter WAF rate limits and enforce canonical root prompt
|
|
246
263
|
pi.on("before_provider_request", async (event, ctx) => {
|
|
247
264
|
const provider = ((event as any)?.model?.provider || ctx?.model?.provider || "").toLowerCase();
|
|
248
265
|
const baseUrl = ((event as any)?.model?.baseUrl || (ctx?.model as any)?.baseUrl || "");
|
|
249
266
|
|
|
250
267
|
if (isAgentRouter(provider, baseUrl)) {
|
|
268
|
+
// 1. Cross-process request pacing
|
|
269
|
+
const lastEnd = getLastRequestEndTime();
|
|
270
|
+
const now = Date.now();
|
|
271
|
+
const elapsed = now - lastEnd;
|
|
272
|
+
if (lastEnd > 0 && elapsed < minIntervalMs) {
|
|
273
|
+
const waitMs = minIntervalMs - elapsed;
|
|
274
|
+
await new Promise((resolve) => setTimeout(resolve, waitMs));
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// 2. Enforce canonical root system prompt in payload (Anthropic & OpenAI formats)
|
|
251
278
|
const payload = event.payload;
|
|
252
279
|
if (payload) {
|
|
253
|
-
// 1. Enforce canonical root system prompt in payload.system (Anthropic format)
|
|
254
280
|
if (payload.system !== undefined) {
|
|
255
281
|
payload.system = enforceCanonicalRootPrompt(payload.system);
|
|
256
282
|
}
|
|
257
|
-
|
|
258
|
-
// 2. Enforce canonical root system prompt in payload.messages[0] (OpenAI format)
|
|
259
283
|
if (Array.isArray(payload.messages) && payload.messages.length > 0) {
|
|
260
284
|
const firstMsg = payload.messages[0];
|
|
261
285
|
if (firstMsg && firstMsg.role === "system") {
|
|
@@ -268,6 +292,28 @@ export default function (pi: ExtensionAPI) {
|
|
|
268
292
|
}
|
|
269
293
|
}
|
|
270
294
|
}
|
|
295
|
+
return undefined;
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
pi.on("message_end", async (_event, ctx) => {
|
|
299
|
+
const model = ctx?.model;
|
|
300
|
+
if (isAgentRouter(model?.provider, (model as any)?.baseUrl)) {
|
|
301
|
+
setLastRequestEndTime(Date.now());
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
pi.on("turn_end", async (_event, ctx) => {
|
|
306
|
+
const model = ctx?.model;
|
|
307
|
+
if (isAgentRouter(model?.provider, (model as any)?.baseUrl)) {
|
|
308
|
+
setLastRequestEndTime(Date.now());
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
pi.on("agent_end", async (_event, ctx) => {
|
|
313
|
+
const model = ctx?.model;
|
|
314
|
+
if (isAgentRouter(model?.provider, (model as any)?.baseUrl)) {
|
|
315
|
+
setLastRequestEndTime(Date.now());
|
|
316
|
+
}
|
|
271
317
|
});
|
|
272
318
|
|
|
273
319
|
pi.on("session_start", async (_event, ctx) => {
|
|
@@ -318,20 +364,6 @@ export default function (pi: ExtensionAPI) {
|
|
|
318
364
|
}
|
|
319
365
|
});
|
|
320
366
|
|
|
321
|
-
pi.on("turn_end", async (_event, ctx) => {
|
|
322
|
-
const model = ctx.model;
|
|
323
|
-
if (isAgentRouter(model?.provider, (model as any)?.baseUrl)) {
|
|
324
|
-
setLastRequestEndTime(Date.now());
|
|
325
|
-
}
|
|
326
|
-
});
|
|
327
|
-
|
|
328
|
-
pi.on("agent_end", async (_event, ctx) => {
|
|
329
|
-
const model = ctx.model;
|
|
330
|
-
if (isAgentRouter(model?.provider, (model as any)?.baseUrl)) {
|
|
331
|
-
setLastRequestEndTime(Date.now());
|
|
332
|
-
}
|
|
333
|
-
});
|
|
334
|
-
|
|
335
367
|
pi.on("session_before_compact", async (event, ctx) => {
|
|
336
368
|
const model = ctx.model;
|
|
337
369
|
if (!model || !isAgentRouter(model.provider, (model as any).baseUrl)) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@madgagarin/pi-agentrouter",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Pi coding agent extension for AgentRouter (GPT-5.6 Sol
|
|
3
|
+
"version": "1.4.0",
|
|
4
|
+
"description": "Pi coding agent extension for AgentRouter (GPT-5.6 Sol, Claude Opus 5, DeepSeek V4F) with rate-limit pacing, prompt caching, and WAF protection.",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
"gpt-5.6-sol",
|
|
18
18
|
"claude-opus-5",
|
|
19
19
|
"claude-opus-4-8",
|
|
20
|
+
"deepseek-v4f",
|
|
21
|
+
"deepseek",
|
|
20
22
|
"prompt-caching",
|
|
21
23
|
"openai",
|
|
22
24
|
"claude",
|