Compare commits

...

26 Commits
0.3.1 ... 0.3.3

Author SHA1 Message Date
zyxucp
9cb36174fd Update README.md 2024-04-23 14:16:50 +08:00
zyxucp
6265f94ef2 fix 修改文档导入问答单独的index 2024-04-23 13:32:57 +08:00
zyxucp
09d90b654c fix 处理文档问答问题 2024-04-23 13:28:38 +08:00
zyxucp
64e2bca2e6 Merge pull request #80 from AIDotNet/fix_chatkmsbug
fix 修改聊天记录知识库保存bug
2024-04-23 12:54:49 +08:00
zyxucp
328ece6d73 fix 修改聊天记录知识库保存bug 2024-04-23 12:53:51 +08:00
zyxucp
fabb8c2044 fix 处理合并 2024-04-23 11:51:08 +08:00
zyxucp
6ca75df880 fix 处理合并 2024-04-23 11:50:46 +08:00
zyxucp
3d4dfaced1 margin 2024-04-23 11:48:43 +08:00
zyxucp
d532bf3bb6 add 聊天历史记录搜索 2024-04-22 23:50:08 +08:00
zyxucp
e1fd288875 fix 样式修改 2024-04-22 23:37:20 +08:00
zyxucp
91eae9cfa8 fix 修改聊天记录存储 2024-04-22 23:31:08 +08:00
zyxucp
b0059942d3 Merge pull request #79 from AIDotNet/feature_chat
Feature chat
2024-04-22 23:17:58 +08:00
zyxucp
a716982878 add 聊天记录 2024-04-22 23:17:16 +08:00
zyxucp
3d4e48f9f5 fix 修改错误 2024-04-22 22:26:45 +08:00
zyxucp
1f212d3156 update semantic kernel to 1.8.0 2024-04-22 22:19:46 +08:00
zyxucp
7d91ef6ba1 Update LICENSE 2024-04-22 22:14:44 +08:00
zyxucp
2a450b00de add 处理在有用户时使用chats表次存储聊天记录,匿名访问时使用localstorage存储聊天记录 2024-04-22 22:03:34 +08:00
zyxucp
3a97068248 Update README.md 2024-04-21 12:12:46 +08:00
zeyu xu
1d9d95899a update 更新antsk logo 2024-04-21 11:17:51 +08:00
zyxucp
7ae8e52b57 Merge pull request #77 from AIDotNet/feature_bge
update kernelMemory nuget版本
2024-04-21 11:01:06 +08:00
zeyu xu
f5c195a1d0 update kernelMemory nuget版本 2024-04-21 11:00:36 +08:00
zyxucp
78a6b662d3 Update docker-compose.simple.yml 2024-04-20 23:30:27 +08:00
zyxucp
5f814eb76c Update docker-compose.yml 2024-04-20 23:30:07 +08:00
zyxucp
d9e5ebb464 Update README.md 2024-04-20 23:29:48 +08:00
zyxucp
bce0e9183c Update README.md 2024-04-20 23:29:26 +08:00
zyxucp
af2930a371 fix 修改WithLog 2024-04-19 18:37:03 +08:00
22 changed files with 515 additions and 158 deletions

View File

