using System.Collections.Concurrent; using System.Reflection; using System.Text; using System.Text.Encodings.Web; using Dm.util; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using ModelContextProtocol; using ModelContextProtocol.Server; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using OpenAI.Chat; using Volo.Abp.Application.Services; using Volo.Abp.Users; using Yi.Framework.AiHub.Application.Contracts.Dtos; using Yi.Framework.AiHub.Application.Contracts.Dtos.Chat; using Yi.Framework.AiHub.Domain; using Yi.Framework.AiHub.Domain.Entities; using Yi.Framework.AiHub.Domain.Entities.Chat; using Yi.Framework.AiHub.Domain.Entities.Model; using Yi.Framework.AiHub.Domain.Extensions; using Yi.Framework.AiHub.Domain.Managers; using Yi.Framework.AiHub.Domain.Shared.Consts; using System.Text.Json; using Yi.Framework.AiHub.Domain.Shared.Dtos; using Yi.Framework.AiHub.Domain.Shared.Dtos.OpenAi; using Yi.Framework.AiHub.Domain.Shared.Enums; using Yi.Framework.Rbac.Application.Contracts.IServices; using Yi.Framework.Rbac.Domain.Shared.Dtos; using Yi.Framework.SqlSugarCore.Abstractions; namespace Yi.Framework.AiHub.Application.Services; /// /// ai服务 /// public class AiChatService : ApplicationService { private readonly IHttpContextAccessor _httpContextAccessor; private readonly AiBlacklistManager _aiBlacklistManager; private readonly ILogger _logger; private readonly AiGateWayManager _aiGateWayManager; private readonly ModelManager _modelManager; private readonly PremiumPackageManager _premiumPackageManager; private readonly ChatManager _chatManager; private readonly TokenManager _tokenManager; private readonly IAccountService _accountService; private readonly ISqlSugarRepository _agentStoreRepository; private readonly ISqlSugarRepository _aiModelRepository; private const string FreeModelId = "DeepSeek-V3-0324"; public AiChatService(IHttpContextAccessor httpContextAccessor, AiBlacklistManager aiBlacklistManager, ILogger logger, AiGateWayManager aiGateWayManager, ModelManager modelManager, PremiumPackageManager premiumPackageManager, ChatManager chatManager, TokenManager tokenManager, IAccountService accountService, ISqlSugarRepository agentStoreRepository, ISqlSugarRepository aiModelRepository) { _httpContextAccessor = httpContextAccessor; _aiBlacklistManager = aiBlacklistManager; _logger = logger; _aiGateWayManager = aiGateWayManager; _modelManager = modelManager; _premiumPackageManager = premiumPackageManager; _chatManager = chatManager; _tokenManager = tokenManager; _accountService = accountService; _agentStoreRepository = agentStoreRepository; _aiModelRepository = aiModelRepository; } /// /// 查询已登录的账户信息 /// /// [Route("ai-chat/account")] [Authorize] public async Task GetAsync() { var accountService = LazyServiceProvider.GetRequiredService(); var output = await accountService.GetAsync(); return output; } /// /// 获取对话模型列表 /// /// public async Task> GetModelAsync() { var output = await _aiModelRepository._DbQueryable .Where(x => x.IsEnabled == true) .Where(x => x.ModelType == ModelTypeEnum.Chat) // .Where(x => x.ModelApiType == ModelApiTypeEnum.Completions) .OrderByDescending(x => x.OrderNum) .Select(x => new ModelGetListOutput { Id = x.Id, ModelId = x.ModelId, ModelName = x.Name, ModelDescribe = x.Description, Remark = x.Description, IsPremiumPackage = x.IsPremium, ModelApiType = x.ModelApiType, IconUrl = x.IconUrl, ProviderName = x.ProviderName }).ToListAsync(); output.ForEach(x => { if (x.ModelId == FreeModelId) { x.IsPremiumPackage = false; x.IsFree = true; } }); return output; } // /// // /// 发送消息 // /// // /// // /// // /// // [HttpPost("ai-chat/send")] // [Obsolete] // public async Task PostSendAsync([FromBody] ThorChatCompletionsRequest input, [FromQuery] Guid? sessionId, // CancellationToken cancellationToken) // { // //除了免费模型,其他的模型都要校验 // if (input.Model!=FreeModelId) // { // //有token,需要黑名单校验 // if (CurrentUser.IsAuthenticated) // { // await _aiBlacklistManager.VerifiyAiBlacklist(CurrentUser.GetId()); // if (!CurrentUser.IsAiVip()) // { // throw new UserFriendlyException("该模型需要VIP用户才能使用,请购买VIP后重新登录重试"); // } // } // else // { // throw new UserFriendlyException("未登录用户,只能使用未加速的DeepSeek-R1,请登录后重试"); // } // } // // //如果是尊享包服务,需要校验是是否尊享包足够 // if (CurrentUser.IsAuthenticated) // { // var isPremium = await _modelManager.IsPremiumModelAsync(input.Model); // // if (isPremium) // { // // 检查尊享token包用量 // var availableTokens = await _premiumPackageManager.GetAvailableTokensAsync(CurrentUser.GetId()); // if (availableTokens <= 0) // { // throw new UserFriendlyException("尊享token包用量不足,请先购买尊享token包"); // } // } // } // // //ai网关代理httpcontext // await _aiGateWayManager.CompleteChatStreamForStatisticsAsync(_httpContextAccessor.HttpContext, input, // CurrentUser.Id, sessionId, null, CancellationToken.None); // } /// /// 发送消息 /// /// /// [HttpPost("ai-chat/FileMaster/send")] public async Task PostFileMasterSendAsync([FromBody] ThorChatCompletionsRequest input, CancellationToken cancellationToken) { if (!string.IsNullOrWhiteSpace(input.Model)) { throw new BusinessException("当前接口不支持第三方使用"); } input.Model = "gpt-5-chat"; if (CurrentUser.IsAuthenticated) { await _aiBlacklistManager.VerifiyAiBlacklist(CurrentUser.GetId()); } //ai网关代理httpcontext await _aiGateWayManager.CompleteChatStreamForStatisticsAsync(_httpContextAccessor.HttpContext, input, CurrentUser.Id, null, null, CancellationToken.None); } /// /// Agent 发送消息 /// [HttpPost("ai-chat/agent/send")] public async Task PostAgentSendAsync([FromBody] AgentSendInput input, CancellationToken cancellationToken) { var tokenValidation = await _tokenManager.ValidateTokenAsync(input.TokenId, input.ModelId); await _aiBlacklistManager.VerifiyAiBlacklist(tokenValidation.UserId); // 验证用户是否为VIP var userInfo = await _accountService.GetAsync(null, null, tokenValidation.UserId); if (userInfo == null) { throw new UserFriendlyException("用户信息不存在"); } // 检查是否为VIP(使用RoleCodes判断) if (!userInfo.RoleCodes.Contains(AiHubConst.VipRole) && userInfo.User.UserName != "cc") { throw new UserFriendlyException("该接口为尊享服务专用,需要VIP权限才能使用"); } //如果是尊享包服务,需要校验是是否尊享包足够 var isPremium = await _modelManager.IsPremiumModelAsync(input.ModelId); if (isPremium) { // 检查尊享token包用量 var availableTokens = await _premiumPackageManager.GetAvailableTokensAsync(tokenValidation.UserId); if (availableTokens <= 0) { throw new UserFriendlyException("尊享token包用量不足,请先购买尊享token包"); } } await _chatManager.AgentCompleteChatStreamAsync(_httpContextAccessor.HttpContext, input.SessionId, input.Content, tokenValidation.Token, tokenValidation.TokenId, input.ModelId, tokenValidation.UserId, input.Tools, CancellationToken.None); } /// /// 获取 Agent 工具 /// /// [HttpPost("ai-chat/agent/tool")] public List GetAgentToolAsync() { var agentTools = _chatManager.GetTools().Select(x => new AgentToolOutput { Code = x.Code, Name = x.Name }).ToList(); return agentTools; } /// /// 获取 Agent 上下文 /// /// [HttpPost("ai-chat/agent/context/{sessionId}")] [Authorize] public async Task GetAgentContextAsync([FromRoute] Guid sessionId) { var data = await _agentStoreRepository.GetFirstAsync(x => x.SessionId == sessionId); return data?.Store; } /// /// 统一发送消息 - 支持4种API类型 /// /// API类型枚举 /// 原始请求体JsonElement /// 模型ID(Gemini格式需要从URL传入) /// 会话ID /// [HttpPost("ai-chat/unified/send")] public async Task PostUnifiedSendAsync( [FromQuery] ModelApiTypeEnum apiType, [FromBody] JsonElement input, [FromQuery] string modelId, [FromQuery] Guid? sessionId, CancellationToken cancellationToken) { // 从请求体中提取模型ID(如果未从URL传入) if (string.IsNullOrEmpty(modelId)) { modelId = ExtractModelIdFromRequest(apiType, input); } // 除了免费模型,其他的模型都要校验 if (modelId != FreeModelId) { if (CurrentUser.IsAuthenticated) { await _aiBlacklistManager.VerifiyAiBlacklist(CurrentUser.GetId()); if (!CurrentUser.IsAiVip()) { throw new UserFriendlyException("该模型需要VIP用户才能使用,请购买VIP后重新登录重试"); } } else { throw new UserFriendlyException("未登录用户,只能使用未加速的DeepSeek-R1,请登录后重试"); } } // 如果是尊享包服务,需要校验是否尊享包足够 if (CurrentUser.IsAuthenticated) { var isPremium = await _modelManager.IsPremiumModelAsync(modelId); if (isPremium) { var availableTokens = await _premiumPackageManager.GetAvailableTokensAsync(CurrentUser.GetId()); if (availableTokens <= 0) { throw new UserFriendlyException("尊享token包用量不足,请先购买尊享token包"); } } } // 调用统一流式处理 await _aiGateWayManager.UnifiedStreamForStatisticsAsync( _httpContextAccessor.HttpContext!, apiType, input, modelId, CurrentUser.Id, sessionId, null, CancellationToken.None); } /// /// 从请求体中提取模型ID /// private string ExtractModelIdFromRequest(ModelApiTypeEnum apiType, JsonElement input) { try { if (input.TryGetProperty("model", out var modelProperty)) { return modelProperty.GetString() ?? string.Empty; } } catch { // 忽略解析错误 } throw new UserFriendlyException("无法从请求中获取模型ID,请在URL参数中指定modelId"); } }