Auto-select default model and clean package conflicts
This commit is contained in:
@@ -4,7 +4,6 @@
|
|||||||
"npm:pi-docparser",
|
"npm:pi-docparser",
|
||||||
"npm:pi-web-access",
|
"npm:pi-web-access",
|
||||||
"npm:pi-markdown-preview",
|
"npm:pi-markdown-preview",
|
||||||
"npm:@kaiserlich-dev/pi-session-search",
|
|
||||||
"npm:@aliou/pi-processes",
|
"npm:@aliou/pi-processes",
|
||||||
"npm:pi-wandb",
|
"npm:pi-wandb",
|
||||||
"npm:pi-zotero"
|
"npm:pi-zotero"
|
||||||
|
|||||||
1
package-lock.json
generated
1
package-lock.json
generated
@@ -7,6 +7,7 @@
|
|||||||
"": {
|
"": {
|
||||||
"name": "@companion-ai/feynman",
|
"name": "@companion-ai/feynman",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@companion-ai/alpha-hub": "^0.1.1",
|
"@companion-ai/alpha-hub": "^0.1.1",
|
||||||
"@mariozechner/pi-ai": "^0.56.1",
|
"@mariozechner/pi-ai": "^0.56.1",
|
||||||
|
|||||||
97
src/index.ts
97
src/index.ts
@@ -101,6 +101,80 @@ function patchEmbeddedPiBranding(piPackageRoot: string): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function choosePreferredModel(
|
||||||
|
availableModels: Array<{ provider: string; id: string }>,
|
||||||
|
): { provider: string; id: string } | undefined {
|
||||||
|
const preferences = [
|
||||||
|
{ provider: "anthropic", id: "claude-opus-4-6" },
|
||||||
|
{ provider: "anthropic", id: "claude-opus-4-5" },
|
||||||
|
{ provider: "anthropic", id: "claude-sonnet-4-5" },
|
||||||
|
{ provider: "openai", id: "gpt-5.4" },
|
||||||
|
{ provider: "openai", id: "gpt-5" },
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const preferred of preferences) {
|
||||||
|
const match = availableModels.find(
|
||||||
|
(model) => model.provider === preferred.provider && model.id === preferred.id,
|
||||||
|
);
|
||||||
|
if (match) {
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return availableModels[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeFeynmanSettings(
|
||||||
|
settingsPath: string,
|
||||||
|
bundledSettingsPath: string,
|
||||||
|
defaultThinkingLevel: ThinkingLevel,
|
||||||
|
authPath: string,
|
||||||
|
): void {
|
||||||
|
let settings: Record<string, unknown> = {};
|
||||||
|
|
||||||
|
if (existsSync(settingsPath)) {
|
||||||
|
try {
|
||||||
|
settings = JSON.parse(readFileSync(settingsPath, "utf8"));
|
||||||
|
} catch {
|
||||||
|
settings = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (existsSync(bundledSettingsPath)) {
|
||||||
|
try {
|
||||||
|
settings = JSON.parse(readFileSync(bundledSettingsPath, "utf8"));
|
||||||
|
} catch {
|
||||||
|
settings = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(settings.packages)) {
|
||||||
|
settings.packages = settings.packages.filter(
|
||||||
|
(entry) => entry !== "npm:@kaiserlich-dev/pi-session-search",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!settings.defaultThinkingLevel) {
|
||||||
|
settings.defaultThinkingLevel = defaultThinkingLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
const authStorage = AuthStorage.create(authPath);
|
||||||
|
const modelRegistry = new ModelRegistry(authStorage);
|
||||||
|
const availableModels = modelRegistry.getAvailable().map((model) => ({
|
||||||
|
provider: model.provider,
|
||||||
|
id: model.id,
|
||||||
|
}));
|
||||||
|
|
||||||
|
if ((!settings.defaultProvider || !settings.defaultModel) && availableModels.length > 0) {
|
||||||
|
const preferredModel = choosePreferredModel(availableModels);
|
||||||
|
if (preferredModel) {
|
||||||
|
settings.defaultProvider = preferredModel.provider;
|
||||||
|
settings.defaultModel = preferredModel.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
||||||
|
}
|
||||||
|
|
||||||
async function main(): Promise<void> {
|
async function main(): Promise<void> {
|
||||||
const here = dirname(fileURLToPath(import.meta.url));
|
const here = dirname(fileURLToPath(import.meta.url));
|
||||||
const appRoot = resolve(here, "..");
|
const appRoot = resolve(here, "..");
|
||||||
@@ -131,8 +205,18 @@ async function main(): Promise<void> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const workingDir = resolve(values.cwd ?? process.cwd());
|
||||||
|
const sessionDir = resolve(values["session-dir"] ?? resolve(homedir(), ".feynman", "sessions"));
|
||||||
|
mkdirSync(sessionDir, { recursive: true });
|
||||||
|
mkdirSync(feynmanAgentDir, { recursive: true });
|
||||||
|
const feynmanSettingsPath = resolve(feynmanAgentDir, "settings.json");
|
||||||
|
const feynmanAuthPath = resolve(feynmanAgentDir, "auth.json");
|
||||||
|
const thinkingLevel = normalizeThinkingLevel(values.thinking ?? process.env.FEYNMAN_THINKING) ?? "medium";
|
||||||
|
normalizeFeynmanSettings(feynmanSettingsPath, bundledSettingsPath, thinkingLevel, feynmanAuthPath);
|
||||||
|
|
||||||
if (values["alpha-login"]) {
|
if (values["alpha-login"]) {
|
||||||
const result = await loginAlpha();
|
const result = await loginAlpha();
|
||||||
|
normalizeFeynmanSettings(feynmanSettingsPath, bundledSettingsPath, thinkingLevel, feynmanAuthPath);
|
||||||
const name =
|
const name =
|
||||||
(result.userInfo &&
|
(result.userInfo &&
|
||||||
typeof result.userInfo === "object" &&
|
typeof result.userInfo === "object" &&
|
||||||
@@ -160,25 +244,14 @@ async function main(): Promise<void> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const workingDir = resolve(values.cwd ?? process.cwd());
|
|
||||||
const sessionDir = resolve(values["session-dir"] ?? resolve(homedir(), ".feynman", "sessions"));
|
|
||||||
mkdirSync(sessionDir, { recursive: true });
|
|
||||||
mkdirSync(feynmanAgentDir, { recursive: true });
|
|
||||||
const feynmanSettingsPath = resolve(feynmanAgentDir, "settings.json");
|
|
||||||
if (!existsSync(feynmanSettingsPath) && existsSync(bundledSettingsPath)) {
|
|
||||||
writeFileSync(feynmanSettingsPath, readFileSync(bundledSettingsPath, "utf8"), "utf8");
|
|
||||||
}
|
|
||||||
|
|
||||||
const explicitModelSpec = values.model ?? process.env.FEYNMAN_MODEL;
|
const explicitModelSpec = values.model ?? process.env.FEYNMAN_MODEL;
|
||||||
if (explicitModelSpec) {
|
if (explicitModelSpec) {
|
||||||
const modelRegistry = new ModelRegistry(AuthStorage.create());
|
const modelRegistry = new ModelRegistry(AuthStorage.create(feynmanAuthPath));
|
||||||
const explicitModel = parseModelSpec(explicitModelSpec, modelRegistry);
|
const explicitModel = parseModelSpec(explicitModelSpec, modelRegistry);
|
||||||
if (!explicitModel) {
|
if (!explicitModel) {
|
||||||
throw new Error(`Unknown model: ${explicitModelSpec}`);
|
throw new Error(`Unknown model: ${explicitModelSpec}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const thinkingLevel = normalizeThinkingLevel(values.thinking ?? process.env.FEYNMAN_THINKING) ?? "medium";
|
|
||||||
const oneShotPrompt = values.prompt;
|
const oneShotPrompt = values.prompt;
|
||||||
const initialPrompt = oneShotPrompt ?? (positionals.length > 0 ? positionals.join(" ") : undefined);
|
const initialPrompt = oneShotPrompt ?? (positionals.length > 0 ? positionals.join(" ") : undefined);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user