@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright [2024] [许泽宇]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -8,7 +8,7 @@
- **内存内核 (Kernel Memory)**具备持续学习和存储知识点的能力AntSK 拥有长期记忆功能,累积经验,提供更个性化的交互体验。
- **知识库**通过文档Word、PDF、Excel、Txt、Markdown、Json、PPT等形式导入知识库可以进行知识库问答。
- **知识库**通过文档Word、PDF、Excel、Txt、Markdown、Json、PPT等形式导入知识库可以进行知识库问答支持本地bge-embedding 向量模型 以及bge-rerank 重排模型
- **文生图**:集成**StableDiffusion** 本地模型,可以进行文生图。
@@ -42,9 +42,11 @@ AntSK 适用于多种业务场景,例如:
## ✏️功能示例
### 在线演示
```
https://antsk.ai-dotnet.com/
```
[文档地址](http://antsk.cn/)
[体验地址](https://antsk.ai-dotnet.com/)
```
默认账号test
@@ -91,7 +93,7 @@ version: '3.8'
services:
antsk:
container_name: antsk
image: registry.cn-hangzhou.aliyuncs.com/AIDotNet/antsk:v0.3.0
image: registry.cn-hangzhou.aliyuncs.com/AIDotNet/antsk:v0.3.1
ports:
- 5000:5000
networks:
@@ -212,7 +214,7 @@ DB我使用的是CodeFirst模式只要配置好数据库链接表结构是
想了解更多信息或开始使用 **AntSK**,可以关注我的公众号以及加入交流群。
## ☎️联系我
如有任何问题或建议,请通过以下方式关注我的公众号,发消息与我联系,我们也有交流群,可以发送进群等消息,然后我会拉你进交流群
如有任何问题或建议,请通过以下方式关注我的公众号《许泽宇的技术分享》,发消息与我联系,我们也有AIDotnet交流群,可以发送进群等消息,然后我会拉你进交流群
![公众号](https://github.com/AIDotNet/AntSK/blob/main/images/gzh.jpg)
## 🌟 Star History

View File

@@ -3,9 +3,9 @@ version: '3.8'
services:
antsk:
container_name: antsk
image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.3.0
image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.3.1
# 如果需要pytorch环境需要使用下面这个镜像镜像比较大
# image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:p0.3.0
# image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:p0.3.1
ports:
- 5000:5000
networks:

View File

@@ -18,9 +18,9 @@ services:
- ./pg/data:/var/lib/postgresql/data
antsk:
container_name: antsk
image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.3.0
image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.3.1
# 如果需要pytorch环境需要使用下面这个镜像镜像比较大
# image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:p0.3.0
# image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:p0.3.1
ports:
- 5000:5000
networks:

View File

@@ -26,9 +26,9 @@
<PackageReference Include="RestSharp" Version="110.2.0" />
<PackageReference Include="NPOI" Version="2.7.0" />
<PackageReference Include="Microsoft.SemanticKernel" Version="1.7.1" />
<PackageReference Include="Microsoft.SemanticKernel.Core" Version="1.7.1" />
<PackageReference Include="Microsoft.SemanticKernel.Plugins.Core" Version="1.7.1-alpha" />
<PackageReference Include="Microsoft.SemanticKernel" Version="1.8.0" />
<PackageReference Include="Microsoft.SemanticKernel.Core" Version="1.8.0" />
<PackageReference Include="Microsoft.SemanticKernel.Plugins.Core" Version="1.8.0-alpha" />
<PackageReference Include="Microsoft.KernelMemory.Core" Version="$(KMVersion)" />
<PackageReference Include="Microsoft.KernelMemory.MemoryDb.Postgres" Version="$(KMVersion)" />
<PackageReference Include="Microsoft.KernelMemory.MemoryDb.Qdrant" Version="$(KMVersion)" />

View File

@@ -157,11 +157,6 @@
模型类型
</summary>
</member>
<member name="P:AntSK.Domain.Domain.Model.MessageInfo.IsSend">
<summary>
发送是true 接收是false
</summary>
</member>
<member name="P:AntSK.Domain.Domain.Model.PageList`1.PageIndex">
<summary>
当前页从1开始
@@ -407,6 +402,36 @@
回答最大token数
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Chats.UserName">
<summary>
用户名
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Chats.AppId">
<summary>
应用ID
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Chats.Context">
<summary>
消息内容
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Chats.IsSend">
<summary>
发送是true 接收是false
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Chats.CreateTime">
<summary>
创建事件
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Chats.FileName">
<summary>
文件名
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Funs.Path">
<summary>
接口描述

View File

@@ -2,7 +2,7 @@
<!-- See https://aka.ms/dotnet/msbuild/customize for more details on customizing your build -->
<PropertyGroup>
<KMVersion>0.36.240416.1</KMVersion>
<KMVersion>0.37.240420.2</KMVersion>
<LLamaSharpVersion>0.11.2</LLamaSharpVersion>
</PropertyGroup>
</Project>

View File

@@ -18,6 +18,6 @@ namespace AntSK.Domain.Domain.Interface
IAsyncEnumerable<StreamingKernelContent> SendKmsByAppAsync(Apps app, string questions, ChatHistory history, string filePath, List<RelevantSource> relevantSources = null);
Task<string> SendImgByAppAsync(Apps app, string questions);
Task<ChatHistory> GetChatHistory(List<MessageInfo> MessageList);
Task<ChatHistory> GetChatHistory(List<Chats> MessageList);
}
}

View File

