mirror of
https://github.com/murashit/codex-panel.git
synced 2026-07-22 06:57:10 +00:00
80 lines
4.2 KiB
TypeScript
80 lines
4.2 KiB
TypeScript
import type { AppServerClient } from "../../app-server/connection/client";
|
|
import type { AppServerClientAccess } from "../../app-server/connection/client-access";
|
|
import { isStaleAppServerSharedQueryContextError } from "../../app-server/query/shared-queries";
|
|
import type { ThreadCatalogArchivedReader, ThreadCatalogEventSink } from "../../app-server/query/thread-catalog";
|
|
import { listHookCatalog, setHookItemEnabled, trustHookItem } from "../../app-server/services/catalog";
|
|
import { restoreArchivedThread as restoreArchivedThreadOnAppServer } from "../../app-server/services/threads";
|
|
import type { ModelMetadata } from "../../domain/catalog/metadata";
|
|
import type { ObservedResultListener } from "../../shared/query/observed-result";
|
|
import { type SettingsDynamicDataAccess, type SettingsHookCatalog, StaleSettingsDynamicDataContextError } from "../dynamic-data";
|
|
|
|
interface SettingsAppServerQueries {
|
|
modelsSnapshot(): readonly ModelMetadata[] | null;
|
|
observeModelsResult(listener: ObservedResultListener<readonly ModelMetadata[]>, options?: { emitCurrent?: boolean }): () => void;
|
|
fetchModels(): Promise<readonly ModelMetadata[]>;
|
|
refreshModels(): Promise<readonly ModelMetadata[]>;
|
|
notifyContextChanged(): void;
|
|
}
|
|
|
|
type SettingsArchivedThreadCatalog = ThreadCatalogArchivedReader & ThreadCatalogEventSink;
|
|
|
|
export interface SettingsAppServerDynamicDataOptions {
|
|
vaultPath: string;
|
|
clientAccess: AppServerClientAccess;
|
|
appServerQueries: SettingsAppServerQueries;
|
|
threadCatalog: SettingsArchivedThreadCatalog;
|
|
}
|
|
|
|
export function createSettingsAppServerDynamicData(options: SettingsAppServerDynamicDataOptions): SettingsDynamicDataAccess {
|
|
const withSettingsConnection = <T>(operation: (client: AppServerClient) => Promise<T>): Promise<T> =>
|
|
options.clientAccess.withClient(operation, {
|
|
serverRequests: { kind: "reject", message: "Codex Panel settings does not handle server requests." },
|
|
});
|
|
|
|
return {
|
|
modelsSnapshot: () => options.appServerQueries.modelsSnapshot(),
|
|
observeModelsResult: (listener, observeOptions) => options.appServerQueries.observeModelsResult(listener, observeOptions),
|
|
fetchModels: () => mapStaleContextError(() => options.appServerQueries.fetchModels()),
|
|
refreshModels: () => mapStaleContextError(() => options.appServerQueries.refreshModels()),
|
|
archivedThreadsSnapshot: () => options.threadCatalog.archivedSnapshot(),
|
|
observeArchivedThreadsResult: (listener, observeOptions) => options.threadCatalog.observeArchived(listener, observeOptions),
|
|
refreshArchivedThreads: () => mapStaleContextError(() => options.threadCatalog.refreshArchived()),
|
|
loadHooks: () => withSettingsConnection((client) => loadSettingsHookCatalog(client, options.vaultPath)),
|
|
trustHook: (hook) => withSettingsConnection((client) => trustHookItem(client, hook)),
|
|
setHookEnabled: (hook, enabled) => withSettingsConnection((client) => setHookItemEnabled(client, hook, enabled)),
|
|
restoreArchivedThread: async (threadId, mutationOptions) => {
|
|
const thread = await withSettingsConnection((client) => restoreArchivedThreadOnAppServer(client, threadId));
|
|
if (mutationOptions?.shouldPublish?.() ?? true) {
|
|
options.threadCatalog.apply({ type: "thread-restored", thread });
|
|
}
|
|
return thread;
|
|
},
|
|
deleteArchivedThread: async (threadId, mutationOptions) => {
|
|
await withSettingsConnection((client) => client.deleteThread(threadId));
|
|
if (mutationOptions?.shouldPublish?.() ?? true) {
|
|
options.threadCatalog.apply({ type: "thread-deleted", threadId });
|
|
}
|
|
},
|
|
notifyContextChanged: () => {
|
|
options.appServerQueries.notifyContextChanged();
|
|
},
|
|
};
|
|
}
|
|
|
|
async function loadSettingsHookCatalog(client: AppServerClient, cwd: string): Promise<SettingsHookCatalog> {
|
|
const hooks = await listHookCatalog(client, cwd);
|
|
const hookCount = hooks.hooks.length;
|
|
return {
|
|
...hooks,
|
|
status: `Loaded ${String(hookCount)} hook${hookCount === 1 ? "" : "s"}.`,
|
|
};
|
|
}
|
|
|
|
async function mapStaleContextError<T>(operation: () => Promise<T>): Promise<T> {
|
|
try {
|
|
return await operation();
|
|
} catch (error) {
|
|
if (isStaleAppServerSharedQueryContextError(error)) throw new StaleSettingsDynamicDataContextError();
|
|
throw error;
|
|
}
|
|
}
|