Move state storage to Postgres

This commit is contained in:
Meta Vens 2026-04-24 15:10:34 +01:00
commit c3d2bf424e
18 changed files with 1667 additions and 470 deletions

View file

@ -16,12 +16,13 @@ import {
import { loadConfig } from "@voidbot/config";
import {
type AuditLog,
buildVoidMcpServerConfig,
ContextBuilder,
FileAuditLog,
FileBackedJobQueue,
FileInteractionMemoryBank,
PermissionEngine,
createStateStorage,
type InteractionMemoryBank,
type JobQueue,
loadStylePack,
loadSystemMessageCatalog,
type SystemMessageCatalog,
@ -142,9 +143,17 @@ export async function startBot(): Promise<void> {
const permissionEngine = new PermissionEngine(config.ownerDiscordId, {
localLlmAllowPublic: config.localLlm.allowPublic,
});
const jobQueue = new FileBackedJobQueue(config.jobsFile);
const auditLog = new FileAuditLog(config.auditLogFile);
const interactionMemory = new FileInteractionMemoryBank(config.interactionMemoryFile);
const {
jobQueue,
auditLog,
interactionMemory,
} = await createStateStorage({
backend: config.stateStorageBackend,
databaseDsn: config.databaseDsn,
jobsFile: config.jobsFile,
auditLogFile: config.auditLogFile,
interactionMemoryFile: config.interactionMemoryFile,
});
const contextBuilder = new ContextBuilder();
let activeStylePack = await loadStylePack(config.stylePackPath);
let activeSystemMessages = await loadSystemMessageCatalog(config.systemMessagesPath);
@ -563,9 +572,9 @@ interface PromptHandlerOptions {
contextBuilder: ContextBuilder;
retrievalService: RetrievalService;
sourceArchiveRepository: FileSourceDocumentArchiveRepository;
jobQueue: FileBackedJobQueue;
auditLog: FileAuditLog;
interactionMemory: FileInteractionMemoryBank;
jobQueue: JobQueue;
auditLog: AuditLog;
interactionMemory: InteractionMemoryBank;
providerRegistry: ProviderRegistry;
stylePack?: StylePack;
systemMessages: SystemMessageCatalog;
@ -715,8 +724,8 @@ async function handleApproveJob(options: {
interaction: ChatInputCommandInteraction<CacheType>;
client: Client;
actor: Actor;
jobQueue: FileBackedJobQueue;
auditLog: FileAuditLog;
jobQueue: JobQueue;
auditLog: AuditLog;
permissionEngine: PermissionEngine;
systemMessages: SystemMessageCatalog;
}): Promise<void> {
@ -795,8 +804,8 @@ async function handleApproveJob(options: {
async function handleRejectJob(options: {
interaction: ChatInputCommandInteraction<CacheType>;
actor: Actor;
jobQueue: FileBackedJobQueue;
auditLog: FileAuditLog;
jobQueue: JobQueue;
auditLog: AuditLog;
permissionEngine: PermissionEngine;
systemMessages: SystemMessageCatalog;
}): Promise<void> {
@ -994,7 +1003,7 @@ async function ingestIfIndexed(
async function rememberAmbientVoidReference(
message: Message,
botUserId: string | undefined,
interactionMemory: FileInteractionMemoryBank,
interactionMemory: InteractionMemoryBank,
): Promise<void> {
if (!isAmbientVoidReference(message, botUserId)) {
return;

View file

@ -5,9 +5,10 @@ import { join } from "node:path";
import { loadConfig } from "@voidbot/config";
import {
type AuditLog,
buildVoidMcpServerConfig,
FileAuditLog,
FileBackedJobQueue,
createStateStorage,
type JobQueue,
loadSystemMessageCatalog,
type SystemMessageCatalog,
} from "@voidbot/core";
@ -33,8 +34,6 @@ import {
} from "@voidbot/shared";
const config = loadConfig();
const jobQueue = new FileBackedJobQueue(config.jobsFile);
const auditLog = new FileAuditLog(config.auditLogFile);
const embedder = createTextEmbedder({
backend: config.ragEmbeddingBackend,
hashDimensions: config.ragEmbeddingDimensions,
@ -72,6 +71,8 @@ const retrievalService = new RetrievalService(
let isProcessing = false;
let providerRegistry: ProviderRegistry;
let systemMessages: SystemMessageCatalog;
let jobQueue: JobQueue;
let auditLog: AuditLog;
void main().catch((error) => {
console.error(error);
@ -79,6 +80,18 @@ void main().catch((error) => {
});
async function main(): Promise<void> {
const {
jobQueue: stateJobQueue,
auditLog: stateAuditLog,
} = await createStateStorage({
backend: config.stateStorageBackend,
databaseDsn: config.databaseDsn,
jobsFile: config.jobsFile,
auditLogFile: config.auditLogFile,
interactionMemoryFile: config.interactionMemoryFile,
});
jobQueue = stateJobQueue;
auditLog = stateAuditLog;
systemMessages = await loadSystemMessageCatalog(config.systemMessagesPath);
providerRegistry = await buildProviderRegistry(systemMessages);
console.log(`VoidBot worker polling every ${config.workerPollIntervalMs}ms.`);