Skip to main content
Glama
ai-provider-service.ts4.12 kB
import { ActivepiecesError, AIProviderConfig, AIProviderModel, AIProviderName, AIProviderWithoutSensitiveData, ApEdition, apId, CreateAIProviderRequest, ErrorCode, PlatformId, } from '@activepieces/shared' import { FastifyBaseLogger } from 'fastify' import cron from 'node-cron' import { repoFactory } from '../core/db/repo-factory' import { platformAiCreditsService } from '../ee/platform/platform-plan/platform-ai-credits' import { encryptUtils } from '../helper/encryption' import { system } from '../helper/system/system' import { AIProviderEntity, AIProviderSchema } from './ai-provider-entity' import { aiProviders } from './providers' const aiProviderRepo = repoFactory<AIProviderSchema>(AIProviderEntity) const modelsCache = new Map<string, AIProviderModel[]>() export const aiProviderService = (log: FastifyBaseLogger) => ({ async setup(): Promise<void> { cron.schedule('0 0 * * *', () => { log.info('Clearing AI provider models cache') modelsCache.clear() }) }, async listProviders(platformId: PlatformId): Promise<AIProviderWithoutSensitiveData[]> { const enableOpenRouterProvider = platformAiCreditsService(log).isEnabled() const configuredProviders = await aiProviderRepo().findBy({ platformId }) const formattedProviders: AIProviderWithoutSensitiveData[] = Object.values(AIProviderName).filter(id => id !== AIProviderName.ACTIVEPIECES).map(id => { return { id, name: aiProviders[id].name, configured: !!configuredProviders.find(c => c.provider === id), } }) if (enableOpenRouterProvider) { formattedProviders.push({ id: AIProviderName.ACTIVEPIECES, name: aiProviders[AIProviderName.ACTIVEPIECES].name, configured: true, }) } return formattedProviders }, async listModels(platformId: PlatformId, providerId: AIProviderName): Promise<AIProviderModel[]> { const config = await this.getConfig(platformId, providerId) const cacheKey = `${providerId}-${config.apiKey}` if (modelsCache.has(cacheKey)) { return modelsCache.get(cacheKey)! } const provider = aiProviders[providerId] const data = await provider.listModels(config) modelsCache.set(cacheKey, data.map(model => ({ id: model.id, name: model.name, type: model.type, }))) return modelsCache.get(cacheKey)! }, async upsert(platformId: PlatformId, request: CreateAIProviderRequest): Promise<void> { if (request.provider === AIProviderName.AZURE && system.getEdition() !== ApEdition.ENTERPRISE) { throw new ActivepiecesError({ code: ErrorCode.FEATURE_DISABLED, params: { message: 'Azure OpenAI is only available for enterprise customers', }, }) } await aiProviderRepo().upsert({ id: apId(), config: await encryptUtils.encryptObject(request.config), provider: request.provider, platformId, }, ['provider', 'platformId']) }, async delete(platformId: PlatformId, provider: AIProviderName): Promise<void> { await aiProviderRepo().delete({ platformId, provider, }) }, async getConfig(platformId: PlatformId, providerId: AIProviderName): Promise<GetProviderConfigResponse> { if (providerId === AIProviderName.ACTIVEPIECES) { const provisionedKey = await platformAiCreditsService(log).provisionKeyIfNeeded(platformId) return { apiKey: provisionedKey.key, } } const aiProvider = await aiProviderRepo().findOneByOrFail({ platformId, provider: providerId, }) return encryptUtils.decryptObject<AIProviderConfig>(aiProvider.config) }, }) export type GetProviderConfigResponse = AIProviderConfig

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/activepieces/activepieces'

If you have feedback or need assistance with the MCP directory API, please join our Discord server