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.Domain; using Yi.Framework.AiHub.Domain.Entities; 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 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 ISqlSugarRepository _aiModelRepository; private readonly AiBlacklistManager _aiBlacklistManager; private readonly ILogger _logger; private readonly AiGateWayManager _aiGateWayManager; private readonly PremiumPackageManager _premiumPackageManager; private readonly ChatManager _chatManager; public AiChatService(IHttpContextAccessor httpContextAccessor, AiBlacklistManager aiBlacklistManager, ISqlSugarRepository aiModelRepository, ILogger logger, AiGateWayManager aiGateWayManager, PremiumPackageManager premiumPackageManager, ChatManager chatManager) { _httpContextAccessor = httpContextAccessor; _aiBlacklistManager = aiBlacklistManager; _aiModelRepository = aiModelRepository; _logger = logger; _aiGateWayManager = aiGateWayManager; _premiumPackageManager = premiumPackageManager; _chatManager = chatManager; } /// /// 查询已登录的账户信息 /// /// [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.ModelType == ModelTypeEnum.Chat) .Where(x => x.ModelApiType == ModelApiTypeEnum.OpenAi) .OrderByDescending(x => x.OrderNum) .Select(x => new ModelGetListOutput { Id = x.Id, Category = "chat", ModelId = x.ModelId, ModelName = x.Name, ModelDescribe = x.Description, ModelPrice = 0, ModelType = "1", ModelShow = "0", SystemPrompt = null, ApiHost = null, ApiKey = null, Remark = x.Description, IsPremiumPackage = PremiumPackageConst.ModeIds.Contains(x.ModelId) }).ToListAsync(); return output; } /// /// 发送消息 /// /// /// /// [HttpPost("ai-chat/send")] public async Task PostSendAsync([FromBody] ThorChatCompletionsRequest input, [FromQuery] Guid? sessionId, CancellationToken cancellationToken) { //除了免费模型,其他的模型都要校验 if (!input.Model.Contains("DeepSeek-R1")) { //有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 && PremiumPackageConst.ModeIds.Contains(input.Model)) { // 检查尊享token包用量 var availableTokens = await _premiumPackageManager.GetAvailableTokensAsync(CurrentUser.GetId()); if (availableTokens <= 0) { throw new UserFriendlyException("尊享token包用量不足,请先购买尊享token包"); } } // 使用 ChatManager } /// /// Agent 发送消息 /// [HttpPost("ai-chat/agent/send")] public async Task PostAgentSendAsync() { await _chatManager.CompleteChatStreamAsync(); } /// /// 发送消息 /// /// /// [HttpPost("ai-chat/FileMaster/send")] public async Task PostFileMasterSendAsync([FromBody] ThorChatCompletionsRequest input, CancellationToken cancellationToken) { if (!string.IsNullOrWhiteSpace(input.Model)) { throw new BusinessException("当前接口不支持第三方使用"); } if (CurrentUser.IsAuthenticated) { await _aiBlacklistManager.VerifiyAiBlacklist(CurrentUser.GetId()); if (CurrentUser.IsAiVip()) { input.Model = "gpt-5-chat"; } else { input.Model = "gpt-4.1-mini"; } } else { input.Model = "DeepSeek-R1-0528"; } //ai网关代理httpcontext await _aiGateWayManager.CompleteChatStreamForStatisticsAsync(_httpContextAccessor.HttpContext, input, CurrentUser.Id, null, null, cancellationToken); } [HttpPost("ai-chat/tool")] public string GetTool() { var toolClasses = typeof(YiFrameworkAiHubDomainModule).Assembly.GetTypes() .Where(x => x.GetCustomAttribute() is not null) .ToList(); List mcpTools = new List(); foreach (var toolClass in toolClasses) { var instance = LazyServiceProvider.GetRequiredService(toolClass); var toolMethods = toolClass.GetMethods() .Where(y => y.GetCustomAttribute() is not null).ToList(); foreach (var toolMethod in toolMethods) { mcpTools.add(McpServerTool.Create(toolMethod, instance)); } } var json = System.Text.Json.JsonSerializer.Serialize(mcpTools.Select(x => x.ProtocolTool).ToList(), McpJsonUtilities.DefaultOptions); return json; } }