feat(coding-agent): replace model registry with model runtime

Move provider auth and OAuth flows onto pi-ai Models, compose models.json and extension overlays through ModelRuntime, and retain ModelRegistry as an extension compatibility facade.
This commit is contained in:
Mario Zechner
2026-07-14 17:48:45 +02:00
parent 6731a0ba9e
commit 9993c96907
133 changed files with 5103 additions and 4340 deletions
@@ -51,6 +51,42 @@ describe("extensions discovery", () => {
expect(result.extensions.map((e) => path.basename(e.path)).sort()).toEqual(["bar.ts", "foo.ts"]);
});
it("loads the coding-agent entrypoint without rewriting pi-ai provider subpaths", async () => {
fs.writeFileSync(
path.join(extensionsDir, "coding-agent-import.ts"),
`
import { getAgentDir } from "@earendil-works/pi-coding-agent";
void getAgentDir;
export default function(pi) {
pi.registerCommand("test", { handler: async () => {} });
}
`,
);
const result = await discoverAndLoadExtensions([], tempDir, tempDir);
expect(result.errors).toHaveLength(0);
expect(result.extensions).toHaveLength(1);
});
it("keeps the type-only pi-ai OAuth compatibility barrel resolvable", async () => {
fs.writeFileSync(
path.join(extensionsDir, "oauth-import.ts"),
`
import * as oauth from "@earendil-works/pi-ai/oauth";
void oauth;
export default function(pi) {
pi.registerCommand("test", { handler: async () => {} });
}
`,
);
const result = await discoverAndLoadExtensions([], tempDir, tempDir);
expect(result.errors).toEqual([]);
expect(result.extensions).toHaveLength(1);
});
it("discovers direct .js files in extensions/", async () => {
fs.writeFileSync(path.join(extensionsDir, "foo.js"), extensionCode);