Files
fusion/packages/dashboard/src/chat-project-services.ts
Fusion 7c0e661e56 fix(FN-4583): route scoped dashboard chat through engine chat store
Fusion-Task-Id: FN-4583
Fusion-Task-Lineage: 4d9b088d-a705-4376-b547-15b37e5370aa
2026-05-15 02:23:27 -07:00

77 lines
2.4 KiB
TypeScript

import { AgentStore, ChatStore, type MessageStore, type TaskStore } from "@fusion/core";
import type { ProjectEngineManager } from "@fusion/engine";
import { ChatManager } from "./chat.js";
import { getOrCreateProjectStore } from "./project-store-resolver.js";
const scopedChatStoreCache = new Map<string, ChatStore>();
function cacheKeyForStore(store: TaskStore): string {
return store.getFusionDir();
}
export function getOrCreateScopedChatStore(store: TaskStore, fallbackChatStore?: ChatStore): ChatStore {
const key = cacheKeyForStore(store);
if (fallbackChatStore) {
scopedChatStoreCache.set(key, fallbackChatStore);
return fallbackChatStore;
}
const cached = scopedChatStoreCache.get(key);
if (cached) return cached;
const chatStore = new ChatStore(store.getFusionDir(), store.getDatabase());
scopedChatStoreCache.set(key, chatStore);
return chatStore;
}
export async function resolveProjectChatContext(options: {
projectId?: string | null;
defaultStore: TaskStore;
defaultChatStore?: ChatStore;
engineManager?: ProjectEngineManager;
}): Promise<{ store: TaskStore; chatStore: ChatStore }> {
const { projectId, defaultStore, defaultChatStore, engineManager } = options;
if (!projectId) {
return {
store: defaultStore,
chatStore: getOrCreateScopedChatStore(defaultStore, defaultChatStore),
};
}
const engine = engineManager?.getEngine(projectId);
try {
const scopedStore = engine?.getTaskStore() ?? await getOrCreateProjectStore(projectId);
const engineChatStore = engine?.getChatStore?.();
return {
store: scopedStore,
chatStore: getOrCreateScopedChatStore(scopedStore, engineChatStore),
};
} catch {
return {
store: defaultStore,
chatStore: getOrCreateScopedChatStore(defaultStore, defaultChatStore),
};
}
}
export async function createProjectScopedChatManager(options: {
store: TaskStore;
chatStore: ChatStore;
pluginRunner?: ConstructorParameters<typeof ChatManager>[3];
messageStore?: MessageStore;
}): Promise<ChatManager> {
const agentStore = new AgentStore({ rootDir: options.store.getFusionDir() });
return new ChatManager(
options.chatStore,
options.store.getRootDir(),
agentStore,
options.pluginRunner,
() => options.store.getSettings(),
options.messageStore,
);
}
export function __resetScopedChatStoreCache(): void {
scopedChatStoreCache.clear();
}