@diegopetrucci/pi-extensions 0.1.61 → 0.1.62
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/.pi-fleet-tested-version +1 -1
- package/extensions/agent-workflow-audit/.pi-fleet-tested-version +1 -1
- package/extensions/agent-workflow-audit/package.json +1 -1
- package/extensions/annotate-git-diff/.pi-fleet-tested-version +1 -1
- package/extensions/annotate-git-diff/package.json +1 -1
- package/extensions/annotate-last-message/.pi-fleet-tested-version +1 -1
- package/extensions/annotate-last-message/package.json +1 -1
- package/extensions/brrr/.pi-fleet-tested-version +1 -1
- package/extensions/brrr/package.json +1 -1
- package/extensions/claude-fast/.pi-fleet-tested-version +1 -1
- package/extensions/claude-fast/package.json +1 -1
- package/extensions/code-reviewer/.pi-fleet-tested-version +1 -1
- package/extensions/code-reviewer/README.md +1 -0
- package/extensions/code-reviewer/index.ts +24 -2
- package/extensions/code-reviewer/package.json +1 -1
- package/extensions/confirm-destructive/.pi-fleet-tested-version +1 -1
- package/extensions/confirm-destructive/package.json +1 -1
- package/extensions/context-cap/.pi-fleet-tested-version +1 -1
- package/extensions/context-cap/package.json +1 -1
- package/extensions/context-inspector/.pi-fleet-tested-version +1 -1
- package/extensions/context-inspector/package.json +1 -1
- package/extensions/contrarian/.pi-fleet-tested-version +1 -1
- package/extensions/contrarian/README.md +2 -0
- package/extensions/contrarian/index.ts +34 -8
- package/extensions/contrarian/package.json +1 -1
- package/extensions/dirty-repo-guard/.pi-fleet-tested-version +1 -1
- package/extensions/dirty-repo-guard/package.json +1 -1
- package/extensions/dynamic-context-pruning/.pi-fleet-tested-version +1 -1
- package/extensions/dynamic-context-pruning/package.json +1 -1
- package/extensions/git-footer/.pi-fleet-tested-version +1 -1
- package/extensions/git-footer/package.json +1 -1
- package/extensions/gnosis/.pi-fleet-tested-version +1 -1
- package/extensions/gnosis/package.json +1 -1
- package/extensions/illustrations-to-explain-things/.pi-fleet-tested-version +1 -1
- package/extensions/illustrations-to-explain-things/package.json +1 -1
- package/extensions/inline-bash/.pi-fleet-tested-version +1 -1
- package/extensions/inline-bash/package.json +1 -1
- package/extensions/librarian/.pi-fleet-tested-version +1 -1
- package/extensions/librarian/README.md +1 -1
- package/extensions/librarian/index.ts +34 -5
- package/extensions/librarian/package.json +1 -1
- package/extensions/minimal-footer/.pi-fleet-tested-version +1 -1
- package/extensions/minimal-footer/package.json +1 -1
- package/extensions/notify/.pi-fleet-tested-version +1 -1
- package/extensions/notify/package.json +1 -1
- package/extensions/openai-fast/.pi-fleet-tested-version +1 -1
- package/extensions/openai-fast/package.json +1 -1
- package/extensions/oracle/.pi-fleet-tested-version +1 -1
- package/extensions/oracle/README.md +2 -0
- package/extensions/oracle/index.ts +34 -8
- package/extensions/oracle/package.json +1 -1
- package/extensions/permission-gate/.pi-fleet-tested-version +1 -1
- package/extensions/permission-gate/package.json +1 -1
- package/extensions/quiet-tools/.pi-fleet-tested-version +1 -1
- package/extensions/quiet-tools/package.json +1 -1
- package/extensions/review/.pi-fleet-tested-version +1 -1
- package/extensions/review/package.json +1 -1
- package/extensions/todo/.pi-fleet-tested-version +1 -1
- package/extensions/todo/package.json +1 -1
- package/extensions/triage-comments/.pi-fleet-tested-version +1 -1
- package/extensions/triage-comments/package.json +1 -1
- package/package.json +4 -4
package/.pi-fleet-tested-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diegopetrucci/pi-annotate-git-diff",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "A standalone pi extension that adds /annotate-git-diff, a native Glimpse UI for annotating git diffs and sending feedback to the editor.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diegopetrucci/pi-annotate-last-message",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "A standalone pi extension that adds /annotate-last-message, a native Glimpse UI for annotating the latest assistant reply.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -44,6 +44,7 @@ When called, it launches an isolated in-memory child agent with:
|
|
|
44
44
|
|
|
45
45
|
- no inherited extensions, skills, prompt templates, themes, context files, or agents files;
|
|
46
46
|
- an auto-selected review model that prefers contrarian-style opposite-provider and opposite-family candidates before same-provider fallbacks;
|
|
47
|
+
- automatic model candidates constrained to the current Pi session's model scope when that scope is non-empty;
|
|
47
48
|
- requested thinking taken from the active session when available, otherwise defaulting to `high` for reasoning models and `off` for non-reasoning models, then clamped to the selected model's supported level;
|
|
48
49
|
- read-only tools only: `read`, `grep`, `find`, `ls`, and guarded `bash`;
|
|
49
50
|
- a local-checkout path guard for file inspection;
|
|
@@ -224,8 +224,28 @@ type PiModel = {
|
|
|
224
224
|
type ModelRegistryContext = {
|
|
225
225
|
model?: PiModel;
|
|
226
226
|
modelRegistry: { getAvailable(): PiModel[] | Promise<PiModel[]> };
|
|
227
|
+
scopedModels?: ReadonlyArray<{ model: PiModel; thinkingLevel?: ThinkingLevel }>;
|
|
227
228
|
};
|
|
228
229
|
|
|
230
|
+
function modelKey(model: PiModel): string {
|
|
231
|
+
return `${model.provider}/${model.id}`.toLowerCase();
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function hasModelScope(ctx: ModelRegistryContext): boolean {
|
|
235
|
+
return Array.isArray(ctx.scopedModels) && ctx.scopedModels.length > 0;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function isModelInScope(ctx: ModelRegistryContext, model: PiModel): boolean {
|
|
239
|
+
if (!hasModelScope(ctx)) return true;
|
|
240
|
+
const key = modelKey(model);
|
|
241
|
+
return ctx.scopedModels!.some((entry) => modelKey(entry.model) === key);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
async function getAutoSelectableModels(ctx: ModelRegistryContext): Promise<PiModel[]> {
|
|
245
|
+
const available = await ctx.modelRegistry.getAvailable();
|
|
246
|
+
return hasModelScope(ctx) ? available.filter((model) => isModelInScope(ctx, model)) : available;
|
|
247
|
+
}
|
|
248
|
+
|
|
229
249
|
type CreateAgentSessionOptions = NonNullable<Parameters<typeof createAgentSession>[0]>;
|
|
230
250
|
type CreateAgentSessionModel = CreateAgentSessionOptions["model"];
|
|
231
251
|
|
|
@@ -354,11 +374,13 @@ function appendOrderedCandidates(
|
|
|
354
374
|
async function selectCodeReviewerModel(
|
|
355
375
|
ctx: ModelRegistryContext,
|
|
356
376
|
): Promise<{ ok: true; selection: PiModel; ordered: PiModel[] } | { ok: false; error: string }> {
|
|
357
|
-
const available = await ctx
|
|
377
|
+
const available = await getAutoSelectableModels(ctx);
|
|
358
378
|
if (available.length === 0) {
|
|
359
379
|
return {
|
|
360
380
|
ok: false,
|
|
361
|
-
error:
|
|
381
|
+
error: hasModelScope(ctx)
|
|
382
|
+
? "No authenticated models are available in the current session model scope. Adjust the scope, log in, or configure an API key."
|
|
383
|
+
: "No authenticated models are available. Log in or configure an API key first.",
|
|
362
384
|
};
|
|
363
385
|
}
|
|
364
386
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -77,6 +77,8 @@ Tool-call parameters still win over these defaults. `auto` clears the configured
|
|
|
77
77
|
- `thinkingLevel` - optional reasoning/thinking override; falls back to the `/contrarian thinking` default, then built-in defaults
|
|
78
78
|
- `cwd` - optional working directory override
|
|
79
79
|
|
|
80
|
+
When the current Pi session has a non-empty model scope, Contrarian limits automatic model selection and automatic fallbacks to that scope. An explicit tool or `/contrarian model` override remains authoritative even when it is outside the session scope.
|
|
81
|
+
|
|
80
82
|
## Notes
|
|
81
83
|
|
|
82
84
|
- The contrarian is intentionally **read-only**.
|
|
@@ -20,6 +20,31 @@ type PiModel = {
|
|
|
20
20
|
thinkingLevelMap?: ThinkingLevelMap;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
+
type ModelSelectionContext = {
|
|
24
|
+
model?: PiModel;
|
|
25
|
+
modelRegistry: { getAvailable(): PiModel[] | Promise<PiModel[]> };
|
|
26
|
+
scopedModels?: ReadonlyArray<{ model: PiModel; thinkingLevel?: ThinkingLevel }>;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
function modelKey(model: PiModel): string {
|
|
30
|
+
return `${model.provider}/${model.id}`.toLowerCase();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function hasModelScope(ctx: ModelSelectionContext): boolean {
|
|
34
|
+
return Array.isArray(ctx.scopedModels) && ctx.scopedModels.length > 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function isModelInScope(ctx: ModelSelectionContext, model: PiModel): boolean {
|
|
38
|
+
if (!hasModelScope(ctx)) return true;
|
|
39
|
+
const key = modelKey(model);
|
|
40
|
+
return ctx.scopedModels!.some((entry) => modelKey(entry.model) === key);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function getAutoSelectableModels(ctx: ModelSelectionContext): Promise<PiModel[]> {
|
|
44
|
+
const available = await ctx.modelRegistry.getAvailable();
|
|
45
|
+
return hasModelScope(ctx) ? available.filter((model) => isModelInScope(ctx, model)) : available;
|
|
46
|
+
}
|
|
47
|
+
|
|
23
48
|
interface UsageStats {
|
|
24
49
|
input: number;
|
|
25
50
|
output: number;
|
|
@@ -180,8 +205,6 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
180
205
|
"accounts/fireworks/models/glm-5p2",
|
|
181
206
|
"accounts/fireworks/routers/glm-5p2-fast",
|
|
182
207
|
"accounts/fireworks/models/minimax-m3",
|
|
183
|
-
"accounts/fireworks/models/glm-5p1",
|
|
184
|
-
"accounts/fireworks/routers/glm-5p1-fast",
|
|
185
208
|
"accounts/fireworks/models/kimi-k2p6",
|
|
186
209
|
"accounts/fireworks/routers/kimi-k2p6-turbo",
|
|
187
210
|
"accounts/fireworks/routers/kimi-k2p6-fast",
|
|
@@ -918,7 +941,7 @@ function appendThinkingLevelClampReason(
|
|
|
918
941
|
}
|
|
919
942
|
|
|
920
943
|
async function findAvailableModel(
|
|
921
|
-
ctx:
|
|
944
|
+
ctx: ModelSelectionContext,
|
|
922
945
|
modelRef: string,
|
|
923
946
|
): Promise<PiModel | undefined> {
|
|
924
947
|
const available = await ctx.modelRegistry.getAvailable();
|
|
@@ -964,11 +987,11 @@ function toContrarianSelection(
|
|
|
964
987
|
}
|
|
965
988
|
|
|
966
989
|
function buildSessionFallbackSelection(
|
|
967
|
-
ctx:
|
|
990
|
+
ctx: ModelSelectionContext,
|
|
968
991
|
thinkingLevelOverride: ThinkingLevel | undefined,
|
|
969
992
|
): ContrarianSelection | undefined {
|
|
970
993
|
const model = ctx.model;
|
|
971
|
-
if (!model) return undefined;
|
|
994
|
+
if (!model || !isModelInScope(ctx, model)) return undefined;
|
|
972
995
|
return toContrarianSelection(
|
|
973
996
|
model,
|
|
974
997
|
thinkingLevelOverride,
|
|
@@ -984,14 +1007,16 @@ function withFallbackReason(selection: ContrarianSelection, previous: Contrarian
|
|
|
984
1007
|
}
|
|
985
1008
|
|
|
986
1009
|
async function selectContrarianModel(
|
|
987
|
-
ctx:
|
|
1010
|
+
ctx: ModelSelectionContext,
|
|
988
1011
|
thinkingLevelOverride?: ThinkingLevel,
|
|
989
1012
|
): Promise<{ ok: true; selection: ContrarianSelection; ordered: ContrarianSelection[] } | { ok: false; error: string }> {
|
|
990
|
-
const available = await ctx
|
|
1013
|
+
const available = await getAutoSelectableModels(ctx);
|
|
991
1014
|
if (available.length === 0) {
|
|
992
1015
|
return {
|
|
993
1016
|
ok: false,
|
|
994
|
-
error:
|
|
1017
|
+
error: hasModelScope(ctx)
|
|
1018
|
+
? "No authenticated models are available in the current session model scope. Adjust the scope, log in, or configure an API key."
|
|
1019
|
+
: "No authenticated models are available. Log in or configure an API key first.",
|
|
995
1020
|
};
|
|
996
1021
|
}
|
|
997
1022
|
|
|
@@ -1340,6 +1365,7 @@ type ContrarianExtensionDeps = {
|
|
|
1340
1365
|
};
|
|
1341
1366
|
|
|
1342
1367
|
export const __test__ = {
|
|
1368
|
+
buildSessionFallbackSelection,
|
|
1343
1369
|
createContrarianExtension,
|
|
1344
1370
|
findAvailableModel,
|
|
1345
1371
|
isModelAvailabilityError,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diegopetrucci/pi-illustrations-to-explain-things",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "A pi skill for generating clean, absurd Xiaohei-style article illustrations, shot lists, and visual metaphors.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -4,7 +4,7 @@ A pi GitHub research scout inspired by `pi-librarian`, with a local checkout cac
|
|
|
4
4
|
|
|
5
5
|
When the `librarian` tool runs, it can cache/reuse repository checkouts locally. Use `/librarian-cache off` to force GitHub API/search and temporary fetched files only, or `/librarian-cache on` to re-enable cached local checkouts.
|
|
6
6
|
|
|
7
|
-
The internal librarian subagent uses a fast auto-selected model by default, requests `low` thinking, and prompts its scout to batch independent GitHub probes in parallel. Use `/librarian-config` to set a persistent internal model or thinking-level preference.
|
|
7
|
+
The internal librarian subagent uses a fast auto-selected model by default, requests `low` thinking, and prompts its scout to batch independent GitHub probes in parallel. Automatic candidates and fallbacks stay within the current Pi session's model scope when that scope is non-empty; an explicit tool or `/librarian-config` model remains authoritative. Use `/librarian-config` to set a persistent internal model or thinking-level preference.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
@@ -46,6 +46,31 @@ type PiModel = {
|
|
|
46
46
|
thinkingLevelMap?: ThinkingLevelMap;
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
+
type ModelSelectionContext = {
|
|
50
|
+
model?: any;
|
|
51
|
+
modelRegistry: { getAvailable(): any[] | Promise<any[]> };
|
|
52
|
+
scopedModels?: ReadonlyArray<{ model: any; thinkingLevel?: ThinkingLevel }>;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
function modelKey(model: any): string {
|
|
56
|
+
return `${model.provider}/${model.id}`.toLowerCase();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function hasModelScope(ctx: ModelSelectionContext): boolean {
|
|
60
|
+
return Array.isArray(ctx.scopedModels) && ctx.scopedModels.length > 0;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function isModelInScope(ctx: ModelSelectionContext, model: any): boolean {
|
|
64
|
+
if (!hasModelScope(ctx)) return true;
|
|
65
|
+
const key = modelKey(model);
|
|
66
|
+
return ctx.scopedModels!.some((entry) => modelKey(entry.model) === key);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function getAutoSelectableModels(ctx: ModelSelectionContext): Promise<any[]> {
|
|
70
|
+
const available = await ctx.modelRegistry.getAvailable();
|
|
71
|
+
return hasModelScope(ctx) ? available.filter((model) => isModelInScope(ctx, model)) : available;
|
|
72
|
+
}
|
|
73
|
+
|
|
49
74
|
type CreateAgentSessionOptions = NonNullable<Parameters<typeof createAgentSession>[0]>;
|
|
50
75
|
|
|
51
76
|
function getModelRuntimeOption(ctx: { modelRegistry?: unknown }): Pick<CreateAgentSessionOptions, "modelRuntime"> {
|
|
@@ -677,7 +702,7 @@ function rankPreferredFastLibrarianModel(model: any): number {
|
|
|
677
702
|
}
|
|
678
703
|
|
|
679
704
|
async function findAvailableModel(
|
|
680
|
-
ctx:
|
|
705
|
+
ctx: ModelSelectionContext,
|
|
681
706
|
modelPreference: string,
|
|
682
707
|
): Promise<any | undefined> {
|
|
683
708
|
const available = await ctx.modelRegistry.getAvailable();
|
|
@@ -732,7 +757,7 @@ function withLibrarianFallbackReason(candidate: LibrarianCandidate, previous: Li
|
|
|
732
757
|
// these in order and skip ones that fail with a model-availability error,
|
|
733
758
|
// ultimately falling back to the known-good current session model.
|
|
734
759
|
async function buildLibrarianCandidates(
|
|
735
|
-
ctx:
|
|
760
|
+
ctx: ModelSelectionContext,
|
|
736
761
|
modelPreference: string | undefined,
|
|
737
762
|
thinkingLevel: ThinkingLevel,
|
|
738
763
|
): Promise<LibrarianCandidate[]> {
|
|
@@ -762,7 +787,7 @@ async function buildLibrarianCandidates(
|
|
|
762
787
|
}
|
|
763
788
|
}
|
|
764
789
|
|
|
765
|
-
const available = await ctx
|
|
790
|
+
const available = await getAutoSelectableModels(ctx);
|
|
766
791
|
const preferred = available.filter(isPreferredFastLibrarianModel);
|
|
767
792
|
const ranked = preferred.length > 0
|
|
768
793
|
? [...preferred].sort((a, b) => rankPreferredFastLibrarianModel(a) - rankPreferredFastLibrarianModel(b))
|
|
@@ -785,7 +810,7 @@ async function buildLibrarianCandidates(
|
|
|
785
810
|
});
|
|
786
811
|
|
|
787
812
|
// Final fallback: the active session model is known to be servable.
|
|
788
|
-
if (ctx.model) {
|
|
813
|
+
if (ctx.model && isModelInScope(ctx, ctx.model)) {
|
|
789
814
|
push(ctx.model, {
|
|
790
815
|
modelRef: modelRef(ctx.model),
|
|
791
816
|
provider: ctx.model.provider,
|
|
@@ -797,7 +822,11 @@ async function buildLibrarianCandidates(
|
|
|
797
822
|
}
|
|
798
823
|
|
|
799
824
|
if (candidates.length === 0) {
|
|
800
|
-
throw new Error(
|
|
825
|
+
throw new Error(
|
|
826
|
+
hasModelScope(ctx)
|
|
827
|
+
? "No authenticated models are available for Librarian in the current session model scope. Adjust the scope, log in, or configure an API key."
|
|
828
|
+
: "No authenticated models are available for Librarian. Log in or configure an API key first.",
|
|
829
|
+
);
|
|
801
830
|
}
|
|
802
831
|
|
|
803
832
|
return candidates;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diegopetrucci/pi-openai-fast",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
4
4
|
"description": "A pi extension that enables OpenAI Codex Fast mode for ChatGPT-auth GPT-5.4, GPT-5.5, and GPT-5.6 Codex variants by injecting the priority service tier.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -106,6 +106,8 @@ Tool-call parameters still win over these defaults. `auto` clears the configured
|
|
|
106
106
|
- `thinkingLevel` - optional reasoning/thinking override; falls back to the `/oracle thinking` default, then built-in defaults
|
|
107
107
|
- `cwd` - optional working directory override
|
|
108
108
|
|
|
109
|
+
When the current Pi session has a non-empty model scope, Oracle limits automatic model selection and automatic fallbacks to that scope. An explicit tool or `/oracle model` override remains authoritative even when it is outside the session scope.
|
|
110
|
+
|
|
109
111
|
## Notes
|
|
110
112
|
|
|
111
113
|
- The oracle is intentionally **read-only by default**.
|
|
@@ -20,6 +20,31 @@ type PiModel = {
|
|
|
20
20
|
thinkingLevelMap?: ThinkingLevelMap;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
+
type ModelSelectionContext = {
|
|
24
|
+
model?: PiModel;
|
|
25
|
+
modelRegistry: { getAvailable(): PiModel[] | Promise<PiModel[]> };
|
|
26
|
+
scopedModels?: ReadonlyArray<{ model: PiModel; thinkingLevel?: ThinkingLevel }>;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
function modelKey(model: PiModel): string {
|
|
30
|
+
return `${model.provider}/${model.id}`.toLowerCase();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function hasModelScope(ctx: ModelSelectionContext): boolean {
|
|
34
|
+
return Array.isArray(ctx.scopedModels) && ctx.scopedModels.length > 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function isModelInScope(ctx: ModelSelectionContext, model: PiModel): boolean {
|
|
38
|
+
if (!hasModelScope(ctx)) return true;
|
|
39
|
+
const key = modelKey(model);
|
|
40
|
+
return ctx.scopedModels!.some((entry) => modelKey(entry.model) === key);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function getAutoSelectableModels(ctx: ModelSelectionContext): Promise<PiModel[]> {
|
|
44
|
+
const available = await ctx.modelRegistry.getAvailable();
|
|
45
|
+
return hasModelScope(ctx) ? available.filter((model) => isModelInScope(ctx, model)) : available;
|
|
46
|
+
}
|
|
47
|
+
|
|
23
48
|
interface UsageStats {
|
|
24
49
|
input: number;
|
|
25
50
|
output: number;
|
|
@@ -163,8 +188,6 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
163
188
|
"accounts/fireworks/models/glm-5p2",
|
|
164
189
|
"accounts/fireworks/routers/glm-5p2-fast",
|
|
165
190
|
"accounts/fireworks/models/minimax-m3",
|
|
166
|
-
"accounts/fireworks/models/glm-5p1",
|
|
167
|
-
"accounts/fireworks/routers/glm-5p1-fast",
|
|
168
191
|
"accounts/fireworks/models/kimi-k2p6",
|
|
169
192
|
"accounts/fireworks/routers/kimi-k2p6-turbo",
|
|
170
193
|
"accounts/fireworks/routers/kimi-k2p6-fast",
|
|
@@ -873,7 +896,7 @@ function appendThinkingLevelClampReason(
|
|
|
873
896
|
}
|
|
874
897
|
|
|
875
898
|
async function findAvailableModel(
|
|
876
|
-
ctx:
|
|
899
|
+
ctx: ModelSelectionContext,
|
|
877
900
|
modelRef: string,
|
|
878
901
|
): Promise<PiModel | undefined> {
|
|
879
902
|
const available = await ctx.modelRegistry.getAvailable();
|
|
@@ -919,11 +942,11 @@ function toOracleSelection(
|
|
|
919
942
|
}
|
|
920
943
|
|
|
921
944
|
function buildSessionFallbackSelection(
|
|
922
|
-
ctx:
|
|
945
|
+
ctx: ModelSelectionContext,
|
|
923
946
|
thinkingLevelOverride: ThinkingLevel | undefined,
|
|
924
947
|
): OracleSelection | undefined {
|
|
925
948
|
const model = ctx.model;
|
|
926
|
-
if (!model) return undefined;
|
|
949
|
+
if (!model || !isModelInScope(ctx, model)) return undefined;
|
|
927
950
|
return toOracleSelection(
|
|
928
951
|
model,
|
|
929
952
|
thinkingLevelOverride,
|
|
@@ -939,14 +962,16 @@ function withFallbackReason(selection: OracleSelection, previous: OracleSelectio
|
|
|
939
962
|
}
|
|
940
963
|
|
|
941
964
|
async function selectOracleModel(
|
|
942
|
-
ctx:
|
|
965
|
+
ctx: ModelSelectionContext,
|
|
943
966
|
thinkingLevelOverride?: ThinkingLevel,
|
|
944
967
|
): Promise<{ ok: true; selection: OracleSelection; ordered: OracleSelection[] } | { ok: false; error: string }> {
|
|
945
|
-
const available = await ctx
|
|
968
|
+
const available = await getAutoSelectableModels(ctx);
|
|
946
969
|
if (available.length === 0) {
|
|
947
970
|
return {
|
|
948
971
|
ok: false,
|
|
949
|
-
error:
|
|
972
|
+
error: hasModelScope(ctx)
|
|
973
|
+
? "No authenticated models are available in the current session model scope. Adjust the scope, log in, or configure an API key."
|
|
974
|
+
: "No authenticated models are available. Log in or configure an API key first.",
|
|
950
975
|
};
|
|
951
976
|
}
|
|
952
977
|
|
|
@@ -1253,6 +1278,7 @@ type OracleExtensionDeps = {
|
|
|
1253
1278
|
};
|
|
1254
1279
|
|
|
1255
1280
|
export const __test__ = {
|
|
1281
|
+
buildSessionFallbackSelection,
|
|
1256
1282
|
createOracleExtension,
|
|
1257
1283
|
findAvailableModel,
|
|
1258
1284
|
isModelAvailabilityError,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diegopetrucci/pi-quiet-tools",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "A pi extension that visually compacts collapsed built-in tool rows in the TUI without changing tool results sent to the model.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.83.0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diegopetrucci/pi-extensions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.62",
|
|
4
4
|
"description": "A collection of pi extensions and skills for annotation UIs, context management, workflow audits, contrarian review, review-comment triage, notifications, brrr push alerts, safety guards, GitHub research, repo-local knowledge, todos, tool rendering, model/provider helpers, and Xiaohei-style article illustrations.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -72,9 +72,9 @@
|
|
|
72
72
|
]
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
|
-
"@earendil-works/pi-ai": "^0.
|
|
76
|
-
"@earendil-works/pi-coding-agent": "^0.
|
|
77
|
-
"@earendil-works/pi-tui": "^0.
|
|
75
|
+
"@earendil-works/pi-ai": "^0.83.0",
|
|
76
|
+
"@earendil-works/pi-coding-agent": "^0.83.0",
|
|
77
|
+
"@earendil-works/pi-tui": "^0.83.0",
|
|
78
78
|
"@types/node": "^25.9.1",
|
|
79
79
|
"husky": "^9.1.7",
|
|
80
80
|
"typebox": "^1.3.6",
|