@diegopetrucci/pi-extensions 0.1.71 → 0.1.73
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 +2 -2
- package/extensions/agent-workflow-audit/index.ts +41 -8
- package/extensions/agent-workflow-audit/package.json +1 -1
- package/extensions/annotate-git-diff/README.md +7 -3
- package/extensions/annotate-git-diff/git.ts +3 -2
- package/extensions/annotate-git-diff/index.ts +366 -81
- package/extensions/annotate-git-diff/package.json +2 -2
- package/extensions/annotate-git-diff/quiet-glimpse.ts +4 -2
- package/extensions/annotate-git-diff/types.ts +6 -0
- package/extensions/annotate-git-diff/web/app.js +54 -4
- package/extensions/annotate-git-diff/web/index.html +2 -2
- package/extensions/annotate-last-message/README.md +9 -1
- package/extensions/annotate-last-message/index.ts +53 -13
- package/extensions/annotate-last-message/package.json +2 -1
- package/extensions/annotate-last-message/quiet-glimpse.ts +4 -2
- package/extensions/annotate-last-message/theme.ts +247 -0
- package/extensions/annotate-last-message/ui.ts +28 -2
- package/extensions/annotate-last-message/web/app.js +351 -162
- package/extensions/annotate-last-message/web/index.html +153 -24
- package/extensions/annotate-last-message/web/md-renderer.js +458 -0
- package/extensions/code-reviewer/index.ts +12 -1
- package/extensions/code-reviewer/package.json +2 -1
- package/extensions/context-cap/README.md +33 -4
- package/extensions/context-cap/index.ts +271 -68
- package/extensions/context-cap/package.json +1 -1
- package/extensions/context-inspector/README.md +2 -0
- package/extensions/context-inspector/index.ts +90 -9
- package/extensions/context-inspector/package.json +1 -1
- package/extensions/contrarian/index.ts +21 -15
- package/extensions/contrarian/package.json +1 -1
- package/extensions/dynamic-context-pruning/README.md +17 -5
- package/extensions/dynamic-context-pruning/index.ts +17 -4
- package/extensions/dynamic-context-pruning/package.json +1 -1
- package/extensions/fast/README.md +25 -4
- package/extensions/fast/index.ts +4 -4
- package/extensions/fast/package.json +1 -1
- package/extensions/git-footer/README.md +1 -0
- package/extensions/git-footer/package.json +1 -1
- package/extensions/librarian/index.ts +7 -0
- package/extensions/librarian/package.json +2 -1
- package/extensions/minimal-footer/README.md +16 -4
- package/extensions/minimal-footer/index.ts +263 -14
- package/extensions/minimal-footer/openai-usage.ts +62 -8
- package/extensions/minimal-footer/package.json +1 -1
- package/extensions/oracle/index.ts +19 -18
- package/extensions/oracle/package.json +1 -1
- package/extensions/permission-gate/README.md +6 -0
- package/extensions/permission-gate/index.ts +37 -16
- package/extensions/permission-gate/package.json +1 -1
- package/extensions/quiet-tools/README.md +1 -1
- package/extensions/quiet-tools/package.json +1 -1
- package/extensions/triage-comments/package.json +2 -1
- package/package.json +4 -4
|
@@ -111,6 +111,11 @@ const CONTRARIAN_MODEL_PREFERENCES = [
|
|
|
111
111
|
"openai.gpt-6-astra ",
|
|
112
112
|
"gpt-6-astra ",
|
|
113
113
|
"gpt-6-astra",
|
|
114
|
+
"openai/gpt-6.1-sol ",
|
|
115
|
+
"global.openai.gpt-6.1-sol ",
|
|
116
|
+
"us.openai.gpt-6.1-sol ",
|
|
117
|
+
"openai.gpt-6.1-sol ",
|
|
118
|
+
"gpt-6.1-sol ",
|
|
114
119
|
"openai/gpt-6-sol ",
|
|
115
120
|
"gpt-6-sol ",
|
|
116
121
|
"gpt-6-sol",
|
|
@@ -171,6 +176,9 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
171
176
|
"us.openai.gpt-6-astra ",
|
|
172
177
|
"openai.gpt-6-astra ",
|
|
173
178
|
"gpt-6-astra",
|
|
179
|
+
"global.openai.gpt-6.1-sol ",
|
|
180
|
+
"us.openai.gpt-6.1-sol ",
|
|
181
|
+
"openai.gpt-6.1-sol ",
|
|
174
182
|
"openai.gpt-5.6-sol",
|
|
175
183
|
"openai.gpt-5.6-terra",
|
|
176
184
|
"openai.gpt-5.6-luna",
|
|
@@ -202,6 +210,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
202
210
|
"azure-openai-responses": [
|
|
203
211
|
"gpt-6-astra ",
|
|
204
212
|
"gpt-6-astra",
|
|
213
|
+
"gpt-6.1-sol ",
|
|
205
214
|
"gpt-6-sol ",
|
|
206
215
|
"gpt-6-sol",
|
|
207
216
|
"gpt-5.6-sol",
|
|
@@ -281,13 +290,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
281
290
|
fireworks: [
|
|
282
291
|
"accounts/fireworks/models/kimi-k3",
|
|
283
292
|
"accounts/fireworks/routers/kimi-k3-fast",
|
|
284
|
-
"accounts/fireworks/models/deepseek-v4-pro",
|
|
285
|
-
"accounts/fireworks/models/kimi-k2p7-code",
|
|
286
|
-
"accounts/fireworks/models/glm-5p2",
|
|
287
|
-
"accounts/fireworks/routers/glm-5p2-fast",
|
|
288
293
|
"accounts/fireworks/models/minimax-m3",
|
|
289
|
-
"accounts/fireworks/models/kimi-k2p6",
|
|
290
|
-
"accounts/fireworks/models/qwen3p7-plus",
|
|
291
294
|
"accounts/fireworks/models/gpt-oss-120b",
|
|
292
295
|
],
|
|
293
296
|
"github-copilot": [
|
|
@@ -299,6 +302,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
299
302
|
"claude-opus-4.7",
|
|
300
303
|
"gpt-6-astra ",
|
|
301
304
|
"gpt-6-astra",
|
|
305
|
+
"gpt-6.1-sol ",
|
|
302
306
|
"gpt-6-sol ",
|
|
303
307
|
"gpt-6-sol",
|
|
304
308
|
"gpt-5.6-sol",
|
|
@@ -386,6 +390,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
386
390
|
openai: [
|
|
387
391
|
"gpt-6-astra ",
|
|
388
392
|
"gpt-6-astra",
|
|
393
|
+
"gpt-6.1-sol ",
|
|
389
394
|
"gpt-6-sol ",
|
|
390
395
|
"gpt-6-sol",
|
|
391
396
|
"gpt-5.6-sol",
|
|
@@ -411,6 +416,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
411
416
|
"openai-codex": [
|
|
412
417
|
"gpt-6-astra ",
|
|
413
418
|
"gpt-6-astra",
|
|
419
|
+
"gpt-6.1-sol ",
|
|
414
420
|
"gpt-6-sol ",
|
|
415
421
|
"gpt-6-sol",
|
|
416
422
|
"gpt-5.6-sol",
|
|
@@ -428,6 +434,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
428
434
|
"claude-fable-5",
|
|
429
435
|
"gpt-6-astra ",
|
|
430
436
|
"gpt-6-astra",
|
|
437
|
+
"gpt-6.1-sol ",
|
|
431
438
|
"gpt-6-sol ",
|
|
432
439
|
"gpt-6-sol",
|
|
433
440
|
"gpt-5.6-sol",
|
|
@@ -466,17 +473,13 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
466
473
|
"deepseek-v4-pro",
|
|
467
474
|
"glm-5.3",
|
|
468
475
|
"glm-5.2",
|
|
469
|
-
"glm-5.1",
|
|
470
|
-
"qwen3.7-max",
|
|
471
476
|
"qwen3.7-plus",
|
|
472
|
-
"qwen3.6-plus",
|
|
473
477
|
"mimo-v2.5-pro",
|
|
474
478
|
"mimo-v2.5",
|
|
475
479
|
"minimax-m3",
|
|
476
480
|
"minimax-m2.7",
|
|
477
481
|
"kimi-k3",
|
|
478
482
|
"kimi-k2.7-code",
|
|
479
|
-
"kimi-k2.6",
|
|
480
483
|
"grok-4.7 ",
|
|
481
484
|
"grok-4.7",
|
|
482
485
|
"grok-4.6",
|
|
@@ -494,6 +497,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
494
497
|
"anthropic/claude-opus-4.1",
|
|
495
498
|
"openai/gpt-6-astra ",
|
|
496
499
|
"openai/gpt-6-astra",
|
|
500
|
+
"openai/gpt-6.1-sol ",
|
|
497
501
|
"openai/gpt-6-sol ",
|
|
498
502
|
"openai/gpt-6-sol",
|
|
499
503
|
"openai/gpt-5.6-sol-pro",
|
|
@@ -582,9 +586,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
582
586
|
"gpt-5.4",
|
|
583
587
|
"gpt-5.3-codex",
|
|
584
588
|
"kimi-k3",
|
|
585
|
-
"deepseek-v4-pro",
|
|
586
589
|
"glm-5.3",
|
|
587
|
-
"kimi-k2.7-code",
|
|
588
590
|
"deepseek-v4.1-flash",
|
|
589
591
|
"gpt-5.4-mini",
|
|
590
592
|
"glm-5.3-flash",
|
|
@@ -594,8 +596,6 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
594
596
|
"moonshotai/Kimi-K3",
|
|
595
597
|
"zai-org/GLM-5.3-Flash",
|
|
596
598
|
"zai-org/GLM-5.2",
|
|
597
|
-
"moonshotai/Kimi-K2.7-Code",
|
|
598
|
-
"moonshotai/Kimi-K2.6",
|
|
599
599
|
"Qwen/Qwen3.7-Max",
|
|
600
600
|
"Qwen/Qwen3.6-Plus",
|
|
601
601
|
"MiniMaxAI/MiniMax-M3",
|
|
@@ -605,6 +605,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
605
605
|
"nvidia/nemotron-3-ultra-550b-a55b",
|
|
606
606
|
"google/gemma-4-31B-it",
|
|
607
607
|
],
|
|
608
|
+
typesafe: [],
|
|
608
609
|
"vercel-ai-gateway": [
|
|
609
610
|
"anthropic/claude-opus-5.5 ",
|
|
610
611
|
"anthropic/claude-opus-5.5",
|
|
@@ -618,6 +619,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
618
619
|
"anthropic/claude-sonnet-4.6",
|
|
619
620
|
"openai/gpt-6-astra ",
|
|
620
621
|
"openai/gpt-6-astra",
|
|
622
|
+
"openai/gpt-6.1-sol ",
|
|
621
623
|
"openai/gpt-6-sol ",
|
|
622
624
|
"openai/gpt-6-sol",
|
|
623
625
|
"openai/gpt-5.6-sol",
|
|
@@ -1387,7 +1389,10 @@ async function runContrarian(
|
|
|
1387
1389
|
}
|
|
1388
1390
|
|
|
1389
1391
|
if (event.type === "message_start" && event.message?.role === "assistant") {
|
|
1392
|
+
// A later assistant turn supersedes any earlier tool/intermediate answer.
|
|
1393
|
+
// Keep only the current message so a tool-only final turn cannot return stale text.
|
|
1390
1394
|
currentText = "";
|
|
1395
|
+
finalOutput = "";
|
|
1391
1396
|
emit();
|
|
1392
1397
|
return;
|
|
1393
1398
|
}
|
|
@@ -1400,7 +1405,8 @@ async function runContrarian(
|
|
|
1400
1405
|
|
|
1401
1406
|
if (event.type === "message_end" && event.message?.role === "assistant") {
|
|
1402
1407
|
const text = extractTextFromContent(event.message.content) || currentText;
|
|
1403
|
-
|
|
1408
|
+
// message_end is authoritative, including an empty tool-only message.
|
|
1409
|
+
finalOutput = text;
|
|
1404
1410
|
currentText = "";
|
|
1405
1411
|
|
|
1406
1412
|
const stopReason = event.message.stopReason;
|
|
@@ -27,11 +27,23 @@ and why it hasn't been built yet.
|
|
|
27
27
|
key wins when replaying history, so a decision can be pruned, restored, and
|
|
28
28
|
re-pruned any number of times.
|
|
29
29
|
- **Recomputed every call, not on a timer.** All three automatic strategies run
|
|
30
|
-
fresh on every `context` event, over the current message array.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
fresh on every `context` event, over the current message array. Pi 0.99's
|
|
31
|
+
`context` hook intentionally receives the mutable conversation without system
|
|
32
|
+
messages; Pi restores its system prompt and tool state after the handler. The
|
|
33
|
+
extension does not try to rebuild that request-only envelope.
|
|
34
|
+
- **Canonical picker input.** `/prune` uses Pi's canonical session projection when
|
|
35
|
+
available, so context omissions and replacements, branch selection, and tool
|
|
36
|
+
pairing match the provider-visible conversation. Older hosts retain the raw
|
|
37
|
+
message-entry fallback.
|
|
38
|
+
- **Nested calls stay metadata.** Pi records bounded `nestedCalls` metadata on a
|
|
39
|
+
parent tool result, but nested results are not transcript messages. Strategies
|
|
40
|
+
count and prune only the parent transcript tool result; they never materialize
|
|
41
|
+
child entries, double-count child output, or infer complete history from a
|
|
42
|
+
truncated/incomplete record.
|
|
43
|
+
- **Persisted decisions remain branch-local.** Nothing is pruned "once and
|
|
44
|
+
forgotten"; if a tool result would no longer qualify (e.g. it's now within the
|
|
45
|
+
protected recency window), it isn't proposed again, but an already-applied,
|
|
46
|
+
persisted decision still applies until explicitly restored.
|
|
35
47
|
|
|
36
48
|
## Strategies
|
|
37
49
|
|
|
@@ -51,6 +51,8 @@ export interface MinimalToolResultMessage {
|
|
|
51
51
|
toolCallId: string;
|
|
52
52
|
toolName: string;
|
|
53
53
|
content: (MinimalTextContent | MinimalImageContent)[];
|
|
54
|
+
/** Bounded nested-call metadata; child calls have no transcript results to prune. */
|
|
55
|
+
nestedCalls?: unknown;
|
|
54
56
|
isError: boolean;
|
|
55
57
|
timestamp?: number;
|
|
56
58
|
[key: string]: unknown;
|
|
@@ -114,13 +116,16 @@ export function normalizeSessionProjection(value: unknown): MinimalSessionProjec
|
|
|
114
116
|
});
|
|
115
117
|
}
|
|
116
118
|
|
|
119
|
+
// Entries carry the provenance that Pi uses to apply omissions and
|
|
120
|
+
// replacements. Validate the optional flattened field for compatibility, but
|
|
121
|
+
// derive the messages used by pruning from entries so stale/invented records
|
|
122
|
+
// cannot bypass canonical context edits.
|
|
117
123
|
if ("messages" in value && (!Array.isArray(value.messages) || !value.messages.every(isMinimalMessage))) return undefined;
|
|
118
|
-
|
|
119
|
-
return { entries, messages };
|
|
124
|
+
return { entries, messages: entries.flatMap((entry) => entry.messages) };
|
|
120
125
|
}
|
|
121
126
|
|
|
122
127
|
export function sessionProjectionToMessages(projection: MinimalSessionProjection): MinimalMessage[] {
|
|
123
|
-
return projection.
|
|
128
|
+
return projection.entries.flatMap((entry) => entry.messages);
|
|
124
129
|
}
|
|
125
130
|
|
|
126
131
|
// ============================================================================
|
|
@@ -1598,7 +1603,13 @@ export interface ToolCallOccurrence {
|
|
|
1598
1603
|
isError: boolean;
|
|
1599
1604
|
}
|
|
1600
1605
|
|
|
1601
|
-
/**
|
|
1606
|
+
/**
|
|
1607
|
+
* Collect every transcript assistant toolCall block that has a matching
|
|
1608
|
+
* transcript toolResult message, in message order. `nestedCalls` is deliberately
|
|
1609
|
+
* not expanded: Pi keeps only bounded call metadata there and does not record
|
|
1610
|
+
* child results as transcript messages, so expanding it would double-count or
|
|
1611
|
+
* invent prune targets.
|
|
1612
|
+
*/
|
|
1602
1613
|
export function collectCompletedToolCallOccurrences(messages: MinimalMessage[]): ToolCallOccurrence[] {
|
|
1603
1614
|
const resultIndexById = new Map<string, number>();
|
|
1604
1615
|
const isErrorById = new Map<string, boolean>();
|
|
@@ -2318,6 +2329,8 @@ export function buildPrunableItems(
|
|
|
2318
2329
|
const items: PrunableItem[] = [];
|
|
2319
2330
|
for (const occurrence of collectCompletedToolCallOccurrences(messages)) {
|
|
2320
2331
|
const resultMessage = messages[occurrence.resultIndex] as MinimalToolResultMessage;
|
|
2332
|
+
// Only provider-visible transcript content is economically attributable;
|
|
2333
|
+
// bounded nested-call metadata has no child result content to estimate.
|
|
2321
2334
|
const estimatedTokens = estimateTokensForContent(resultMessage.content);
|
|
2322
2335
|
const activeDecision = activeByToolCallId.get(occurrence.toolCallId);
|
|
2323
2336
|
const status: PrunableItemStatus = activeDecision
|
|
@@ -38,9 +38,19 @@ Direct OpenAI API Fast mode requires all of the following:
|
|
|
38
38
|
|
|
39
39
|
- Provider `openai`.
|
|
40
40
|
- API `openai-responses` or `openai-completions`.
|
|
41
|
-
- Model `gpt-6-astra`, `gpt-6-sol`, or `gpt-6-luna`.
|
|
41
|
+
- Model `gpt-6.1-sol`, `gpt-6-astra`, `gpt-6-sol`, or `gpt-6-luna`.
|
|
42
|
+
- API-key auth or Pi's `openai` ChatGPT OAuth (`Sign in with ChatGPT`).
|
|
42
43
|
- No existing `service_tier` field in the request payload.
|
|
43
44
|
|
|
45
|
+
The direct OpenAI route stays on OpenAI's direct API contract for both API-key
|
|
46
|
+
auth and Pi's `openai` ChatGPT OAuth. Acceptance of `service_tier: "fast"` by
|
|
47
|
+
Pi's `openai` ChatGPT OAuth sign-in endpoint has not been live-verified and
|
|
48
|
+
remains deferred to manual gate `pel-71t6`. This direct route is never forwarded
|
|
49
|
+
to legacy `openai-codex` or its subscription-usage endpoint. The documented
|
|
50
|
+
request shape is support evidence, not live certification; this change was
|
|
51
|
+
validated only with mocked eligibility and request payloads, not live or paid
|
|
52
|
+
provider calls.
|
|
53
|
+
|
|
44
54
|
OpenAI Codex Fast mode requires all of the following:
|
|
45
55
|
|
|
46
56
|
- Provider `openai-codex`.
|
|
@@ -49,11 +59,18 @@ OpenAI Codex Fast mode requires all of the following:
|
|
|
49
59
|
- ChatGPT OAuth/subscription auth, not API-key auth.
|
|
50
60
|
- No existing `service_tier` field in the request payload.
|
|
51
61
|
|
|
62
|
+
GPT-6.1 Sol is intentionally unsupported on this legacy Codex route. The
|
|
63
|
+
Codex speed documentation lists GPT-6.1 Sol Fast with `service_tier: "fast"`,
|
|
64
|
+
but Pi's legacy Codex service-tier cost handling currently accounts for
|
|
65
|
+
`priority` and `flex`, not `fast`. The direct OpenAI API's `priority` alias is
|
|
66
|
+
not evidence for the legacy Codex endpoint, so this extension leaves the route
|
|
67
|
+
fail-closed without patching upstream pricing.
|
|
68
|
+
|
|
52
69
|
Anthropic Fast mode requires all of the following:
|
|
53
70
|
|
|
54
71
|
- Provider `anthropic`.
|
|
55
72
|
- API `anthropic-messages`.
|
|
56
|
-
- Model `claude-opus-4-8` or `claude-opus-5`.
|
|
73
|
+
- Model `claude-opus-4-8`, `claude-opus-5`, or `claude-opus-5-5`.
|
|
57
74
|
- No existing `speed` field in the request payload.
|
|
58
75
|
|
|
59
76
|
Anthropic Fast mode supports both API-key and Claude Code OAuth access when the account has access to the research preview.
|
|
@@ -129,7 +146,11 @@ The collection package loads this unified extension instead of `openai-fast` and
|
|
|
129
146
|
## Notes
|
|
130
147
|
|
|
131
148
|
- Anthropic Fast mode has separate rate limits, costs more than standard speed, and does not share prompt-cache prefixes with standard-speed requests.
|
|
132
|
-
- Direct OpenAI Fast mode is limited to the confirmed
|
|
133
|
-
- OpenAI
|
|
149
|
+
- Direct OpenAI Fast mode is limited to the confirmed GPT-6 API models above; Fast pricing, availability, and rate limits remain provider- and account-dependent.
|
|
150
|
+
- Authoritative support evidence: [OpenAI Fast mode](https://developers.openai.com/api/docs/guides/fast-mode) explicitly uses `gpt-6.1-sol` with `service_tier: "fast"` and documents `priority` as an equivalent alias for supported API models; the [GPT-6.1 Sol model page](https://developers.openai.com/api/docs/models/gpt-6.1-sol) documents the model itself.
|
|
151
|
+
- The [Codex speed guide](https://developers.openai.com/codex/speed/) documents GPT-6.1 Sol Fast for ChatGPT-signed-in Codex, but legacy Codex support remains pending separate wire and cost validation; this ticket makes no live-certification claim.
|
|
152
|
+
- Pi's provider catalog remains the source of reported model pricing, including any tiered pricing; this extension does not apply guessed discounts or rewrite cost metadata.
|
|
153
|
+
- OpenAI Codex Fast mode intentionally does not affect API-key models, and GPT-6.1 Sol remains blocked on the legacy Codex route.
|
|
154
|
+
- The retired `openai-fast` and `claude-fast` packages remain legacy standalone boundaries; new provider/auth behavior belongs only to this unified extension.
|
|
134
155
|
- Existing `speed` and `service_tier` fields are never overwritten.
|
|
135
156
|
- Pi's model catalog may not include a Fast-mode premium. Cost accounting depends on the provider reporting the effective tier in its streamed response, and this extension does not patch usage totals.
|
package/extensions/fast/index.ts
CHANGED
|
@@ -15,7 +15,7 @@ const ANTHROPIC_FAST_BETA = "fast-mode-2026-02-01";
|
|
|
15
15
|
const CLAUDE_CODE_OAUTH_BETAS = ["claude-code-20250219", "oauth-2025-04-20"];
|
|
16
16
|
const FINE_GRAINED_TOOL_STREAMING_BETA = "fine-grained-tool-streaming-2025-05-14";
|
|
17
17
|
const INTERLEAVED_THINKING_BETA = "interleaved-thinking-2025-05-14";
|
|
18
|
-
const ANTHROPIC_SUPPORTED_MODELS = new Set(["claude-opus-4-8", "claude-opus-5"]);
|
|
18
|
+
const ANTHROPIC_SUPPORTED_MODELS = new Set(["claude-opus-4-8", "claude-opus-5", "claude-opus-5-5"]);
|
|
19
19
|
|
|
20
20
|
const OPENAI_PROVIDER_ID = "openai-codex";
|
|
21
21
|
const OPENAI_API_ID = "openai-codex-responses";
|
|
@@ -29,7 +29,7 @@ const OPENAI_SUPPORTED_MODELS = new Set([
|
|
|
29
29
|
const OPENAI_API_PROVIDER_ID = "openai";
|
|
30
30
|
const OPENAI_API_IDS = new Set(["openai-responses", "openai-completions"]);
|
|
31
31
|
const OPENAI_API_FAST_SERVICE_TIER = "fast";
|
|
32
|
-
const OPENAI_API_SUPPORTED_MODELS = new Set(["gpt-6-astra", "gpt-6-sol", "gpt-6-luna"]);
|
|
32
|
+
const OPENAI_API_SUPPORTED_MODELS = new Set(["gpt-6.1-sol", "gpt-6-astra", "gpt-6-sol", "gpt-6-luna"]);
|
|
33
33
|
|
|
34
34
|
const DEFAULT_CONFIG: FastConfig = {
|
|
35
35
|
enabled: false,
|
|
@@ -163,7 +163,7 @@ function getEligibility(ctx: ExtensionContext): Eligibility {
|
|
|
163
163
|
return {
|
|
164
164
|
eligible: false,
|
|
165
165
|
modelKey: key,
|
|
166
|
-
reason: "Fast mode is only enabled for Claude Opus 4.8 and Claude Opus 5",
|
|
166
|
+
reason: "Fast mode is only enabled for Claude Opus 4.8, Claude Opus 5, and Claude Opus 5.5",
|
|
167
167
|
};
|
|
168
168
|
}
|
|
169
169
|
|
|
@@ -216,7 +216,7 @@ function getEligibility(ctx: ExtensionContext): Eligibility {
|
|
|
216
216
|
return {
|
|
217
217
|
eligible: false,
|
|
218
218
|
modelKey: key,
|
|
219
|
-
reason: "Fast mode is only enabled for GPT-6 Astra, GPT-6 Sol, and GPT-6 Luna on direct OpenAI APIs",
|
|
219
|
+
reason: "Fast mode is only enabled for GPT-6.1 Sol, GPT-6 Astra, GPT-6 Sol, and GPT-6 Luna on direct OpenAI APIs",
|
|
220
220
|
};
|
|
221
221
|
}
|
|
222
222
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diegopetrucci/pi-fast",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "A pi extension that enables Fast mode for supported direct OpenAI API, OpenAI Codex, and Anthropic Claude models based on the currently selected model.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -40,4 +40,5 @@ Then reload pi:
|
|
|
40
40
|
- Does not replace pi's built-in footer.
|
|
41
41
|
- Uses `ctx.ui.setStatus()`, so pi renders the git summary with other extension statuses.
|
|
42
42
|
- The current pi extension API does not support literally appending text inside the built-in footer's first `cwd (branch)` line without replacing the footer.
|
|
43
|
+
- Status text is passed through Pi's active `dim` theme color; the extension does not embed terminal escape sequences, so theme changes remain host-controlled.
|
|
43
44
|
- Git and GitHub CLI lookups run on a short background interval with timeouts.
|
|
@@ -10,6 +10,7 @@ import type { Usage } from "@earendil-works/pi-ai";
|
|
|
10
10
|
import {
|
|
11
11
|
DefaultResourceLoader,
|
|
12
12
|
SessionManager,
|
|
13
|
+
SettingsManager,
|
|
13
14
|
createAgentSession,
|
|
14
15
|
getAgentDir,
|
|
15
16
|
getMarkdownTheme,
|
|
@@ -1434,9 +1435,14 @@ export default function librarianExtension(pi: ExtensionAPI) {
|
|
|
1434
1435
|
cacheRoot,
|
|
1435
1436
|
});
|
|
1436
1437
|
|
|
1438
|
+
// Keep the research session from inheriting user/project tool, shell,
|
|
1439
|
+
// retry, or provider-request settings. The host model runtime is still
|
|
1440
|
+
// passed explicitly below so the selected provider/auth policy is kept.
|
|
1441
|
+
const isolatedSettingsManager = SettingsManager.inMemory({});
|
|
1437
1442
|
const resourceLoader = new DefaultResourceLoader({
|
|
1438
1443
|
cwd: workspace,
|
|
1439
1444
|
agentDir: getAgentDir(),
|
|
1445
|
+
settingsManager: isolatedSettingsManager,
|
|
1440
1446
|
noExtensions: true,
|
|
1441
1447
|
noSkills: true,
|
|
1442
1448
|
noPromptTemplates: true,
|
|
@@ -1469,6 +1475,7 @@ export default function librarianExtension(pi: ExtensionAPI) {
|
|
|
1469
1475
|
cwd: workspace,
|
|
1470
1476
|
...getModelRuntimeOption(ctx),
|
|
1471
1477
|
resourceLoader,
|
|
1478
|
+
settingsManager: isolatedSettingsManager,
|
|
1472
1479
|
sessionManager: SessionManager.inMemory(workspace),
|
|
1473
1480
|
model: candidate.model,
|
|
1474
1481
|
thinkingLevel: candidate.details.thinkingLevel,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diegopetrucci/pi-librarian",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
4
4
|
"description": "A pi GitHub research scout with a toggleable local repo checkout cache under the user's OS cache directory.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
]
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
|
+
"@earendil-works/pi-ai": "*",
|
|
33
34
|
"@earendil-works/pi-coding-agent": "*",
|
|
34
35
|
"@earendil-works/pi-tui": "*",
|
|
35
36
|
"typebox": "*"
|
|
@@ -45,7 +45,7 @@ When context usage is above 200k tokens, the bottom-left line includes a red war
|
|
|
45
45
|
44.1% · DUMB ZONE
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
When using `openai-codex`, the bottom-left line also includes subscription usage. A typical account with both windows looks like:
|
|
48
|
+
When using legacy `openai-codex`, the bottom-left line also includes subscription usage. A typical account with both windows looks like:
|
|
49
49
|
|
|
50
50
|
```text
|
|
51
51
|
44.1% · 5h 12% · 7d 38%
|
|
@@ -53,6 +53,15 @@ When using `openai-codex`, the bottom-left line also includes subscription usage
|
|
|
53
53
|
|
|
54
54
|
Window labels come from OpenAI's reported durations, so an account that reports only a weekly primary window is shown correctly (for example, `7d 38%`) instead of being assumed to have a 5-hour window.
|
|
55
55
|
|
|
56
|
+
Pi's `openai` ChatGPT OAuth uses the direct OpenAI API and has no documented
|
|
57
|
+
account-usage endpoint compatible with this legacy WHAM reader. In that case,
|
|
58
|
+
the footer shows `usage unsupported` and does not send the new token to
|
|
59
|
+
`chatgpt.com/backend-api/wham/usage`. Direct OpenAI API-key users have no
|
|
60
|
+
subscription-usage line. Legacy Codex fetch failures, missing OAuth, or a
|
|
61
|
+
malformed/mismatched token account claim show `usage unavailable` rather than
|
|
62
|
+
retaining an older account's snapshot; the request is not sent until the token
|
|
63
|
+
claim and lifecycle identity agree.
|
|
64
|
+
|
|
56
65
|
When `PI_EXPERIMENTAL=1`, the bottom-left line also includes an experimental marker:
|
|
57
66
|
|
|
58
67
|
```text
|
|
@@ -203,8 +212,8 @@ Disable git dirty/ahead/PR status:
|
|
|
203
212
|
- `context.dumbZone.thresholdTokens`: token threshold for `DUMB ZONE`
|
|
204
213
|
- `context.dumbZone.label`: warning text
|
|
205
214
|
- `context.dumbZone.color`: theme color for the warning (`error`, `warning`, `accent`, `text`, or `dim`)
|
|
206
|
-
- `codexUsage.enabled`: show OpenAI Codex session-limit usage when using `openai-codex
|
|
207
|
-
- `codexUsage.cacheTtlMs`: in-memory usage cache duration
|
|
215
|
+
- `codexUsage.enabled`: show OpenAI Codex session-limit usage when using `openai-codex`; also controls the explicit unsupported/unavailable status for account usage
|
|
216
|
+
- `codexUsage.cacheTtlMs`: in-memory usage-result cache duration and account-only login detection interval; provider/model/account changes invalidate the cached snapshot. The timer only compares identity and does not fetch unchanged-account usage. The default is 5 minutes; `0` disables usage-result caching but keeps identity checks every 5 minutes. Positive values above Node's `2,147,483,647` ms timer limit use that maximum only for scheduling; the configured TTL still controls lifecycle cache semantics.
|
|
208
217
|
- `codexUsage.requestTimeoutMs`: usage request timeout
|
|
209
218
|
- `codexUsage.windows.primary.enabled`: show the primary usage window
|
|
210
219
|
- `codexUsage.windows.primary.label`: `"auto"` derives the primary label from OpenAI's reported duration; any other value overrides it
|
|
@@ -224,6 +233,7 @@ Disable git dirty/ahead/PR status:
|
|
|
224
233
|
- **Top right:** current repo directory name
|
|
225
234
|
- **Bottom left:** current context usage percentage, plus red `DUMB ZONE` above 200k context tokens
|
|
226
235
|
- **Bottom left on `openai-codex`:** current context usage percentage plus the Codex usage windows reported for the account
|
|
236
|
+
- **Bottom left on `openai` ChatGPT OAuth:** current context usage percentage plus `usage unsupported`; no legacy WHAM request is attempted
|
|
227
237
|
- **Bottom left with `PI_EXPERIMENTAL=1`:** current context usage percentage plus `xp`
|
|
228
238
|
- **Bottom right:** model id and thinking level
|
|
229
239
|
|
|
@@ -240,4 +250,6 @@ This extension also lives inside the broader [`pi-extensions`](../../README.md)
|
|
|
240
250
|
- Shows the model id rather than a provider-specific display label.
|
|
241
251
|
- Shows `xp` when `PI_EXPERIMENTAL=1`.
|
|
242
252
|
- For `openai-codex`, reads pi's stored OAuth login and fetches usage from ChatGPT's backend usage endpoint. Window labels are inferred from each window's reported duration; missing or unrecognized durations use neutral `usage` labels rather than guessing from window position.
|
|
243
|
-
-
|
|
253
|
+
- For direct `openai` ChatGPT OAuth, no usage endpoint is assumed: the footer marks usage unsupported and never calls the legacy WHAM endpoint. API-key requests do not use subscription usage.
|
|
254
|
+
- Usage is cached briefly in memory and refreshed after turns. A provider/model/account boundary clears the old snapshot, and late results from an earlier request are ignored. Because Pi 0.99 emits no auth-change event, account-only logins are detected by one per-session identity-only timer: it uses `cacheTtlMs` when positive, checks every five minutes when `cacheTtlMs: 0`, and clamps larger schedules to Node's `2,147,483,647` ms maximum. Unchanged-account ticks make no WHAM request; an account change uses the normal safe refresh. The timer is disposed on shutdown/restart, and no credential file is read during footer rendering.
|
|
255
|
+
- Footer colors continue to come from Pi's active theme; the extension does not embed ANSI color codes.
|