mirror of
https://github.com/murashit/codex-panel.git
synced 2026-07-22 17:30:31 +00:00
75 lines
4.2 KiB
TypeScript
75 lines
4.2 KiB
TypeScript
import type { AppServerClient } from "../app-server/connection/client";
|
|
import type { AppServerClientAccess } from "../app-server/connection/client-access";
|
|
import type { ObservedResultListener } from "../app-server/query/observed-result";
|
|
import { listHookCatalog, setHookItemEnabled, trustHookItem } from "../app-server/services/catalog";
|
|
import { deleteThread, restoreArchivedThread as restoreArchivedThreadOnAppServer } from "../app-server/services/threads";
|
|
import type { HookItem, ModelMetadata } from "../domain/catalog/metadata";
|
|
import type { ThreadCatalogArchivedReader, ThreadCatalogEventSink } from "../features/threads/catalog/thread-catalog";
|
|
import { createKeyedOperationQueue } from "../shared/runtime/keyed-operation-queue";
|
|
import type { SettingsDynamicDataAccess, SettingsHookCatalog } 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[]>;
|
|
}
|
|
|
|
type SettingsArchivedThreadCatalog = ThreadCatalogArchivedReader & ThreadCatalogEventSink;
|
|
|
|
export interface SettingsAppServerDynamicDataOptions {
|
|
vaultPath: string;
|
|
clientAccess: AppServerClientAccess;
|
|
appServerQueries: SettingsAppServerQueries;
|
|
threadCatalog: SettingsArchivedThreadCatalog;
|
|
}
|
|
|
|
export function createSettingsAppServerDynamicData(options: SettingsAppServerDynamicDataOptions): SettingsDynamicDataAccess {
|
|
const archivedThreadMutations = createKeyedOperationQueue<string>();
|
|
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." },
|
|
});
|
|
const runArchivedThreadMutation = <T>(threadId: string, operation: () => Promise<T>): Promise<T> => {
|
|
return archivedThreadMutations.run(threadId, operation);
|
|
};
|
|
const loadHooks = (client: AppServerClient): Promise<SettingsHookCatalog> => loadSettingsHookCatalog(client, options.vaultPath);
|
|
const mutateHook = (hook: HookItem, mutation: (client: AppServerClient, hook: HookItem) => Promise<void>): Promise<SettingsHookCatalog> =>
|
|
withSettingsConnection(async (client) => {
|
|
await mutation(client, hook);
|
|
return loadHooks(client);
|
|
});
|
|
|
|
return {
|
|
modelsSnapshot: () => options.appServerQueries.modelsSnapshot(),
|
|
observeModelsResult: (listener, observeOptions) => options.appServerQueries.observeModelsResult(listener, observeOptions),
|
|
fetchModels: () => options.appServerQueries.fetchModels(),
|
|
refreshModels: () => options.appServerQueries.refreshModels(),
|
|
archivedThreadsSnapshot: () => options.threadCatalog.archivedSnapshot(),
|
|
observeArchivedThreadsResult: (listener, observeOptions) => options.threadCatalog.observeArchived(listener, observeOptions),
|
|
refreshArchivedThreads: () => options.threadCatalog.refreshArchived(),
|
|
refreshHooks: () => withSettingsConnection(loadHooks),
|
|
trustHook: (hook) => mutateHook(hook, trustHookItem),
|
|
setHookEnabled: (hook, enabled) => mutateHook(hook, (client, item) => setHookItemEnabled(client, item, enabled)),
|
|
restoreArchivedThread: (threadId) =>
|
|
runArchivedThreadMutation(threadId, async () => {
|
|
const thread = await withSettingsConnection((client) => restoreArchivedThreadOnAppServer(client, threadId));
|
|
options.threadCatalog.apply({ type: "thread-restored", thread });
|
|
return thread;
|
|
}),
|
|
deleteArchivedThread: (threadId) =>
|
|
runArchivedThreadMutation(threadId, async () => {
|
|
await withSettingsConnection((client) => deleteThread(client, threadId));
|
|
options.threadCatalog.apply({ type: "thread-deleted", threadId });
|
|
}),
|
|
};
|
|
}
|
|
|
|
async function loadSettingsHookCatalog(client: AppServerClient, vaultPath: string): Promise<SettingsHookCatalog> {
|
|
const catalog = await listHookCatalog(client, vaultPath);
|
|
const hookCount = catalog.hooks.length;
|
|
return {
|
|
...catalog,
|
|
status: `Loaded ${String(hookCount)} hook${hookCount === 1 ? "" : "s"}.`,
|
|
};
|
|
}
|