61 lines
3.1 KiB
TypeScript
61 lines
3.1 KiB
TypeScript
import { createEmbeddingClientFromEnvironment, type EmbeddingEnvironment } from './embedding-client';
|
|
import { createQdrantRegulatoryIndexFromEnvironment, type QdrantEnvironment } from './qdrant-regulatory-index';
|
|
import { RegulatoryFindingRetrievalService } from './regulatory-finding-retrieval';
|
|
import {
|
|
DenseRegulatoryCandidateRetriever,
|
|
HybridRegulatoryCandidateRetriever,
|
|
RegulatoryIngestionService,
|
|
RegulatoryRetrievalPipeline,
|
|
SparseRegulatoryCandidateRetriever
|
|
} from './regulatory-rag-service';
|
|
|
|
export interface RegulatoryRagEnvironment extends EmbeddingEnvironment, QdrantEnvironment {
|
|
ASSESSOR_RAG_CHUNK_CHARACTERS?: string;
|
|
ASSESSOR_RAG_EMBEDDING_BATCH_SIZE?: string;
|
|
}
|
|
|
|
export function createRegulatoryRagRuntime(
|
|
environment: RegulatoryRagEnvironment = {
|
|
ASSESSOR_QDRANT_URL: process.env.ASSESSOR_QDRANT_URL,
|
|
ASSESSOR_QDRANT_API_KEY: process.env.ASSESSOR_QDRANT_API_KEY,
|
|
ASSESSOR_QDRANT_TIMEOUT_MS: process.env.ASSESSOR_QDRANT_TIMEOUT_MS,
|
|
ASSESSOR_RAG_EMBEDDING_BASE_URL: process.env.ASSESSOR_RAG_EMBEDDING_BASE_URL,
|
|
ASSESSOR_RAG_EMBEDDING_MODEL: process.env.ASSESSOR_RAG_EMBEDDING_MODEL,
|
|
ASSESSOR_RAG_EMBEDDING_API_KEY: process.env.ASSESSOR_RAG_EMBEDDING_API_KEY,
|
|
ASSESSOR_RAG_EMBEDDING_DIMENSIONS: process.env.ASSESSOR_RAG_EMBEDDING_DIMENSIONS,
|
|
ASSESSOR_RAG_EMBEDDING_REQUEST_DIMENSIONS: process.env.ASSESSOR_RAG_EMBEDDING_REQUEST_DIMENSIONS,
|
|
ASSESSOR_RAG_EMBEDDING_TIMEOUT_MS: process.env.ASSESSOR_RAG_EMBEDDING_TIMEOUT_MS,
|
|
ASSESSOR_RAG_CHUNK_CHARACTERS: process.env.ASSESSOR_RAG_CHUNK_CHARACTERS,
|
|
ASSESSOR_RAG_EMBEDDING_BATCH_SIZE: process.env.ASSESSOR_RAG_EMBEDDING_BATCH_SIZE
|
|
}
|
|
): {
|
|
ingestion: RegulatoryIngestionService;
|
|
retrieval: RegulatoryRetrievalPipeline;
|
|
findingRetrieval: RegulatoryFindingRetrievalService;
|
|
index: ReturnType<typeof createQdrantRegulatoryIndexFromEnvironment>;
|
|
embeddingModel: string;
|
|
} {
|
|
const embeddings = createEmbeddingClientFromEnvironment(environment);
|
|
const index = createQdrantRegulatoryIndexFromEnvironment(embeddings.dimensions, embeddings.model, environment);
|
|
const dense = new DenseRegulatoryCandidateRetriever(embeddings, index);
|
|
const sparse = new SparseRegulatoryCandidateRetriever(index);
|
|
const retrieval = new RegulatoryRetrievalPipeline(new HybridRegulatoryCandidateRetriever(dense, sparse));
|
|
return {
|
|
ingestion: new RegulatoryIngestionService(embeddings, index, {
|
|
maximumChunkCharacters: boundedInteger(environment.ASSESSOR_RAG_CHUNK_CHARACTERS, 1_600, 200, 20_000, 'ASSESSOR_RAG_CHUNK_CHARACTERS'),
|
|
embeddingBatchSize: boundedInteger(environment.ASSESSOR_RAG_EMBEDDING_BATCH_SIZE, 32, 1, 128, 'ASSESSOR_RAG_EMBEDDING_BATCH_SIZE')
|
|
}),
|
|
retrieval,
|
|
findingRetrieval: new RegulatoryFindingRetrievalService(retrieval),
|
|
index,
|
|
embeddingModel: embeddings.model
|
|
};
|
|
}
|
|
|
|
function boundedInteger(value: string | undefined, fallback: number, minimum: number, maximum: number, name: string): number {
|
|
if (!value?.trim()) return fallback;
|
|
const parsed = Number(value);
|
|
if (!Number.isInteger(parsed) || parsed < minimum || parsed > maximum) throw new Error(`${name} must be an integer between ${minimum} and ${maximum}.`);
|
|
return parsed;
|
|
}
|