UNPKG

@mvkproject/nexus

Version:

Free AI SDK with API key (500 free daily requests). Access 25+ LLM models (GPT-4, Gemini, Llama, DeepSeek), generate images with 14+ models (Flux, Stable Diffusion), and integrate Akinator game - all completely free.

316 lines (255 loc) 7.19 kB
const axios = require('axios'); class APIClient { constructor(apiKey, baseURL = 'https://nexus.drexus.xyz') { if (!apiKey) { throw new Error('API key is required. Get your free API key at https://nexus.drexus.xyz'); } this.apiKey = apiKey; this.baseURL = baseURL; this.client = axios.create({ baseURL: this.baseURL, headers: { 'Authorization': `Bearer ${this.apiKey}`, 'Content-Type': 'application/json' } }); } async request(method, endpoint, data = null, config = {}) { try { const response = await this.client.request({ method, url: endpoint, data, ...config }); return response.data; } catch (error) { this.handleError(error); } } handleError(error) { if (error.response) { const { status, data } = error.response; const message = data?.message || data?.error || 'Unknown error occurred'; switch (status) { case 400: throw new Error(`Bad Request: ${message}`); case 401: throw new Error('Unauthorized: Invalid or missing API key'); case 403: throw new Error('Forbidden: Access denied'); case 404: throw new Error(`Not Found: ${message}`); case 429: throw new Error('Too Many Requests: Daily limit exceeded'); case 500: throw new Error(`Server Error: ${message}`); default: throw new Error(`API Error (${status}): ${message}`); } } else if (error.request) { throw new Error('Network Error: Unable to reach the Nexus API'); } else { throw new Error(`Request Error: ${error.message}`); } } get(endpoint, config) { return this.request('GET', endpoint, null, config); } post(endpoint, data, config) { return this.request('POST', endpoint, data, config); } delete(endpoint, config) { return this.request('DELETE', endpoint, null, config); } } class ImageAPI { constructor(client) { this.client = client; } async generate(options) { const { prompt, model = 'flux', width = 512, height = 512 } = options; if (!prompt) { throw new Error('Prompt is required for image generation'); } const data = { prompt, model, width, height }; return await this.client.post('/v1/generate-image', data); } } class TextAPI { constructor(client) { this.client = client; } async generate(options) { const { model, prompt, userid, systemInstruction, temperature = 1.0, maxOutputTokens = 8192, images, stream = false } = options; if (!model) { throw new Error('Model is required for text generation'); } if (!prompt) { throw new Error('Prompt is required for text generation'); } if (stream) { throw new Error('For streaming, use generateStream() method instead'); } const data = { model, prompt, temperature, maxOutputTokens }; if (userid) data.userid = userid; if (systemInstruction) data.systemInstruction = systemInstruction; if (images) data.images = images; return await this.client.post('/v1/text/generate', data); } async generateStream(options, onChunk) { const { model, prompt, userid, systemInstruction, temperature = 1.0, maxOutputTokens = 8192, images } = options; if (!model) { throw new Error('Model is required for text generation'); } if (!prompt) { throw new Error('Prompt is required for text generation'); } if (typeof onChunk !== 'function') { throw new Error('onChunk callback function is required for streaming'); } const data = { model, prompt, temperature, maxOutputTokens, stream: true }; if (userid) data.userid = userid; if (systemInstruction) data.systemInstruction = systemInstruction; if (images) data.images = images; try { const response = await this.client.client.post('/v1/text/generate', data, { responseType: 'stream' }); return new Promise((resolve, reject) => { let buffer = ''; response.data.on('data', (chunk) => { buffer += chunk.toString(); const lines = buffer.split('\n'); buffer = lines.pop(); for (const line of lines) { if (line.startsWith('data: ')) { const data = line.slice(6).trim(); if (data === '[DONE]') { resolve(); return; } try { const parsed = JSON.parse(data); if (parsed.chunk) { onChunk(parsed.chunk); } } catch (e) { } } } }); response.data.on('end', () => { resolve(); }); response.data.on('error', (error) => { reject(error); }); }); } catch (error) { this.client.handleError(error); } } async clearHistory(userid) { if (!userid) { throw new Error('User ID is required to clear history'); } return await this.client.delete(`/v1/text/history/${userid}`); } } class AkinatorAPI { constructor(client) { this.client = client; } async start(options = {}) { const { region = 'en', childMode = false } = options; return await this.client.get( `/v1/games/akinator/start?region=${region}&childMode=${childMode}` ); } async answer(gameId, answer) { if (!gameId) { throw new Error('Game ID is required'); } const validAnswers = ['yes', 'no', 'dont-know', 'probably', 'probably-not']; if (!validAnswers.includes(answer)) { throw new Error(`Invalid answer. Must be one of: ${validAnswers.join(', ')}`); } return await this.client.get( `/v1/games/akinator/answer/${gameId}?answer=${answer}` ); } async back(gameId) { if (!gameId) { throw new Error('Game ID is required'); } return await this.client.get(`/v1/games/akinator/back/${gameId}`); } async progress(gameId) { if (!gameId) { throw new Error('Game ID is required'); } return await this.client.get(`/v1/games/akinator/progress/${gameId}`); } async delete(gameId) { if (!gameId) { throw new Error('Game ID is required'); } return await this.client.delete(`/v1/games/akinator/game/${gameId}`); } } class NexusClient { constructor(options) { if (typeof options === 'string') { options = { apiKey: options }; } const { apiKey, baseURL } = options; if (!apiKey) { throw new Error('API key is required. Get your free API key at https://nexus.drexus.xyz'); } this.client = new APIClient(apiKey, baseURL); this.image = new ImageAPI(this.client); this.text = new TextAPI(this.client); this.akinator = new AkinatorAPI(this.client); } } module.exports = { NexusClient }; module.exports.default = NexusClient;