@@ -9,7 +9,10 @@ namespace AntSK.Domain.Domain.Model.Constant
public class KmsConstantcs
{
public const string KmsIdTag = "kmsid";
public const string FileIdTag = "fileid";
public const string AppIdTag = "appid";
public const string KmsIndex = "kms";
public const string FileIndex = "kms";
public const string KmsSearchNull="知识库未搜索到相关内容";
public const string KmsPrompt = @"使用<data></data>标记的内容作为你的知识:

View File

@@ -1,17 +0,0 @@
namespace AntSK.Domain.Domain.Model
{
public class MessageInfo
{
public string ID { get; set; } = "";
public string Context { get; set; } = "";
/// <summary>
/// 发送是true 接收是false
/// </summary>
public bool IsSend { get; set; } = false;
public DateTime CreateTime { get; set; }
public string? FileName { get; set; }
}
}

View File

@@ -85,20 +85,39 @@ namespace AntSK.Domain.Domain.Service
if (!string.IsNullOrWhiteSpace(filePath))
{
var memory = _kMService.GetMemoryByApp(app);
var fileId = Guid.NewGuid().ToString();
var result = await memory.ImportDocumentAsync(new Microsoft.KernelMemory.Document(fileId).AddFile(filePath)
.AddTag(KmsConstantcs.KmsIdTag, app.Id)
, index: KmsConstantcs.KmsIndex);
var filters = new MemoryFilter().ByTag(KmsConstantcs.KmsIdTag, app.Id);
// 匹配GUID的正则表达式
string pattern = @"\b[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\b";
var searchResult = await memory.SearchAsync(questions, index: KmsConstantcs.KmsIndex, filters: [filters]);
relevantSourceList.AddRange(searchResult.Results.SelectMany(item => item.Partitions.Select(part => new RelevantSource()
// 使用正则表达式找到匹配
Match match = Regex.Match(filePath, pattern);
if (match.Success)
{
SourceName = item.SourceName,
Text = Markdown.ToHtml(part.Text),
Relevance = part.Relevance
})));
var fileId = match.Value;
var status=await memory.IsDocumentReadyAsync(fileId, index: KmsConstantcs.KmsIndex);
if (!status)
{
var result = await memory.ImportDocumentAsync(new Document(fileId).AddFile(filePath)
.AddTag(KmsConstantcs.AppIdTag, app.Id)
.AddTag(KmsConstantcs.FileIdTag, fileId)
, index: KmsConstantcs.FileIndex);
}
var filters = new List<MemoryFilter>() {
new MemoryFilter().ByTag(KmsConstantcs.AppIdTag, app.Id),
new MemoryFilter().ByTag(KmsConstantcs.FileIdTag, fileId)
};
var searchResult = await memory.SearchAsync(questions, index: KmsConstantcs.FileIndex, filters: filters);
relevantSourceList.AddRange(searchResult.Results.SelectMany(item => item.Partitions.Select(part => new RelevantSource()
{
SourceName = item.SourceName,
Text = Markdown.ToHtml(part.Text),
Relevance = part.Relevance
})));
app.Prompt = KmsConstantcs.KmsPrompt;
}
}
@@ -155,11 +174,13 @@ namespace AntSK.Domain.Domain.Service
}
else
{
string fileName = _kmsDetails_Repositories.GetFirst(p => p.FileGuidName == item.SourceName).FileName;
fileDic.Add(item.SourceName, fileName);
item.SourceName = fileName;
var fileDetail = _kmsDetails_Repositories.GetFirst(p => p.FileGuidName == item.SourceName);
if (fileDetail.IsNotNull())
{
string fileName = fileDetail.FileName;
fileDic.Add(item.SourceName, fileName);
item.SourceName = fileName;
}
}
item.Text = Markdown.ToHtml(item.Text);
}
@@ -169,7 +190,7 @@ namespace AntSK.Domain.Domain.Service
//KernelFunction jsonFun = _kernel.Plugins.GetFunction("KMSPlugin", "Ask1");
var temperature = app.Temperature / 100;//存的是0~100需要缩小
OpenAIPromptExecutionSettings settings = new() { Temperature = temperature };
var func = _kernel.CreateFunctionFromPrompt(app.Prompt, settings);
var func = _kernel.CreateFunctionFromPrompt(app.Prompt , settings);
var chatResult = _kernel.InvokeStreamingAsync(function: func,
arguments: new KernelArguments() { ["doc"] = dataMsg.ToString(), ["history"] = string.Join("\n", history.Select(x => x.Role + ": " + x.Content)), ["input"] = questions });
@@ -297,7 +318,7 @@ namespace AntSK.Domain.Domain.Service
}
}
public async Task<ChatHistory> GetChatHistory(List<MessageInfo> MessageList)
public async Task<ChatHistory> GetChatHistory(List<Chats> MessageList)
{
ChatHistory history = new ChatHistory();
if (MessageList.Count > 1)

View File

@@ -0,0 +1,41 @@
using AntSK.Domain.Domain.Model.Enum;
using SqlSugar;
using System.ComponentModel.DataAnnotations;
namespace AntSK.Domain.Repositories
{
[SugarTable("Chats")]
public partial class Chats
{
[SugarColumn(IsPrimaryKey = true)]
public string Id { get; set; }
/// <summary>
/// 用户名
/// </summary>
public string UserName { get; set; }
/// <summary>
/// 应用ID
/// </summary>
public string AppId { get; set; }
/// <summary>
/// 消息内容
/// </summary>
[SugarColumn(ColumnDataType = "varchar(4000)")]
public string Context { get; set; } = "";
/// <summary>
/// 发送是true 接收是false
/// </summary>
public bool IsSend { get; set; } = false;
/// <summary>
/// 创建事件
/// </summary>
public DateTime CreateTime { get; set; }
/// <summary>
/// 文件名
/// </summary>
public string? FileName { get; set; }
}
}

View File

@@ -0,0 +1,11 @@

using AntSK.Domain.Common.DependencyInjection;
using AntSK.Domain.Repositories.Base;
namespace AntSK.Domain.Repositories
{
[ServiceDescription(typeof(IChats_Repositories), ServiceLifetime.Scoped)]
public class Chats_Repositories : Repository<Chats>, IChats_Repositories
{
}
}

View File

@@ -0,0 +1,8 @@
using AntSK.Domain.Repositories.Base;
namespace AntSK.Domain.Repositories
{
public interface IChats_Repositories : IRepository<Chats>
{
}
}

View File

@@ -8,7 +8,7 @@
@inject INotificationService _notice
@inherits LayoutComponentBase
<AntDesign.ProLayout.BasicLayout Logo="@("https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg")"
<AntDesign.ProLayout.BasicLayout Logo="@("/assets/logo.svg")"
MenuData="_menuData">
<RightContentRender>
<AntSK.Components.RightContent />

View File

@@ -6,14 +6,18 @@ using AntSK.Domain.Domain.Model.Enum;
using AntSK.Domain.Repositories;
using AntSK.Domain.Utils;
using AntSK.LLM.StableDiffusion;
using AntSK.Models;
using Blazored.LocalStorage;
using DocumentFormat.OpenXml.InkML;
using Markdig;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
using Microsoft.JSInterop;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Newtonsoft.Json;
using System.Collections.Generic;
namespace AntSK.Pages.ChatPage.Components
{
@@ -36,8 +40,10 @@ namespace AntSK.Pages.ChatPage.Components
[Inject] IChatService _chatService { get; set; }
[Inject] IJSRuntime _JSRuntime { get; set; }
[Inject] ILocalStorageService _localStorage { get; set; }
[Inject] IChats_Repositories _chats_Repositories { get; set; }
[Inject] ProtectedSessionStorage _protectedSessionStore { get; set; }
protected List<MessageInfo> MessageList = [];
protected List<Chats> MessageList = [];
protected string? _messageInput;
protected string _json = "";
protected bool Sendding = false;
@@ -48,25 +54,87 @@ namespace AntSK.Pages.ChatPage.Components
private List<RelevantSource> _relevantSources = new List<RelevantSource>();
private string _userName { get; set; }
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
LoadData();
var msgs = await _localStorage.GetItemAsync<List<MessageInfo>>("msgs");
await LoadData();
}
protected override async Task OnParametersSetAsync()
{
await LoadData();
}
/// <summary>
/// 初始化加载数据
/// </summary>
/// <returns></returns>
private async Task LoadData()
{
app = _apps_Repositories.GetFirst(p => p.Id == AppId);
var userSessionStorageResult = await _protectedSessionStore.GetAsync<UserSession>("UserSession");
var userSession = userSessionStorageResult.Success ? userSessionStorageResult.Value : null;
_userName = userSession?.UserName;
await GetMsgList();
}
/// <summary>
/// 获取聊天记录列表
/// </summary>
/// <returns></returns>
private async Task GetMsgList()
{
List<Chats> msgs = new List<Chats>();
if (string.IsNullOrEmpty(_userName))
{
//匿名访问使用localstore
msgs = await _localStorage.GetItemAsync<List<Chats>>($"msgs:{AppId}");
}
else
{
msgs = await _chats_Repositories.GetListAsync(p => p.AppId == AppId && p.UserName == _userName);
}
if (msgs != null && msgs.Count > 0)
{
MessageList = msgs;
}
}
protected override async Task OnParametersSetAsync()
/// <summary>
/// 清空聊天记录列表
/// </summary>
/// <returns></returns>
private async Task ClearMsgList()
{
LoadData();
MessageList.Clear();
if (string.IsNullOrEmpty(_userName))
{
await _localStorage.SetItemAsync<List<Chats>>($"msgs:{AppId}", MessageList);
}
else
{
await _chats_Repositories.DeleteAsync(p => p.AppId == AppId && p.UserName == _userName);
}
}
private void LoadData()
/// <summary>
/// 保存聊天记录
/// </summary>
/// <returns></returns>
private async Task SaveMsg(List<Chats> MessageList)
{
app = _apps_Repositories.GetFirst(p => p.Id == AppId);
if (string.IsNullOrEmpty(_userName))
{
await _localStorage.SetItemAsync<List<Chats>>($"msgs:{AppId}", MessageList);
}
else
{
if (MessageList.Count() > 0)
{
await _chats_Repositories.InsertAsync(MessageList.LastOrDefault());
}
}
}
protected async Task OnClearAsync()
@@ -78,11 +146,11 @@ namespace AntSK.Pages.ChatPage.Components
var result = await _confirmService.Show(content, title, ConfirmButtons.YesNo);
if (result == ConfirmResult.Yes)
{
MessageList.Clear();
await _localStorage.SetItemAsync<List<MessageInfo>>("msgs", MessageList);
await ClearMsgList();
await InvokeAsync(StateHasChanged);
_ = Message.Info("清理成功");
}
}
else
@@ -102,18 +170,25 @@ namespace AntSK.Pages.ChatPage.Components
var filePath = fileList.FirstOrDefault()?.Url;
var fileName = fileList.FirstOrDefault()?.FileName;
MessageList.Add(new MessageInfo()
var chat = new Chats()
{
ID = Guid.NewGuid().ToString(),
Id = Guid.NewGuid().ToString(),
UserName = _userName,
AppId = AppId,
Context = _messageInput,
CreateTime = DateTime.Now,
IsSend = true
});
};
MessageList.Add(chat);
if (!string.IsNullOrEmpty(_userName))
{
await _chats_Repositories.InsertAsync(chat);
}
Sendding = true;
await SendAsync(_messageInput,filePath);
await SendAsync(_messageInput, filePath);
_messageInput = "";
Sendding = false;
Sendding = false;
}
catch (System.Exception ex)
{
@@ -123,7 +198,9 @@ namespace AntSK.Pages.ChatPage.Components
}
}
protected async Task OnCopyAsync(MessageInfo item)
protected async Task OnCopyAsync(Chats item)
{
await Task.Run(() =>
{
@@ -135,10 +212,16 @@ namespace AntSK.Pages.ChatPage.Components
{
await Task.Run(() =>
{
MessageList = MessageList.Where(w => w.ID != id).ToList();
MessageList = MessageList.Where(w => w.Id != id).ToList();
});
}
/// <summary>
/// 开始发送消息
/// </summary>
/// <param name="questions"></param>
/// <param name="filePath"></param>
/// <returns></returns>
protected async Task<bool> SendAsync(string questions, string? filePath)
{
ChatHistory history = new ChatHistory();
@@ -166,17 +249,29 @@ namespace AntSK.Pages.ChatPage.Components
//缓存消息记录
if (app.Type != AppType.img.ToString())
{
await _localStorage.SetItemAsync<List<MessageInfo>>("msgs", MessageList);
await SaveMsg(MessageList);
if (OnRelevantSources.IsNotNull())
{
await OnRelevantSources.InvokeAsync(_relevantSources);
}
}
return await Task.FromResult(true);
}
/// <summary>
/// 发送图片对话
/// </summary>
/// <param name="questions"></param>
/// <param name="app"></param>
/// <returns></returns>
private async Task SendImg(string questions,Apps app)
{
MessageInfo info = new MessageInfo();
info.ID = Guid.NewGuid().ToString();
Chats info = new Chats();
info.Id = Guid.NewGuid().ToString();
info.UserName=_userName;
info.AppId=AppId;
info.CreateTime = DateTime.Now;
var base64= await _chatService.SendImgByAppAsync(app, questions);
if (string.IsNullOrEmpty(base64))
@@ -199,27 +294,23 @@ namespace AntSK.Pages.ChatPage.Components
/// <returns></returns>
private async Task SendKms(string questions, ChatHistory history, Apps app, string? filePath)
{
MessageInfo info = null;
Chats info = new Chats()
{
Id = Guid.NewGuid().ToString(),
AppId = AppId,
UserName = _userName,
CreateTime = DateTime.Now,
Context=""
};
MessageList.Add(info);
var chatResult = _chatService.SendKmsByAppAsync(app, questions, history, filePath, _relevantSources);
await foreach (var content in chatResult)
{
if (info == null)
{
info = new MessageInfo();
info.ID = Guid.NewGuid().ToString();
info.Context = content.ConvertToString();
info.CreateTime = DateTime.Now;
MessageList.Add(info);
}
else
{
info.Context += content.ConvertToString();
await Task.Delay(50);
}
info.Context += content.ConvertToString();
await Task.Delay(50);
await InvokeAsync(StateHasChanged);
}
await OnRelevantSources.InvokeAsync(_relevantSources);
//全部处理完后再处理一次Markdown
await MarkDown(info);
}
@@ -233,14 +324,16 @@ namespace AntSK.Pages.ChatPage.Components
/// <returns></returns>
private async Task SendChat(string questions, ChatHistory history, Apps app)
{
MessageInfo info = null;
Chats info = null;
var chatResult = _chatService.SendChatByAppAsync(app, questions, history);
await foreach (var content in chatResult)
{
if (info == null)
{
info = new MessageInfo();
info.ID = Guid.NewGuid().ToString();
info = new Chats();
info.Id = Guid.NewGuid().ToString();
info.UserName = _userName;
info.AppId = AppId;
info.Context = content.ConvertToString();
info.CreateTime = DateTime.Now;
@@ -257,7 +350,12 @@ namespace AntSK.Pages.ChatPage.Components
await MarkDown(info);
}
private async Task MarkDown(MessageInfo info)
/// <summary>
/// 处理markdown
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
private async Task MarkDown(Chats info)
{
if (info.IsNotNull())
{
@@ -270,6 +368,10 @@ namespace AntSK.Pages.ChatPage.Components
await _JSRuntime.ScrollToBottomAsync("scrollDiv");
}
/// <summary>
/// 上传文件事件
/// </summary>
/// <param name="fileInfo"></param>
private void OnSingleCompleted(UploadInfo fileInfo)
{
fileList.Add(new()
@@ -281,6 +383,11 @@ namespace AntSK.Pages.ChatPage.Components
});
_kMService.OnSingleCompleted(fileInfo);
}
/// <summary>
/// 移除文件事件
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
private async Task<bool> HandleFileRemove(UploadFileItem file)
{
fileList.RemoveAll(x => x.FileName == file.FileName);

View File

@@ -3,67 +3,67 @@
@using AntSK.Services.Auth
@inherits AuthComponentBase
@using Microsoft.AspNetCore.Authorization
@using AntSK.Domain.Domain.Model.hfmirror;
using AntSK.Domain.Domain.Model.hfmirror
@using AntSK.Domain.Domain.Model.hfmirror
@attribute [Authorize(Roles = "AntSKAdmin")]
<div>
<PageContainer Title="模型列表">
<Content>
<RadioGroup @bind-Value="@_modelType" OnChange="OnModelTypeChange" TValue="string">
<Radio Value="@("gguf")" DefaultChecked=true>LLama本地模型(gguf)</Radio>
<Radio Value="@("safetensors")">StableDiffusion(safetensors)</Radio>
<Radio Value="@("ckpt")">StableDiffusion2(ckpt)</Radio>
</RadioGroup>
<div style="text-align: center;">
<PageContainer Title="模型列表">
<Content>
<RadioGroup @bind-Value="@_modelType" OnChange="OnModelTypeChange" TValue="string">
<Radio Value="@("gguf")" DefaultChecked=true>LLama本地模型(gguf)</Radio>
<Radio Value="@("safetensors")">StableDiffusion(safetensors)</Radio>
<Radio Value="@("ckpt")">StableDiffusion2(ckpt)</Radio>
</RadioGroup>
<div style="text-align: center;">
<Search Placeholder="输入回车"
EnterButton="@("搜索")"
Size="large"
Style="max-width: 522px; width: 100%;"
OnSearch="Search" />
</div>
</Content>
<ChildContent>
<div class="filterCardList">
<Spin Tip="加载中..." Spinning="@(loaddding)">
<AntList TItem="HfModels"
Grid="LayoutModel._listGridType"
DataSource="_modelList">
<ListItem NoFlex>
<Card Hoverable
BodyStyle="padding-bottom: 20px;"
Actions="new[] {
down(()=> Down(context.Id))
<Search Placeholder="输入回车"
EnterButton="@("搜索")"
Size="large"
Style="max-width: 522px; width: 100%;"
OnSearch="Search" />
</div>
</Content>
<ChildContent>
<div class="filterCardList">
<Spin Tip="加载中..." Spinning="@(loaddding)">
<AntList TItem="HfModels"
Grid="LayoutModel._listGridType"
DataSource="_modelList">
<ListItem NoFlex>
<Card Hoverable
BodyStyle="padding-bottom: 20px;"
Actions="new[] {
down(()=> Down(context.Id))
}">
<CardMeta>
<TitleTemplate>
@context.Id
</TitleTemplate>
<AvatarTemplate>
<Avatar Size="small" Src="@context.AuthorData.AvatarUrl" />
</AvatarTemplate>
</CardMeta>
<div class="cardItemContent">
<div class="cardInfo">
<div>
<p>Downloads</p>
<p>@context.Downloads.ToString("0,0")</p>
<CardMeta>
<TitleTemplate>
@context.Id
</TitleTemplate>
<AvatarTemplate>
<Avatar Size="small" Src="@context.AuthorData.AvatarUrl" />
</AvatarTemplate>
</CardMeta>
<div class="cardItemContent">
<div class="cardInfo">
<div>
<p>Downloads</p>
<p>@context.Downloads.ToString("0,0")</p>
</div>
<div>
<p>Likes</p>
<p>@context.Likes.ToString("0,0")</p>
</div>
</div>
</div>
<div>
<p>Likes</p>
<p>@context.Likes.ToString("0,0")</p>
</div>
</div>
</div>
</Card>
</ListItem>
</AntList>
</Spin>
</div>
</ChildContent>
</PageContainer>
</Card>
</ListItem>
</AntList>
</Spin>
</div>
</ChildContent>
</PageContainer>
</div>
@code
{
RenderFragment down(Action clickAction) =>@<a key="down" @onclick="@clickAction">下载</a>;

View File

@@ -0,0 +1,121 @@
@namespace AntSK.Pages.Setting.AIModel
@page "/setting/chathistory"
@using AntSK.Services.Auth
@inherits AuthComponentBase
@using Microsoft.AspNetCore.Authorization
@using System.ComponentModel
@using AntDesign.TableModels
@using AntSK.Domain.Repositories
@using AntSK.Domain.Common.Map
@attribute [Authorize(Roles = "AntSKAdmin")]
<Table @ref="table"
TItem="ChatsDto"
DataSource="@chatDtoList"
Total="_total"
@bind-PageIndex="_pageIndex"
@bind-PageSize="_pageSize"
OnChange="OnChange"
Size="TableSize.Small"
RowKey="x=>x.Id">
<TitleTemplate>
<GridRow>
<GridCol Span="4">
<Title Level="3">聊天记录</Title>
</GridCol>
<GridCol Span="8" Offset="12">
<Search Placeholder="搜索" @bind-Value="searchString" OnSearch="Search" />
</GridCol>
</GridRow>
</TitleTemplate>
<ColumnDefinitions>
<PropertyColumn Property="c=>c.Id" />
<PropertyColumn Title="用户名" Property="c=>c.UserName" />
<PropertyColumn Title="应用名称" Property="c=>c.AppName" />
<PropertyColumn Title="发送/接收" Property="c=>c.SendReveice" />
<ActionColumn Title="消息内容" Width="30%">
<Space>
<SpaceItem>
@((MarkupString)(context.Context))
</SpaceItem>
</Space>
</ActionColumn>
<PropertyColumn Title="时间" Property="c=>c.CreateTime" Format="yyyy-MM-dd HH:mm:ss" />
</ColumnDefinitions>
</Table>
@using System.Text.Json;
@code {
[Inject] IChats_Repositories _chats_Repositories { get; set; }
ChatsDto[] chatDtoList;
ITable table;
int _pageIndex = 1;
int _pageSize = 10;
int _total = 0;
string searchString;
protected override async Task OnInitializedAsync()
{
await InitData();
}
public async Task OnChange(QueryModel<ChatsDto> queryModel)
{
await InitData();
}
private async Task InitData()
{
if (string.IsNullOrEmpty(searchString))
{
_total = _chats_Repositories.Count(p => true);
var chatList = _chats_Repositories.GetDB().Queryable<Chats, Apps>((c, a) => new object[] {
SqlSugar.JoinType.Left,c.AppId==a.Id
}).Select((c, a) => new ChatsDto
{
Id = c.Id,
UserName = c.UserName,
AppId = c.AppId,
IsSend = c.IsSend,
SendReveice = c.IsSend ? "发送" : "接收",
Context = c.Context,
CreateTime = c.CreateTime,
AppName = a.Name
}).ToPageList(_pageIndex, _pageSize);
chatDtoList = chatList.ToArray();
}
else
{
_total = _chats_Repositories.Count(p => p.UserName.Contains(searchString) || p.Context.Contains(searchString));
var chatList = _chats_Repositories.GetDB().Queryable<Chats, Apps>((c, a) => new object[] {
SqlSugar.JoinType.Left,c.AppId==a.Id
}).Select((c, a) => new ChatsDto
{
Id = c.Id,
UserName = c.UserName,
AppId = c.AppId,
IsSend = c.IsSend,
SendReveice = c.IsSend ? "发送" : "接收",
Context = c.Context,
CreateTime = c.CreateTime,
AppName = a.Name
}).Where(c => c.UserName.Contains(searchString) || c.Context.Contains(searchString)).ToPageList(_pageIndex, _pageSize);
chatDtoList = chatList.ToArray();
}
}
private async Task Search(string searchKey)
{
await InitData();
}
public class ChatsDto : Chats
{
public string AppName { get; set; }
public string SendReveice { get; set; }
}
}

View File

@@ -72,6 +72,7 @@
}
kmsDetails_Repositories.GetDB().Ado.ExecuteCommand("DROP TABLE IF EXISTS \"km-kms\"");
kmsDetails_Repositories.GetDB().Ado.ExecuteCommand("DROP TABLE IF EXISTS \"km-file\"");
var kmsDetails = await kmsDetails_Repositories.GetListAsync();
foreach (var detail in kmsDetails)
{

View File

@@ -68,17 +68,17 @@ builder.Services.AddBackgroundTaskBroker().AddHandler<ImportKMSTaskReq, BackGrou
.WithCuda(false)
.WithLogCallback((level, message) => {
Console.WriteLine($"[llama {level}]: {message.TrimEnd('\n')}");
});
});
}
else if (LLamaSharpOption.RunType.ToUpper() == "GPU")
{
NativeLibraryConfig
.Instance
.WithCuda(true)
.WithAvx(NativeLibraryConfig.AvxLevel.Avx)
.WithLogCallback((level, message) => {
Console.WriteLine($"[llama {level}]: {message.TrimEnd('\n')}");
});
})
.WithAvx(NativeLibraryConfig.AvxLevel.Avx);
}
}

View File

@@ -1 +1,30 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" version="1.1" viewBox="0 0 200 200"><title>Group 28 Copy 5</title><desc>Created with Sketch.</desc><defs><linearGradient id="linearGradient-1" x1="62.102%" x2="108.197%" y1="0%" y2="37.864%"><stop offset="0%" stop-color="#4285EB"/><stop offset="100%" stop-color="#2EC7FF"/></linearGradient><linearGradient id="linearGradient-2" x1="69.644%" x2="54.043%" y1="0%" y2="108.457%"><stop offset="0%" stop-color="#29CDFF"/><stop offset="37.86%" stop-color="#148EFF"/><stop offset="100%" stop-color="#0A60FF"/></linearGradient><linearGradient id="linearGradient-3" x1="69.691%" x2="16.723%" y1="-12.974%" y2="117.391%"><stop offset="0%" stop-color="#FA816E"/><stop offset="41.473%" stop-color="#F74A5C"/><stop offset="100%" stop-color="#F51D2C"/></linearGradient><linearGradient id="linearGradient-4" x1="68.128%" x2="30.44%" y1="-35.691%" y2="114.943%"><stop offset="0%" stop-color="#FA8E7D"/><stop offset="51.264%" stop-color="#F74A5C"/><stop offset="100%" stop-color="#F51D2C"/></linearGradient></defs><g id="Page-1" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="logo" transform="translate(-20.000000, -20.000000)"><g id="Group-28-Copy-5" transform="translate(20.000000, 20.000000)"><g id="Group-27-Copy-3"><g id="Group-25" fill-rule="nonzero"><g id="2"><path id="Shape" fill="url(#linearGradient-1)" d="M91.5880863,4.17652823 L4.17996544,91.5127728 C-0.519240605,96.2081146 -0.519240605,103.791885 4.17996544,108.487227 L91.5880863,195.823472 C96.2872923,200.518814 103.877304,200.518814 108.57651,195.823472 L145.225487,159.204632 C149.433969,154.999611 149.433969,148.181924 145.225487,143.976903 C141.017005,139.771881 134.193707,139.771881 129.985225,143.976903 L102.20193,171.737352 C101.032305,172.906015 99.2571609,172.906015 98.0875359,171.737352 L28.285908,101.993122 C27.1162831,100.824459 27.1162831,99.050775 28.285908,97.8821118 L98.0875359,28.1378823 C99.2571609,26.9692191 101.032305,26.9692191 102.20193,28.1378823 L129.985225,55.8983314 C134.193707,60.1033528 141.017005,60.1033528 145.225487,55.8983314 C149.433969,51.69331 149.433969,44.8756232 145.225487,40.6706018 L108.58055,4.05574592 C103.862049,-0.537986846 96.2692618,-0.500797906 91.5880863,4.17652823 Z"/><path id="Shape" fill="url(#linearGradient-2)" d="M91.5880863,4.17652823 L4.17996544,91.5127728 C-0.519240605,96.2081146 -0.519240605,103.791885 4.17996544,108.487227 L91.5880863,195.823472 C96.2872923,200.518814 103.877304,200.518814 108.57651,195.823472 L145.225487,159.204632 C149.433969,154.999611 149.433969,148.181924 145.225487,143.976903 C141.017005,139.771881 134.193707,139.771881 129.985225,143.976903 L102.20193,171.737352 C101.032305,172.906015 99.2571609,172.906015 98.0875359,171.737352 L28.285908,101.993122 C27.1162831,100.824459 27.1162831,99.050775 28.285908,97.8821118 L98.0875359,28.1378823 C100.999864,25.6271836 105.751642,20.541824 112.729652,19.3524487 C117.915585,18.4685261 123.585219,20.4140239 129.738554,25.1889424 C125.624663,21.0784292 118.571995,14.0340304 108.58055,4.05574592 C103.862049,-0.537986846 96.2692618,-0.500797906 91.5880863,4.17652823 Z"/></g><path id="Shape" fill="url(#linearGradient-3)" d="M153.685633,135.854579 C157.894115,140.0596 164.717412,140.0596 168.925894,135.854579 L195.959977,108.842726 C200.659183,104.147384 200.659183,96.5636133 195.960527,91.8688194 L168.690777,64.7181159 C164.472332,60.5180858 157.646868,60.5241425 153.435895,64.7316526 C149.227413,68.936674 149.227413,75.7543607 153.435895,79.9593821 L171.854035,98.3623765 C173.02366,99.5310396 173.02366,101.304724 171.854035,102.473387 L153.685633,120.626849 C149.47715,124.83187 149.47715,131.649557 153.685633,135.854579 Z"/></g><ellipse id="Combined-Shape" cx="100.519" cy="100.437" fill="url(#linearGradient-4)" rx="23.6" ry="23.581"/></g></g></g></g></svg>
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="370.000000pt" height="370.000000pt" viewBox="0 0 370.000000 370.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,370.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M1914 3198 c-87 -152 -450 -815 -526 -960 l-46 -86 26 -7 c15 -4 116
-3 225 1 l197 7 69 121 c38 66 83 150 101 185 l32 65 19 -25 c10 -13 44 -71
75 -129 32 -58 73 -134 92 -168 l35 -64 213 4 c117 1 215 6 219 9 8 9 -57 139
-203 404 -177 324 -439 785 -446 785 0 0 -38 -64 -82 -142z"/>
<path d="M772 3019 c-198 -53 -353 -165 -459 -332 -13 -20 -41 -72 -63 -115
-51 -102 -64 -184 -58 -372 5 -129 8 -153 33 -215 48 -118 105 -205 195 -295
75 -75 101 -93 215 -152 l130 -66 440 -11 c242 -7 467 -16 499 -22 119 -21
211 -93 263 -204 24 -51 28 -72 28 -145 -2 -190 -105 -314 -305 -365 l-45 -11
-3 -212 -2 -212 22 0 c63 1 202 43 298 91 93 45 116 63 201 148 86 87 102 109
153 211 65 131 76 182 76 345 -1 248 -46 365 -209 537 -80 85 -157 141 -277
201 l-91 46 -494 11 -494 11 -40 26 c-76 50 -142 121 -171 186 -25 54 -29 74
-29 152 1 76 5 99 27 147 47 101 142 175 263 205 l65 16 0 208 0 209 -47 -1
c-27 0 -81 -9 -121 -20z"/>
<path d="M830 1153 c-38 -7 -42 -14 -123 -156 -153 -271 -169 -304 -151 -311
8 -3 109 -6 224 -6 l209 0 70 128 c132 242 176 330 168 339 -9 9 -356 14 -397
6z"/>
<path d="M2802 1152 l-42 -7 93 -170 c121 -220 154 -273 175 -279 55 -15 114
-17 263 -11 l166 7 -119 222 c-66 121 -122 224 -126 227 -10 10 -359 18 -410
11z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -64,6 +64,11 @@
"name": "用户管理",
"key": "setting.user"
},
{
"path": "/setting/chathistory",
"name": "聊天记录",
"key": "setting.chathistory"
},
{
"path": "/setting/delkms",
"name": "删除向量表",