Initial commit of akmon project

This commit is contained in:
2026-01-20 08:04:15 +08:00
commit 77a2bab985
1309 changed files with 343305 additions and 0 deletions

View File

@@ -0,0 +1,563 @@
// AI Service Manager - Unified coordinator for all AI services
import {
AIServiceConfig,
AIProvider,
AIResponse,
AIServiceError,
UsageStatistics,
CacheOptions
} from '../types/ai-types.uts'
import { AITranslationService } from './AITranslationService.uts'
import { AIContentAnalysisService } from './AIContentAnalysisService.uts'
import { AIChatService } from './AIChatService.uts'
import { AIRecommendationService } from './AIRecommendationService.uts'
import { ContentProcessingPipeline } from './ContentProcessingPipeline.uts'
// 服务状态枚举
type ServiceStatus = 'initializing' | 'ready' | 'busy' | 'error' | 'maintenance'
// 服务健康状态
type ServiceHealth = {
status: ServiceStatus
lastChecked: number
responseTime: number
errorRate: number
uptime: number
version: string
capabilities: string[]
}
// 负载均衡策略
type LoadBalanceStrategy = 'round_robin' | 'least_connections' | 'weighted' | 'random'
// 服务监控配置
type MonitoringConfig = {
healthCheckInterval: number // 健康检查间隔(毫秒)
maxErrorRate: number // 最大错误率
maxResponseTime: number // 最大响应时间(毫秒)
alertThresholds: {
errorRate: number
responseTime: number
dailyCost: number
}
}
// 成本控制配置
type CostControlConfig = {
dailyLimit: number // 每日成本限制USD
monthlyLimit: number // 每月成本限制USD
perRequestLimit: number // 单次请求成本限制USD
alertThresholds: {
daily: number // 每日预警阈值
monthly: number // 每月预警阈值
}
}
// 管理器统计
type ManagerStats = {
totalRequests: number
successfulRequests: number
failedRequests: number
totalCost: number
avgResponseTime: number
servicesHealth: Record<string, ServiceHealth>
dailyUsage: UsageStatistics[]
costBreakdown: Record<AIProvider, number>
lastReset: number
}
/**
* AI服务管理器
* 统一管理所有AI服务提供负载均衡、监控、成本控制等功能
*/
export class AIServiceManager {
private config: AIServiceConfig
private monitoringConfig: MonitoringConfig
private costControlConfig: CostControlConfig
private cacheOptions: CacheOptions
// 服务实例
private translationService: AITranslationService
private analysisService: AIContentAnalysisService
private chatService: AIChatService
private recommendationService: AIRecommendationService
private processingPipeline: ContentProcessingPipeline
// 状态管理
private servicesHealth: Map<string, ServiceHealth> = new Map()
private loadBalanceState: Map<AIProvider, number> = new Map()
private stats: ManagerStats
private healthCheckInterval: any
private isInitialized: boolean = false
constructor(
config: AIServiceConfig,
monitoringConfig: Partial<MonitoringConfig> = {},
costControlConfig: Partial<CostControlConfig> = {},
cacheOptions: Partial<CacheOptions> = {}
) {
this.config = config
this.monitoringConfig = this.createDefaultMonitoringConfig(monitoringConfig)
this.costControlConfig = this.createDefaultCostControlConfig(costControlConfig)
this.cacheOptions = this.createDefaultCacheOptions(cacheOptions)
this.stats = this.initializeStats()
this.initializeServices()
}
/**
* 初始化所有服务
*/
async initialize(): Promise<AIResponse<boolean>> {
try {
console.log('Initializing AI Service Manager...')
// 初始化各个服务
this.translationService = new AITranslationService(this.config, this.cacheOptions)
this.analysisService = new AIContentAnalysisService(this.config)
this.chatService = new AIChatService(this.config)
this.recommendationService = new AIRecommendationService(this.config)
this.processingPipeline = new ContentProcessingPipeline(this.config)
// 初始化服务健康状态
await this.initializeHealthStatus()
// 启动健康检查
this.startHealthMonitoring()
// 初始化负载均衡状态
this.initializeLoadBalancing()
this.isInitialized = true
console.log('AI Service Manager initialized successfully')
return { success: true, data: true }
} catch (error) {
console.error('Failed to initialize AI Service Manager:', error)
return {
success: false,
error: error.message || 'Initialization failed'
}
}
}
/**
* 获取翻译服务
*/
getTranslationService(): AITranslationService {
this.ensureInitialized()
return this.translationService
}
/**
* 获取内容分析服务
*/
getAnalysisService(): AIContentAnalysisService {
this.ensureInitialized()
return this.analysisService
}
/**
* 获取聊天服务
*/
getChatService(): AIChatService {
this.ensureInitialized()
return this.chatService
}
/**
* 获取推荐服务
*/
getRecommendationService(): AIRecommendationService {
this.ensureInitialized()
return this.recommendationService
}
/**
* 获取内容处理管道
*/
getProcessingPipeline(): ContentProcessingPipeline {
this.ensureInitialized()
return this.processingPipeline
}
/**
* 选择最佳提供商
* @param serviceType 服务类型
*/
selectBestProvider(serviceType: string = 'general'): AIProvider {
const availableProviders = this.getAvailableProviders()
if (availableProviders.length === 0) {
return 'openai' // 默认提供商
}
// 基于健康状态和负载均衡策略选择
return this.applyLoadBalancing(availableProviders, serviceType)
}
/**
* 检查成本限制
* @param estimatedCost 预估成本
*/
checkCostLimits(estimatedCost: number): boolean {
const now = new Date()
const today = now.toISOString().split('T')[0]
const currentMonth = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}`
// 检查每日限制
const dailyCost = this.getDailyCost(today)
if (dailyCost + estimatedCost > this.costControlConfig.dailyLimit) {
console.warn(`Daily cost limit exceeded: ${dailyCost + estimatedCost} > ${this.costControlConfig.dailyLimit}`)
return false
}
// 检查每月限制
const monthlyCost = this.getMonthlyCost(currentMonth)
if (monthlyCost + estimatedCost > this.costControlConfig.monthlyLimit) {
console.warn(`Monthly cost limit exceeded: ${monthlyCost + estimatedCost} > ${this.costControlConfig.monthlyLimit}`)
return false
}
// 检查单次请求限制
if (estimatedCost > this.costControlConfig.perRequestLimit) {
console.warn(`Per-request cost limit exceeded: ${estimatedCost} > ${this.costControlConfig.perRequestLimit}`)
return false
}
return true
}
/**
* 记录使用统计
* @param provider 提供商
* @param serviceType 服务类型
* @param stats 统计信息
*/
recordUsage(provider: AIProvider, serviceType: string, stats: Partial<UsageStatistics>): void {
this.stats.totalRequests++
if (stats.requestsCount && stats.requestsCount > 0) {
this.stats.successfulRequests++
} else {
this.stats.failedRequests++
}
this.stats.totalCost += stats.costUSD || 0
this.stats.costBreakdown[provider] = (this.stats.costBreakdown[provider] || 0) + (stats.costUSD || 0)
if (stats.avgResponseTimeMs) {
this.stats.avgResponseTime = (
this.stats.avgResponseTime * (this.stats.totalRequests - 1) + stats.avgResponseTimeMs
) / this.stats.totalRequests
}
// 记录每日使用情况
const today = new Date().toISOString().split('T')[0]
const hour = new Date().getHours()
const dailyStats: UsageStatistics = {
provider,
serviceType,
tokensUsed: stats.tokensUsed || 0,
requestsCount: stats.requestsCount || 0,
costUSD: stats.costUSD || 0,
successCount: stats.successCount || 0,
errorCount: stats.errorCount || 0,
avgResponseTimeMs: stats.avgResponseTimeMs || 0,
date: today,
hour
}
this.stats.dailyUsage.push(dailyStats)
// 保持最近30天的数据
const cutoffDate = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0]
this.stats.dailyUsage = this.stats.dailyUsage.filter(usage => usage.date >= cutoffDate)
}
/**
* 获取服务健康状态
*/
getServicesHealth(): Record<string, ServiceHealth> {
const health: Record<string, ServiceHealth> = {}
for (const [serviceName, serviceHealth] of this.servicesHealth.entries()) {
health[serviceName] = { ...serviceHealth }
}
return health
}
/**
* 获取管理器统计
*/
getManagerStatistics(): ManagerStats {
return {
...this.stats,
servicesHealth: this.getServicesHealth()
}
}
/**
* 重置统计数据
*/
resetStatistics(): void {
this.stats = this.initializeStats()
}
/**
* 停止所有服务
*/
async shutdown(): Promise<void> {
console.log('Shutting down AI Service Manager...')
// 停止健康检查
if (this.healthCheckInterval) {
clearInterval(this.healthCheckInterval)
}
// 清理缓存
if (this.translationService) {
this.translationService.clearCache()
}
this.isInitialized = false
console.log('AI Service Manager shut down completed')
}
// Private methods
private initializeServices(): void {
// 初始化负载均衡状态
const providers: AIProvider[] = ['openai', 'google', 'baidu', 'custom']
providers.forEach(provider => {
this.loadBalanceState.set(provider, 0)
})
}
private async initializeHealthStatus(): Promise<void> {
const services = ['translation', 'analysis', 'chat', 'recommendation', 'pipeline']
for (const serviceName of services) {
const health: ServiceHealth = {
status: 'ready',
lastChecked: Date.now(),
responseTime: 0,
errorRate: 0,
uptime: Date.now(),
version: '1.0.0',
capabilities: this.getServiceCapabilities(serviceName)
}
this.servicesHealth.set(serviceName, health)
}
}
private getServiceCapabilities(serviceName: string): string[] {
const capabilities: Record<string, string[]> = {
translation: ['text_translation', 'language_detection', 'batch_translation'],
analysis: ['sentiment_analysis', 'entity_extraction', 'content_classification', 'quality_assessment'],
chat: ['conversation', 'multilingual_support', 'context_awareness'],
recommendation: ['personalized_recommendations', 'trending_content', 'similarity_matching'],
pipeline: ['automated_processing', 'batch_processing', 'workflow_management']
}
return capabilities[serviceName] || []
}
private startHealthMonitoring(): void {
this.healthCheckInterval = setInterval(() => {
this.performHealthCheck()
}, this.monitoringConfig.healthCheckInterval)
}
private async performHealthCheck(): Promise<void> {
for (const [serviceName, health] of this.servicesHealth.entries()) {
try {
const startTime = Date.now()
// 执行简单的健康检查
await this.checkServiceHealth(serviceName)
const responseTime = Date.now() - startTime
// 更新健康状态
health.lastChecked = Date.now()
health.responseTime = responseTime
health.status = responseTime > this.monitoringConfig.maxResponseTime ? 'error' : 'ready'
// 检查错误率
if (health.errorRate > this.monitoringConfig.maxErrorRate) {
health.status = 'error'
}
} catch (error) {
console.error(`Health check failed for ${serviceName}:`, error)
this.servicesHealth.get(serviceName)!.status = 'error'
}
}
}
private async checkServiceHealth(serviceName: string): Promise<void> {
// 简单的健康检查实现
switch (serviceName) {
case 'translation':
// 可以测试一个简单的翻译
break
case 'analysis':
// 可以测试一个简单的分析
break
case 'chat':
// 可以检查会话状态
break
case 'recommendation':
// 可以检查推荐算法状态
break
case 'pipeline':
// 可以检查处理管道状态
break
}
// 模拟健康检查延迟
await this.delay(Math.random() * 100 + 50)
}
private initializeLoadBalancing(): void {
const providers = this.getAvailableProviders()
providers.forEach(provider => {
this.loadBalanceState.set(provider, 0)
})
}
private getAvailableProviders(): AIProvider[] {
const providers: AIProvider[] = []
if (this.config.openai?.apiKey) providers.push('openai')
if (this.config.google?.apiKey) providers.push('google')
if (this.config.baidu?.apiKey) providers.push('baidu')
return providers
}
private applyLoadBalancing(providers: AIProvider[], serviceType: string): AIProvider {
// 过滤健康的提供商
const healthyProviders = providers.filter(provider => {
const serviceName = this.getServiceNameForProvider(provider, serviceType)
const health = this.servicesHealth.get(serviceName)
return health && health.status === 'ready'
})
if (healthyProviders.length === 0) {
return providers[0] // 回退到第一个可用提供商
}
// 轮询策略
const providerCounts = healthyProviders.map(provider => ({
provider,
count: this.loadBalanceState.get(provider) || 0
}))
// 选择使用次数最少的提供商
const selectedProvider = providerCounts.reduce((min, current) =>
current.count < min.count ? current : min
).provider
// 更新计数
this.loadBalanceState.set(selectedProvider, (this.loadBalanceState.get(selectedProvider) || 0) + 1)
return selectedProvider
}
private getServiceNameForProvider(provider: AIProvider, serviceType: string): string {
// 根据提供商和服务类型映射到内部服务名称
const serviceMap: Record<string, string> = {
'translation': 'translation',
'analysis': 'analysis',
'chat': 'chat',
'recommendation': 'recommendation'
}
return serviceMap[serviceType] || 'translation'
}
private getDailyCost(date: string): number {
return this.stats.dailyUsage
.filter(usage => usage.date === date)
.reduce((total, usage) => total + usage.costUSD, 0)
}
private getMonthlyCost(month: string): number {
return this.stats.dailyUsage
.filter(usage => usage.date.startsWith(month))
.reduce((total, usage) => total + usage.costUSD, 0)
}
private ensureInitialized(): void {
if (!this.isInitialized) {
throw new Error('AI Service Manager not initialized. Call initialize() first.')
}
}
private createDefaultMonitoringConfig(overrides: Partial<MonitoringConfig>): MonitoringConfig {
return {
healthCheckInterval: 60000, // 1分钟
maxErrorRate: 0.1, // 10%
maxResponseTime: 5000, // 5秒
alertThresholds: {
errorRate: 0.05, // 5%
responseTime: 3000, // 3秒
dailyCost: 100 // $100
},
...overrides
}
}
private createDefaultCostControlConfig(overrides: Partial<CostControlConfig>): CostControlConfig {
return {
dailyLimit: 200, // $200
monthlyLimit: 5000, // $5000
perRequestLimit: 10, // $10
alertThresholds: {
daily: 150, // $150
monthly: 4000 // $4000
},
...overrides
}
}
private createDefaultCacheOptions(overrides: Partial<CacheOptions>): CacheOptions {
return {
enabled: true,
ttlHours: 24,
maxSize: 10000,
strategy: 'lru',
...overrides
}
}
private initializeStats(): ManagerStats {
const providers: AIProvider[] = ['openai', 'google', 'baidu', 'custom']
const costBreakdown: Record<AIProvider, number> = {} as Record<AIProvider, number>
providers.forEach(provider => {
costBreakdown[provider] = 0
})
return {
totalRequests: 0,
successfulRequests: 0,
failedRequests: 0,
totalCost: 0,
avgResponseTime: 0,
servicesHealth: {},
dailyUsage: [],
costBreakdown,
lastReset: Date.now()
}
}
private async delay(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms))
}
}