UNPKG

llmforge

Version:

One API, every AI model, instant switching. Change from GPT-4 to Gemini to local models with a single config update. LLMForge is the lightweight, TypeScript-first solution for multi-provider AI applications with zero vendor lock-in.

192 lines 6.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MessageValidator = exports.FileEncoder = exports.ContentBuilder = void 0; class ContentBuilder { constructor() { this.contents = []; } static create() { return new ContentBuilder(); } addTextMessage(text, role = 'user') { this.contents.push({ role, parts: [{ text }] }); return this; } addImageFromBase64(base64Data, mimeType, text, role = 'user') { const parts = [ { inline_data: { mime_type: mimeType, data: base64Data, }, }, ]; if (text) { parts.push({ text }); } this.contents.push({ role, parts }); return this; } addImageFromFile(fileUri, mimeType, text, role = 'user') { const parts = [ { file_data: { mime_type: mimeType, file_uri: fileUri, }, }, ]; if (text) { parts.push({ text }); } this.contents.push({ role, parts }); return this; } addDocumentFromBase64(base64Data, mimeType, text, role = 'user') { const parts = [ { inline_data: { mime_type: mimeType, data: base64Data, }, }, ]; if (text) { parts.push({ text }); } this.contents.push({ role, parts }); return this; } addConversationTurn(userText, modelText) { this.addTextMessage(userText, 'user'); this.addTextMessage(modelText, 'model'); return this; } build() { return [...this.contents]; } clear() { this.contents = []; return this; } getLastContent() { return this.contents[this.contents.length - 1]; } removeLastContent() { this.contents.pop(); return this; } static fromMessages(messages) { return messages.map(msg => ({ role: msg.role, parts: [{ text: msg.text }], })); } static textOnly(text, role = 'user') { return [{ role, parts: [{ text }] }]; } } exports.ContentBuilder = ContentBuilder; class FileEncoder { static async encodeFileToBase64(file) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => { const result = reader.result; // Remove data URL prefix (e.g., "data:image/jpeg;base64,") const base64 = result.split(',')[1]; resolve(base64); }; reader.onerror = reject; reader.readAsDataURL(file); }); } static async encodeBufferToBase64(buffer) { const bytes = new Uint8Array(buffer); let binary = ''; for (let i = 0; i < bytes.byteLength; i++) { binary += String.fromCharCode(bytes[i]); } return btoa(binary); } static getMimeTypeFromFile(file) { return file.type || this.getMimeTypeFromExtension(file.name); } static getMimeTypeFromExtension(filename) { const ext = filename.toLowerCase().split('.').pop(); const mimeTypes = { // Images 'jpg': 'image/jpeg', 'jpeg': 'image/jpeg', 'png': 'image/png', 'gif': 'image/gif', 'webp': 'image/webp', 'bmp': 'image/bmp', 'svg': 'image/svg+xml', // Documents 'pdf': 'application/pdf', 'txt': 'text/plain', 'md': 'text/markdown', 'html': 'text/html', 'css': 'text/css', 'js': 'application/javascript', 'json': 'application/json', 'xml': 'application/xml', // Office documents 'doc': 'application/msword', 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'xls': 'application/vnd.ms-excel', 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'ppt': 'application/vnd.ms-powerpoint', 'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation', // Audio/Video 'mp3': 'audio/mpeg', 'wav': 'audio/wav', 'mp4': 'video/mp4', 'avi': 'video/x-msvideo', 'mov': 'video/quicktime', }; return mimeTypes[ext || ''] || 'application/octet-stream'; } } exports.FileEncoder = FileEncoder; class MessageValidator { static validateContent(content) { if (!content.parts || content.parts.length === 0) { throw new Error('Content must have at least one part'); } for (const part of content.parts) { if ('text' in part) { if (!part.text || typeof part.text !== 'string') { throw new Error('Text part must have non-empty text string'); } } else if ('inline_data' in part) { if (!part.inline_data.mime_type || !part.inline_data.data) { throw new Error('Inline data part must have mime_type and data'); } } else if ('file_data' in part) { if (!part.file_data.mime_type || !part.file_data.file_uri) { throw new Error('File data part must have mime_type and file_uri'); } } else { throw new Error('Invalid content part type'); } } } static validateContents(contents) { if (!contents || contents.length === 0) { throw new Error('Contents array cannot be empty'); } for (const content of contents) { this.validateContent(content); } } } exports.MessageValidator = MessageValidator; //# sourceMappingURL=ai.builder.js.map