Fix extension repair and add Opus 4.7 overlay

This commit is contained in:
Advait Paliwal
2026-04-16 14:05:17 -07:00
parent 46b2aa93d0
commit ca559dfd91
13 changed files with 152 additions and 15 deletions

View File

@@ -1,11 +1,41 @@
import { dirname, resolve } from "node:path";
import { AuthStorage, ModelRegistry } from "@mariozechner/pi-coding-agent";
import { getModels } from "@mariozechner/pi-ai";
import { anthropicOAuthProvider } from "@mariozechner/pi-ai/oauth";
export function getModelsJsonPath(authPath: string): string {
return resolve(dirname(authPath), "models.json");
}
export function createModelRegistry(authPath: string): ModelRegistry {
return ModelRegistry.create(AuthStorage.create(authPath), getModelsJsonPath(authPath));
function registerFeynmanModelOverlays(modelRegistry: ModelRegistry): void {
const anthropicModels = getModels("anthropic");
if (anthropicModels.some((model) => model.id === "claude-opus-4-7")) {
return;
}
const opus46 = anthropicModels.find((model) => model.id === "claude-opus-4-6");
if (!opus46) {
return;
}
modelRegistry.registerProvider("anthropic", {
baseUrl: "https://api.anthropic.com",
api: "anthropic-messages",
oauth: anthropicOAuthProvider,
models: [
...anthropicModels,
{
...opus46,
id: "claude-opus-4-7",
name: "Claude Opus 4.7",
},
],
});
}
export function createModelRegistry(authPath: string): ModelRegistry {
const registry = ModelRegistry.create(AuthStorage.create(authPath), getModelsJsonPath(authPath));
registerFeynmanModelOverlays(registry);
return registry;
}

View File

@@ -1,5 +1,5 @@
import { spawn } from "node:child_process";
import { cpSync, existsSync, lstatSync, mkdirSync, readlinkSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
import { cpSync, existsSync, lstatSync, mkdirSync, readFileSync, readlinkSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { dirname, join, resolve } from "node:path";
@@ -423,6 +423,47 @@ function linkDirectory(linkPath: string, targetPath: string): void {
}
}
function packageNameToPath(root: string, packageName: string): string {
return resolve(root, packageName);
}
function packageDependencyExists(packagePath: string, globalNodeModulesRoot: string, dependency: string): boolean {
return existsSync(packageNameToPath(resolve(packagePath, "node_modules"), dependency)) ||
existsSync(packageNameToPath(globalNodeModulesRoot, dependency));
}
function installedPackageLooksUsable(packagePath: string, globalNodeModulesRoot: string): boolean {
if (!existsSync(resolve(packagePath, "package.json"))) {
return false;
}
try {
const pkg = JSON.parse(readFileSync(resolve(packagePath, "package.json"), "utf8")) as {
dependencies?: Record<string, string>;
};
const dependencies = Object.keys(pkg.dependencies ?? {});
return dependencies.every((dependency) => packageDependencyExists(packagePath, globalNodeModulesRoot, dependency));
} catch {
return false;
}
}
function replaceBrokenPackageWithBundledCopy(targetPath: string, bundledPackagePath: string, globalNodeModulesRoot: string): boolean {
if (!existsSync(targetPath)) {
return false;
}
if (pathsMatchSymlinkTarget(targetPath, bundledPackagePath)) {
return false;
}
if (installedPackageLooksUsable(targetPath, globalNodeModulesRoot)) {
return false;
}
rmSync(targetPath, { recursive: true, force: true });
linkDirectory(targetPath, bundledPackagePath);
return true;
}
export function seedBundledWorkspacePackages(
agentDir: string,
appRoot: string,
@@ -446,6 +487,10 @@ export function seedBundledWorkspacePackages(
if (!existsSync(bundledPackagePath)) continue;
const targetPath = resolve(globalNodeModulesRoot, parsed.name);
if (replaceBrokenPackageWithBundledCopy(targetPath, bundledPackagePath, globalNodeModulesRoot)) {
seeded.push(source);
continue;
}
if (!existsSync(targetPath)) {
linkDirectory(targetPath, bundledPackagePath);
seeded.push(source);