KnowledgeBridge / server /modal-client.ts
fazeel007's picture
update index
07b8ac9
/**
* Modal API Client for Serverless Compute Integration
*/
interface ModalConfig {
tokenId: string;
tokenSecret: string;
baseUrl: string;
}
interface DocumentProcessingTask {
taskId: string;
status: 'pending' | 'running' | 'completed' | 'failed';
result?: any;
error?: string;
}
interface VectorProcessingRequest {
documents: Array<{
id: string;
content: string;
metadata?: Record<string, any>;
}>;
modelName?: string;
batchSize?: number;
}
class ModalClient {
private config: ModalConfig;
private authToken: string;
constructor() {
// Use environment variables - NEVER hardcode credentials
const tokenId = process.env.MODAL_TOKEN_ID;
const tokenSecret = process.env.MODAL_TOKEN_SECRET;
if (!tokenId || !tokenSecret) {
throw new Error('Modal credentials not configured. Please set MODAL_TOKEN_ID and MODAL_TOKEN_SECRET environment variables.');
}
this.config = {
tokenId,
tokenSecret,
baseUrl: 'https://fazeelusmani18--knowledgebridge-main-fastapi-app.modal.run'
};
// Create base64 encoded auth token
this.authToken = Buffer.from(`${this.config.tokenId}:${this.config.tokenSecret}`).toString('base64');
}
private async makeRequest(endpoint: string, options: RequestInit = {}) {
const url = `${this.config.baseUrl}${endpoint}`;
console.log(`Modal API request: ${options.method || 'GET'} ${url}`);
const response = await fetch(url, {
...options,
headers: {
'Content-Type': 'application/json',
...options.headers,
},
});
console.log(`Modal API response: ${response.status} ${response.statusText}`);
if (!response.ok) {
throw new Error(`Modal API request failed: ${response.status} ${response.statusText}`);
}
return response.json();
}
/**
* Process documents in batch using Modal's serverless compute
*/
async batchProcessDocuments(request: VectorProcessingRequest): Promise<DocumentProcessingTask> {
return this.makeRequest('/batch-process', {
method: 'POST',
body: JSON.stringify({
documents: request.documents,
config: {
modelName: request.modelName || 'text-embedding-3-small',
batchSize: request.batchSize || 50,
computeResources: {
cpu: 2,
memory: '4Gi'
}
}
})
});
}
/**
* Get status of a processing task
*/
async getTaskStatus(taskId: string): Promise<DocumentProcessingTask> {
return this.makeRequest(`/task/${taskId}`);
}
/**
* Build FAISS index using Modal's distributed computing
*/
async buildVectorIndex(documents: any[], indexConfig?: any): Promise<DocumentProcessingTask> {
const indexName = indexConfig?.indexName || 'main_index';
return this.makeRequest('/build-index', {
method: 'POST',
body: JSON.stringify({
documents,
index_name: indexName
})
});
}
/**
* Perform high-performance vector search
*/
async vectorSearch(query: string, indexId: string, k: number = 10): Promise<any> {
return this.makeRequest('/vector-search', {
method: 'POST',
body: JSON.stringify({
query,
indexId,
k,
includeMetadata: true
})
});
}
/**
* Extract text from documents using OCR
*/
async extractTextFromDocuments(documentUrls: string[]): Promise<DocumentProcessingTask> {
return this.makeRequest('/ocr-extract', {
method: 'POST',
body: JSON.stringify({
documentUrls,
config: {
languages: ['en'],
outputFormat: 'structured'
}
})
});
}
/**
* Auto-categorize documents using distributed ML
*/
async categorizeDocuments(documents: any[]): Promise<DocumentProcessingTask> {
return this.makeRequest('/categorize', {
method: 'POST',
body: JSON.stringify({
documents,
categories: [
'academic_paper',
'technical_documentation',
'research_report',
'code_repository',
'blog_post',
'news_article'
]
})
});
}
}
export const modalClient = new ModalClient();
export type { DocumentProcessingTask, VectorProcessingRequest };