feat(ai): add max thinking level
This commit is contained in:
@@ -54,7 +54,7 @@ export interface Args {
|
||||
diagnostics: Array<{ type: "warning" | "error"; message: string }>;
|
||||
}
|
||||
|
||||
const VALID_THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh"] as const;
|
||||
const VALID_THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh", "max"] as const;
|
||||
|
||||
export function isValidThinkingLevel(level: string): level is ThinkingLevel {
|
||||
return VALID_THINKING_LEVELS.includes(level as ThinkingLevel);
|
||||
@@ -258,7 +258,7 @@ ${chalk.bold("Options:")}
|
||||
Applies to built-in, extension, and custom tools
|
||||
--exclude-tools, -xt <tools> Comma-separated denylist of tool names to disable
|
||||
Applies to built-in, extension, and custom tools
|
||||
--thinking <level> Set thinking level: off, minimal, low, medium, high, xhigh
|
||||
--thinking <level> Set thinking level: off, minimal, low, medium, high, xhigh, max
|
||||
--extension, -e <path> Load an extension file (can be used multiple times)
|
||||
--no-extensions, -ne Disable extension discovery (explicit -e paths still work)
|
||||
--skill <path> Load a skill file or directory (can be used multiple times)
|
||||
|
||||
@@ -94,6 +94,7 @@ const ThinkingLevelMapSchema = Type.Object({
|
||||
medium: Type.Optional(ThinkingLevelMapValueSchema),
|
||||
high: Type.Optional(ThinkingLevelMapValueSchema),
|
||||
xhigh: Type.Optional(ThinkingLevelMapValueSchema),
|
||||
max: Type.Optional(ThinkingLevelMapValueSchema),
|
||||
});
|
||||
|
||||
const ChatTemplateKwargScalarSchema = Type.Union([Type.String(), Type.Number(), Type.Boolean(), Type.Null()]);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { ThinkingLevel } from "@earendil-works/pi-agent-core";
|
||||
import type { Transport } from "@earendil-works/pi-ai";
|
||||
import { randomUUID } from "crypto";
|
||||
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
||||
@@ -83,7 +84,7 @@ export interface Settings {
|
||||
lastChangelogVersion?: string;
|
||||
defaultProvider?: string;
|
||||
defaultModel?: string;
|
||||
defaultThinkingLevel?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
|
||||
defaultThinkingLevel?: ThinkingLevel;
|
||||
transport?: TransportSetting; // default: "auto"
|
||||
steeringMode?: "all" | "one-at-a-time";
|
||||
followUpMode?: "all" | "one-at-a-time";
|
||||
@@ -736,11 +737,11 @@ export class SettingsManager {
|
||||
this.save();
|
||||
}
|
||||
|
||||
getDefaultThinkingLevel(): "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | undefined {
|
||||
getDefaultThinkingLevel(): ThinkingLevel | undefined {
|
||||
return this.settings.defaultThinkingLevel;
|
||||
}
|
||||
|
||||
setDefaultThinkingLevel(level: "off" | "minimal" | "low" | "medium" | "high" | "xhigh"): void {
|
||||
setDefaultThinkingLevel(level: ThinkingLevel): void {
|
||||
this.globalSettings.defaultThinkingLevel = level;
|
||||
this.markModified("defaultThinkingLevel");
|
||||
this.save();
|
||||
|
||||
@@ -35,7 +35,8 @@ const THINKING_DESCRIPTIONS: Record<ThinkingLevel, string> = {
|
||||
low: "Light reasoning (~2k tokens)",
|
||||
medium: "Moderate reasoning (~8k tokens)",
|
||||
high: "Deep reasoning (~16k tokens)",
|
||||
xhigh: "Maximum reasoning (~32k tokens)",
|
||||
xhigh: "Extra-high reasoning (~32k tokens)",
|
||||
max: "Maximum reasoning",
|
||||
};
|
||||
|
||||
const DEFAULT_PROJECT_TRUST_LABELS: Record<DefaultProjectTrust, string> = {
|
||||
|
||||
@@ -14,7 +14,8 @@ const LEVEL_DESCRIPTIONS: Record<ThinkingLevel, string> = {
|
||||
low: "Light reasoning (~2k tokens)",
|
||||
medium: "Moderate reasoning (~8k tokens)",
|
||||
high: "Deep reasoning (~16k tokens)",
|
||||
xhigh: "Maximum reasoning (~32k tokens)",
|
||||
xhigh: "Extra-high reasoning (~32k tokens)",
|
||||
max: "Maximum reasoning",
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
"thinkingMedium": "#81a2be",
|
||||
"thinkingHigh": "#b294bb",
|
||||
"thinkingXhigh": "#d183e8",
|
||||
"thinkingMax": "#ff5fff",
|
||||
|
||||
"bashMode": "green"
|
||||
},
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
"thinkingMedium": "teal",
|
||||
"thinkingHigh": "#875f87",
|
||||
"thinkingXhigh": "#8b008b",
|
||||
"thinkingMax": "#af005f",
|
||||
|
||||
"bashMode": "green"
|
||||
},
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
},
|
||||
"colors": {
|
||||
"type": "object",
|
||||
"description": "Theme color definitions (all required)",
|
||||
"description": "Theme color definitions (thinkingMax is optional and falls back to thinkingXhigh)",
|
||||
"required": [
|
||||
"accent",
|
||||
"border",
|
||||
@@ -287,7 +287,11 @@
|
||||
},
|
||||
"thinkingXhigh": {
|
||||
"$ref": "#/$defs/colorValue",
|
||||
"description": "Thinking level border: xhigh (OpenAI codex-max only)"
|
||||
"description": "Thinking level border: xhigh"
|
||||
},
|
||||
"thinkingMax": {
|
||||
"$ref": "#/$defs/colorValue",
|
||||
"description": "Thinking level border: max (falls back to thinkingXhigh when omitted)"
|
||||
},
|
||||
"bashMode": {
|
||||
"$ref": "#/$defs/colorValue",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as fs from "node:fs";
|
||||
import * as path from "node:path";
|
||||
import type { ThinkingLevel } from "@earendil-works/pi-agent-core";
|
||||
import {
|
||||
type EditorTheme,
|
||||
getCapabilities,
|
||||
@@ -88,6 +89,7 @@ const ThemeJsonSchema = Type.Object({
|
||||
thinkingMedium: ColorValueSchema,
|
||||
thinkingHigh: ColorValueSchema,
|
||||
thinkingXhigh: ColorValueSchema,
|
||||
thinkingMax: Type.Optional(ColorValueSchema),
|
||||
// Bash Mode (1 color)
|
||||
bashMode: ColorValueSchema,
|
||||
}),
|
||||
@@ -149,6 +151,7 @@ export type ThemeColor =
|
||||
| "thinkingMedium"
|
||||
| "thinkingHigh"
|
||||
| "thinkingXhigh"
|
||||
| "thinkingMax"
|
||||
| "bashMode";
|
||||
|
||||
export type ThemeBg =
|
||||
@@ -316,6 +319,10 @@ function resolveThemeColors<T extends Record<string, ColorValue>>(
|
||||
return resolved as Record<keyof T, string | number>;
|
||||
}
|
||||
|
||||
function withThemeColorFallbacks(colors: ThemeJson["colors"]): ThemeJson["colors"] & { thinkingMax: ColorValue } {
|
||||
return { ...colors, thinkingMax: colors.thinkingMax ?? colors.thinkingXhigh };
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Theme Class
|
||||
// ============================================================================
|
||||
@@ -339,7 +346,8 @@ export class Theme {
|
||||
this.sourceInfo = options.sourceInfo;
|
||||
this.mode = mode;
|
||||
this.fgColors = new Map();
|
||||
for (const [key, value] of Object.entries(fgColors) as [ThemeColor, string | number][]) {
|
||||
const colors = { ...fgColors, thinkingMax: fgColors.thinkingMax ?? fgColors.thinkingXhigh };
|
||||
for (const [key, value] of Object.entries(colors) as [ThemeColor, string | number][]) {
|
||||
this.fgColors.set(key, fgAnsi(value, mode));
|
||||
}
|
||||
this.bgColors = new Map();
|
||||
@@ -396,7 +404,7 @@ export class Theme {
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
getThinkingBorderColor(level: "off" | "minimal" | "low" | "medium" | "high" | "xhigh"): (str: string) => string {
|
||||
getThinkingBorderColor(level: ThinkingLevel): (str: string) => string {
|
||||
// Map thinking levels to dedicated theme colors
|
||||
switch (level) {
|
||||
case "off":
|
||||
@@ -411,6 +419,8 @@ export class Theme {
|
||||
return (str: string) => this.fg("thinkingHigh", str);
|
||||
case "xhigh":
|
||||
return (str: string) => this.fg("thinkingXhigh", str);
|
||||
case "max":
|
||||
return (str: string) => this.fg("thinkingMax", str);
|
||||
default:
|
||||
return (str: string) => this.fg("thinkingOff", str);
|
||||
}
|
||||
@@ -586,7 +596,7 @@ function loadThemeJson(name: string): ThemeJson {
|
||||
|
||||
function createTheme(themeJson: ThemeJson, mode?: ColorMode, sourcePath?: string): Theme {
|
||||
const colorMode = mode ?? (getCapabilities().trueColor ? "truecolor" : "256color");
|
||||
const resolvedColors = resolveThemeColors(themeJson.colors, themeJson.vars);
|
||||
const resolvedColors = resolveThemeColors(withThemeColorFallbacks(themeJson.colors), themeJson.vars);
|
||||
const fgColors: Record<ThemeColor, string | number> = {} as Record<ThemeColor, string | number>;
|
||||
const bgColors: Record<ThemeBg, string | number> = {} as Record<ThemeBg, string | number>;
|
||||
const bgColorKeys: Set<string> = new Set([
|
||||
@@ -1013,7 +1023,7 @@ export function getResolvedThemeColors(themeName?: string): Record<string, strin
|
||||
const name = themeName ?? currentThemeName ?? getDefaultTheme();
|
||||
const isLight = name === "light";
|
||||
const themeJson = loadThemeJson(name);
|
||||
const resolved = resolveThemeColors(themeJson.colors, themeJson.vars);
|
||||
const resolved = resolveThemeColors(withThemeColorFallbacks(themeJson.colors), themeJson.vars);
|
||||
|
||||
// Default text color for empty values (terminal uses default fg color)
|
||||
const defaultText = isLight ? "#000000" : "#e5e5e7";
|
||||
|
||||
Reference in New Issue
Block a user