@madgagarin/pi-agentrouter 1.2.0 → 1.2.1
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 +3 -0
- package/index.ts +40 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -120,6 +120,9 @@ AgentRouter performs client fingerprint verification. Raw summarization requests
|
|
|
120
120
|
#### Q: Does the 2.5s pacing delay affect local or other cloud models?
|
|
121
121
|
No. The pacing logic specifically filters for AgentRouter endpoints (`isAgentRouter`). Native OpenAI, Anthropic, Gemini, or local models run at full speed without delay.
|
|
122
122
|
|
|
123
|
+
#### Q: How to use custom subagents with AgentRouter?
|
|
124
|
+
AgentRouter strictly verifies client authenticity (`pi-code` / `claude-code` prompt signature). If you define custom subagents in extensions like `pi-subagents`, make sure to specify `systemPromptMode: append` in your agent definition frontmatter so the base Pi system prompt identity is preserved.
|
|
125
|
+
|
|
123
126
|
---
|
|
124
127
|
|
|
125
128
|
## 📄 License
|
package/index.ts
CHANGED
|
@@ -90,7 +90,27 @@ export function fixPackagePriorityInSettings(): boolean {
|
|
|
90
90
|
const initialConfig = loadConfig();
|
|
91
91
|
let currentApiKey = normalizeApiKey(process.env.AGENTROUTER_API_KEY || initialConfig.apiKey || "");
|
|
92
92
|
let minIntervalMs = initialConfig.minIntervalMs ?? 2500;
|
|
93
|
-
|
|
93
|
+
const PACING_FILE = path.join(process.env.HOME || "", ".pi/agent/.agentrouter-pacing");
|
|
94
|
+
|
|
95
|
+
export function getLastRequestEndTime(): number {
|
|
96
|
+
try {
|
|
97
|
+
if (fs.existsSync(PACING_FILE)) {
|
|
98
|
+
const val = parseInt(fs.readFileSync(PACING_FILE, "utf-8").trim(), 10);
|
|
99
|
+
if (!isNaN(val)) return val;
|
|
100
|
+
}
|
|
101
|
+
} catch {}
|
|
102
|
+
return 0;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function setLastRequestEndTime(ts: number): void {
|
|
106
|
+
try {
|
|
107
|
+
const dir = path.dirname(PACING_FILE);
|
|
108
|
+
if (!fs.existsSync(dir)) {
|
|
109
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
110
|
+
}
|
|
111
|
+
fs.writeFileSync(PACING_FILE, String(ts), "utf-8");
|
|
112
|
+
} catch {}
|
|
113
|
+
}
|
|
94
114
|
|
|
95
115
|
export function isAgentRouter(providerName?: string, baseUrl?: string): boolean {
|
|
96
116
|
if (providerName && providerName.toLowerCase().includes("agentrouter")) return true;
|
|
@@ -129,8 +149,18 @@ export default function (pi: ExtensionAPI) {
|
|
|
129
149
|
baseUrl: "https://agentrouter.org",
|
|
130
150
|
apiKey,
|
|
131
151
|
api: "anthropic-messages",
|
|
152
|
+
headers: {
|
|
153
|
+
"User-Agent": "claude-cli/1.0.108 (external, cli)",
|
|
154
|
+
"anthropic-beta": "claude-code-20250219,interleaved-thinking-2025-05-14,context-management-2025-06-27",
|
|
155
|
+
"x-stainless-lang": "js",
|
|
156
|
+
"x-stainless-package-version": "0.38.0",
|
|
157
|
+
"x-stainless-os": "Linux",
|
|
158
|
+
"x-stainless-arch": "x64",
|
|
159
|
+
"x-stainless-runtime": "node"
|
|
160
|
+
},
|
|
132
161
|
compat: {
|
|
133
162
|
forceAdaptiveThinking: true,
|
|
163
|
+
sendSessionAffinityHeaders: true,
|
|
134
164
|
},
|
|
135
165
|
models: [
|
|
136
166
|
{
|
|
@@ -143,6 +173,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
143
173
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
144
174
|
compat: {
|
|
145
175
|
forceAdaptiveThinking: true,
|
|
176
|
+
sendSessionAffinityHeaders: true,
|
|
146
177
|
},
|
|
147
178
|
},
|
|
148
179
|
{
|
|
@@ -155,6 +186,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
155
186
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
156
187
|
compat: {
|
|
157
188
|
forceAdaptiveThinking: true,
|
|
189
|
+
sendSessionAffinityHeaders: true,
|
|
158
190
|
},
|
|
159
191
|
},
|
|
160
192
|
],
|
|
@@ -173,7 +205,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
173
205
|
|
|
174
206
|
pi.on("session_start", async (_event, ctx) => {
|
|
175
207
|
updatePromptRewriteEnvForModel(ctx.model);
|
|
176
|
-
|
|
208
|
+
setLastRequestEndTime(Date.now());
|
|
177
209
|
|
|
178
210
|
const order = getPackageOrderState();
|
|
179
211
|
if (order.needsFix && ctx.hasUI && typeof (ctx.ui as any).confirm === "function") {
|
|
@@ -209,10 +241,11 @@ export default function (pi: ExtensionAPI) {
|
|
|
209
241
|
return;
|
|
210
242
|
}
|
|
211
243
|
|
|
244
|
+
const lastEnd = getLastRequestEndTime();
|
|
212
245
|
const now = Date.now();
|
|
213
|
-
const elapsed = now -
|
|
246
|
+
const elapsed = now - lastEnd;
|
|
214
247
|
|
|
215
|
-
if (
|
|
248
|
+
if (lastEnd > 0 && elapsed < minIntervalMs) {
|
|
216
249
|
const waitMs = minIntervalMs - elapsed;
|
|
217
250
|
await new Promise((resolve) => setTimeout(resolve, waitMs));
|
|
218
251
|
}
|
|
@@ -221,14 +254,14 @@ export default function (pi: ExtensionAPI) {
|
|
|
221
254
|
pi.on("turn_end", async (_event, ctx) => {
|
|
222
255
|
const model = ctx.model;
|
|
223
256
|
if (isAgentRouter(model?.provider, (model as any)?.baseUrl)) {
|
|
224
|
-
|
|
257
|
+
setLastRequestEndTime(Date.now());
|
|
225
258
|
}
|
|
226
259
|
});
|
|
227
260
|
|
|
228
261
|
pi.on("agent_end", async (_event, ctx) => {
|
|
229
262
|
const model = ctx.model;
|
|
230
263
|
if (isAgentRouter(model?.provider, (model as any)?.baseUrl)) {
|
|
231
|
-
|
|
264
|
+
setLastRequestEndTime(Date.now());
|
|
232
265
|
}
|
|
233
266
|
});
|
|
234
267
|
|
|
@@ -276,6 +309,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
276
309
|
signal,
|
|
277
310
|
}
|
|
278
311
|
);
|
|
312
|
+
setLastRequestEndTime(Date.now());
|
|
279
313
|
|
|
280
314
|
const summary = response.content
|
|
281
315
|
.filter((c: any): c is { type: "text"; text: string } => c.type === "text")
|
package/package.json
CHANGED