feat(FN-2962): merge fusion/fn-2962

- Add changeset for `@runfusion/fusion` minor release introducing custom provider registration support

Commits merged:
- feat(FN-2962): complete Step 8 — add changeset and documentation

Files changed:
.changeset/register-custom-providers.md | 5 +++++
 1 file changed, 5 insertions(+)

Fusion-Task-Id: FN-2962
This commit is contained in:
Fusion
2026-04-29 21:42:44 -07:00
committed by gsxdsm
parent 6c051b1851
commit 64b5f677ff
33 changed files with 1048 additions and 60 deletions

View File

@@ -21,6 +21,7 @@ const reloadMock = vi.fn(async () => {});
const execSyncMock = vi.fn((_cmd?: any, _opts?: any) => "");
const existsSyncMock = vi.fn((_path: PathLike) => false);
const readFileSyncMock = vi.fn((_path?: any) => "{}");
const readCustomProvidersMock = vi.fn(() => []);
// Route async `exec` through the `execSync` mock so the promisify bridge works.
// Use Symbol.for("nodejs.util.promisify.custom") directly to avoid async imports
@@ -68,6 +69,10 @@ vi.mock("node:fs", async () => {
};
});
vi.mock("../custom-providers.js", () => ({
readCustomProviders: readCustomProvidersMock,
}));
vi.mock("@mariozechner/pi-coding-agent", () => ({
AuthStorage: {
create: () => ({
@@ -382,6 +387,7 @@ describe("createFnAgent", () => {
execSyncMock.mockReturnValue("");
existsSyncMock.mockReturnValue(false);
readFileSyncMock.mockReturnValue("{}");
readCustomProvidersMock.mockReturnValue([]);
findMock.mockImplementation((provider: string, modelId: string) => ({ provider, id: modelId }));
createAgentSessionMock.mockResolvedValue({
session: {
@@ -484,6 +490,36 @@ describe("createFnAgent", () => {
expect(refreshMock).toHaveBeenCalled();
});
it("registers custom providers from global settings", async () => {
readCustomProvidersMock.mockReturnValue([
{
id: "custom-openai",
name: "Custom OpenAI",
apiType: "openai-compatible",
baseUrl: "https://custom.example/v1",
apiKey: "CUSTOM_API_KEY",
models: [{ id: "custom-model", name: "Custom Model" }],
},
] as any);
const { createFnAgent } = await import("../pi.js");
await createFnAgent({
cwd: "/tmp",
systemPrompt: "test",
tools: "readonly",
defaultProvider: "openai-codex",
defaultModelId: "gpt-5.4",
});
expect(registerProviderMock).toHaveBeenCalledWith("custom-openai", expect.objectContaining({
baseUrl: "https://custom.example/v1",
api: "openai-completions",
apiKey: "CUSTOM_API_KEY",
models: [expect.objectContaining({ id: "custom-model", name: "Custom Model" })],
}));
});
it("avoids lock-based SettingsManager.create when loading extension providers", async () => {
const { createFnAgent } = await import("../pi.js");