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
@@ -11,11 +11,12 @@ import {
} from "@earendil-works/pi-ai";
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import { AuthStorage } from "../src/core/auth-storage.ts";
import { ModelRegistry } from "../src/core/model-registry.ts";
import { createAgentSession } from "../src/core/sdk.ts";
import { SessionManager } from "../src/core/session-manager.ts";
import { SettingsManager } from "../src/core/settings-manager.ts";
import { createModelRegistry, getModelRuntime } from "./model-runtime-test-utils.ts";
describe("createAgentSession provider attribution headers", () => {
let tempDir: string;
let cwd: string;
@@ -96,24 +97,20 @@ describe("createAgentSession provider attribution headers", () => {
}
const authStorage = AuthStorage.create(join(agentDir, "auth.json"));
authStorage.setRuntimeApiKey(model.provider, "test-api-key");
const modelRegistry = ModelRegistry.create(authStorage, join(agentDir, "models.json"));
const registeredProviders = ["capture-provider"];
await authStorage.modify(model.provider, async () => ({ type: "api_key", key: "test-api-key" }));
const modelRegistry = await createModelRegistry(authStorage, join(agentDir, "models.json"));
let capturedOptions: SimpleStreamOptions | undefined;
modelRegistry.registerProvider("capture-provider", {
api: "openai-completions",
modelRegistry.registerProvider(model.provider, {
api: model.api,
headers: options.providerHeaders,
streamSimple: (_model, _context, providerOptions) => {
capturedOptions = providerOptions;
return createDoneStream();
},
});
if (options.providerHeaders) {
modelRegistry.registerProvider(model.provider, { headers: options.providerHeaders });
registeredProviders.push(model.provider);
}
const modelRuntime = getModelRuntime(modelRegistry);
const sessionManager = SessionManager.inMemory(cwd);
if (options.sessionId) {
sessionManager.newSession({ id: options.sessionId });
@@ -123,14 +120,13 @@ describe("createAgentSession provider attribution headers", () => {
cwd,
agentDir,
model,
authStorage,
modelRegistry,
modelRuntime,
settingsManager,
sessionManager,
});
try {
await session.agent.streamFn(
const stream = await session.agent.streamFn(
model,
{ messages: [] },
{
@@ -138,12 +134,11 @@ describe("createAgentSession provider attribution headers", () => {
...(options.requestHeaders ? { headers: options.requestHeaders } : {}),
},
);
await stream.result();
return capturedOptions?.headers;
} finally {
session.dispose();
for (const provider of registeredProviders.reverse()) {
modelRegistry.unregisterProvider(provider);
}
modelRegistry.unregisterProvider(model.provider);
}
}