UNPKG

@future-agi/sdk

Version:

We help GenAI teams maintain high-accuracy for their Models in production.

303 lines 9.29 kB
import { APIKeyAuth, ResponseHandler } from './auth.js'; import { ModelProvider, HttpMethod } from './types.js'; import { Routes } from '../utils/routes.js'; /** * Response handler for API key operations */ class ProviderAPIKeyResponseHandler extends ResponseHandler { /** * Parse successful API key response */ static _parseSuccess(response) { const data = response.data; const method = response.config.method?.toUpperCase(); if (method === HttpMethod.POST) { return { success: true }; } else if (method === HttpMethod.GET) { const results = data.results || data; if (Array.isArray(results)) { return results.map(apiKey => ({ provider: apiKey.provider, key: apiKey.key })); } return results; } else { return data; } } /** * Handle API key operation errors */ static _handleError(response) { if (response.status >= 400) { const message = response.data?.message || response.statusText || 'API key operation failed'; throw new Error(`API Key Error [${response.status}]: ${message}`); } throw new Error('Unknown API key error'); } } /** * Client for API key operations * * This client can be used in two ways: * 1. As class methods for simple one-off operations: * ProviderAPIKeyClient.setApiKey(apiKey) * * 2. As an instance for chained operations: * client = new ProviderAPIKeyClient(apiKey) * client.set().get() */ class ProviderAPIKeyClient extends APIKeyAuth { constructor(apiKey, fiApiKey, fiSecretKey, fiBaseUrl) { super({ fiApiKey, fiSecretKey, fiBaseUrl }); this.apiKey = apiKey; } // Instance methods for chaining /** * Set the API key and return self for chaining */ async set() { if (!this.apiKey.key) { throw new Error('API key is required'); } await this._setApiKey(this.apiKey); return this; } /** * Get the API key by provider */ async get() { if (!this.apiKey.provider) { throw new Error('Provider is required'); } const response = await this._getApiKey(this.apiKey.provider); if (response) { this.apiKey = response; } return response; } // Protected internal methods /** * Internal method for setting API key */ async _setApiKey(apiKey) { const response = await this.request({ method: HttpMethod.POST, url: `${this.baseUrl}/${Routes.model_hub_api_keys}`, json: { provider: apiKey.provider, key: apiKey.key } }, ProviderAPIKeyResponseHandler); return response; } /** * Internal method to get API key by provider */ async _getApiKey(provider) { const response = await this.request({ method: HttpMethod.GET, url: `${this.baseUrl}/${Routes.model_hub_api_keys}` }, ProviderAPIKeyResponseHandler); if (Array.isArray(response)) { return response.find(apiKey => apiKey.provider === provider); } return undefined; } // Class methods for simple operations /** * Create a new ProviderAPIKeyClient instance */ static _getInstance(apiKey, options = {}) { return new ProviderAPIKeyClient(apiKey, options.fiApiKey, options.fiSecretKey, options.fiBaseUrl); } /** * Class method for simple API key creation */ static async setApiKey(apiKey, options = {}) { const instance = this._getInstance(apiKey, options); await instance.set(); return instance.apiKey; } /** * Class method for simple API key retrieval */ static async getApiKey(provider, options = {}) { const apiKey = { provider }; const instance = this._getInstance(apiKey, options); return await instance.get(); } /** * List all API keys for the organization */ static async listApiKeys(options = {}) { // The apiKey object is required for the constructor, but not used in this method. const instance = this._getInstance({}, options); const response = await instance.request({ method: HttpMethod.GET, url: `${instance.baseUrl}/${Routes.model_hub_api_keys}` }, ProviderAPIKeyResponseHandler); return Array.isArray(response) ? response : []; } } /** * Singleton API Key Manager for managing FutureAGI credentials (fi_api_key, fi_secret_key) */ class APIKeyManager extends APIKeyAuth { constructor() { super(); this._initialized = false; const fiApiKey = this.getFiApiKey(); const fiSecretKey = this.getFiSecretKey(); if (!fiApiKey || !fiSecretKey) { console.warn('FutureAGI credentials not found in environment variables. Please set FI_API_KEY and FI_SECRET_KEY.'); } } /** * Get the singleton instance */ static getInstance() { if (!APIKeyManager._instance) { APIKeyManager._instance = new APIKeyManager(); } return APIKeyManager._instance; } /** * Get the API URL for key management */ get url() { return `${this.baseUrl}/${Routes.model_hub_api_keys}`; } /** * Get FutureAGI API key */ getFiApiKey() { return this.fiApiKey; } /** * Get FutureAGI secret key */ getFiSecretKey() { return this.fiSecretKey; } /** * Check if FutureAGI credentials are configured */ isAuthenticated() { return !!(this.getFiApiKey() && this.getFiSecretKey()); } /** * Get authentication headers for FutureAGI API */ getAuthHeaders() { const apiKey = this.getFiApiKey(); const secretKey = this.getFiSecretKey(); if (!apiKey || !secretKey) { throw new Error('FutureAGI credentials not configured'); } return { 'X-Api-Key': apiKey, 'X-Secret-Key': secretKey }; } /** * Provider API key operations (delegated to ProviderAPIKeyClient) */ /** * Set a provider API key via FutureAGI API */ async setProviderApiKey(provider, key) { await ProviderAPIKeyClient.setApiKey({ provider, key }, { fiApiKey: this.getFiApiKey(), fiSecretKey: this.getFiSecretKey() }); } /** * Get a provider API key via FutureAGI API */ async getProviderApiKey(provider) { return await ProviderAPIKeyClient.getApiKey(provider, { fiApiKey: this.getFiApiKey(), fiSecretKey: this.getFiSecretKey() }); } /** * List all provider API keys via FutureAGI API */ async listProviderApiKeys() { return await ProviderAPIKeyClient.listApiKeys({ fiApiKey: this.getFiApiKey(), fiSecretKey: this.getFiSecretKey() }); } /** * Check if a provider API key is configured */ async isProviderConfigured(provider) { try { const apiKey = await this.getProviderApiKey(provider); return !!apiKey; } catch (error) { if (error.message && error.message.includes('404')) { return false; } throw error; } } /** * Validate that required provider API keys are present */ async validateRequiredProviders(requiredProviders) { if (!requiredProviders || requiredProviders.length === 0) { return true; } const results = await Promise.allSettled(requiredProviders.map(provider => this.isProviderConfigured(provider))); const missingProviders = requiredProviders.filter((provider, index) => { const result = results[index]; return result.status === 'rejected' || !result.value; }); if (missingProviders.length > 0) { throw new Error(`Missing required provider API keys: ${missingProviders.join(', ')}`); } return true; } /** * Reset the singleton instance (mainly for testing) */ static resetInstance() { if (APIKeyManager._instance) { APIKeyManager._instance.close(); APIKeyManager._instance = undefined; } } } /** * Factory function to get API key manager instance */ function getAPIKeyManager() { return APIKeyManager.getInstance(); } /** * Helper function to check if a provider is supported */ function isSupportedProvider(provider) { return Object.values(ModelProvider).includes(provider); } /** * Get all supported providers */ function getSupportedProviders() { return Object.values(ModelProvider); } export { APIKeyManager, ProviderAPIKeyClient, ProviderAPIKeyResponseHandler, getAPIKeyManager, isSupportedProvider, getSupportedProviders, HttpMethod, ModelProvider, }; //# sourceMappingURL=apikeys.js.map