From ff8038a616a790abfc741ada668fceba9806d775 Mon Sep 17 00:00:00 2001 From: chenchun Date: Fri, 21 Mar 2025 15:36:22 +0800 Subject: [PATCH 1/4] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=82=A1=E5=B8=82?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/StockMarketService.cs | 1 + .../Managers/StockMarketManager.cs | 1 + Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/stock/marketPrompt.txt | 3 ++- Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/stock/newsPrompt.txt | 7 ++----- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Application/Services/StockMarketService.cs b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Application/Services/StockMarketService.cs index 10cddca7..2f22bfb2 100644 --- a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Application/Services/StockMarketService.cs +++ b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Application/Services/StockMarketService.cs @@ -96,6 +96,7 @@ namespace Yi.Framework.Stock.Application.Services .WhereIF(input.StartTime.HasValue, p => p.RecordTime >= input.StartTime.Value) .WhereIF(input.EndTime.HasValue, p => p.RecordTime <= input.EndTime.Value) .WhereIF(input.PeriodType.HasValue, p => p.PeriodType == input.PeriodType.Value) + .Where(x=>x.RecordTime<=DateTime.Now) .OrderByIF(!string.IsNullOrEmpty(input.Sorting),input.Sorting) .OrderByIF(string.IsNullOrEmpty(input.Sorting),p=>p.RecordTime); diff --git a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/StockMarketManager.cs b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/StockMarketManager.cs index 13949f28..648f232d 100644 --- a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/StockMarketManager.cs +++ b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/StockMarketManager.cs @@ -211,6 +211,7 @@ namespace Yi.Framework.Stock.Domain.Managers // 获取最新的价格记录 var latestPriceRecord = await _stockPriceRecordRepository._DbQueryable .Where(p => p.StockId == stockId) + .Where(x=>x.RecordTime<=DateTime.Now) .OrderByDescending(p => p.RecordTime) .FirstAsync(); diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/stock/marketPrompt.txt b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/stock/marketPrompt.txt index 6fc4d04a..3fa09b1e 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/stock/marketPrompt.txt +++ b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/stock/marketPrompt.txt @@ -22,6 +22,7 @@ - 一天24小时下来整体价格变化的趋势应该比较连贯,可以部分小时的价格大幅度变化 - 变化幅度可以大一些,为了更吸引用户 - 可能下跌,可能上涨 -- 最低价值为1,最高价值为100 +- 最低价格为5,最高价格为100,如果小于等于5,就固定一直是5,如果大于等于100,要即时的修正扣减 +- 可能出现暴跌或者暴涨,一天直接减少或增加百分之50 请确保数据格式正确,以便系统能够自动处理。 \ No newline at end of file diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/stock/newsPrompt.txt b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/stock/newsPrompt.txt index c12fd80b..7d747db6 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/stock/newsPrompt.txt +++ b/Yi.Abp.Net8/src/Yi.Abp.Web/wwwroot/stock/newsPrompt.txt @@ -1,6 +1,4 @@ -基于以下最近的新闻背景,预测趋势生成一条其他新闻。 - -{{newsContext}} +生成一条有趣并通俗易懂的新闻 包含以下要素: 1. 新闻标题:吸引人且简短,涉及不同行业 @@ -14,6 +12,5 @@ - 内容应当暗示可能对不同行业公司产生某种影响(积极或消极),不能太过于明显 - 行业焦点可以包括娱乐、科技、金融、医疗、食品等多个领域 - 新闻有很小的概率造假,如果是造假的,新闻来源就得来自小的工作室 -- 不要一直重复着一个公司、一个行业的新闻 -- 可以加一些很离谱的元素增加新闻的趣味性 +- 不要一直重复着一个公司、一个行业、一个事件的新闻 - 只需生成一次即可 \ No newline at end of file From 0b111852ece1181dface6de585337c5a98604785 Mon Sep 17 00:00:00 2001 From: chenchun Date: Fri, 21 Mar 2025 15:51:44 +0800 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=82=B9=E6=95=B0?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Yi.Bbs.Vue3/src/apis/stockApi.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Yi.Bbs.Vue3/src/apis/stockApi.js b/Yi.Bbs.Vue3/src/apis/stockApi.js index c57d3863..f7a2109e 100644 --- a/Yi.Bbs.Vue3/src/apis/stockApi.js +++ b/Yi.Bbs.Vue3/src/apis/stockApi.js @@ -35,7 +35,8 @@ export function getStockPriceRecords(stockId, startTime, endTime, periodType = ' StockId: stockId, StartTime: startTime, EndTime: endTime, - PeriodType: periodType + PeriodType: periodType, + MaxResultCount : 100 } }); } From cbb3510d942ed47bee463eb6ee60809694647a6b Mon Sep 17 00:00:00 2001 From: chenchun Date: Fri, 21 Mar 2025 18:24:59 +0800 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20=E9=87=8D=E6=9E=84=E8=81=8A?= =?UTF-8?q?=E5=A4=A9=E5=AE=A4=E8=AF=AD=E4=B9=89=E5=86=85=E6=A0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Options/SemanticKernelOptions.cs | 8 ++ .../SemanticKernel/SemanticKernelOptions.cs | 2 +- .../YiFrameworkStockDomainModule.cs | 3 +- .../Managers/AiManager.cs | 90 ++++++++----------- .../Yi.Framework.ChatHub.Domain.csproj | 2 +- .../YiFrameworkChatHubDomainModule.cs | 28 +++++- Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.json | 12 +-- 7 files changed, 78 insertions(+), 67 deletions(-) create mode 100644 Yi.Abp.Net8/framework/Yi.Framework.Core/Options/SemanticKernelOptions.cs diff --git a/Yi.Abp.Net8/framework/Yi.Framework.Core/Options/SemanticKernelOptions.cs b/Yi.Abp.Net8/framework/Yi.Framework.Core/Options/SemanticKernelOptions.cs new file mode 100644 index 00000000..23833bcb --- /dev/null +++ b/Yi.Abp.Net8/framework/Yi.Framework.Core/Options/SemanticKernelOptions.cs @@ -0,0 +1,8 @@ +namespace Yi.Framework.Core.Options; + +public class SemanticKernelOptions +{ + public List ModelIds { get; set; } + public string Endpoint { get; set; } + public string ApiKey { get; set; } +} \ No newline at end of file diff --git a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/SemanticKernel/SemanticKernelOptions.cs b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/SemanticKernel/SemanticKernelOptions.cs index 15ba372c..afa754d4 100644 --- a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/SemanticKernel/SemanticKernelOptions.cs +++ b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/SemanticKernel/SemanticKernelOptions.cs @@ -2,7 +2,7 @@ namespace Yi.Framework.Stock.Domain.Managers.SemanticKernel { public class SemanticKernelOptions { - public string ModelId { get; set; } + public List ModelIds { get; set; } public string Endpoint { get; set; } public string ApiKey { get; set; } } diff --git a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/YiFrameworkStockDomainModule.cs b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/YiFrameworkStockDomainModule.cs index 79b60b3d..35820783 100644 --- a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/YiFrameworkStockDomainModule.cs +++ b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/YiFrameworkStockDomainModule.cs @@ -32,9 +32,10 @@ namespace Yi.Framework.Stock.Domain #pragma warning disable SKEXP0010 // 从配置中获取值 var options = semanticKernelSection.Get(); + //股市优先使用第一个ai模型 services.AddKernel() .AddOpenAIChatCompletion( - modelId: options.ModelId, + modelId: options.ModelIds.FirstOrDefault(), endpoint: new Uri(options.Endpoint), apiKey: options.ApiKey); #pragma warning restore SKEXP0010 diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Managers/AiManager.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Managers/AiManager.cs index 44f3a2ca..8fdab588 100644 --- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Managers/AiManager.cs +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Managers/AiManager.cs @@ -1,6 +1,9 @@ using System.Collections.Generic; using System.Net; using Microsoft.Extensions.Options; +using Microsoft.SemanticKernel; +using Microsoft.SemanticKernel.ChatCompletion; +using Microsoft.SemanticKernel.Connectors.OpenAI; // using OpenAI; // using OpenAI.Managers; // using OpenAI.ObjectModels; @@ -14,61 +17,46 @@ namespace Yi.Framework.ChatHub.Domain.Managers { public class AiManager : ISingletonDependency { - public AiManager(IOptions options) + private readonly Kernel _kernel; + public AiManager(Kernel kernel) { - // this.OpenAIService = new OpenAIService(new OpenAiOptions() - // { - // ApiKey = options.Value.ApiKey, - // BaseDomain = options.Value.BaseDomain - // }); + _kernel = kernel; } - // private OpenAIService OpenAIService { get; } - public async IAsyncEnumerable ChatAsStreamAsync(string model, List aiChatContextDtos) + public async IAsyncEnumerable ChatAsStreamAsync(string model, List aiChatContextDtos) { - throw new NotImplementedException("准备sk重构"); - yield break; - // if (aiChatContextDtos.Count == 0) - // { - // yield return null; - // } - // - // List messages = aiChatContextDtos.Select(x => - // { - // if (x.AnswererType == AnswererTypeEnum.Ai) - // { - // return ChatMessage.FromSystem(x.Message); - // } - // else - // { - // return ChatMessage.FromUser(x.Message); - // } - // }).ToList(); - // var completionResult = OpenAIService.ChatCompletion.CreateCompletionAsStream(new ChatCompletionCreateRequest - // { - // Messages = messages, - // Model =model - // }); - // - // HttpStatusCode? error = null; - // await foreach (var result in completionResult) - // { - // if (result.Successful) - // { - // yield return result.Choices.FirstOrDefault()?.Message.Content ?? null; - // } - // else - // { - // error = result.HttpStatusCode; - // break; - // } - // - // } - // if (error == HttpStatusCode.PaymentRequired) - // { - // yield return "余额不足,请联系站长充值"; - // - // } + if (aiChatContextDtos.Count == 0) + { + yield return null; + } + var openSettings = new OpenAIPromptExecutionSettings() + { + MaxTokens =1000 + }; + + var chatCompletionService = this._kernel.GetRequiredService(model); + + var history =new ChatHistory(); + foreach (var aiChatContextDto in aiChatContextDtos) + { + if (aiChatContextDto.AnswererType==AnswererTypeEnum.Ai) + { + history.AddSystemMessage(aiChatContextDto.Message); + } + else if(aiChatContextDto.AnswererType==AnswererTypeEnum.User) + { + history.AddUserMessage(aiChatContextDto.Message); + } + } + + var results = chatCompletionService.GetStreamingChatMessageContentsAsync( + chatHistory: history, + executionSettings: openSettings, + kernel: _kernel); + await foreach (var result in results) + { + yield return result.Content; + } } } } diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Yi.Framework.ChatHub.Domain.csproj b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Yi.Framework.ChatHub.Domain.csproj index de7bf76d..b158ec5e 100644 --- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Yi.Framework.ChatHub.Domain.csproj +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Yi.Framework.ChatHub.Domain.csproj @@ -8,7 +8,7 @@ - + diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/YiFrameworkChatHubDomainModule.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/YiFrameworkChatHubDomainModule.cs index 5554c43e..02a4b90e 100644 --- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/YiFrameworkChatHubDomainModule.cs +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/YiFrameworkChatHubDomainModule.cs @@ -1,6 +1,10 @@ -using Volo.Abp.Domain; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.SemanticKernel; +using Volo.Abp.Domain; using Yi.Framework.Caching.FreeRedis; using Yi.Framework.ChatHub.Domain.Shared; +using Yi.Framework.Core.Options; namespace Yi.Framework.ChatHub.Domain @@ -13,9 +17,27 @@ namespace Yi.Framework.ChatHub.Domain )] public class YiFrameworkChatHubDomainModule : AbpModule { - public override async Task OnPostApplicationInitializationAsync(ApplicationInitializationContext context) + public override void ConfigureServices(ServiceConfigurationContext context) { - + var configuration = context.Services.GetConfiguration(); + var services = context.Services; + + // 配置绑定 + var semanticKernelSection = configuration.GetSection("SemanticKernel"); + services.Configure(configuration.GetSection("SemanticKernel")); +#pragma warning disable SKEXP0010 + // 从配置中获取值 + var options = semanticKernelSection.Get(); + foreach (var optionsModelId in options.ModelIds) + { + services.AddKernel() + .AddOpenAIChatCompletion( + serviceId: optionsModelId, + modelId: optionsModelId, + endpoint: new Uri(options.Endpoint), + apiKey: options.ApiKey); + } +#pragma warning restore SKEXP0010 } } } \ No newline at end of file diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.json b/Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.json index 15a8d63e..1b1eee0e 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.json +++ b/Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.json @@ -103,18 +103,10 @@ //开启定时数据库备份 "EnableDataBaseBackup": false }, - - - //OpenAi - "AiOptions": { - "ApiKey": "", - "BaseDomain": "" - }, - - + //语义内核 "SemanticKernel": { - "ModelId": "gpt-4o", + "ModelIds": ["gpt-4o"], "Endpoint": "https://xxx.com/v1", "ApiKey": "sk-xxxxxx" } From 224c2b96e44496663ad39d2e5a4df798ea4d58e9 Mon Sep 17 00:00:00 2001 From: chenchun Date: Fri, 21 Mar 2025 18:25:22 +0800 Subject: [PATCH 4/4] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Yi.Bbs.Vue3/src/views/chathub/Index.vue | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Yi.Bbs.Vue3/src/views/chathub/Index.vue b/Yi.Bbs.Vue3/src/views/chathub/Index.vue index 5c14f377..6d116aab 100644 --- a/Yi.Bbs.Vue3/src/views/chathub/Index.vue +++ b/Yi.Bbs.Vue3/src/views/chathub/Index.vue @@ -44,12 +44,14 @@ const inputListDataStore = ref([ {key: "ai@gpt-4o-mini", name: "ChatGpt聊天", titleName: "ChatGpt-全能神!综合能力最强!", logo: "openAi.png", value: ""}, {key: "ai@claude-3-7-sonnet-20250219", name: "Claude聊天", titleName: "Claude3.7 代码逻辑地表最强!", logo: "claudeAi.png", value: ""}, + {key: "ai@claude-3-7-sonnet-20250219-thinking", name: "Claude思索", titleName: "Claude3.7 思索模式,强中强!", logo: "claudeAi.png", value: ""}, + {key: "ai@grok-2-latest", name: "Grok聊天", titleName: "Grok2 即将为3.0王的诞生献上礼炮", logo: "grokAi.png", value: ""}, {key: "ai@Qwen/QVQ-72B-Preview", name: "QWen聊天", titleName: "国产阿里千问通义72B", logo: "qwenAi.png", value: ""}, - {key: "ai@deepseek-chat", name: "DeepSeek聊天", titleName: "满血DeepSeek-聊天模式,开源模型第一", logo: "deepSeekAi.png", value: ""}, - {key: "ai@deepseek-ai/deepseek-r1", name: "DeepSeek思索", titleName: "满血DeepSeek-思索模式", logo: "deepSeekAi.png", value: ""} + {key: "ai@DeepSeek-V3", name: "DeepSeek聊天", titleName: "满血DeepSeek-聊天模式,开源模型第一", logo: "deepSeekAi.png", value: ""}, + {key: "ai@deepseek-r1-250120", name: "DeepSeek思索", titleName: "满血DeepSeek-思索模式", logo: "deepSeekAi.png", value: ""} ]); //AI聊天临时存储 const sendAiChatContext = ref([]); @@ -440,7 +442,7 @@ const clickCopyEvent = async function (event) {