fix(FN-1952): restore pi auth and extension loading
This commit is contained in:
@@ -22,6 +22,10 @@ export function getFusionAuthPath(home = getHomeDir()): string {
|
||||
return join(home, ".fusion", "agent", "auth.json");
|
||||
}
|
||||
|
||||
export function getFusionModelsPath(home = getHomeDir()): string {
|
||||
return join(home, ".fusion", "agent", "models.json");
|
||||
}
|
||||
|
||||
function getLegacyAuthPaths(home = getHomeDir()): string[] {
|
||||
return [
|
||||
join(home, ".pi", "agent", "auth.json"),
|
||||
@@ -29,6 +33,22 @@ function getLegacyAuthPaths(home = getHomeDir()): string[] {
|
||||
];
|
||||
}
|
||||
|
||||
function getLegacyModelsPaths(home = getHomeDir()): string[] {
|
||||
return [
|
||||
join(home, ".pi", "agent", "models.json"),
|
||||
join(home, ".pi", "models.json"),
|
||||
];
|
||||
}
|
||||
|
||||
export function getModelRegistryModelsPath(home = getHomeDir()): string {
|
||||
const fusionModelsPath = getFusionModelsPath(home);
|
||||
if (existsSync(fusionModelsPath)) {
|
||||
return fusionModelsPath;
|
||||
}
|
||||
|
||||
return getLegacyModelsPaths(home).find((modelsPath) => existsSync(modelsPath)) ?? fusionModelsPath;
|
||||
}
|
||||
|
||||
function readLegacyCredentials(authPaths = getLegacyAuthPaths()): Record<string, StoredCredential> {
|
||||
const credentials: Record<string, StoredCredential> = {};
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import { Type, type Static } from "@mariozechner/pi-ai";
|
||||
import { createKbAgent, describeModel, promptWithFallback, compactSessionContext } from "./pi.js";
|
||||
import { buildSessionSkillContext } from "./session-skill-context.js";
|
||||
import { reviewStep, type ReviewVerdict } from "./reviewer.js";
|
||||
import { ModelRegistry, SessionManager, getAgentDir, type ToolDefinition, type AgentSession } from "@mariozechner/pi-coding-agent";
|
||||
import { ModelRegistry, SessionManager, type ToolDefinition, type AgentSession } from "@mariozechner/pi-coding-agent";
|
||||
import { PRIORITY_EXECUTE, type AgentSemaphore } from "./concurrency.js";
|
||||
import { isRegisteredGitWorktree, isUsableTaskWorktree, type WorktreePool } from "./worktree-pool.js";
|
||||
import { AgentLogger } from "./agent-logger.js";
|
||||
@@ -42,7 +42,7 @@ import {
|
||||
createTaskLogTool as sharedCreateTaskLogTool,
|
||||
} from "./agent-tools.js";
|
||||
import { getTaskCompletionBlockerForStore } from "./task-completion.js";
|
||||
import { createFusionAuthStorage } from "./auth-storage.js";
|
||||
import { createFusionAuthStorage, getModelRegistryModelsPath } from "./auth-storage.js";
|
||||
|
||||
// Re-export for backward compatibility (tests import from executor.ts)
|
||||
export { summarizeToolArgs } from "./agent-logger.js";
|
||||
@@ -392,7 +392,7 @@ export class TaskExecutor {
|
||||
private get modelRegistry(): InstanceType<typeof ModelRegistry> {
|
||||
if (!this._modelRegistry) {
|
||||
const authStorage = createFusionAuthStorage();
|
||||
this._modelRegistry = new ModelRegistry(authStorage, join(getAgentDir(), "models.json"));
|
||||
this._modelRegistry = new ModelRegistry(authStorage, getModelRegistryModelsPath());
|
||||
this._modelRegistry.refresh();
|
||||
}
|
||||
return this._modelRegistry;
|
||||
|
||||
@@ -422,7 +422,11 @@ describe("createKbAgent", () => {
|
||||
defaultModelId: "glm-5.1",
|
||||
});
|
||||
|
||||
expect(discoverAndLoadExtensionsMock).toHaveBeenCalledWith(["/extensions/zai-provider"], "/tmp", undefined);
|
||||
expect(discoverAndLoadExtensionsMock).toHaveBeenCalledWith(
|
||||
["/extensions/zai-provider"],
|
||||
"/tmp",
|
||||
"/tmp/.fusion/disabled-auto-extension-discovery",
|
||||
);
|
||||
expect(registerProviderMock).toHaveBeenCalledWith("zai", expect.objectContaining({
|
||||
models: [{ id: "glm-5.1" }],
|
||||
}));
|
||||
|
||||
@@ -20,20 +20,20 @@ import {
|
||||
DefaultResourceLoader,
|
||||
DefaultPackageManager,
|
||||
discoverAndLoadExtensions,
|
||||
getAgentDir,
|
||||
ModelRegistry,
|
||||
SessionManager,
|
||||
SettingsManager,
|
||||
type AgentSession,
|
||||
type ToolDefinition,
|
||||
} from "@mariozechner/pi-coding-agent";
|
||||
import { getEnabledPiExtensionPaths, getFusionAgentDir, getLegacyPiAgentDir, resolvePiExtensionProjectRoot } from "@fusion/core";
|
||||
import {
|
||||
resolveSessionSkills,
|
||||
createSkillsOverrideFromSelection,
|
||||
type SkillSelectionContext,
|
||||
} from "./skill-resolver.js";
|
||||
import { isContextLimitError } from "./context-limit-detector.js";
|
||||
import { createFusionAuthStorage } from "./auth-storage.js";
|
||||
import { createFusionAuthStorage, getModelRegistryModelsPath } from "./auth-storage.js";
|
||||
|
||||
export interface AgentResult {
|
||||
session: AgentSession;
|
||||
@@ -252,8 +252,9 @@ function readJsonObject(path: string): Record<string, any> {
|
||||
}
|
||||
|
||||
function createReadOnlyPiSettingsView(cwd: string, agentDir: string): PackageManagerSettingsView {
|
||||
const projectRoot = resolvePiExtensionProjectRoot(cwd);
|
||||
const globalSettings = readJsonObject(join(agentDir, "settings.json"));
|
||||
const fusionProjectSettings = readJsonObject(join(cwd, ".fusion", "settings.json"));
|
||||
const fusionProjectSettings = readJsonObject(join(projectRoot, ".fusion", "settings.json"));
|
||||
const mergedSettings = { ...globalSettings, ...fusionProjectSettings };
|
||||
|
||||
return {
|
||||
@@ -265,9 +266,22 @@ function createReadOnlyPiSettingsView(cwd: string, agentDir: string): PackageMan
|
||||
};
|
||||
}
|
||||
|
||||
function getPackageManagerAgentDir(): string {
|
||||
const fusionAgentDir = getFusionAgentDir();
|
||||
if (
|
||||
existsSync(join(fusionAgentDir, "settings.json")) ||
|
||||
existsSync(join(fusionAgentDir, "extensions"))
|
||||
) {
|
||||
return fusionAgentDir;
|
||||
}
|
||||
|
||||
const legacyAgentDir = getLegacyPiAgentDir();
|
||||
return existsSync(legacyAgentDir) ? legacyAgentDir : fusionAgentDir;
|
||||
}
|
||||
|
||||
async function registerExtensionProviders(cwd: string, modelRegistry: ModelRegistry): Promise<void> {
|
||||
try {
|
||||
const agentDir = getAgentDir();
|
||||
const agentDir = getPackageManagerAgentDir();
|
||||
const packageManager = new DefaultPackageManager({
|
||||
cwd,
|
||||
agentDir,
|
||||
@@ -278,7 +292,11 @@ async function registerExtensionProviders(cwd: string, modelRegistry: ModelRegis
|
||||
.filter((resource) => resource.enabled)
|
||||
.map((resource) => resource.path);
|
||||
|
||||
const extensionsResult = await discoverAndLoadExtensions(packageExtensionPaths, cwd, undefined);
|
||||
const extensionsResult = await discoverAndLoadExtensions(
|
||||
[...getEnabledPiExtensionPaths(cwd), ...packageExtensionPaths],
|
||||
cwd,
|
||||
join(resolvePiExtensionProjectRoot(cwd), ".fusion", "disabled-auto-extension-discovery"),
|
||||
);
|
||||
|
||||
for (const { path, error } of extensionsResult.errors) {
|
||||
console.error(`[extensions] Failed to load ${path}: ${error}`);
|
||||
@@ -475,7 +493,7 @@ export function wrapToolsWithBoundary(
|
||||
export async function createKbAgent(options: AgentOptions): Promise<AgentResult> {
|
||||
console.error(`[pi] createKbAgent called (cwd=${options.cwd}, tools=${options.tools}, provider=${options.defaultProvider}, model=${options.defaultModelId})`);
|
||||
const authStorage = createFusionAuthStorage();
|
||||
const modelRegistry = new ModelRegistry(authStorage, join(getAgentDir(), "models.json"));
|
||||
const modelRegistry = new ModelRegistry(authStorage, getModelRegistryModelsPath());
|
||||
await registerExtensionProviders(options.cwd, modelRegistry);
|
||||
|
||||
const tools =
|
||||
|
||||
@@ -97,6 +97,7 @@ export class ProjectManager extends EventEmitter<ProjectManagerEvents> {
|
||||
private globalSemaphore: AgentSemaphore;
|
||||
/** Mutable limit read by the shared semaphore's getter function. */
|
||||
private currentGlobalLimit = 4;
|
||||
private globalLimitRefreshInterval: ReturnType<typeof setInterval>;
|
||||
|
||||
/**
|
||||
* @param centralCore - CentralCore reference for global coordination
|
||||
@@ -112,7 +113,8 @@ export class ProjectManager extends EventEmitter<ProjectManagerEvents> {
|
||||
|
||||
// Refresh the global limit periodically
|
||||
this.refreshGlobalLimit();
|
||||
setInterval(() => this.refreshGlobalLimit(), 30000); // Refresh every 30s
|
||||
this.globalLimitRefreshInterval = setInterval(() => this.refreshGlobalLimit(), 30000);
|
||||
this.globalLimitRefreshInterval.unref?.();
|
||||
|
||||
projectManagerLog.log("ProjectManager initialized");
|
||||
}
|
||||
@@ -475,6 +477,7 @@ export class ProjectManager extends EventEmitter<ProjectManagerEvents> {
|
||||
|
||||
await Promise.all(stopPromises);
|
||||
|
||||
clearInterval(this.globalLimitRefreshInterval);
|
||||
projectManagerLog.log("All project runtimes stopped");
|
||||
this.removeAllListeners();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user