mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
Add generation-safe catalog publication, cancellable auth and storage operations, locally consistent credential mutations, and cache-first interactive model flows.
62 lines
2.4 KiB
TypeScript
62 lines
2.4 KiB
TypeScript
import { join } from "node:path";
|
|
import type { ModelsStore, ModelsStoreEntry, ModelsStoreOperationOptions } from "@earendil-works/pi-ai";
|
|
import { getAgentDir } from "../config.ts";
|
|
import { type AuthStorageBackend, FileAuthStorageBackend } from "./auth-storage.ts";
|
|
|
|
type StoredModels = Record<string, ModelsStoreEntry>;
|
|
|
|
export class InMemoryCodingAgentModelsStore implements ModelsStore {
|
|
private readonly entries = new Map<string, ModelsStoreEntry>();
|
|
|
|
async read(providerId: string, options?: ModelsStoreOperationOptions): Promise<ModelsStoreEntry | undefined> {
|
|
options?.signal?.throwIfAborted();
|
|
const entry = this.entries.get(providerId);
|
|
return entry ? structuredClone(entry) : undefined;
|
|
}
|
|
|
|
async write(providerId: string, entry: ModelsStoreEntry, options?: ModelsStoreOperationOptions): Promise<void> {
|
|
options?.signal?.throwIfAborted();
|
|
this.entries.set(providerId, structuredClone(entry));
|
|
}
|
|
|
|
async delete(providerId: string, options?: ModelsStoreOperationOptions): Promise<void> {
|
|
options?.signal?.throwIfAborted();
|
|
this.entries.delete(providerId);
|
|
}
|
|
}
|
|
|
|
/** Locked JSON-backed storage for dynamically refreshed provider catalogs. */
|
|
export class FileModelsStore implements ModelsStore {
|
|
private readonly storage: AuthStorageBackend;
|
|
|
|
constructor(path: string = join(getAgentDir(), "models-store.json")) {
|
|
this.storage = new FileAuthStorageBackend(path);
|
|
}
|
|
|
|
private parse(content: string | undefined): StoredModels {
|
|
return content ? (JSON.parse(content) as StoredModels) : {};
|
|
}
|
|
|
|
async read(providerId: string, options?: ModelsStoreOperationOptions): Promise<ModelsStoreEntry | undefined> {
|
|
return this.storage.withLockAsync(
|
|
async (content) => ({ result: structuredClone(this.parse(content)[providerId]) }),
|
|
options,
|
|
);
|
|
}
|
|
|
|
async write(providerId: string, entry: ModelsStoreEntry, options?: ModelsStoreOperationOptions): Promise<void> {
|
|
await this.storage.withLockAsync(async (content) => {
|
|
const current = this.parse(content);
|
|
current[providerId] = structuredClone(entry);
|
|
return { result: undefined, next: JSON.stringify(current, null, 2) };
|
|
}, options);
|
|
}
|
|
|
|
async delete(providerId: string, options?: ModelsStoreOperationOptions): Promise<void> {
|
|
await this.storage.withLockAsync(async (content) => {
|
|
const current = this.parse(content);
|
|
delete current[providerId];
|
|
return { result: undefined, next: JSON.stringify(current, null, 2) };
|
|
}, options);
|
|
}
|
|
}
|