@diegopetrucci/pi-oracle 0.1.8 → 0.1.10
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 -0
- package/README.md +19 -2
- package/index.ts +231 -30
- package/package.json +10 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.76.0
|
package/README.md
CHANGED
|
@@ -38,6 +38,7 @@ Yes — the extension explicitly sets the oracle reasoning level.
|
|
|
38
38
|
- reasoning models request `xhigh` by default, then use the Pi-compatible effective thinking level supported by the matched model
|
|
39
39
|
- non-reasoning models default to `off`
|
|
40
40
|
- you can override it with the tool's optional `thinkingLevel` parameter; matched models still clamp unsupported overrides and report the effective level
|
|
41
|
+
- you can persist a default thinking level with `/oracle thinking <level>` so future automatic oracle tool calls use it when the agent does not pass a per-call override
|
|
41
42
|
|
|
42
43
|
Use `/oracle-model` inside pi to see what it would pick right now.
|
|
43
44
|
|
|
@@ -81,12 +82,28 @@ Ask pi normally, for example:
|
|
|
81
82
|
|
|
82
83
|
The main agent can call the tool directly.
|
|
83
84
|
|
|
85
|
+
## User defaults
|
|
86
|
+
|
|
87
|
+
Use `/oracle` to set persisted defaults that apply to future oracle tool calls, including calls the agent launches automatically without per-call overrides.
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
/oracle status
|
|
91
|
+
/oracle model anthropic/claude-opus-4-5
|
|
92
|
+
/oracle thinking high
|
|
93
|
+
/oracle thinking auto
|
|
94
|
+
/oracle clear model
|
|
95
|
+
/oracle clear thinking
|
|
96
|
+
/oracle clear
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Tool-call parameters still win over these defaults. `auto` clears the configured default and restores the built-in selection behavior. Preferences are saved under pi's agent directory in `extensions/oracle.json`.
|
|
100
|
+
|
|
84
101
|
## Tool parameters
|
|
85
102
|
|
|
86
103
|
- `task` - required prompt for the oracle
|
|
87
104
|
- `includeBash` - optional, adds `bash` for non-mutating inspection
|
|
88
|
-
- `model` - optional explicit model override
|
|
89
|
-
- `thinkingLevel` - optional reasoning/thinking override
|
|
105
|
+
- `model` - optional explicit model override; falls back to the `/oracle model` default, then auto-selection
|
|
106
|
+
- `thinkingLevel` - optional reasoning/thinking override; falls back to the `/oracle thinking` default, then built-in defaults
|
|
90
107
|
- `cwd` - optional working directory override
|
|
91
108
|
|
|
92
109
|
## Notes
|
package/index.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
|
-
import
|
|
3
|
+
import * as fs from "node:fs/promises";
|
|
4
|
+
import * as path from "node:path";
|
|
4
5
|
import { StringEnum } from "@earendil-works/pi-ai";
|
|
5
|
-
import { getMarkdownTheme, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
6
|
+
import { getAgentDir, getMarkdownTheme, type ExtensionAPI, type ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
6
7
|
import { Container, Markdown, Spacer, Text } from "@earendil-works/pi-tui";
|
|
7
8
|
import { Type } from "typebox";
|
|
8
9
|
|
|
@@ -58,6 +59,11 @@ interface OracleUiRun {
|
|
|
58
59
|
preview?: string;
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
interface OraclePreferences {
|
|
63
|
+
model?: string;
|
|
64
|
+
thinkingLevel?: ThinkingLevel;
|
|
65
|
+
}
|
|
66
|
+
|
|
61
67
|
const READ_ONLY_TOOLS = ["read", "grep", "find", "ls"];
|
|
62
68
|
const READ_ONLY_PLUS_BASH_TOOLS = [...READ_ONLY_TOOLS, "bash"];
|
|
63
69
|
const DEFAULT_THINKING_LEVEL: ThinkingLevel = "xhigh";
|
|
@@ -65,6 +71,7 @@ const THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh"] as
|
|
|
65
71
|
const COLLAPSED_LINE_LIMIT = 8;
|
|
66
72
|
const ORACLE_STATUS_ID = "oracle";
|
|
67
73
|
const ORACLE_WIDGET_ID = "oracle";
|
|
74
|
+
const ORACLE_CONFIG_FILE = "oracle.json";
|
|
68
75
|
|
|
69
76
|
const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
70
77
|
"amazon-bedrock": [
|
|
@@ -429,6 +436,74 @@ function createEmptyUsage(): UsageStats {
|
|
|
429
436
|
};
|
|
430
437
|
}
|
|
431
438
|
|
|
439
|
+
function getOracleConfigPath(): string {
|
|
440
|
+
return path.join(getAgentDir(), "extensions", ORACLE_CONFIG_FILE);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
function parseThinkingLevel(value: unknown): ThinkingLevel | undefined {
|
|
444
|
+
if (typeof value !== "string") return undefined;
|
|
445
|
+
const normalized = value.trim().toLowerCase();
|
|
446
|
+
return (THINKING_LEVELS as readonly string[]).includes(normalized) ? (normalized as ThinkingLevel) : undefined;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
function normalizeModelPreference(value: unknown): string | undefined {
|
|
450
|
+
if (typeof value !== "string") return undefined;
|
|
451
|
+
const trimmed = value.trim();
|
|
452
|
+
return trimmed ? trimmed : undefined;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
function parseModelPreference(value: unknown): { model?: string; thinkingLevel?: ThinkingLevel } {
|
|
456
|
+
const model = normalizeModelPreference(value);
|
|
457
|
+
if (!model) return {};
|
|
458
|
+
const match = model.match(/^(.*):(off|minimal|low|medium|high|xhigh)$/i);
|
|
459
|
+
if (!match?.[1]) return { model };
|
|
460
|
+
return { model: match[1], thinkingLevel: parseThinkingLevel(match[2]) };
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
async function readOraclePreferences(): Promise<OraclePreferences> {
|
|
464
|
+
try {
|
|
465
|
+
const raw = await fs.readFile(getOracleConfigPath(), "utf8");
|
|
466
|
+
const parsed = JSON.parse(raw) as {
|
|
467
|
+
model?: unknown;
|
|
468
|
+
defaultModel?: unknown;
|
|
469
|
+
thinkingLevel?: unknown;
|
|
470
|
+
defaultThinkingLevel?: unknown;
|
|
471
|
+
};
|
|
472
|
+
return {
|
|
473
|
+
model: parseModelPreference(parsed.model).model ?? parseModelPreference(parsed.defaultModel).model,
|
|
474
|
+
thinkingLevel:
|
|
475
|
+
parseThinkingLevel(parsed.thinkingLevel) ??
|
|
476
|
+
parseThinkingLevel(parsed.defaultThinkingLevel) ??
|
|
477
|
+
parseModelPreference(parsed.model).thinkingLevel ??
|
|
478
|
+
parseModelPreference(parsed.defaultModel).thinkingLevel,
|
|
479
|
+
};
|
|
480
|
+
} catch {
|
|
481
|
+
return {};
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
async function writeOraclePreferences(preferences: OraclePreferences): Promise<void> {
|
|
486
|
+
const configPath = getOracleConfigPath();
|
|
487
|
+
const config = {
|
|
488
|
+
...(preferences.model ? { model: preferences.model } : {}),
|
|
489
|
+
...(preferences.thinkingLevel ? { thinkingLevel: preferences.thinkingLevel } : {}),
|
|
490
|
+
updatedAt: new Date().toISOString(),
|
|
491
|
+
};
|
|
492
|
+
await fs.mkdir(path.dirname(configPath), { recursive: true });
|
|
493
|
+
await fs.writeFile(configPath, `${JSON.stringify(config, null, 2)}\n`, "utf8");
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
function formatOraclePreferences(preferences: OraclePreferences): string {
|
|
497
|
+
const model = preferences.model ?? "auto";
|
|
498
|
+
const thinkingLevel = preferences.thinkingLevel ?? "auto";
|
|
499
|
+
return `Oracle defaults: model=${model}, thinkingLevel=${thinkingLevel}. Config: ${getOracleConfigPath()}`;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
function notifyCommand(ctx: any, message: string, kind = "info"): void {
|
|
503
|
+
if (ctx.hasUI && ctx.ui) ctx.ui.notify(message, kind);
|
|
504
|
+
else console.log(message);
|
|
505
|
+
}
|
|
506
|
+
|
|
432
507
|
function formatTokens(count: number): string {
|
|
433
508
|
if (count < 1000) return count.toString();
|
|
434
509
|
if (count < 10000) return `${(count / 1000).toFixed(1)}k`;
|
|
@@ -534,7 +609,7 @@ function getPiInvocation(args: string[]): { command: string; args: string[] } {
|
|
|
534
609
|
return { command: process.execPath, args: [currentScript, ...args] };
|
|
535
610
|
}
|
|
536
611
|
|
|
537
|
-
const execName = basename(process.execPath).toLowerCase();
|
|
612
|
+
const execName = path.basename(process.execPath).toLowerCase();
|
|
538
613
|
const isGenericRuntime = /^(node|bun)(\.exe)?$/.test(execName);
|
|
539
614
|
if (!isGenericRuntime) {
|
|
540
615
|
return { command: process.execPath, args };
|
|
@@ -593,7 +668,7 @@ function appendThinkingLevelClampReason(
|
|
|
593
668
|
}
|
|
594
669
|
|
|
595
670
|
async function findAvailableModel(
|
|
596
|
-
ctx: { model?: PiModel; modelRegistry: { getAvailable(): Promise<PiModel[]> } },
|
|
671
|
+
ctx: { model?: PiModel; modelRegistry: { getAvailable(): PiModel[] | Promise<PiModel[]> } },
|
|
597
672
|
modelRef: string,
|
|
598
673
|
): Promise<PiModel | undefined> {
|
|
599
674
|
const available = await ctx.modelRegistry.getAvailable();
|
|
@@ -621,7 +696,7 @@ async function findAvailableModel(
|
|
|
621
696
|
}
|
|
622
697
|
|
|
623
698
|
async function selectOracleModel(
|
|
624
|
-
ctx: { model?: PiModel; modelRegistry: { getAvailable(): Promise<PiModel[]> } },
|
|
699
|
+
ctx: { model?: PiModel; modelRegistry: { getAvailable(): PiModel[] | Promise<PiModel[]> } },
|
|
625
700
|
thinkingLevelOverride?: ThinkingLevel,
|
|
626
701
|
): Promise<{ ok: true; selection: OracleSelection } | { ok: false; error: string }> {
|
|
627
702
|
const available = await ctx.modelRegistry.getAvailable();
|
|
@@ -677,14 +752,7 @@ async function selectOracleModel(
|
|
|
677
752
|
};
|
|
678
753
|
}
|
|
679
754
|
|
|
680
|
-
function updateOracleUi(ctx:
|
|
681
|
-
args: any,
|
|
682
|
-
ctx: infer T,
|
|
683
|
-
) => any
|
|
684
|
-
? T
|
|
685
|
-
: never,
|
|
686
|
-
activeRuns: Map<string, OracleUiRun>,
|
|
687
|
-
): void {
|
|
755
|
+
function updateOracleUi(ctx: ExtensionContext, activeRuns: Map<string, OracleUiRun>): void {
|
|
688
756
|
if (!ctx.hasUI) return;
|
|
689
757
|
const theme = ctx.ui.theme;
|
|
690
758
|
if (activeRuns.size === 0) {
|
|
@@ -893,26 +961,147 @@ function renderCollapsedText(text: string, lineLimit = COLLAPSED_LINE_LIMIT): st
|
|
|
893
961
|
|
|
894
962
|
export default function oracleExtension(pi: ExtensionAPI) {
|
|
895
963
|
const activeRuns = new Map<string, OracleUiRun>();
|
|
964
|
+
let preferences: OraclePreferences = {};
|
|
896
965
|
|
|
897
966
|
pi.on("session_start", async (_event, ctx) => {
|
|
967
|
+
preferences = await readOraclePreferences();
|
|
898
968
|
activeRuns.clear();
|
|
899
969
|
updateOracleUi(ctx, activeRuns);
|
|
900
970
|
});
|
|
901
971
|
|
|
972
|
+
pi.registerCommand("oracle", {
|
|
973
|
+
description: "Configure Oracle default model and thinking level for future oracle tool calls",
|
|
974
|
+
getArgumentCompletions: (prefix) => {
|
|
975
|
+
const parts = prefix.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
976
|
+
const first = parts[0] ?? "";
|
|
977
|
+
if (parts.length <= 1) {
|
|
978
|
+
const commands = ["status", "model", "thinking", "clear"];
|
|
979
|
+
const matches = commands.filter((command) => command.startsWith(first));
|
|
980
|
+
return matches.length > 0 ? matches.map((value) => ({ value, label: value })) : null;
|
|
981
|
+
}
|
|
982
|
+
if (parts[0] === "thinking") {
|
|
983
|
+
const query = parts[1] ?? "";
|
|
984
|
+
const values = ["auto", ...THINKING_LEVELS];
|
|
985
|
+
const matches = values.filter((value) => value.startsWith(query));
|
|
986
|
+
return matches.length > 0 ? matches.map((value) => ({ value, label: value })) : null;
|
|
987
|
+
}
|
|
988
|
+
if (parts[0] === "clear") {
|
|
989
|
+
const query = parts[1] ?? "";
|
|
990
|
+
const values = ["all", "model", "thinking"];
|
|
991
|
+
const matches = values.filter((value) => value.startsWith(query));
|
|
992
|
+
return matches.length > 0 ? matches.map((value) => ({ value, label: value })) : null;
|
|
993
|
+
}
|
|
994
|
+
return null;
|
|
995
|
+
},
|
|
996
|
+
handler: async (args, ctx) => {
|
|
997
|
+
const raw = args.trim();
|
|
998
|
+
const tokens = raw ? raw.split(/\s+/) : [];
|
|
999
|
+
const [command = "status", ...rest] = tokens;
|
|
1000
|
+
const action = command.toLowerCase();
|
|
1001
|
+
const configPath = getOracleConfigPath();
|
|
1002
|
+
|
|
1003
|
+
const save = async (next: OraclePreferences): Promise<string | undefined> => {
|
|
1004
|
+
preferences = next;
|
|
1005
|
+
try {
|
|
1006
|
+
await writeOraclePreferences(preferences);
|
|
1007
|
+
return undefined;
|
|
1008
|
+
} catch (error) {
|
|
1009
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1010
|
+
return `Preference changed for this process, but could not save ${configPath}: ${message}`;
|
|
1011
|
+
}
|
|
1012
|
+
};
|
|
1013
|
+
|
|
1014
|
+
if (action === "status" || action === "show") {
|
|
1015
|
+
notifyCommand(ctx, formatOraclePreferences(preferences));
|
|
1016
|
+
return;
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
if (action === "model") {
|
|
1020
|
+
const model = rest.join(" ").trim();
|
|
1021
|
+
const normalizedModelAction = model.toLowerCase();
|
|
1022
|
+
if (!model) {
|
|
1023
|
+
notifyCommand(ctx, "Usage: /oracle model <provider/model|auto>", "warning");
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
if (normalizedModelAction === "auto" || normalizedModelAction === "clear" || normalizedModelAction === "default") {
|
|
1027
|
+
const warning = await save({ ...preferences, model: undefined });
|
|
1028
|
+
notifyCommand(ctx, `Oracle default model cleared; future oracle calls will auto-select. ${warning ?? formatOraclePreferences(preferences)}`, warning ? "warning" : "info");
|
|
1029
|
+
return;
|
|
1030
|
+
}
|
|
1031
|
+
const parsedModel = parseModelPreference(model);
|
|
1032
|
+
const next = {
|
|
1033
|
+
...preferences,
|
|
1034
|
+
model: parsedModel.model,
|
|
1035
|
+
thinkingLevel: parsedModel.thinkingLevel ?? preferences.thinkingLevel,
|
|
1036
|
+
};
|
|
1037
|
+
const warning = await save(next);
|
|
1038
|
+
notifyCommand(ctx, `Oracle default model set to ${parsedModel.model}. ${warning ?? formatOraclePreferences(preferences)}`, warning ? "warning" : "info");
|
|
1039
|
+
return;
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
if (action === "thinking" || action === "think" || action === "thinking-level") {
|
|
1043
|
+
const value = rest[0]?.trim().toLowerCase();
|
|
1044
|
+
if (!value) {
|
|
1045
|
+
notifyCommand(ctx, `Usage: /oracle thinking ${THINKING_LEVELS.join(" | ")} | auto`, "warning");
|
|
1046
|
+
return;
|
|
1047
|
+
}
|
|
1048
|
+
if (value === "auto" || value === "clear" || value === "default") {
|
|
1049
|
+
const warning = await save({ ...preferences, thinkingLevel: undefined });
|
|
1050
|
+
notifyCommand(ctx, `Oracle default thinking level cleared; future oracle calls will use built-in defaults. ${warning ?? formatOraclePreferences(preferences)}`, warning ? "warning" : "info");
|
|
1051
|
+
return;
|
|
1052
|
+
}
|
|
1053
|
+
const thinkingLevel = parseThinkingLevel(value);
|
|
1054
|
+
if (!thinkingLevel) {
|
|
1055
|
+
notifyCommand(ctx, `Usage: /oracle thinking ${THINKING_LEVELS.join(" | ")} | auto`, "warning");
|
|
1056
|
+
return;
|
|
1057
|
+
}
|
|
1058
|
+
const warning = await save({ ...preferences, thinkingLevel });
|
|
1059
|
+
notifyCommand(ctx, `Oracle default thinking level set to ${thinkingLevel}. ${warning ?? formatOraclePreferences(preferences)}`, warning ? "warning" : "info");
|
|
1060
|
+
return;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
if (action === "clear" || action === "reset") {
|
|
1064
|
+
const target = rest[0]?.trim().toLowerCase() || "all";
|
|
1065
|
+
let next: OraclePreferences;
|
|
1066
|
+
if (target === "all") next = {};
|
|
1067
|
+
else if (target === "model") next = { ...preferences, model: undefined };
|
|
1068
|
+
else if (target === "thinking" || target === "thinking-level") next = { ...preferences, thinkingLevel: undefined };
|
|
1069
|
+
else {
|
|
1070
|
+
notifyCommand(ctx, "Usage: /oracle clear [all|model|thinking]", "warning");
|
|
1071
|
+
return;
|
|
1072
|
+
}
|
|
1073
|
+
const warning = await save(next);
|
|
1074
|
+
notifyCommand(ctx, `Oracle defaults cleared (${target}). ${warning ?? formatOraclePreferences(preferences)}`, warning ? "warning" : "info");
|
|
1075
|
+
return;
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
notifyCommand(ctx, "Usage: /oracle status | model <provider/model|auto> | thinking <off|minimal|low|medium|high|xhigh|auto> | clear [all|model|thinking]", "warning");
|
|
1079
|
+
},
|
|
1080
|
+
});
|
|
1081
|
+
|
|
902
1082
|
pi.registerCommand("oracle-model", {
|
|
903
1083
|
description: "Show which model the oracle would use right now",
|
|
904
1084
|
handler: async (_args, ctx) => {
|
|
905
|
-
const
|
|
1085
|
+
const defaultModel = parseModelPreference(preferences.model);
|
|
1086
|
+
if (defaultModel.model) {
|
|
1087
|
+
const matched = await findAvailableModel(ctx, defaultModel.model);
|
|
1088
|
+
const thinking = resolveThinkingLevel(matched, preferences.thinkingLevel ?? defaultModel.thinkingLevel);
|
|
1089
|
+
const modelRef = matched ? `${matched.provider}/${matched.id}` : defaultModel.model;
|
|
1090
|
+
const suffix = matched
|
|
1091
|
+
? appendThinkingLevelClampReason("Configured default oracle model is active.", thinking)
|
|
1092
|
+
: "Configured default oracle model is active, but it was not matched against the authenticated model list.";
|
|
1093
|
+
notifyCommand(ctx, `Oracle: ${modelRef} (${thinking.effective}) — ${suffix}`);
|
|
1094
|
+
return;
|
|
1095
|
+
}
|
|
1096
|
+
const selectionResult = await selectOracleModel(ctx, preferences.thinkingLevel);
|
|
906
1097
|
if (!selectionResult.ok) {
|
|
907
|
-
|
|
908
|
-
else console.log(selectionResult.error);
|
|
1098
|
+
notifyCommand(ctx, selectionResult.error, "error");
|
|
909
1099
|
return;
|
|
910
1100
|
}
|
|
911
1101
|
|
|
912
1102
|
const { selection } = selectionResult;
|
|
913
1103
|
const message = `Oracle: ${selection.modelRef} (${selection.thinkingLevel}) — ${selection.selectionReason}`;
|
|
914
|
-
|
|
915
|
-
else console.log(message);
|
|
1104
|
+
notifyCommand(ctx, message);
|
|
916
1105
|
},
|
|
917
1106
|
});
|
|
918
1107
|
|
|
@@ -932,6 +1121,11 @@ export default function oracleExtension(pi: ExtensionAPI) {
|
|
|
932
1121
|
parameters: OracleParams,
|
|
933
1122
|
|
|
934
1123
|
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
|
1124
|
+
const explicitModel = parseModelPreference(params.model);
|
|
1125
|
+
const defaultModel = parseModelPreference(preferences.model);
|
|
1126
|
+
const configuredModel = explicitModel.model ?? defaultModel.model;
|
|
1127
|
+
const configuredThinkingLevel =
|
|
1128
|
+
params.thinkingLevel ?? explicitModel.thinkingLevel ?? preferences.thinkingLevel ?? defaultModel.thinkingLevel;
|
|
935
1129
|
const uiRun: OracleUiRun = {
|
|
936
1130
|
task: params.task,
|
|
937
1131
|
includeBash: params.includeBash ?? false,
|
|
@@ -942,16 +1136,24 @@ export default function oracleExtension(pi: ExtensionAPI) {
|
|
|
942
1136
|
|
|
943
1137
|
try {
|
|
944
1138
|
let selection: OracleSelection;
|
|
945
|
-
if (
|
|
946
|
-
const modelRef =
|
|
1139
|
+
if (configuredModel) {
|
|
1140
|
+
const modelRef = configuredModel;
|
|
947
1141
|
const matched = await findAvailableModel(ctx, modelRef);
|
|
948
1142
|
const provider =
|
|
949
1143
|
matched?.provider ?? (modelRef.includes("/") ? modelRef.split("/")[0] : ctx.model?.provider ?? "unknown");
|
|
950
1144
|
const modelId = matched?.id ?? (modelRef.includes("/") ? modelRef.split("/").slice(1).join("/") : modelRef);
|
|
951
|
-
const thinking = resolveThinkingLevel(matched,
|
|
1145
|
+
const thinking = resolveThinkingLevel(matched, configuredThinkingLevel);
|
|
1146
|
+
const usedToolOverride = !!explicitModel.model;
|
|
952
1147
|
const selectionReason = matched
|
|
953
|
-
? appendThinkingLevelClampReason(
|
|
954
|
-
|
|
1148
|
+
? appendThinkingLevelClampReason(
|
|
1149
|
+
usedToolOverride
|
|
1150
|
+
? "Used the explicit model override provided in the tool call."
|
|
1151
|
+
: "Used the configured default oracle model.",
|
|
1152
|
+
thinking,
|
|
1153
|
+
)
|
|
1154
|
+
: usedToolOverride
|
|
1155
|
+
? "Used the explicit model override provided in the tool call. The model was not matched against the authenticated model list, so the reasoning level fallback was applied."
|
|
1156
|
+
: "Used the configured default oracle model. The model was not matched against the authenticated model list, so the reasoning level fallback was applied.";
|
|
955
1157
|
selection = {
|
|
956
1158
|
modelRef: matched ? `${matched.provider}/${matched.id}` : modelRef,
|
|
957
1159
|
provider,
|
|
@@ -965,7 +1167,7 @@ export default function oracleExtension(pi: ExtensionAPI) {
|
|
|
965
1167
|
selectionReason,
|
|
966
1168
|
};
|
|
967
1169
|
} else {
|
|
968
|
-
const selectionResult = await selectOracleModel(ctx,
|
|
1170
|
+
const selectionResult = await selectOracleModel(ctx, configuredThinkingLevel);
|
|
969
1171
|
if (!selectionResult.ok) {
|
|
970
1172
|
return {
|
|
971
1173
|
content: [{ type: "text", text: selectionResult.error }],
|
|
@@ -974,7 +1176,7 @@ export default function oracleExtension(pi: ExtensionAPI) {
|
|
|
974
1176
|
provider: ctx.model?.provider ?? "unknown",
|
|
975
1177
|
modelId: "",
|
|
976
1178
|
modelName: undefined,
|
|
977
|
-
thinkingLevel:
|
|
1179
|
+
thinkingLevel: configuredThinkingLevel ?? DEFAULT_THINKING_LEVEL,
|
|
978
1180
|
autoSelected: true,
|
|
979
1181
|
selectionReason: selectionResult.error,
|
|
980
1182
|
includeBash: params.includeBash ?? false,
|
|
@@ -984,7 +1186,6 @@ export default function oracleExtension(pi: ExtensionAPI) {
|
|
|
984
1186
|
durationMs: 0,
|
|
985
1187
|
cwd: params.cwd ?? ctx.cwd,
|
|
986
1188
|
},
|
|
987
|
-
isError: true,
|
|
988
1189
|
};
|
|
989
1190
|
}
|
|
990
1191
|
selection = selectionResult.selection;
|
|
@@ -1004,7 +1205,6 @@ export default function oracleExtension(pi: ExtensionAPI) {
|
|
|
1004
1205
|
return {
|
|
1005
1206
|
content: [{ type: "text", text: result.error }],
|
|
1006
1207
|
details: result.details,
|
|
1007
|
-
isError: true,
|
|
1008
1208
|
};
|
|
1009
1209
|
}
|
|
1010
1210
|
|
|
@@ -1035,7 +1235,8 @@ export default function oracleExtension(pi: ExtensionAPI) {
|
|
|
1035
1235
|
const body = result.content[0]?.type === "text" ? result.content[0].text : "(no output)";
|
|
1036
1236
|
if (!details) return new Text(body, 0, 0);
|
|
1037
1237
|
|
|
1038
|
-
const
|
|
1238
|
+
const isError = (details.exitCode ?? 0) !== 0;
|
|
1239
|
+
const icon = isError ? theme.fg("error", "✗") : theme.fg("success", "✓");
|
|
1039
1240
|
const header = `${icon} ${theme.fg("toolTitle", theme.bold("oracle "))}${theme.fg("accent", details.modelRef || "(auto)")}`;
|
|
1040
1241
|
const subheader = [
|
|
1041
1242
|
details.thinkingLevel !== "off" ? details.thinkingLevel : undefined,
|
|
@@ -1051,7 +1252,7 @@ export default function oracleExtension(pi: ExtensionAPI) {
|
|
|
1051
1252
|
if (subheader) text += `\n${theme.fg("dim", subheader)}`;
|
|
1052
1253
|
text += `\n\n${theme.fg("toolOutput", renderCollapsedText(body))}`;
|
|
1053
1254
|
if (usage) text += `\n\n${theme.fg("dim", usage)}`;
|
|
1054
|
-
if (
|
|
1255
|
+
if (isError && details.stderr) text += `\n${theme.fg("error", renderCollapsedText(details.stderr, 4))}`;
|
|
1055
1256
|
text += `\n${theme.fg("muted", "(Ctrl+O to expand)")}`;
|
|
1056
1257
|
return new Text(text, 0, 0);
|
|
1057
1258
|
}
|
|
@@ -1074,7 +1275,7 @@ export default function oracleExtension(pi: ExtensionAPI) {
|
|
|
1074
1275
|
container.addChild(new Spacer(1));
|
|
1075
1276
|
container.addChild(new Text(theme.fg("muted", "stderr"), 0, 0));
|
|
1076
1277
|
container.addChild(
|
|
1077
|
-
new Text(
|
|
1278
|
+
new Text(isError ? theme.fg("error", details.stderr) : theme.fg("dim", details.stderr), 0, 0),
|
|
1078
1279
|
);
|
|
1079
1280
|
}
|
|
1080
1281
|
return container;
|
package/package.json
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diegopetrucci/pi-oracle",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "An Amp-style oracle extension for pi that consults the strongest reasoning model on your current provider.",
|
|
5
|
-
"keywords": [
|
|
5
|
+
"keywords": [
|
|
6
|
+
"pi-package",
|
|
7
|
+
"pi",
|
|
8
|
+
"oracle",
|
|
9
|
+
"reasoning",
|
|
10
|
+
"subagent"
|
|
11
|
+
],
|
|
6
12
|
"license": "MIT",
|
|
7
13
|
"repository": {
|
|
8
14
|
"type": "git",
|
|
@@ -11,7 +17,8 @@
|
|
|
11
17
|
},
|
|
12
18
|
"files": [
|
|
13
19
|
"index.ts",
|
|
14
|
-
"README.md"
|
|
20
|
+
"README.md",
|
|
21
|
+
".pi-fleet-tested-version"
|
|
15
22
|
],
|
|
16
23
|
"publishConfig": {
|
|
17
24
|
"access": "public"
|