UNPKG

okeymeta-ai-sdk

Version:

Official SDK for OkeyMeta AI models, including OkeyAI—Africa's first trained AI. Seamlessly integrate text, image, and conversational AI into any JavaScript project with enterprise-grade reliability and security.

449 lines (404 loc) 20.2 kB
import axios from 'axios'; const DEFAULT_MODEL_ENDPOINTS = { 'okeyai2.0-basic': 'https://api.okeymeta.com.ng/api/ssailm/model/okeyai2.0-basic/okeyai', 'okeyai2.0-mega': 'https://api.okeymeta.com.ng/api/ssailm/model/okeyai2.0-mega/okeyai', 'okeyai3.0-vanguard': 'https://api.okeymeta.com.ng/api/ssailm/model/okeyai3.0-vanguard/okeyai', 'okeyai4.0-DeepCognition': 'https://api.okeymeta.com.ng/api/ssailm/model/okeyai4.0-DeepCognition/okeyai', }; const MODEL_FEATURES = { 'okeyai2.0-basic': { text: true, image: false, params: ['input', 'ask'] }, 'okeyai2.0-mega': { text: true, image: true, params: ['input', 'ask', 'imgUrl'] }, 'okeyai3.0-vanguard': { text: true, image: true, params: ['input', 'imgUrl'] }, 'okeyai4.0-DeepCognition': { text: true, image: true, params: ['input', 'imgUrl', 'deepCognition', 'reasoningFormat'] }, }; function validateParams(model, params) { const features = MODEL_FEATURES[model]; if (!features) throw new Error(`Unknown model: ${model}`); // Enforce correct prompt parameter per model if (model === 'okeyai2.0-basic' || model === 'okeyai2.0-mega') { if (!('ask' in params) || !params.ask) { throw new Error(`Parameter 'ask' is required for model '${model}'.`); } if ('input' in params) { throw new Error(`Parameter 'input' is not allowed for model '${model}'. Use 'ask' instead.`); } } else if (model === 'okeyai3.0-vanguard' || model === 'okeyai4.0-DeepCognition') { if (!('input' in params) || !params.input) { throw new Error(`Parameter 'input' is required for model '${model}'.`); } if ('ask' in params) { throw new Error(`Parameter 'ask' is not allowed for model '${model}'. Use 'input' instead.`); } } for (const key of Object.keys(params)) { if (!features.params.includes(key) && key !== 'contextKey' && key !== 'APiKey' && key !== 'stream') { throw new Error(`Parameter '${key}' is not supported by model '${model}'.`); } } if (model === 'okeyai4.0-DeepCognition' && params.deepCognition === 'on') { if (!params.reasoningFormat) { throw new Error('reasoningFormat is required when deepCognition is on.'); } if (!['raw', 'parsed', 'hidden'].includes(params.reasoningFormat)) { throw new Error(`Invalid reasoningFormat: ${params.reasoningFormat}`); } } } class Conversation { constructor({ client, model, contextKey }) { this.client = client; this.model = model; this.contextKey = contextKey; } setContextKey(contextKey) { this.contextKey = contextKey; } async send(input, params = {}) { const response = await this.client.textCompletion({ model: this.model, input, contextKey: this.contextKey, ...params, }); this.contextKey = response.API_KEY || response.APiKey || this.contextKey; return response; } async *sendStream(input, params = {}) { const stream = this.client.textCompletion({ model: this.model, input, contextKey: this.contextKey, stream: true, ...params, }); let lastResponse = null; for await (const chunk of stream) { lastResponse = chunk; yield chunk; } if (lastResponse && lastResponse.apiResponse) { this.contextKey = lastResponse.apiResponse.API_KEY || lastResponse.apiResponse.APiKey || this.contextKey; } } } export function createOkeyMetaProvider({ auth_token, headers = {}, endpoints = {}, } = {}) { return new OkeyMetaClient({ auth_token, headers, endpoints }); } export class OkeyMetaClient { constructor({ auth_token, headers = {}, endpoints = {} } = {}) { this.auth_token = auth_token || process.env.OKEYMETA_AUTH_TOKEN; if (!this.auth_token) { throw new Error('OkeyMeta authorization token is required. Set OKEYMETA_AUTH_TOKEN env variable or pass auth_token.'); } this.headers = headers; this.endpoints = { ...DEFAULT_MODEL_ENDPOINTS, ...endpoints }; } async *streamTextCompletion({ model = 'okeyai3.0-vanguard', ask, input, contextKey, APiKey, ...params }) { if (params.raw) { throw new Error('Streaming is not supported with raw mode. Remove raw: true to enable streaming.'); } let fullResponse = ''; let apiResponse = null; // Enforce correct prompt parameter per model if (model === 'okeyai2.0-basic' || model === 'okeyai2.0-mega') { if (!ask) throw new Error(`Parameter 'ask' is required for model '${model}'.`); validateParams(model, { ask, contextKey, APiKey, ...params }); const url = this.endpoints[model]; if (!url) throw new Error(`Unknown model: ${model}`); const headers = { Authorization: this.auth_token, ...this.headers }; const query = { ask, ...params }; if (contextKey) query.API_KEY = contextKey; if (APiKey) query.API_KEY = APiKey; try { const response = await axios.get(url, { headers, params: query }); apiResponse = response.data; const responseText = response.data && typeof response.data.response === 'string' ? response.data.response : response.data; if (typeof responseText === 'string') { const words = responseText.split(' '); for (let i = 0; i < words.length; i++) { const chunk = words[i] + (i < words.length - 1 ? ' ' : ''); fullResponse += chunk; yield { chunk, fullResponse, done: false }; } } else { yield { chunk: responseText, fullResponse: responseText, done: false }; } } catch (error) { throw new Error(`Streaming error: ${error.message}`); } } else if (model === 'okeyai3.0-vanguard' || model === 'okeyai4.0-DeepCognition') { if (!input) throw new Error(`Parameter 'input' is required for model '${model}'.`); validateParams(model, { input, contextKey, APiKey, ...params }); const url = this.endpoints[model]; if (!url) throw new Error(`Unknown model: ${model}`); const headers = { Authorization: this.auth_token, ...this.headers }; const query = { input, ...params }; if (contextKey) query.API_KEY = contextKey; if (APiKey) query.API_KEY = APiKey; try { const response = await axios.get(url, { headers, params: query }); apiResponse = response.data; let responseText = response.data && typeof response.data.response === 'string' ? response.data.response : response.data; if (model === 'okeyai4.0-DeepCognition' && params.deepCognition === 'on' && params.reasoningFormat === 'raw') { if (typeof response.data === 'string' && response.data.includes('<think>')) { responseText = response.data; } else if (response.data && response.data.response && typeof response.data.response === 'string' && response.data.response.includes('<think>')) { responseText = response.data; } } if (typeof responseText === 'string') { const words = responseText.split(' '); for (let i = 0; i < words.length; i++) { const chunk = words[i] + (i < words.length - 1 ? ' ' : ''); fullResponse += chunk; yield { chunk, fullResponse, done: false }; } } else { yield { chunk: responseText, fullResponse: responseText, done: false }; } } catch (error) { throw new Error(`Streaming error: ${error.message}`); } } else { throw new Error(`Unknown model: ${model}`); } yield { chunk: '', fullResponse, done: true, apiResponse }; } textCompletion({ model = 'okeyai3.0-vanguard', ask, input, contextKey, APiKey, raw = false, stream = false, ...params }) { if (stream && raw) { throw new Error('Streaming is not supported with raw mode. Remove raw: true to enable streaming.'); } if (stream) { return this.streamTextCompletion({ model, ask, input, contextKey, APiKey, ...params }); } // For non-streaming, use async wrapper return this._textCompletionAsync({ model, ask, input, contextKey, APiKey, raw, ...params }); } async _textCompletionAsync({ model = 'okeyai3.0-vanguard', ask, input, contextKey, APiKey, raw = false, ...params }) { // Enforce correct prompt parameter per model if (model === 'okeyai2.0-basic' || model === 'okeyai2.0-mega') { if (!ask) throw new Error(`Parameter 'ask' is required for model '${model}'.`); validateParams(model, { ask, contextKey, APiKey, ...params }); const url = this.endpoints[model]; if (!url) throw new Error(`Unknown model: ${model}`); const headers = { Authorization: this.auth_token, ...this.headers }; const query = { ask, ...params }; if (contextKey) query.API_KEY = contextKey; if (APiKey) query.API_KEY = APiKey; const response = await axios.get(url, { headers, params: query }); if (raw) return response.data; return response.data && typeof response.data.response === 'string' ? response.data.response : response.data; } else if (model === 'okeyai3.0-vanguard' || model === 'okeyai4.0-DeepCognition') { if (!input) throw new Error(`Parameter 'input' is required for model '${model}'.`); validateParams(model, { input, contextKey, APiKey, ...params }); const url = this.endpoints[model]; if (!url) throw new Error(`Unknown model: ${model}`); const headers = { Authorization: this.auth_token, ...this.headers }; const query = { input, ...params }; if (contextKey) query.API_KEY = contextKey; if (APiKey) query.API_KEY = APiKey; const response = await axios.get(url, { headers, params: query }); if (model === 'okeyai4.0-DeepCognition' && params.deepCognition === 'on' && params.reasoningFormat === 'raw') { if (typeof response.data === 'string' && response.data.includes('<think>')) { return response.data; } if (response.data && response.data.response && typeof response.data.response === 'string' && response.data.response.includes('<think>')) { return response.data; } } if (raw) return response.data; return response.data && typeof response.data.response === 'string' ? response.data.response : response.data; } else { throw new Error(`Unknown model: ${model}`); } } async *streamImageToText({ model = 'okeyai4.0-DeepCognition', ask, input, imgUrl, contextKey, APiKey, ...params }) { if (params.raw) { throw new Error('Streaming is not supported with raw mode. Remove raw: true to enable streaming.'); } if (!imgUrl) throw new Error('imgUrl is required for image-to-text.'); let fullResponse = ''; let apiResponse = null; // Enforce correct prompt parameter per model if (model === 'okeyai2.0-basic' || model === 'okeyai2.0-mega') { if (!ask) throw new Error(`Parameter 'ask' is required for model '${model}'.`); validateParams(model, { ask, imgUrl, contextKey, APiKey, ...params }); const url = this.endpoints[model]; if (!url) throw new Error(`Unknown model: ${model}`); const headers = { Authorization: this.auth_token, ...this.headers }; const query = { ask, imgUrl, ...params }; if (contextKey) query.API_KEY = contextKey; if (APiKey) query.API_KEY = APiKey; try { const response = await axios.get(url, { headers, params: query }); apiResponse = response.data; const responseText = response.data && typeof response.data.response === 'string' ? response.data.response : response.data; if (typeof responseText === 'string') { const words = responseText.split(' '); for (let i = 0; i < words.length; i++) { const chunk = words[i] + (i < words.length - 1 ? ' ' : ''); fullResponse += chunk; yield { chunk, fullResponse, done: false }; } } else { yield { chunk: responseText, fullResponse: responseText, done: false }; } } catch (error) { throw new Error(`Streaming error: ${error.message}`); } } else if (model === 'okeyai3.0-vanguard' || model === 'okeyai4.0-DeepCognition') { if (!input) throw new Error(`Parameter 'input' is required for model '${model}'.`); validateParams(model, { input, imgUrl, contextKey, APiKey, ...params }); const url = this.endpoints[model]; if (!url) throw new Error(`Unknown model: ${model}`); const headers = { Authorization: this.auth_token, ...this.headers }; const query = { input, imgUrl, ...params }; if (contextKey) query.API_KEY = contextKey; if (APiKey) query.API_KEY = APiKey; try { const response = await axios.get(url, { headers, params: query }); apiResponse = response.data; let responseText = response.data && typeof response.data.response === 'string' ? response.data.response : response.data; if (model === 'okeyai4.0-DeepCognition' && params.deepCognition === 'on' && params.reasoningFormat === 'raw') { if (typeof response.data === 'string' && response.data.includes('<think>')) { responseText = response.data; } else if (response.data && response.data.response && typeof response.data.response === 'string' && response.data.response.includes('<think>')) { responseText = response.data; } } if (typeof responseText === 'string') { const words = responseText.split(' '); for (let i = 0; i < words.length; i++) { const chunk = words[i] + (i < words.length - 1 ? ' ' : ''); fullResponse += chunk; yield { chunk, fullResponse, done: false }; } } else { yield { chunk: responseText, fullResponse: responseText, done: false }; } } catch (error) { throw new Error(`Streaming error: ${error.message}`); } } else { throw new Error(`Unknown model: ${model}`); } yield { chunk: '', fullResponse, done: true, apiResponse }; } imageToText({ model = 'okeyai4.0-DeepCognition', ask, input, imgUrl, contextKey, APiKey, raw = false, stream = false, ...params }) { if (stream && raw) { throw new Error('Streaming is not supported with raw mode. Remove raw: true to enable streaming.'); } if (stream) { return this.streamImageToText({ model, ask, input, imgUrl, contextKey, APiKey, ...params }); } // For non-streaming, use async wrapper return this._imageToTextAsync({ model, ask, input, imgUrl, contextKey, APiKey, raw, ...params }); } async _imageToTextAsync({ model = 'okeyai4.0-DeepCognition', ask, input, imgUrl, contextKey, APiKey, raw = false, ...params }) { if (!imgUrl) throw new Error('imgUrl is required for image-to-text.'); // Enforce correct prompt parameter per model if (model === 'okeyai2.0-basic' || model === 'okeyai2.0-mega') { if (!ask) throw new Error(`Parameter 'ask' is required for model '${model}'.`); validateParams(model, { ask, imgUrl, contextKey, APiKey, ...params }); const url = this.endpoints[model]; if (!url) throw new Error(`Unknown model: ${model}`); const headers = { Authorization: this.auth_token, ...this.headers }; const query = { ask, imgUrl, ...params }; if (contextKey) query.API_KEY = contextKey; if (APiKey) query.API_KEY = APiKey; const response = await axios.get(url, { headers, params: query }); if (raw) return response.data; return response.data && typeof response.data.response === 'string' ? response.data.response : response.data; } else if (model === 'okeyai3.0-vanguard' || model === 'okeyai4.0-DeepCognition') { if (!input) throw new Error(`Parameter 'input' is required for model '${model}'.`); validateParams(model, { input, imgUrl, contextKey, APiKey, ...params }); const url = this.endpoints[model]; if (!url) throw new Error(`Unknown model: ${model}`); const headers = { Authorization: this.auth_token, ...this.headers }; const query = { input, imgUrl, ...params }; if (contextKey) query.API_KEY = contextKey; if (APiKey) query.API_KEY = APiKey; const response = await axios.get(url, { headers, params: query }); if (model === 'okeyai4.0-DeepCognition' && params.deepCognition === 'on' && params.reasoningFormat === 'raw') { if (typeof response.data === 'string' && response.data.includes('<think>')) { return response.data; } if (response.data && response.data.response && typeof response.data.response === 'string' && response.data.response.includes('<think>')) { return response.data; } } if (raw) return response.data; return response.data && typeof response.data.response === 'string' ? response.data.response : response.data; } else { throw new Error(`Unknown model: ${model}`); } } /** * Fine-tune a model (OkeyMeta 3.0/4.0) * @param {Object} options - Fine-tuning options * @param {string} options.baseModel - The base model to fine-tune (e.g., 'okeyai3.0-vanguard', 'okeyai4.0-DeepCognition') * @param {string} options.modelName - Name for your fine-tuned model * @param {string} options.version - Version string * @param {string} options.developer - Developer name * @param {string} options.specialization - Specialization/domain * @param {string} options.tone - Tone/style * @param {string} options.instructions - Instructions for the model * @param {Array|Object} options.trainingData - Array or object of training examples * @param {boolean} [options.raw=false] - If true, return the full API response; otherwise, return only the accessKey * @returns {Promise<Object|string>} Fine-tune response (accessKey or full API object) */ async fineTuneModel({ baseModel, modelName, version, developer, specialization, tone, instructions, trainingData, raw = false }) { if (!baseModel || !modelName || !version || !developer || !specialization || !tone || !instructions || !trainingData) { throw new Error('All fine-tuning parameters are required.'); } const url = this.endpoints[baseModel]; if (!url) throw new Error(`Unknown base model: ${baseModel}`); const params = { mode: 'finetune', modelName, version, developer, specialization, tone, instructions, trainingData: JSON.stringify(trainingData) }; const headers = { Authorization: this.auth_token, ...this.headers }; const response = await axios.get(url, { headers, params }); if (raw) return response.data; return response.data && response.data.accessKey ? response.data.accessKey : response.data; } /** * Use a fine-tuned model (OkeyMeta 3.0/4.0) * @param {Object} options - Usage options * @param {string} options.baseModel - The base model (e.g., 'okeyai3.0-vanguard', 'okeyai4.0-DeepCognition') * @param {string} options.accessKey - The fine-tuned model access key * @param {string} options.input - Input prompt (required) * @param {string} [options.imgUrl] - Optional image URL (for image-to-text) * @param {Object} [options.extra] - Any extra params (e.g., deepCognition, reasoningFormat) * @returns {Promise<Object>} Model response */ async useFineTunedModel({ baseModel, accessKey, input, imgUrl, extra = {} }) { if (!baseModel || !accessKey || !input) { throw new Error('baseModel, accessKey, and input are required.'); } const url = this.endpoints[baseModel]; if (!url) throw new Error(`Unknown base model: ${baseModel}`); const params = { input, fineTunedAccessKey: accessKey, ...extra }; if (imgUrl) params.imgUrl = imgUrl; const headers = { Authorization: this.auth_token, ...this.headers }; const response = await axios.get(url, { headers, params }); return response.data; } startConversation(model = 'okeyai3.0-vanguard', contextKey) { return new Conversation({ client: this, model, contextKey }); } }