morpheus-node
Version:
Official Node.js SDK for the Morpheus API Gateway - Connect to the Morpheus-Lumerin AI Marketplace
264 lines (263 loc) • 10.5 kB
JavaScript
"use strict";
/**
* Main Morpheus Client
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.MorpheusClient = void 0;
const eventemitter3_1 = require("eventemitter3");
const http_client_1 = require("./http-client");
const errors_1 = require("./errors");
class MorpheusClient {
constructor(config) {
if (!config.apiKey && !config.accessToken) {
throw new errors_1.MorpheusValidationError('Either API key or access token is required');
}
this.config = {
apiKey: config.apiKey,
accessToken: config.accessToken,
baseURL: config.baseURL || 'https://api.mor.org',
timeout: config.timeout || 30000,
maxRetries: config.maxRetries || 3,
retryDelay: config.retryDelay || 1000,
headers: config.headers || {}
};
this.accessToken = config.accessToken;
this.httpClient = new http_client_1.HttpClient({
apiKey: config.apiKey,
accessToken: this.accessToken,
baseURL: this.config.baseURL,
timeout: this.config.timeout,
maxRetries: this.config.maxRetries,
retryDelay: this.config.retryDelay,
headers: this.config.headers
});
}
/**
* Auth API
*/
async register(params, options) {
if (!params.email || !params.password) {
throw new errors_1.MorpheusValidationError('Email and password are required');
}
const response = await this.httpClient.request('POST', '/api/v1/auth/register', params, options);
// Store the access token for future requests
if (response.access_token) {
this.setAccessToken(response.access_token);
}
return response;
}
async login(params, options) {
if (!params.email || !params.password) {
throw new errors_1.MorpheusValidationError('Email and password are required');
}
const response = await this.httpClient.request('POST', '/api/v1/auth/login', params, options);
// Store the access token for future requests
if (response.access_token) {
this.setAccessToken(response.access_token);
}
return response;
}
async refreshToken(params, options) {
if (!params.refresh_token) {
throw new errors_1.MorpheusValidationError('Refresh token is required');
}
const response = await this.httpClient.request('POST', '/api/v1/auth/refresh', params, options);
// Update the access token
if (response.access_token) {
this.setAccessToken(response.access_token);
}
return response;
}
async getApiKeys(options) {
return this.httpClient.request('GET', '/api/v1/auth/keys', undefined, options);
}
async createApiKey(params, options) {
return this.httpClient.request('POST', '/api/v1/auth/keys', params || {}, options);
}
async deleteApiKey(keyId, options) {
if (!keyId) {
throw new errors_1.MorpheusValidationError('Key ID is required');
}
await this.httpClient.request('DELETE', `/api/v1/auth/keys/${keyId}`, undefined, options);
}
async storePrivateKey(params, options) {
if (!params.private_key) {
throw new errors_1.MorpheusValidationError('Private key is required');
}
await this.httpClient.request('POST', '/api/v1/auth/private-key', params, options);
}
async getPrivateKeyStatus(options) {
return this.httpClient.request('GET', '/api/v1/auth/private-key', undefined, options);
}
async deletePrivateKey(options) {
await this.httpClient.request('DELETE', '/api/v1/auth/private-key', undefined, options);
}
async storeDelegation(params, options) {
if (!params.delegatee_address) {
throw new errors_1.MorpheusValidationError('Delegatee address is required');
}
return this.httpClient.request('POST', '/api/v1/auth/delegation', params, options);
}
async getUserDelegations(options) {
return this.httpClient.request('GET', '/api/v1/auth/delegation', undefined, options);
}
async getActiveDelegation(options) {
return this.httpClient.request('GET', '/api/v1/auth/delegation/active', undefined, options);
}
async deleteDelegation(delegationId, options) {
if (!delegationId) {
throw new errors_1.MorpheusValidationError('Delegation ID is required');
}
await this.httpClient.request('DELETE', `/api/v1/auth/delegation/${delegationId}`, undefined, options);
}
/**
* Models API
*/
async listModels(options) {
const response = await this.httpClient.request('GET', '/api/v1/models', undefined, options);
return response.data;
}
async listAllModels(options) {
return this.httpClient.request('GET', '/api/v1/models/allmodels', undefined, options);
}
async getRatedBids(options) {
return this.httpClient.request('GET', '/api/v1/models/ratedbids', undefined, options);
}
/**
* Chat Completions API
*/
async createChatCompletion(params, options) {
this.validateChatCompletionParams(params);
return this.httpClient.request('POST', '/api/v1/chat/completions', params, options);
}
async *streamChatCompletion(params, options) {
this.validateChatCompletionParams(params);
const streamParams = { ...params, stream: true };
const stream = this.httpClient.stream('POST', '/api/v1/chat/completions', streamParams, options);
for await (const data of stream) {
try {
const chunk = JSON.parse(data);
yield chunk;
}
catch (error) {
console.warn('Failed to parse streaming chunk:', data);
continue;
}
}
}
/**
* Stream chat completion with event emitter
*/
streamChatCompletionEvents(params, options) {
const emitter = new eventemitter3_1.EventEmitter();
(async () => {
try {
const stream = this.streamChatCompletion(params, options);
for await (const chunk of stream) {
emitter.emit('message', { type: 'message', data: chunk });
}
emitter.emit('done', { type: 'done' });
}
catch (error) {
emitter.emit('error', { type: 'error', error: error });
}
})();
return emitter;
}
/**
* Session API
*/
async approveSpending(params, options) {
if (!params.amount) {
throw new errors_1.MorpheusValidationError('Amount is required');
}
await this.httpClient.request('POST', '/api/v1/session/approve', params, options);
}
async createBidSession(params, options) {
if (!params.bid_id) {
throw new errors_1.MorpheusValidationError('Bid ID is required');
}
return this.httpClient.request('POST', '/api/v1/session/bidsession', params, options);
}
async createModelSession(params, options) {
if (!params.model) {
throw new errors_1.MorpheusValidationError('Model is required');
}
return this.httpClient.request('POST', '/api/v1/session/modelsession', params, options);
}
async closeSession(params, options) {
if (!params.session_id) {
throw new errors_1.MorpheusValidationError('Session ID is required');
}
await this.httpClient.request('POST', '/api/v1/session/closesession', params, options);
}
async pingSession(params, options) {
if (!params.session_id) {
throw new errors_1.MorpheusValidationError('Session ID is required');
}
await this.httpClient.request('POST', '/api/v1/session/pingsession', params, options);
}
/**
* Automation API
*/
async getAutomationSettings(options) {
return this.httpClient.request('GET', '/api/v1/automation/settings', undefined, options);
}
async updateAutomationSettings(params, options) {
return this.httpClient.request('PUT', '/api/v1/automation/settings', params, options);
}
/**
* Health Check
*/
async healthCheck(options) {
return this.httpClient.request('GET', '/health', undefined, options);
}
/**
* Root endpoint
*/
async getRoot(options) {
return this.httpClient.request('GET', '/', undefined, options);
}
/**
* Helper methods
*/
setAccessToken(token) {
this.accessToken = token;
this.httpClient.setAccessToken(token);
}
getAccessToken() {
return this.accessToken;
}
/**
* Validation methods
*/
validateChatCompletionParams(params) {
if (!params.model) {
throw new errors_1.MorpheusValidationError('Model is required');
}
if (!params.messages || !Array.isArray(params.messages) || params.messages.length === 0) {
throw new errors_1.MorpheusValidationError('Messages array is required and cannot be empty');
}
for (const [index, message] of params.messages.entries()) {
if (!message.role || !['system', 'user', 'assistant', 'function'].includes(message.role)) {
throw new errors_1.MorpheusValidationError(`Invalid role for message at index ${index}`);
}
if (message.content === undefined || message.content === null) {
throw new errors_1.MorpheusValidationError(`Content is required for message at index ${index}`);
}
}
if (params.temperature !== undefined && (params.temperature < 0 || params.temperature > 2)) {
throw new errors_1.MorpheusValidationError('Temperature must be between 0 and 2');
}
if (params.top_p !== undefined && (params.top_p < 0 || params.top_p > 1)) {
throw new errors_1.MorpheusValidationError('top_p must be between 0 and 1');
}
if (params.n !== undefined && params.n < 1) {
throw new errors_1.MorpheusValidationError('n must be at least 1');
}
if (params.max_tokens !== undefined && params.max_tokens < 1) {
throw new errors_1.MorpheusValidationError('max_tokens must be at least 1');
}
}
}
exports.MorpheusClient = MorpheusClient;