Compare commits

...

102 Commits
0.1.6 ... 0.2.0

Author SHA1 Message Date
zyxucp
e84b05a39b fix 修改普通特性 2024-03-15 22:16:07 +08:00
zyxucp
631c563e71 fix 修改为普通特性,避免上传DLL需要引用特殊特性 2024-03-15 22:15:02 +08:00
zyxucp
47b304e46f update 升级SK到1.6.2 2024-03-15 22:08:22 +08:00
zyxucp
27ccfc5e88 add 增加分享使用 2024-03-15 21:57:21 +08:00
zyxucp
69441167d3 fix 修改高度自适应 2024-03-15 21:50:55 +08:00
zyxucp
4b97594217 fix 调整会话总结 2024-03-15 21:15:28 +08:00
zyxucp
9ee601f88c fix 首页调整 2024-03-15 21:12:31 +08:00
zyxucp
75b1a299e3 add 限制移动端屏幕缩放 2024-03-15 21:07:59 +08:00
zyxucp
2613c463a1 Merge branch 'main' of https://github.com/xuzeyu91/AntSK 2024-03-15 14:45:15 +08:00
zyxucp
78e0350d36 add 首页调整 2024-03-15 14:39:13 +08:00
zyxucp
bc2425fc3f Update README.md 2024-03-15 14:18:15 +08:00
zyxucp
3e861bc72f Update README.md 2024-03-15 13:01:35 +08:00
zyxucp
b41c464753 fix 暂时取消星火的会话拆分 2024-03-14 16:58:19 +08:00
zyxucp
2817275091 fix 暂时取消注册时间函数 2024-03-14 12:57:28 +08:00
zyxucp
e76b0cf326 fix 调整目录结构 2024-03-14 12:24:09 +08:00
zyxucp
cf34103e15 update docker-compose.yml 2024-03-14 12:07:17 +08:00
zyxucp
1588fd7d7a add 增加ErrorBoundary全局异常 2024-03-14 11:32:42 +08:00
zyxucp
4507ccde6c margin 2024-03-14 10:03:40 +08:00
zyxucp
73fffd766f fix 修复LLamaSharp给一个默认下载路径 2024-03-14 10:02:15 +08:00
zyxucp
e529146c5b fix 修改LLamaSharp文件夹给一个默认路径 2024-03-14 09:59:51 +08:00
zyxucp
7050e52009 Merge pull request #28 from ElderJames/main
Fix DI and OpenAI function calling
2024-03-13 22:25:45 +08:00
James Yeung
4f3238c4f6 Fix DI and OpenAI function calling 2024-03-13 22:22:22 +08:00
zyxucp
b7d27c5d50 fix 修复bug 2024-03-13 22:11:35 +08:00
zyxucp
fe94aa0564 fix 修复修改自身重复问题 2024-03-13 20:59:14 +08:00
zyxucp
ae60a9aced Merge branch 'main' of https://github.com/xuzeyu91/AntSK 2024-03-13 12:13:56 +08:00
zyxucp
4f686b0871 fix 修复按钮停止不了的问题 2024-03-13 10:23:52 +08:00
zyxucp
c61840b7e8 Update README.md 2024-03-13 10:17:50 +08:00
zyxucp
9adce95367 fix appsettings.json示例 2024-03-13 10:10:52 +08:00
zyxucp
eef943458e fix 模型选择只能选gguf,修复搜索空指针页面 2024-03-13 10:02:00 +08:00
zyxucp
f5c80689d4 add 增加模型列表 自动下载模型 2024-03-13 00:52:46 +08:00
zyxucp
5eaee3130a add 增加模型下载页面 2024-03-13 00:10:30 +08:00
zyxucp
5846473f28 Merge branch 'main' of https://github.com/xuzeyu91/AntSK 2024-03-12 23:20:02 +08:00
zyxucp
94c019b484 Merge pull request #25 from ElderJames/model-download
support model download and file list
2024-03-12 22:51:15 +08:00
zyxucp
7e1140c022 add 增加下载页面 2024-03-12 22:50:06 +08:00
James Yeung
ea9044719a support model download and file list 2024-03-12 22:41:12 +08:00
zyxucp
8a96095448 add 增加模型下载地址 2024-03-12 21:57:34 +08:00
zyxucp
fcc8f8751b add 修改对外接口授权添加Bearer 2024-03-12 21:34:58 +08:00
zyxucp
af09ae7c3e Update docker-compose.simple.yml 2024-03-12 10:22:39 +08:00
zyxucp
e8e6a36d7b Update docker-compose.yml 2024-03-12 10:22:12 +08:00
zyxucp
4f89d54ef0 add mock类型便于测试 2024-03-12 09:57:12 +08:00
zyxucp
2f9e2fb114 fix 增加导入后清空文件列表 2024-03-12 09:33:55 +08:00
zyxucp
b6098024b8 add 更换markdown组件,实现代码高亮 2024-03-12 01:11:48 +08:00
zyxucp
1700131066 add 增加首页点击跳转 2024-03-12 00:31:17 +08:00
zyxucp
189536471a fix 先隐藏星火的KM选择器 2024-03-12 00:15:04 +08:00
zyxucp
f534e0bcc3 fix 修复多文件不能同时导入的bug 2024-03-12 00:12:41 +08:00
zyxucp
e203a18e92 add 增加原生插件调用示例 2024-03-11 23:42:26 +08:00
zyxucp
575a69bf4d add 增加首页,暂时取消本地函数调用 2024-03-11 23:16:23 +08:00
zyxucp
69fd3a0367 fix 修改命名空间 2024-03-11 21:23:07 +08:00
zyxucp
8f7e70298e fix 修改描述错误 2024-03-11 21:16:23 +08:00
zyxucp
0fa3f5a554 fix 移动文件目录 2024-03-11 19:41:51 +08:00
zyxucp
f420012752 fix 移动文件目录 2024-03-11 19:40:15 +08:00
zyxucp
c1ca916549 fix 增加openai模型示例 2024-03-11 19:38:26 +08:00
zyxucp
dfcf2bdc85 fix 取消非空类型 2024-03-11 19:12:47 +08:00
zyxucp
72e7acfb7d 修改写法 2024-03-11 19:09:41 +08:00
zyxucp
9d06c127dc fix 增加注释 2024-03-11 19:08:52 +08:00
zyxucp
0460b388ab fix 修改kernel 和km 每次build的问题,进行缓存 2024-03-11 19:02:17 +08:00
zyxucp
45b84ae898 fix 修改类名 2024-03-11 18:26:26 +08:00
zyxucp
41b1cb6f2d Merge pull request #24 from ElderJames/feat/sparkdesk-func-cal
Add support for the Function Calling of Spark Desk
2024-03-11 18:16:27 +08:00
James Yeung
159aaab38e Add support for the Function Calling of Spark Desk 2024-03-11 18:10:14 +08:00
zyxucp
dc351238f6 Update README.md 2024-03-11 15:13:23 +08:00
zyxucp
e6491b39c6 Update README.md 2024-03-11 15:11:11 +08:00
zyxucp
91b4ed8940 Update README.md 2024-03-11 14:23:16 +08:00
zyxucp
ab99098afd Update README.md 2024-03-11 13:26:41 +08:00
zyxucp
d14ce2faa0 add 增加系统设置管理权限 2024-03-10 21:26:01 +08:00
zyxucp
ca293691a8 fix 修改GpuLayerCount 默认值为10 2024-03-10 17:48:00 +08:00
zyxucp
cf8955b9b6 add 更新AntDesign KernelMemory nuget包版本 2024-03-10 16:31:16 +08:00
zyxucp
512828fdc9 fix 调整星火key和screct的位置 2024-03-10 10:55:44 +08:00
zyxucp
91299a96e7 Merge pull request #22 from ElderJames/main
Add Spark Desk text ceneration support
2024-03-10 09:21:35 +08:00
James Yeung
4876d9e727 fix build 2024-03-10 01:34:18 +08:00
James Yeung
a856f2a0e3 clean 2024-03-10 01:31:21 +08:00
James Yeung
0e8113e7b0 Add Spark Desk text ceneration support 2024-03-10 00:55:33 +08:00
zyxucp
34a953589d Update docker-compose.simple.yml 2024-03-09 23:55:50 +08:00
zyxucp
504ea5a238 Update docker-compose.yml 2024-03-09 23:55:40 +08:00
zyxucp
3b5997fce6 Merge branch 'main' of https://github.com/xuzeyu91/AntSK 2024-03-09 23:43:30 +08:00
zyxucp
7b0f6c3e75 add 增加消息结束后滚动条滚到底部 2024-03-09 23:40:00 +08:00
zyxucp
099b85619c add 增加消息时间的气泡 2024-03-09 23:12:28 +08:00
zyxucp
0129cd3f39 fix 修改头像样式为固定大小 2024-03-09 23:04:09 +08:00
zyxucp
84f3cbf9a9 add 增加消息复制按钮 2024-03-09 22:55:45 +08:00
zyxucp
a7af462a44 add 增加知识库外部使用流式接口 2024-03-09 22:20:05 +08:00
zyxucp
fdca08eb3d fix 抽象KMS结构 2024-03-09 22:09:31 +08:00
zyxucp
c3eeefe9fe fix 抽象sendkms 2024-03-09 21:40:36 +08:00
zyxucp
2f6990320c fix 封装Chat方法 2024-03-09 21:21:32 +08:00
zyxucp
ef83450425 fix 调整名称 2024-03-09 21:12:22 +08:00
zyxucp
f2f10ec9f4 fix 调整项目结构,抽象发送消息接口 2024-03-09 21:10:50 +08:00
zyxucp
7346ff2e78 add 更新图片 2024-03-09 19:35:38 +08:00
zyxucp
1dc274ce82 fix 执行code clear 2024-03-09 19:19:05 +08:00
zyxucp
2be438f9c3 fix 调整项目结构 2024-03-09 19:12:40 +08:00
zyxucp
1f7f51ff1e fix 优化代码 2024-03-09 18:24:17 +08:00
zyxucp
338a7ae083 Update docker-compose.simple.yml 2024-03-09 17:47:30 +08:00
zyxucp
04d7896a92 Update docker-compose.yml 2024-03-09 17:47:17 +08:00
zyxucp
4b8c8c0f96 fix 修改openai azue 和llama 流式不一致的问题 2024-03-09 17:30:11 +08:00
zyxucp
8296476d94 Update docker-compose.simple.yml 2024-03-09 12:40:04 +08:00
zyxucp
38b3fc26ed Update docker-compose.yml 2024-03-09 12:39:48 +08:00
zyxucp
6852b458fa fix 字典修改 2024-03-09 12:15:32 +08:00
zyxucp
cdb41023d4 Merge branch 'main' of https://github.com/xuzeyu91/AntSK 2024-03-09 12:10:05 +08:00
zyxucp
8e00e681f0 fix 修改StreamingTextContent 2024-03-09 12:09:53 +08:00
zyxucp
577d6dd3a6 add 增加异常日志 2024-03-09 12:02:47 +08:00
zyxucp
eeecd15d9e fix 修改StreamingTextContent 2024-03-09 11:59:36 +08:00
zyxucp
e39b26bcc3 更新 README.md 2024-03-09 00:05:20 +08:00
zyxucp
6b5a77f8c1 Update appsettings.json 2024-03-08 23:38:36 +08:00
zyxucp
0dc9736c35 Update docker-compose.simple.yml 2024-03-08 23:18:15 +08:00
zyxucp
bbe2471815 Update docker-compose.yml 2024-03-08 23:17:49 +08:00
187 changed files with 3995 additions and 1961 deletions

2
.gitignore vendored
View File

@@ -340,3 +340,5 @@ ASALocalRun/
/src/AntSK/AntSK.db
/src/AntSK/appsettings.Development.json
/src/AntSK.db
/src/AntSK/llama_models
/src/AntSK/AntSK.xml

View File

@@ -10,15 +10,19 @@
- **知识库**通过文档Word、PDF、Excel、Txt、Markdown、Json、PPT等形式导入知识库可以进行知识库文档。
- **API插件系统**开放式API插件系统允许第三方开发者或服务商轻松将其服务集成到AntSK不断增强应用功能。
- **联网搜索**AntSK实时获取最新信息确保用户接受到的资料总是最及时、最相关的。
- **GPTs 生成**此平台支持创建个性化的GPT模型尝试构建您自己的GPT模型。
- **API接口发布**将内部功能以API的形式对外提供便于开发者将AntSK 集成进其他应用,增强应用智慧。
- **模型管理**:适配和管理集成不同厂商的不同模型
- **API插件系统**开放式API插件系统允许第三方开发者或服务商轻松将其服务集成到AntSK不断增强应用功能
- **.Net插件系统**开放式dll插件系统允许第三方开发者或服务商轻松将其业务功能通过标准格式的代码生成dll后集成到AntSK不断增强应用功能。
- **联网搜索**AntSK实时获取最新信息确保用户接受到的资料总是最及时、最相关的。
- **模型管理**适配和管理集成不同厂商的不同模型。并且支持llama.cpp所支持的gguf类型的模型离线运行
- **国产信创**AntSK支持国产模型和国产数据库可以在信创条件下运行
## 应用场景
@@ -63,9 +67,9 @@ AntSK 适用于多种业务场景,例如:
在这里我使用的是Postgres 作为数据存储和向量存储因为Semantic Kernel和Kernel Memory都支持他当然你也可以换成其他的。
模型默认支持openai,如果需要使用azure openai需要调整SK的依赖注入可以使用one-api进行集成。
模型默认支持openaiazure openai 和llama支持的gguf本地模型,如果需要使用其他模型,可以使用one-api进行集成。
Login是默认的登陆账号和密码
配置文件中的Login配置是默认的登陆账号和密码
需要配置如下的配置文件
@@ -83,7 +87,7 @@ docker-compose up -d
```
来启动AntSK
## 如何在docker中挂载本地模型
## 如何在docker中挂载本地模型,和模型下载的目录
```
# 非 host 版本, 不使用本机代理
version: '3.8'
@@ -118,12 +122,6 @@ model/xxx.gguf
"DbType": "Sqlite",
"ConnectionStrings": "Data Source=AntSK.db;"
},
"OpenAIOption": {
"EndPoint": "http://localhost:5000/llama/",
"Key": "NotNull",
"Model": "gpt4-turbo",
"EmbeddingModel": "text-embedding-ada-002"
},
"KernelMemory": {
"VectorDb": "Disk",
"ConnectionString": "Host=;Port=;Database=antsk;Username=;Password=",
@@ -132,7 +130,8 @@ model/xxx.gguf
"LLamaSharp": {
"RunType": "GPU",
"Chat": "D:\\Code\\AI\\AntBlazor\\model\\qwen1_5-1_8b-chat-q8_0.gguf",
"Embedding": "D:\\Code\\AI\\AntBlazor\\model\\qwen1_5-1_8b-chat-q8_0.gguf"
"Embedding": "D:\\Code\\AI\\AntBlazor\\model\\qwen1_5-1_8b-chat-q8_0.gguf",
"FileDirectory": "D:\\Code\\AI\\AntBlazor\\model\\"
},
"Login": {
"User": "admin",
@@ -150,18 +149,19 @@ model/xxx.gguf
DBConnection.DbType
//连接字符串需要根据不同DB类型用对应的字符串
DBConnection.ConnectionStrings
//可以使用符合openai格式的在线API国产模型使用one-api转接 也可以使用AntSK自带的llama apiip和端口是AntSK启动地址
OpenAIOption.EndPoint
//模型秘钥如果使用本地模型可以默认NotNull 这里不能用中文
OpenAIOption.Key
//向量存储的类型,支持 Postgres Disk Memory 其中Postgres需要配置 ConnectionString
KernelMemory.VectorDb
//本地模型使用的运行方式 GUP CPU ,如果用在线API 这个随意使用一个即可
LLamaSharp.RunType
//本地会话模型的模型路径 注意区分linux和windows盘符不同
LLamaSharp.Chat
//本地向量模型的模型路径 注意区分linux和windows盘符不同
LLamaSharp.Embedding
//本地模型路径用于在选择llama时可以快速选择目录下的模型以及保存下载的模型
LLamaSharp.FileDirectory
//默认管理员账号密码
Login
//导入异步处理的线程数使用在线API可以高一点本地模型建议1 否则容易内存溢出崩掉

View File

@@ -3,7 +3,7 @@ version: '3.8'
services:
antsk:
container_name: antsk
image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.1.5
image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.1.9
ports:
- 5000:5000
networks:

View File

@@ -18,7 +18,7 @@ services:
- ./pg/data:/var/lib/postgresql/data
antsk:
container_name: antsk
image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.1.5
image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.1.9
ports:
- 5000:5000
networks:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 174 KiB

After

Width:  |  Height:  |  Size: 170 KiB

View File

@@ -8,19 +8,22 @@
<NoWarn>CA1050,CA1707,CA2007,VSTHRD111,CS1591,RCS1110,CA5394,SKEXP0001,SKEXP0002,SKEXP0003,SKEXP0004,SKEXP0010,SKEXP0011,,SKEXP0012,SKEXP0020,SKEXP0021,SKEXP0022,SKEXP0023,SKEXP0024,SKEXP0025,SKEXP0026,SKEXP0027,SKEXP0028,SKEXP0029,SKEXP0030,SKEXP0031,SKEXP0032,SKEXP0040,SKEXP0041,SKEXP0042,SKEXP0050,SKEXP0051,SKEXP0052,SKEXP0053,SKEXP0054,SKEXP0055,SKEXP0060,SKEXP0061,SKEXP0101,SKEXP0102</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AntDesign.Charts" Version="0.5.1" />
<PackageReference Include="AntDesign.ProLayout" Version="0.18.0" />
<PackageReference Include="AutoMapper" Version="8.1.0" />
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
<PackageReference Include="MarkdownSharp" Version="2.0.5" />
<PackageReference Include="Markdig" Version="0.36.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.143" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.145" />
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.118" />
<PackageReference Include="RestSharp" Version="110.2.0" />
<PackageReference Include="Microsoft.SemanticKernel" Version="1.4.0" />
<PackageReference Include="Microsoft.SemanticKernel.Core" Version="1.4.0" />
<PackageReference Include="Microsoft.SemanticKernel.Plugins.Core" Version="1.4.0-alpha" />
<PackageReference Include="Microsoft.KernelMemory.Core" Version="0.30.240227.1" />
<PackageReference Include="Microsoft.KernelMemory.MemoryDb.Postgres" Version="0.30.240227.1" />
<PackageReference Include="Microsoft.SemanticKernel" Version="1.6.2" />
<PackageReference Include="Microsoft.SemanticKernel.Core" Version="1.6.2" />
<PackageReference Include="Microsoft.SemanticKernel.Plugins.Core" Version="1.6.2-alpha" />
<PackageReference Include="Microsoft.KernelMemory.Core" Version="0.34.240313.1" />
<PackageReference Include="Microsoft.KernelMemory.MemoryDb.Postgres" Version="0.34.240313.1" />
<PackageReference Include="LLamaSharp" Version="0.10.0" />
<PackageReference Include="LLamaSharp.Backend.Cpu" Version="0.10.0" />
@@ -31,6 +34,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AntSk.LLM\AntSK.LLM.csproj" />
<ProjectReference Include="..\MiddleWare\AntSK.BackgroundTask\AntSK.BackgroundTask.csproj" />
</ItemGroup>

View File

@@ -48,6 +48,55 @@
<param name="value"></param>
<returns></returns>
</member>
<member name="T:AntSK.Domain.Domain.Model.Enum.AIType">
<summary>
AI类型
</summary>
</member>
<member name="T:AntSK.Domain.Domain.Model.Enum.AIModelType">
<summary>
模型类型
</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开始
</summary>
</member>
<member name="P:AntSK.Domain.Domain.Model.PageList`1.PageSize">
<summary>
每页数量
</summary>
</member>
<member name="P:AntSK.Domain.Domain.Model.PageList`1.TotalCount">
<summary>
总数
</summary>
</member>
<member name="F:AntSK.Domain.Domain.Other.LLamaConfig.dicLLamaWeights">
<summary>
避免模型重复加载,本地缓存
</summary>
</member>
<member name="M:AntSK.Domain.Domain.Service.ChatService.SendChatByAppAsync(AntSK.Domain.Repositories.Apps,System.String,System.String)">
<summary>
发送消息
</summary>
<param name="app"></param>
<param name="questions"></param>
<param name="history"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Domain.Service.FunctionService.SearchMarkedMethods">
<summary>
查询程序集中的方法委托后续利用Source Generators生成
</summary>
</member>
<member name="M:AntSK.Domain.Domain.Service.KernelService.GetKernelByApp(AntSK.Domain.Repositories.Apps)">
<summary>
获取kernel实例依赖注入不好按每个用户去Import不同的插件所以每次new一个新的kernel
@@ -78,66 +127,6 @@
<param name="history"></param>
<returns></returns>
</member>
<member name="F:AntSK.Domain.Domain.Service.LLamaConfig.dicLLamaWeights">
<summary>
避免模型重复加载,本地缓存
</summary>
</member>
<member name="M:AntSK.Domain.Map.MapperExtend.ToDTOList``1(System.Object)">
<summary>
Entity集合转DTO集合
</summary>
<typeparam name="T"></typeparam>
<param name="value"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Map.MapperExtend.ToDTO``1(System.Object)">
<summary>
Entity转DTO
</summary>
<typeparam name="T"></typeparam>
<param name="value"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Map.MapperExtend.MapTo``1(System.Object,``0)">
<summary>
给已有对象map,适合update场景如需过滤空值需要在AutoMapProfile 设置
</summary>
<typeparam name="T"></typeparam>
<param name="self"></param>
<param name="result"></param>
<returns></returns>
</member>
<member name="T:AntSK.Domain.Model.Enum.AIType">
<summary>
AI类型
</summary>
</member>
<member name="T:AntSK.Domain.Model.Enum.AIModelType">
<summary>
模型类型
</summary>
</member>
<member name="P:AntSK.Domain.Model.MessageInfo.IsSend">
<summary>
发送是true 接收是false
</summary>
</member>
<member name="P:AntSK.Domain.Model.PageList`1.PageIndex">
<summary>
当前页从1开始
</summary>
</member>
<member name="P:AntSK.Domain.Model.PageList`1.PageSize">
<summary>
每页数量
</summary>
</member>
<member name="P:AntSK.Domain.Model.PageList`1.TotalCount">
<summary>
总数
</summary>
</member>
<member name="P:AntSK.Domain.Options.DBConnectionOption.DbType">
<summary>
sqlite连接字符串
@@ -243,6 +232,11 @@
插件列表
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Apps.NativeFunctionList">
<summary>
本地函数列表
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Apps.KmsIdList">
<summary>
知识库ID列表
@@ -731,5 +725,130 @@
</summary>
<returns>The full path to samples/plugins</returns>
</member>
<member name="T:AntSK.Domain.Utils.XmlCommentHelper">
<summary>
注释辅助类
</summary>
</member>
<member name="M:AntSK.Domain.Utils.XmlCommentHelper.LoadAll">
<summary>
从当前dll文件中加载所有的xml文件
</summary>
</member>
<member name="M:AntSK.Domain.Utils.XmlCommentHelper.LoadXml(System.String[])">
<summary>
从xml中加载
</summary>
<param name="xmls"></param>
</member>
<member name="M:AntSK.Domain.Utils.XmlCommentHelper.Load(System.String[])">
<summary>
从文件中加载
</summary>
<param name="xmlFiles"></param>
</member>
<member name="M:AntSK.Domain.Utils.XmlCommentHelper.Load(System.IO.Stream[])">
<summary>
从流中加载
</summary>
<param name="streams"></param>
</member>
<member name="M:AntSK.Domain.Utils.XmlCommentHelper.GetTypeComment(System.Type,System.String,System.Boolean)">
<summary>
读取类型中的注释
</summary>
<param name="type">类型</param>
<param name="xPath">注释路径</param>
<param name="humanize">可读性优化(比如去掉xml标记)</param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.XmlCommentHelper.GetFieldOrPropertyComment(System.Reflection.MemberInfo,System.String,System.Boolean)">
<summary>
读取字段或者属性的注释
</summary>
<param name="fieldOrPropertyInfo">字段或者属性</param>
<param name="xPath">注释路径</param>
<param name="humanize">可读性优化(比如去掉xml标记)</param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.XmlCommentHelper.GetMethodComment(System.Reflection.MethodInfo,System.String,System.Boolean)">
<summary>
读取方法中的注释
</summary>
<param name="methodInfo">方法</param>
<param name="xPath">注释路径</param>
<param name="humanize">可读性优化(比如去掉xml标记)</param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.XmlCommentHelper.GetMethodReturnComment(System.Reflection.MethodInfo,System.Boolean)">
<summary>
读取方法中的返回值注释
</summary>
<param name="methodInfo">方法</param>
<param name="humanize">可读性优化(比如去掉xml标记)</param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.XmlCommentHelper.GetParameterComment(System.Reflection.ParameterInfo,System.Boolean)">
<summary>
读取参数的注释
</summary>
<param name="parameterInfo">参数</param>
<param name="humanize">可读性优化(比如去掉xml标记)</param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.XmlCommentHelper.GetParameterComments(System.Reflection.MethodInfo,System.Boolean)">
<summary>
读取方法的所有参数的注释
</summary>
<param name="methodInfo">方法</param>
<param name="humanize">可读性优化(比如去掉xml标记)</param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.XmlCommentHelper.GetComment(System.String,System.String,System.Boolean)">
<summary>
读取指定名称节点的注释
</summary>
<param name="name">节点名称</param>
<param name="xPath">注释路径</param>
<param name="humanize">可读性优化(比如去掉xml标记)</param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.XmlCommentHelper.GetSummary(System.String,System.Boolean)">
<summary>
读取指定节点的summary注释
</summary>
<param name="name">节点名称</param>
<param name="humanize">可读性优化(比如去掉xml标记)</param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.XmlCommentHelper.GetExample(System.String,System.Boolean)">
<summary>
读取指定节点的example注释
</summary>
<param name="name">节点名称</param>
<param name="humanize">可读性优化(比如去掉xml标记)</param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.XmlCommentHelper.GetMemberNameForMethod(System.Reflection.MethodInfo)">
<summary>
获取方法的节点名称
</summary>
<param name="method"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.XmlCommentHelper.GetMemberNameForType(System.Type)">
<summary>
获取类型的节点名称
</summary>
<param name="type"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.XmlCommentHelper.GetMemberNameForFieldOrProperty(System.Reflection.MemberInfo)">
<summary>
获取字段或者属性的节点名称
</summary>
<param name="fieldOrPropertyInfo"></param>
<returns></returns>
</member>
</members>
</doc>

View File

@@ -0,0 +1,8 @@
namespace AntSK.Domain.Common
{
[AttributeUsage(AttributeTargets.Method)]
public class AntSkFunctionAttribute : Attribute
{
// 自定义的ActionAttribute
}
}

View File

@@ -1,10 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Common.DependencyInjection
{

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Common.DependencyInjection
namespace AntSK.Domain.Common.DependencyInjection
{
public class ServiceDescriptionAttribute : Attribute
{

View File

@@ -1,7 +1,4 @@
using AutoMapper;
using System;
using System.Collections.Generic;
using System.Text;
namespace AntSK.Domain.Common.Map
{

View File

@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace AntSK.Domain.Common.Map
namespace AntSK.Domain.Common.Map
{
public static class MapperExtend
{

View File

@@ -1,8 +1,5 @@
using AutoMapper;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Text;
namespace AntSK.Domain.Common.Map
{

View File

@@ -0,0 +1,18 @@
using AntSK.Domain.Domain.Model.Dto;
using AntSK.Domain.Repositories;
using Microsoft.SemanticKernel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Domain.Interface
{
public interface IChatService
{
IAsyncEnumerable<StreamingKernelContent> SendChatByAppAsync(Apps app, string questions, string history);
IAsyncEnumerable<StreamingKernelContent> SendKmsByAppAsync(Apps app, string questions, string history, List<RelevantSource> relevantSources = null);
}
}

View File

@@ -1,9 +1,4 @@
using RestSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Domain.Interface
{

View File

@@ -1,9 +1,4 @@
using AntSK.Domain.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AntSK.Domain.Domain.Model;
namespace AntSK.Domain.Domain.Interface
{

View File

@@ -1,11 +1,5 @@
using AntSK.Domain.Domain.Dto;
using Microsoft.KernelMemory.Configuration;
using AntSK.Domain.Domain.Model.Dto;
using Microsoft.KernelMemory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Domain.Interface
{

View File

@@ -1,10 +1,5 @@
using AntSK.Domain.Repositories;
using Microsoft.SemanticKernel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Domain.Interface
{

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Domain.Dto
namespace AntSK.Domain.Domain.Model.Dto
{
public class KMFile
{

View File

@@ -1,11 +1,4 @@
using Microsoft.AspNetCore.Identity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Models
namespace AntSK.Domain.Domain.Model.Dto.OpenAPI
{
public class OpenAIModel
{

View File

@@ -1,7 +1,6 @@
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace AntSK.Models.OpenAPI
namespace AntSK.Domain.Domain.Model.Dto.OpenAPI
{
public class OpenAIResult
{
@@ -21,7 +20,7 @@ namespace AntSK.Models.OpenAPI
public OpenAIMessage message { get; set; }
}
public class OpenAIEmbeddingResult
public class OpenAIEmbeddingResult
{
[JsonProperty("object")]
public string obj { get; set; } = "list";
@@ -29,17 +28,17 @@ namespace AntSK.Models.OpenAPI
public UsageModel usage { get; set; } = new UsageModel();
public List<DataModel> data { get; set; } = new List<DataModel>() { new DataModel() };
public List<DataModel> data { get; set; } = new List<DataModel>() { new DataModel() };
}
public class UsageModel
public class UsageModel
{
public long prompt_tokens { get; set; } = 0;
public long total_tokens { get; set; } = 0;
}
public class DataModel
public class DataModel
{
[JsonProperty("object")]
public string obj { get; set; } = "embedding";

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Domain.Model.Dto
{
public class RelevantSource
{
public string SourceName { get; set; }
public string Text { get; set; }
public float Relevance { get; set; }
}
}

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Model.Enum
namespace AntSK.Domain.Domain.Model.Enum
{
/// <summary>
/// AI类型
@@ -13,7 +7,9 @@ namespace AntSK.Domain.Model.Enum
{
OpenAI = 1,
AzureOpenAI = 2,
LLamaSharp=3
LLamaSharp = 3,
SparkDesk = 4,
Mock = 5,
}
/// <summary>

View File

@@ -4,12 +4,11 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Model
namespace AntSK.Domain.Domain.Model.Enum
{
public enum HttpMethodType
public enum AppType
{
Get = 1,
Post = 2,
chat = 1,
kms = 2
}
}

View File

@@ -0,0 +1,8 @@
namespace AntSK.Domain.Domain.Model.Enum
{
public enum HttpMethodType
{
Get = 1,
Post = 2,
}
}

View File

@@ -0,0 +1,9 @@
namespace AntSK.Domain.Domain.Model.Enum
{
public enum ImportKmsStatus
{
Loadding = 0,
Success = 1,
Fail = 2
}
}

View File

@@ -1,12 +1,6 @@
using AntSK.Domain.Repositories;
using Microsoft.KernelMemory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Model
namespace AntSK.Domain.Domain.Model
{
public class ImportKMSTaskDTO
{
@@ -26,14 +20,15 @@ namespace AntSK.Domain.Model
}
public class ImportKMSTaskReq: ImportKMSTaskDTO
public class ImportKMSTaskReq : ImportKMSTaskDTO
{
public KmsDetails KmsDetail { get; set; } = new KmsDetails();
}
public enum ImportType {
File=1,
Url=2,
Text=3
public enum ImportType
{
File = 1,
Url = 2,
Text = 3
}
}

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Model
namespace AntSK.Domain.Domain.Model
{
public class MessageInfo
{

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Model
namespace AntSK.Domain.Domain.Model
{
public class PageList<T>
{

View File

@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Domain.Model.hfmirror
{
public class HfModel
{
public List<HfModels> models { get; set; }
public int numItemsPerPage { get; set; }
public int numTotalItems { get; set; }
public int pageIndex { get; set; }
}
public class HfModels
{
public string Author { get; set; }
public HfAuthorData AuthorData { get; set; }
public int Downloads { get; set; }
public bool Gated { get; set; }
public string Id { get; set; }
public DateTime LastModified { get; set; }
public int Likes { get; set; }
public string PipelineTag { get; set; }
public bool Private { get; set; }
public string RepoType { get; set; }
public bool IsLikedByUser { get; set; }
}
public class HfAuthorData
{
public string AvatarUrl { get; set; }
public string Fullname { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public bool IsHf { get; set; }
public bool IsEnterprise { get; set; }
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Domain.Model.hfmirror
{
public class HfModelDetail
{
public string Name { get; set; }
public string Size { get; set; }
public string Path { get; set; }
public string Time { get; set; }
}
}

View File

@@ -1,14 +1,9 @@
using AntSK.BackgroundTask;
using AntSK.Domain.Domain.Interface;
using AntSK.Domain.Model;
using AntSK.Domain.Domain.Model;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Domain.Service
namespace AntSK.Domain.Domain.Other
{
public class BackGroundTaskHandler : IBackgroundTaskHandler<ImportKMSTaskReq>
{
@@ -23,7 +18,7 @@ namespace AntSK.Domain.Domain.Service
using (var scope = _scopeFactory.CreateScope())
{
Console.WriteLine("ExecuteAsync.开始执行后台任务");
var importKMSService = scope.ServiceProvider.GetRequiredService<IImportKMSService>();
var importKMSService = scope.ServiceProvider.GetRequiredService<IImportKMSService>();
//不能使用异步
importKMSService.ImportKMSTask(item);
Console.WriteLine("ExecuteAsync.后台任务执行完成");

View File

@@ -1,13 +1,8 @@
using LLama.Common;
using LLama;
using LLama;
using LLama.Common;
using LLamaSharp.KernelMemory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Domain.Service
namespace AntSK.Domain.Domain.Other
{
public static class LLamaConfig
{
@@ -16,7 +11,7 @@ namespace AntSK.Domain.Domain.Service
/// 避免模型重复加载,本地缓存
/// </summary>
static Dictionary<string, (LLamaWeights, ModelParams)> dicLLamaWeights = new Dictionary<string, (LLamaWeights, ModelParams)>();
public static (LLamaWeights, ModelParams) GetLLamaConfig(string modelPath, LLamaSharpConfig config =null)
public static (LLamaWeights, ModelParams) GetLLamaConfig(string modelPath, LLamaSharpConfig config = null)
{
lock (lockobj)
{
@@ -28,7 +23,7 @@ namespace AntSK.Domain.Domain.Service
{
InferenceParams infParams = new() { AntiPrompts = ["\n\n"] };
LLamaSharpConfig lsConfig = new(modelPath) { DefaultInferenceParams = infParams };
if (config!=null)
if (config != null)
{
lsConfig = config;
}
@@ -36,14 +31,14 @@ namespace AntSK.Domain.Domain.Service
{
ContextSize = lsConfig?.ContextSize ?? 2048,
Seed = lsConfig?.Seed ?? 0,
GpuLayerCount = lsConfig?.GpuLayerCount ?? 20,
GpuLayerCount = lsConfig?.GpuLayerCount ?? 10,
EmbeddingMode = true
};
var weights = LLamaWeights.LoadFromFile(parameters);
dicLLamaWeights.Add(modelPath, (weights, parameters));
return (weights, parameters);
}
}
}
}
}
}

View File

@@ -0,0 +1,102 @@
using AntSK.Domain.Common.DependencyInjection;
using AntSK.Domain.Domain.Interface;
using AntSK.Domain.Repositories;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Microsoft.SemanticKernel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AntSK.Domain.Utils;
using Microsoft.KernelMemory;
using Markdig;
using AntSK.Domain.Domain.Model;
using AntSK.Domain.Domain.Model.Dto;
namespace AntSK.Domain.Domain.Service
{
[ServiceDescription(typeof(IChatService), ServiceLifetime.Scoped)]
public class ChatService(
IKernelService _kernelService,
IKMService _kMService,
IKmsDetails_Repositories _kmsDetails_Repositories
) : IChatService
{
/// <summary>
/// 发送消息
/// </summary>
/// <param name="app"></param>
/// <param name="questions"></param>
/// <param name="history"></param>
/// <returns></returns>
public async IAsyncEnumerable<StreamingKernelContent> SendChatByAppAsync(Apps app, string questions, string history)
{
if (string.IsNullOrEmpty(app.Prompt) || !app.Prompt.Contains("{{$input}}"))
{
//如果模板为空,给默认提示词
app.Prompt = app.Prompt.ConvertToString() + "{{$input}}";
}
var _kernel = _kernelService.GetKernelByApp(app);
var temperature = app.Temperature / 100;//存的是0~100需要缩小
OpenAIPromptExecutionSettings settings = new() { Temperature = temperature };
if (!string.IsNullOrEmpty(app.ApiFunctionList)|| !string.IsNullOrEmpty(app.NativeFunctionList))//这里还需要加上本地插件的
{
_kernelService.ImportFunctionsByApp(app, _kernel);
settings.ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions;
}
var func = _kernel.CreateFunctionFromPrompt(app.Prompt, settings);
var chatResult = _kernel.InvokeStreamingAsync(function: func, arguments: new KernelArguments() { ["input"] = $"{history}{Environment.NewLine} user:{questions}" });
await foreach (var content in chatResult)
{
yield return content;
}
}
public async IAsyncEnumerable<StreamingKernelContent> SendKmsByAppAsync(Apps app, string questions, string history, List<RelevantSource> relevantSources = null)
{
var _kernel = _kernelService.GetKernelByApp(app);
//知识库问答
var filters = new List<MemoryFilter>();
var kmsidList = app.KmsIdList.Split(",");
//只取第一个知识库的配置
var _memory = _kMService.GetMemoryByKMS(kmsidList.FirstOrDefault());
foreach (var kmsid in kmsidList)
{
filters.Add(new MemoryFilter().ByTag("kmsid", kmsid));
}
var xlresult = await _memory.SearchAsync(questions, index: "kms", filters: filters);
string dataMsg = "";
if (xlresult != null)
{
foreach (var item in xlresult.Results)
{
foreach (var part in item.Partitions)
{
dataMsg += $"[file:{item.SourceName};Relevance:{(part.Relevance * 100).ToString("F2")}%]:{part.Text}{Environment.NewLine}";
if (relevantSources.IsNotNull())
{
string sourceName = item.SourceName;
var fileDetail = _kmsDetails_Repositories.GetFirst(p => p.FileGuidName == item.SourceName);
if (fileDetail.IsNotNull())
{
sourceName = fileDetail.FileName;
}
relevantSources.Add(new RelevantSource() { SourceName = sourceName, Text = Markdown.ToHtml(part.Text), Relevance = part.Relevance });
}
}
}
KernelFunction jsonFun = _kernel.Plugins.GetFunction("KMSPlugin", "Ask");
var chatResult = _kernel.InvokeStreamingAsync(function: jsonFun,
arguments: new KernelArguments() { ["doc"] = dataMsg, ["history"] = history, ["questions"] = questions });
MessageInfo info = null;
await foreach (var content in chatResult)
{
yield return content;
}
}
}
}
}

View File

@@ -0,0 +1,70 @@
using System.ComponentModel;
using System.Reflection;
using System.Xml;
using AntSK.Domain.Common;
using AntSK.Domain.Utils;
namespace AntSK.Domain.Domain.Service
{
public class FunctionService
{
private readonly Dictionary<string, MethodInfo> _methodCache;
private readonly Dictionary<string, (string Description, (Type ParameterType, string Description) ReturnType, (string ParameterName, Type ParameterType, string Description)[] Parameters)> _methodInfos;
private readonly IServiceProvider _serviceProvider;
private readonly Assembly[] _assemblies;
public FunctionService(IServiceProvider serviceProvider, Assembly[] assemblies)
{
_methodCache = [];
_methodInfos = [];
_serviceProvider = serviceProvider;
_assemblies = assemblies;
}
public Dictionary<string, MethodInfo> Functions => _methodCache;
public Dictionary<string, (string Description, (Type ParameterType, string Description) ReturnType, (string ParameterName, Type ParameterType, string Description)[] Parameters)> MethodInfos => _methodInfos;
/// <summary>
/// 查询程序集中的方法委托后续利用Source Generators生成
/// </summary>
public void SearchMarkedMethods()
{
var markedMethods = new List<MethodInfo>();
_methodCache.Clear();
_methodInfos.Clear();
foreach (var assembly in _assemblies)
{
// 从缓存中获取标记了ActionAttribute的方法
foreach (var type in assembly.GetTypes())
{
markedMethods.AddRange(type.GetMethods().Where(m =>
{
DescriptionAttribute da = (DescriptionAttribute)m.GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault();
return da != null && da.Description == "AntSK";
}));
}
}
// 构建方法调用
foreach (var method in markedMethods)
{
var key = $"{method.DeclaringType.Assembly.GetName().Name}_{method.DeclaringType.Name}_{method.Name}";
_methodCache.TryAdd(key, method);
var xmlCommentHelper = new XmlCommentHelper();
xmlCommentHelper.LoadAll();
var description = xmlCommentHelper.GetMethodComment(method);
var dict = xmlCommentHelper.GetParameterComments(method);
var parameters = method.GetParameters().Select(x => (x.Name, x.ParameterType, dict[x.Name])).ToArray();
var returnType = xmlCommentHelper.GetMethodReturnComment(method);
_methodInfos.TryAdd(key, (description, (method.ReflectedType, returnType), parameters));
}
}
}
}

View File

@@ -1,30 +1,21 @@
using AntSK.Domain.Common.DependencyInjection;
using AntSK.Domain.Domain.Interface;
using AntSK.Domain.Model;
using AntSK.Domain.Utils;
using Microsoft.KernelMemory;
using Newtonsoft.Json;
using RestSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Domain.Service
{
[ServiceDescription(typeof(IHttpService), ServiceLifetime.Scoped)]
public class HttpService: IHttpService
public class HttpService : IHttpService
{
public async Task< RestResponse> PostAsync(string url ,Object jsonBody)
public async Task<RestResponse> PostAsync(string url, Object jsonBody)
{
RestClient client = new RestClient();
RestRequest request= new RestRequest(url, Method.Post);
RestRequest request = new RestRequest(url, Method.Post);
string josn = JsonConvert.SerializeObject(jsonBody);
request.AddJsonBody(jsonBody);
var result =await client.ExecuteAsync(request);
return result;
var result = await client.ExecuteAsync(request);
return result;
}
}
}

View File

@@ -1,15 +1,8 @@
using AntSK.Domain.Common.DependencyInjection;
using AntSK.Domain.Domain.Interface;
using AntSK.Domain.Model;
using AntSK.Domain.Domain.Model;
using AntSK.Domain.Repositories;
using Microsoft.KernelMemory;
using Microsoft.KernelMemory.Configuration;
using Microsoft.SemanticKernel.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Domain.Service
{
@@ -34,12 +27,12 @@ namespace AntSK.Domain.Domain.Service
case ImportType.File:
//导入文件
{
var importResult= _memory.ImportDocumentAsync(new Document(fileid)
.AddFile(req.FilePath)
.AddTag("kmsid", req.KmsId)
, index: "kms").Result;
var importResult = _memory.ImportDocumentAsync(new Document(fileid)
.AddFile(req.FilePath)
.AddTag("kmsid", req.KmsId)
, index: "kms").Result;
//查询文档数量
var docTextList = _kMService.GetDocumentByFileID(km.Id,fileid).Result;
var docTextList = _kMService.GetDocumentByFileID(km.Id, fileid).Result;
string fileGuidName = Path.GetFileName(req.FilePath);
req.KmsDetail.FileName = req.FileName;
req.KmsDetail.FileGuidName = fileGuidName;
@@ -53,7 +46,7 @@ namespace AntSK.Domain.Domain.Service
var importResult = _memory.ImportWebPageAsync(req.Url, fileid, new TagCollection() { { "kmsid", req.KmsId } }
, index: "kms").Result;
//查询文档数量
var docTextList = _kMService.GetDocumentByFileID(km.Id,fileid).Result;
var docTextList = _kMService.GetDocumentByFileID(km.Id, fileid).Result;
req.KmsDetail.Url = req.Url;
req.KmsDetail.DataCount = docTextList.Count;
}
@@ -64,7 +57,7 @@ namespace AntSK.Domain.Domain.Service
var importResult = _memory.ImportTextAsync(req.Text, fileid, new TagCollection() { { "kmsid", req.KmsId } }
, index: "kms").Result;
//查询文档数量
var docTextList = _kMService.GetDocumentByFileID(km.Id,fileid).Result;
var docTextList = _kMService.GetDocumentByFileID(km.Id, fileid).Result;
req.KmsDetail.Url = req.Url;
req.KmsDetail.DataCount = docTextList.Count;
@@ -72,14 +65,14 @@ namespace AntSK.Domain.Domain.Service
break;
}
req.KmsDetail.Status = Model.Enum.ImportKmsStatus.Success;
_kmsDetails_Repositories.Update(req.KmsDetail);
//_kmsDetails_Repositories.GetList(p => p.KmsId == req.KmsId);
_kmsDetails_Repositories.Update(req.KmsDetail);
//_kmsDetails_Repositories.GetList(p => p.KmsId == req.KmsId);
Console.WriteLine("后台导入任务成功:" + req.KmsDetail.DataCount);
}
catch (Exception ex)
{
req.KmsDetail.Status = Model.Enum.ImportKmsStatus.Fail;
_kmsDetails_Repositories.Update(req.KmsDetail);
_kmsDetails_Repositories.Update(req.KmsDetail);
Console.WriteLine("后台导入任务异常:" + ex.Message);
}
}

View File

@@ -1,21 +1,17 @@
using AntSK.Domain.Common.DependencyInjection;
using AntSK.Domain.Domain.Interface;
using Microsoft.KernelMemory;
using AntSK.Domain.Domain.Model.Dto;
using AntSK.Domain.Domain.Other;
using AntSK.Domain.Repositories;
using AntSK.Domain.Utils;
using AntSK.Domain.Domain.Dto;
using AntSK.Domain.Options;
using LLama;
using LLamaSharp.KernelMemory;
using Microsoft.Extensions.Configuration;
using Microsoft.KernelMemory;
using Microsoft.KernelMemory.Configuration;
using Microsoft.KernelMemory.ContentStorage.DevTools;
using Microsoft.KernelMemory.FileSystem.DevTools;
using Microsoft.KernelMemory.Postgres;
using System.Net.Http;
using Microsoft.Extensions.Options;
using Microsoft.KernelMemory.Configuration;
using Microsoft.Extensions.Configuration;
using AntSK.Domain.Repositories;
using LLamaSharp.KernelMemory;
using LLama.Common;
using DocumentFormat.OpenXml.Spreadsheet;
using LLama;
namespace AntSK.Domain.Domain.Service
{
@@ -26,50 +22,58 @@ namespace AntSK.Domain.Domain.Service
IAIModels_Repositories _aIModels_Repositories
) : IKMService
{
private MemoryServerless _memory;
public MemoryServerless GetMemoryByKMS(string kmsID, SearchClientConfig searchClientConfig = null)
{
//获取KMS配置
var kms = _kmss_Repositories.GetFirst(p => p.Id == kmsID);
var chatModel = _aIModels_Repositories.GetFirst(p => p.Id == kms.ChatModelID);
var embedModel = _aIModels_Repositories.GetFirst(p => p.Id == kms.EmbeddingModelID);
//http代理
var chatHttpClient = OpenAIHttpClientHandlerUtil.GetHttpClient(chatModel.EndPoint);
var embeddingHttpClient = OpenAIHttpClientHandlerUtil.GetHttpClient(embedModel.EndPoint);
//搜索配置
if (searchClientConfig.IsNull())
//if (_memory.IsNull())
{
searchClientConfig = new SearchClientConfig
//获取KMS配置
var kms = _kmss_Repositories.GetFirst(p => p.Id == kmsID);
var chatModel = _aIModels_Repositories.GetFirst(p => p.Id == kms.ChatModelID);
var embedModel = _aIModels_Repositories.GetFirst(p => p.Id == kms.EmbeddingModelID);
//http代理
var chatHttpClient = OpenAIHttpClientHandlerUtil.GetHttpClient(chatModel.EndPoint);
var embeddingHttpClient = OpenAIHttpClientHandlerUtil.GetHttpClient(embedModel.EndPoint);
//搜索配置
if (searchClientConfig.IsNull())
{
MaxAskPromptSize = 2048,
MaxMatchesCount = 3,
AnswerTokens = 1000,
EmptyAnswer = "知识库未搜索到相关内容"
};
searchClientConfig = new SearchClientConfig
{
MaxAskPromptSize = 2048,
MaxMatchesCount = 3,
AnswerTokens = 1000,
EmptyAnswer = "知识库未搜索到相关内容"
};
}
var memoryBuild = new KernelMemoryBuilder()
.WithSearchClientConfig(searchClientConfig)
.WithCustomTextPartitioningOptions(new TextPartitioningOptions
{
MaxTokensPerLine = kms.MaxTokensPerLine,
MaxTokensPerParagraph = kms.MaxTokensPerParagraph,
OverlappingTokens = kms.OverlappingTokens
});
//加载huihu 模型
WithTextGenerationByAIType(memoryBuild, chatModel, chatHttpClient);
//加载向量模型
WithTextEmbeddingGenerationByAIType(memoryBuild, embedModel, embeddingHttpClient);
//加载向量库
WithMemoryDbByVectorDB(memoryBuild, _config);
_memory = memoryBuild.Build<MemoryServerless>();
return _memory;
}
var memory = new KernelMemoryBuilder()
.WithSearchClientConfig(searchClientConfig)
.WithCustomTextPartitioningOptions(new TextPartitioningOptions
{
MaxTokensPerLine = kms.MaxTokensPerLine,
MaxTokensPerParagraph = kms.MaxTokensPerParagraph,
OverlappingTokens = kms.OverlappingTokens
});
//加载huihu 模型
WithTextGenerationByAIType(memory, chatModel, chatHttpClient);
//加载向量模型
WithTextEmbeddingGenerationByAIType(memory,embedModel, embeddingHttpClient);
//加载向量库
WithMemoryDbByVectorDB(memory, _config);
var result = memory.Build<MemoryServerless>();
return result;
//else {
// return _memory;
//}
}
private void WithTextEmbeddingGenerationByAIType(IKernelMemoryBuilder memory,AIModels embedModel, HttpClient embeddingHttpClient )
private void WithTextEmbeddingGenerationByAIType(IKernelMemoryBuilder memory, AIModels embedModel, HttpClient embeddingHttpClient)
{
switch (embedModel.AIType)
{
@@ -85,7 +89,9 @@ namespace AntSK.Domain.Domain.Service
{
APIKey = embedModel.ModelKey,
Deployment = embedModel.ModelName.ConvertToString(),
Endpoint = embedModel.EndPoint.ConvertToString()
Endpoint = embedModel.EndPoint.ConvertToString(),
Auth = AzureOpenAIConfig.AuthTypes.APIKey,
APIType = AzureOpenAIConfig.APITypes.EmbeddingGeneration,
});
break;
case Model.Enum.AIType.LLamaSharp:
@@ -96,7 +102,7 @@ namespace AntSK.Domain.Domain.Service
}
}
private void WithTextGenerationByAIType(IKernelMemoryBuilder memory,AIModels chatModel, HttpClient chatHttpClient )
private void WithTextGenerationByAIType(IKernelMemoryBuilder memory, AIModels chatModel, HttpClient chatHttpClient)
{
switch (chatModel.AIType)
{
@@ -112,7 +118,9 @@ namespace AntSK.Domain.Domain.Service
{
APIKey = chatModel.ModelKey,
Deployment = chatModel.ModelName.ConvertToString(),
Endpoint = chatModel.EndPoint.ConvertToString()
Endpoint = chatModel.EndPoint.ConvertToString(),
Auth = AzureOpenAIConfig.AuthTypes.APIKey,
APIType = AzureOpenAIConfig.APITypes.TextCompletion,
});
break;
case Model.Enum.AIType.LLamaSharp:
@@ -124,7 +132,7 @@ namespace AntSK.Domain.Domain.Service
}
}
private void WithMemoryDbByVectorDB(IKernelMemoryBuilder memory,IConfiguration _config)
private void WithMemoryDbByVectorDB(IKernelMemoryBuilder memory, IConfiguration _config)
{
string VectorDb = _config["KernelMemory:VectorDb"].ConvertToString();
string ConnectionString = _config["KernelMemory:ConnectionString"].ConvertToString();
@@ -153,7 +161,7 @@ namespace AntSK.Domain.Domain.Service
}
}
public async Task<List<KMFile>> GetDocumentByFileID(string kmsid,string fileid)
public async Task<List<KMFile>> GetDocumentByFileID(string kmsid, string fileid)
{
var _memory = GetMemoryByKMS(kmsid);
var memories = await _memory.ListIndexesAsync();
@@ -183,6 +191,6 @@ namespace AntSK.Domain.Domain.Service
return docTextList;
}
}
}

View File

@@ -1,43 +1,44 @@
using AntSK.Domain.Common.DependencyInjection;
using AntSK.LLM.SparkDesk;
using AntSK.Domain.Common.DependencyInjection;
using AntSK.Domain.Domain.Interface;
using AntSK.Domain.Model;
using AntSK.Domain.Options;
using AntSK.Domain.Domain.Other;
using AntSK.Domain.Repositories;
using AntSK.Domain.Utils;
using DocumentFormat.OpenXml.EMMA;
using LLama;
using LLamaSharp.KernelMemory;
using LLamaSharp.SemanticKernel.TextCompletion;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.KernelMemory;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Plugins.Core;
using Microsoft.SemanticKernel.TextGeneration;
using RestSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using ServiceLifetime = AntSK.Domain.Common.DependencyInjection.ServiceLifetime;
using AntSK.LLM.Mock;
using AntSK.Domain.Domain.Model.Enum;
namespace AntSK.Domain.Domain.Service
{
[ServiceDescription(typeof(IKernelService), ServiceLifetime.Scoped)]
public class KernelService: IKernelService
public class KernelService : IKernelService
{
private readonly IApis_Repositories _apis_Repositories;
private readonly IAIModels_Repositories _aIModels_Repositories;
private readonly FunctionService _functionService;
private readonly IServiceProvider _serviceProvider;
private Kernel _kernel;
public KernelService(
IApis_Repositories apis_Repositories,
IAIModels_Repositories aIModels_Repositories
)
IAIModels_Repositories aIModels_Repositories,
FunctionService functionService,
IServiceProvider serviceProvider)
{
_apis_Repositories = apis_Repositories;
_aIModels_Repositories = aIModels_Repositories;
_functionService = functionService;
_serviceProvider = serviceProvider;
}
/// <summary>
/// 获取kernel实例依赖注入不好按每个用户去Import不同的插件所以每次new一个新的kernel
/// </summary>
@@ -46,20 +47,26 @@ namespace AntSK.Domain.Domain.Service
/// <returns></returns>
public Kernel GetKernelByApp(Apps app)
{
var chatModel= _aIModels_Repositories.GetFirst(p => p.Id == app.ChatModelID);
//if (_kernel.IsNull())
{
var chatModel = _aIModels_Repositories.GetFirst(p => p.Id == app.ChatModelID);
var chatHttpClient = OpenAIHttpClientHandlerUtil.GetHttpClient(chatModel.EndPoint);
var chatHttpClient = OpenAIHttpClientHandlerUtil.GetHttpClient(chatModel.EndPoint);
var builder = Kernel.CreateBuilder();
WithTextGenerationByAIType(builder, chatModel, chatHttpClient);
var builder = Kernel.CreateBuilder();
WithTextGenerationByAIType(builder, app, chatModel, chatHttpClient);
var kernel= builder.Build();
RegisterPluginsWithKernel(kernel);
return kernel;
_kernel = builder.Build();
RegisterPluginsWithKernel(_kernel);
return _kernel;
}
//else
//{
// return _kernel;
//}
}
private void WithTextGenerationByAIType(IKernelBuilder builder, AIModels chatModel, HttpClient chatHttpClient)
private void WithTextGenerationByAIType(IKernelBuilder builder, Apps app, AIModels chatModel, HttpClient chatHttpClient)
{
switch (chatModel.AIType)
{
@@ -69,18 +76,28 @@ namespace AntSK.Domain.Domain.Service
apiKey: chatModel.ModelKey,
httpClient: chatHttpClient);
break;
case Model.Enum.AIType.AzureOpenAI:
builder.AddAzureOpenAIChatCompletion(
deploymentName:chatModel.ModelName,
deploymentName: chatModel.ModelName,
apiKey: chatModel.ModelKey,
endpoint: chatModel.EndPoint
);
break;
case Model.Enum.AIType.LLamaSharp:
var (weights, parameters) = LLamaConfig.GetLLamaConfig(chatModel.ModelName);
var ex = new StatelessExecutor(weights, parameters);
builder.Services.AddKeyedSingleton<ITextGenerationService>("local-llama", new LLamaSharpTextCompletion(ex));
break;
case Model.Enum.AIType.SparkDesk:
var options = new SparkDeskOptions { AppId = chatModel.EndPoint, ApiSecret = chatModel.ModelKey, ApiKey = chatModel.ModelName, ModelVersion = Sdcb.SparkDesk.ModelVersion.V3_5 };
builder.Services.AddKeyedSingleton<ITextGenerationService>("spark-desk", new SparkDeskTextCompletion(options, app.Id));
break;
case Model.Enum.AIType.Mock:
builder.Services.AddKeyedSingleton<ITextGenerationService>("mock", new MockTextCompletion());
break;
}
}
@@ -91,25 +108,33 @@ namespace AntSK.Domain.Domain.Service
/// <param name="_kernel"></param>
public void ImportFunctionsByApp(Apps app, Kernel _kernel)
{
//开启自动插件调用
var apiIdList = app.ApiFunctionList.Split(",");
var apiList = _apis_Repositories.GetList(p => apiIdList.Contains(p.Id));
List<KernelFunction> functions = new List<KernelFunction>();
var plugin = _kernel.Plugins.FirstOrDefault(p => p.Name == "ApiFunctions");
//插件不能重复注册,否则会异常
if (_kernel.Plugins.Any(p => p.Name == "AntSkFunctions"))
{
return;
}
List<KernelFunction> apiFunctions = new List<KernelFunction>();
//API插件
if (!string.IsNullOrWhiteSpace(app.ApiFunctionList))
{
//开启自动插件调用
var apiIdList = app.ApiFunctionList.Split(",");
var apiList = _apis_Repositories.GetList(p => apiIdList.Contains(p.Id));
foreach (var api in apiList)
{
switch (api.Method)
{
case HttpMethodType.Get:
functions.Add(_kernel.CreateFunctionFromMethod((string msg) =>
apiFunctions.Add(_kernel.CreateFunctionFromMethod((string msg) =>
{
try
{
Console.WriteLine(msg);
RestClient client = new RestClient();
RestRequest request = new RestRequest(api.Url, Method.Get);
foreach (var header in api.Header.Split("\n"))
foreach (var header in api.Header.ConvertToString().Split("\n"))
{
var headerArray = header.Split(":");
if (headerArray.Length == 2)
@@ -118,7 +143,7 @@ namespace AntSK.Domain.Domain.Service
}
}
//这里应该还要处理一次参数提取,等后面再迭代
foreach (var query in api.Query.Split("\n"))
foreach (var query in api.Query.ConvertToString().Split("\n"))
{
var queryArray = query.Split("=");
if (queryArray.Length == 2)
@@ -135,15 +160,16 @@ namespace AntSK.Domain.Domain.Service
}
}, api.Name, $"{api.Describe}"));
break;
case HttpMethodType.Post:
functions.Add(_kernel.CreateFunctionFromMethod((string msg) =>
apiFunctions.Add(_kernel.CreateFunctionFromMethod((string msg) =>
{
try
{
Console.WriteLine(msg);
RestClient client = new RestClient();
RestRequest request = new RestRequest(api.Url, Method.Post);
foreach (var header in api.Header.Split("\n"))
foreach (var header in api.Header.ConvertToString().Split("\n"))
{
var headerArray = header.Split(":");
if (headerArray.Length == 2)
@@ -152,7 +178,7 @@ namespace AntSK.Domain.Domain.Service
}
}
//这里应该还要处理一次参数提取,等后面再迭代
request.AddJsonBody(api.JsonBody);
request.AddJsonBody(api.JsonBody.ConvertToString());
var result = client.Execute(request);
return result.Content;
}
@@ -164,19 +190,39 @@ namespace AntSK.Domain.Domain.Service
break;
}
}
_kernel.ImportPluginFromFunctions("ApiFunctions", functions);
}
//本地函数插件
if (!string.IsNullOrWhiteSpace(app.NativeFunctionList))//需要添加判断应用是否开启了本地函数插件
{
var nativeIdList = app.NativeFunctionList.Split(",");
_functionService.SearchMarkedMethods();
using var scope= _serviceProvider.CreateScope();
foreach (var func in _functionService.Functions)
{
if (nativeIdList.Contains(func.Key))
{
var methodInfo = _functionService.MethodInfos[func.Key];
var parameters = methodInfo.Parameters.Select(x => new KernelParameterMetadata(x.ParameterName) { ParameterType = x.ParameterType, Description = x.Description });
var returnType = new KernelReturnParameterMetadata() { ParameterType = methodInfo.ReturnType.ParameterType, Description = methodInfo.ReturnType.Description };
var target = ActivatorUtilities.CreateInstance(scope.ServiceProvider, func.Value.DeclaringType);
apiFunctions.Add(_kernel.CreateFunctionFromMethod(func.Value, target, func.Key, methodInfo.Description, parameters, returnType));
}
}
}
_kernel.ImportPluginFromFunctions("AntSkFunctions", apiFunctions);
}
/// <summary>
/// 注册默认插件
/// </summary>
/// <param name="kernel"></param>
void RegisterPluginsWithKernel(Kernel kernel)
private void RegisterPluginsWithKernel(Kernel kernel)
{
kernel.ImportPluginFromObject(new ConversationSummaryPlugin(), "ConversationSummaryPlugin");
kernel.ImportPluginFromObject(new TimePlugin(), "TimePlugin");
//kernel.ImportPluginFromObject(new TimePlugin(), "TimePlugin");
kernel.ImportPluginFromPromptDirectory(Path.Combine(RepoFiles.SamplePluginsPath(), "KMSPlugin"));
}
@@ -187,13 +233,13 @@ namespace AntSK.Domain.Domain.Service
/// <param name="questions"></param>
/// <param name="history"></param>
/// <returns></returns>
public async Task<string> HistorySummarize(Kernel _kernel,string questions, string history)
public async Task<string> HistorySummarize(Kernel _kernel, string questions, string history)
{
KernelFunction sunFun = _kernel.Plugins.GetFunction("ConversationSummaryPlugin", "SummarizeConversation");
var summary = await _kernel.InvokeAsync(sunFun, new() { ["input"] = $"内容是:{history.ToString()} {Environment.NewLine} 请注意用中文总结" });
string his = summary.GetValue<string>();
var msg = $"history{history.ToString()}{Environment.NewLine} user{questions}"; ;
var msg = $"history{Environment.NewLine}{history.ToString()}{Environment.NewLine} user{questions}{Environment.NewLine}"; ;
return msg;
}
}
}
}

View File

@@ -1,18 +0,0 @@
using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Map
{
public class AutoMapProfile : Profile
{
public AutoMapProfile()
{
}
}
}

View File

@@ -1,53 +0,0 @@
using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Map
{
public static class MapperExtend
{
/// <summary>
/// Entity集合转DTO集合
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static List<T> ToDTOList<T>(this object value)
{
if (value == null)
return new List<T>();
return Mapper.Map<List<T>>(value);
}
/// <summary>
/// Entity转DTO
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static T ToDTO<T>(this object value)
{
if (value == null)
return default(T);
return Mapper.Map<T>(value);
}
/// <summary>
/// 给已有对象map,适合update场景如需过滤空值需要在AutoMapProfile 设置
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="self"></param>
/// <param name="result"></param>
/// <returns></returns>
public static T MapTo<T>(this object self, T result)
{
if (self == null)
return default(T);
return (T)Mapper.Map(self, result, self.GetType(), typeof(T));
}
}
}

View File

@@ -1,35 +0,0 @@
using AutoMapper;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Map
{
public static class MapperRegister
{
public static void AddMapper(this IServiceCollection services)
{
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMissingTypeMaps = true;
cfg.ValidateInlineMaps = false;
cfg.ShouldMapMethod = m => false;
cfg.AddProfile<AutoMapProfile>();
});
IMapper mapper = config.CreateMapper();
//启动实体映射
Mapper.Initialize(cfg =>
{
cfg.CreateMissingTypeMaps = true;
cfg.ValidateInlineMaps = false;
cfg.ShouldMapMethod = m => false;
cfg.AddProfile<AutoMapProfile>();
});
}
}
}

View File

@@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Model.Enum
{
public enum ImportKmsStatus
{
Loadding=0,
Success=1,
Fail=2
}
}

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Options
namespace AntSK.Domain.Options
{
public class DBConnectionOption
{

View File

@@ -1,16 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Options
namespace AntSK.Domain.Options
{
public class KernelMemoryOption
{
/// <summary>
/// 向量库
/// </summary>
/// <summary>
/// 向量库
/// </summary>
public static string VectorDb { get; set; }
/// <summary>
/// 连接字符串

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Options
namespace AntSK.Domain.Options
{
public class LLamaSharpOption
{
@@ -12,5 +6,7 @@ namespace AntSK.Domain.Options
public static string Chat { get; set; }
public static string Embedding { get; set; }
public static string FileDirectory { get; set; } = Directory.GetCurrentDirectory();
}
}

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Options
namespace AntSK.Domain.Options
{
public class LoginOption
{

View File

@@ -1,11 +1,6 @@
using AntSK.Domain.Model;
using AntSK.Domain.Domain.Model.Enum;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Repositories
{

View File

@@ -1,11 +1,6 @@

using AntSK.Domain.Repositories.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AntSK.Domain.Common.DependencyInjection;
using AntSK.Domain.Repositories.Base;
namespace AntSK.Domain.Repositories
{

View File

@@ -1,9 +1,4 @@
using AntSK.Domain.Repositories.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Repositories
{

View File

@@ -1,10 +1,5 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Repositories
{
@@ -47,7 +42,7 @@ namespace AntSK.Domain.Repositories
/// 温度
/// </summary>
[SugarColumn(DefaultValue = "70")]
public double Temperature { get; set; }=70f;
public double Temperature { get; set; } = 70f;
/// <summary>
/// 提示词
@@ -57,8 +52,15 @@ namespace AntSK.Domain.Repositories
/// <summary>
/// 插件列表
/// </summary>
[SugarColumn(ColumnDataType = "varchar(1000)")]
public string? ApiFunctionList { get; set; }
/// <summary>
/// 本地函数列表
/// </summary>
[SugarColumn(ColumnDataType = "varchar(1000)")]
public string? NativeFunctionList { get; set; }
/// <summary>
/// 知识库ID列表

View File

@@ -1,11 +1,6 @@

using AntSK.Domain.Repositories.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AntSK.Domain.Common.DependencyInjection;
using AntSK.Domain.Repositories.Base;
namespace AntSK.Domain.Repositories
{

View File

@@ -1,9 +1,4 @@
using AntSK.Domain.Repositories.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Repositories
{

View File

@@ -1,9 +1,4 @@
using AntSK.Domain.Repositories.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Repositories
{

View File

@@ -1,10 +1,5 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Repositories
{
@@ -60,6 +55,6 @@ namespace AntSK.Domain.Repositories
[SugarColumn(DefaultValue = "49")]
public int OverlappingTokens { get; set; } = 49;
}
}

View File

@@ -1,11 +1,6 @@

using AntSK.Domain.Repositories.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AntSK.Domain.Common.DependencyInjection;
using AntSK.Domain.Repositories.Base;
namespace AntSK.Domain.Repositories
{

View File

@@ -1,9 +1,4 @@
using AntSK.Domain.Repositories.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Repositories
{

View File

@@ -1,10 +1,5 @@
using AntSK.Domain.Model.Enum;
using AntSK.Domain.Domain.Model.Enum;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Repositories
{

View File

@@ -1,11 +1,6 @@

using AntSK.Domain.Repositories.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AntSK.Domain.Common.DependencyInjection;
using AntSK.Domain.Repositories.Base;
namespace AntSK.Domain.Repositories
{

View File

@@ -1,11 +1,6 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using AntSK.Domain.Domain.Model;
using SqlSugar;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using AntSK.Domain.Model;
namespace AntSK.Domain.Repositories.Base
{

View File

@@ -1,13 +1,8 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using AntSK.Domain.Common.Map;
using AntSK.Domain.Domain.Model;
using SqlSugar;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using AntSK.Domain.Map;
using AntSK.Domain.Model;
using Microsoft.Extensions.Configuration;
namespace AntSK.Domain.Repositories.Base
@@ -15,7 +10,7 @@ namespace AntSK.Domain.Repositories.Base
public class Repository<T> : SimpleClient<T> where T : class, new()
{
public Repository( ISqlSugarClient context = null) : base(context)//注意这里要有默认值等于null
public Repository(ISqlSugarClient context = null) : base(context)//注意这里要有默认值等于null
{
if (context == null)

View File

@@ -1,13 +1,6 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AntSK.Domain.Options;
using AntSK.Domain.Utils;
using AntSK.Domain.Options;
using SqlSugar;
using System.Reflection;
using Microsoft.Extensions.Configuration;
namespace AntSK.Domain.Repositories.Base
{
@@ -17,7 +10,8 @@ namespace AntSK.Domain.Repositories.Base
/// <summary>
/// sqlserver连接
/// </summary>
public static SqlSugarScope SqlScope() {
public static SqlSugarScope SqlScope()
{
string DBType = DBConnectionOption.DbType;
string ConnectionString = DBConnectionOption.ConnectionStrings;
@@ -43,12 +37,12 @@ namespace AntSK.Domain.Repositories.Base
}
};
DbType dbType = (DbType)Enum.Parse(typeof(DbType), DBType);
config.DbType = dbType;
var scope= new SqlSugarScope(config, Db =>
config.DbType = dbType;
var scope = new SqlSugarScope(config, Db =>
{
});
return scope;
}
}
}
}

View File

@@ -1,11 +1,6 @@
using AntSK.Domain.Model.Enum;
using AntSK.Domain.Domain.Model.Enum;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Repositories
{
@@ -25,7 +20,7 @@ namespace AntSK.Domain.Repositories
/// 模型类型
/// </summary>
[Required]
public AIModelType AIModelType { get; set; }= AIModelType.Chat;
public AIModelType AIModelType { get; set; } = AIModelType.Chat;
/// <summary>
/// 模型地址
/// </summary>

View File

@@ -1,11 +1,6 @@

using AntSK.Domain.Repositories.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AntSK.Domain.Common.DependencyInjection;
using AntSK.Domain.Repositories.Base;
namespace AntSK.Domain.Repositories
{

View File

@@ -1,9 +1,4 @@
using AntSK.Domain.Repositories.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Repositories
{

View File

@@ -1,9 +1,4 @@
using AntSK.Domain.Repositories.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Repositories
{

View File

@@ -1,10 +1,5 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Repositories
{

View File

@@ -1,11 +1,6 @@

using AntSK.Domain.Repositories.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AntSK.Domain.Common.DependencyInjection;
using AntSK.Domain.Repositories.Base;
namespace AntSK.Domain.Repositories
{

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Utils
namespace AntSK.Domain.Utils
{
public static class ConvertUtils
{

View File

@@ -1,10 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace AntSK.Domain.Utils
{

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.JSInterop;
namespace AntSK.Domain.Utils
{
public static class JSUtils
{
public static async Task ScrollToBottomAsync(this IJSRuntime _JSRuntime, string elementId)
{
await _JSRuntime.InvokeVoidAsync("scrollToBottom", elementId);
}
}
}

View File

@@ -1,5 +1,4 @@
using System;
using System.Buffers.Text;
using System.Buffers.Text;
using System.Text.Json;
using System.Text.Json.Serialization;

View File

@@ -1,11 +1,4 @@
using AntSK.Domain.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
namespace AntSK.Domain.Utils
{
@@ -23,7 +16,7 @@ namespace AntSK.Domain.Utils
Regex regex = new Regex(@"(https?)://([^/:]+)(:\d+)?/(.*)");
Match match = regex.Match(_endPoint);
if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development" && request.Content != null)
{
{
string requestBody = await request.Content.ReadAsStringAsync();
//便于调试查看请求prompt
Console.WriteLine(requestBody);
@@ -47,14 +40,14 @@ namespace AntSK.Domain.Utils
{
// 这里是你要修改的 URL
Scheme = $"{xieyi}://{hostnew}/",
Host = host,
Host = host,
Path = route + "v1/chat/completions",
};
if (port.ConvertToInt32() != 0)
{
uriBuilder.Port = port.ConvertToInt32();
}
request.RequestUri = uriBuilder.Uri;
break;
@@ -83,9 +76,9 @@ namespace AntSK.Domain.Utils
}
public class OpenAIHttpClientHandlerUtil
public class OpenAIHttpClientHandlerUtil
{
public static HttpClient GetHttpClient( string endPoint)
public static HttpClient GetHttpClient(string endPoint)
{
var handler = new OpenAIHttpClientHandler(endPoint.ConvertToString());
var httpClient = new HttpClient(handler);

View File

@@ -1,6 +1,4 @@
using BCrypt.Net;
namespace AntSK.Domain.Utils
namespace AntSK.Domain.Utils
{
public class PasswordUtil
{

View File

@@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
namespace AntSK.Domain.Utils
{

View File

@@ -0,0 +1,375 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml.XPath;
namespace AntSK.Domain.Utils
{
/// <summary>
/// 注释辅助类
/// </summary>
public class XmlCommentHelper
{
private static Regex RefTagPattern = new Regex(@"<(see|paramref) (name|cref)=""([TPF]{1}:)?(?<display>.+?)"" ?/>");
private static Regex CodeTagPattern = new Regex(@"<c>(?<display>.+?)</c>");
private static Regex ParaTagPattern = new Regex(@"<para>(?<display>.+?)</para>", RegexOptions.Singleline);
List<XPathNavigator> navigators = new List<XPathNavigator>();
/// <summary>
/// 从当前dll文件中加载所有的xml文件
/// </summary>
public void LoadAll()
{
var files = Directory.GetFiles(Directory.GetCurrentDirectory());
foreach (var file in files)
{
if (string.Equals(Path.GetExtension(file), ".xml", StringComparison.OrdinalIgnoreCase))
{
Load(file);
}
}
}
/// <summary>
/// 从xml中加载
/// </summary>
/// <param name="xmls"></param>
public void LoadXml(params string[] xmls)
{
foreach (var xml in xmls)
{
Load(new MemoryStream(Encoding.UTF8.GetBytes(xml)));
}
}
/// <summary>
/// 从文件中加载
/// </summary>
/// <param name="xmlFiles"></param>
public void Load(params string[] xmlFiles)
{
foreach (var xmlFile in xmlFiles)
{
var doc = new XPathDocument(xmlFile);
navigators.Add(doc.CreateNavigator());
}
}
/// <summary>
/// 从流中加载
/// </summary>
/// <param name="streams"></param>
public void Load(params Stream[] streams)
{
foreach (var stream in streams)
{
var doc = new XPathDocument(stream);
navigators.Add(doc.CreateNavigator());
}
}
/// <summary>
/// 读取类型中的注释
/// </summary>
/// <param name="type">类型</param>
/// <param name="xPath">注释路径</param>
/// <param name="humanize">可读性优化(比如去掉xml标记)</param>
/// <returns></returns>
public string GetTypeComment(Type type, string xPath = "summary", bool humanize = true)
{
var typeMemberName = GetMemberNameForType(type);
return GetComment(typeMemberName, xPath, humanize);
}
/// <summary>
/// 读取字段或者属性的注释
/// </summary>
/// <param name="fieldOrPropertyInfo">字段或者属性</param>
/// <param name="xPath">注释路径</param>
/// <param name="humanize">可读性优化(比如去掉xml标记)</param>
/// <returns></returns>
public string GetFieldOrPropertyComment(MemberInfo fieldOrPropertyInfo, string xPath = "summary", bool humanize = true)
{
var fieldOrPropertyMemberName = GetMemberNameForFieldOrProperty(fieldOrPropertyInfo);
return GetComment(fieldOrPropertyMemberName, xPath, humanize);
}
/// <summary>
/// 读取方法中的注释
/// </summary>
/// <param name="methodInfo">方法</param>
/// <param name="xPath">注释路径</param>
/// <param name="humanize">可读性优化(比如去掉xml标记)</param>
/// <returns></returns>
public string GetMethodComment(MethodInfo methodInfo, string xPath = "summary", bool humanize = true)
{
var methodMemberName = GetMemberNameForMethod(methodInfo);
return GetComment(methodMemberName, xPath, humanize);
}
/// <summary>
/// 读取方法中的返回值注释
/// </summary>
/// <param name="methodInfo">方法</param>
/// <param name="humanize">可读性优化(比如去掉xml标记)</param>
/// <returns></returns>
public string GetMethodReturnComment(MethodInfo methodInfo, bool humanize = true)
{
return GetMethodComment(methodInfo, "returns", humanize);
}
/// <summary>
/// 读取参数的注释
/// </summary>
/// <param name="parameterInfo">参数</param>
/// <param name="humanize">可读性优化(比如去掉xml标记)</param>
/// <returns></returns>
public string GetParameterComment(ParameterInfo parameterInfo, bool humanize = true)
{
if (!(parameterInfo.Member is MethodInfo methodInfo)) return string.Empty;
var methodMemberName = GetMemberNameForMethod(methodInfo);
return GetComment(methodMemberName, $"param[@name='{parameterInfo.Name}']", humanize);
}
/// <summary>
/// 读取方法的所有参数的注释
/// </summary>
/// <param name="methodInfo">方法</param>
/// <param name="humanize">可读性优化(比如去掉xml标记)</param>
/// <returns></returns>
public Dictionary<string, string> GetParameterComments(MethodInfo methodInfo, bool humanize = true)
{
var parameterInfos = methodInfo.GetParameters();
Dictionary<string, string> dict = new Dictionary<string, string>();
foreach (var parameterInfo in parameterInfos)
{
dict[parameterInfo.Name] = GetParameterComment(parameterInfo, humanize);
}
return dict;
}
/// <summary>
/// 读取指定名称节点的注释
/// </summary>
/// <param name="name">节点名称</param>
/// <param name="xPath">注释路径</param>
/// <param name="humanize">可读性优化(比如去掉xml标记)</param>
/// <returns></returns>
public string GetComment(string name, string xPath, bool humanize = true)
{
foreach (var _xmlNavigator in navigators)
{
var typeSummaryNode = _xmlNavigator.SelectSingleNode($"/doc/members/member[@name='{name}']/{xPath.Trim('/', '\\')}");
if (typeSummaryNode != null)
{
return humanize ? Humanize(typeSummaryNode.InnerXml) : typeSummaryNode.InnerXml;
}
}
return string.Empty;
}
/// <summary>
/// 读取指定节点的summary注释
/// </summary>
/// <param name="name">节点名称</param>
/// <param name="humanize">可读性优化(比如去掉xml标记)</param>
/// <returns></returns>
public string GetSummary(string name, bool humanize = true)
{
return GetComment(name, "summary", humanize);
}
/// <summary>
/// 读取指定节点的example注释
/// </summary>
/// <param name="name">节点名称</param>
/// <param name="humanize">可读性优化(比如去掉xml标记)</param>
/// <returns></returns>
public string GetExample(string name, bool humanize = true)
{
return GetComment(name, "example", humanize);
}
/// <summary>
/// 获取方法的节点名称
/// </summary>
/// <param name="method"></param>
/// <returns></returns>
public string GetMemberNameForMethod(MethodInfo method)
{
var builder = new StringBuilder("M:");
builder.Append(QualifiedNameFor(method.DeclaringType));
builder.Append($".{method.Name}");
var parameters = method.GetParameters();
if (parameters.Any())
{
var parametersNames = parameters.Select(p =>
{
return p.ParameterType.IsGenericParameter
? $"`{p.ParameterType.GenericParameterPosition}"
: QualifiedNameFor(p.ParameterType, expandGenericArgs: true);
});
builder.Append($"({string.Join(",", parametersNames)})");
}
return builder.ToString();
}
/// <summary>
/// 获取类型的节点名称
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public string GetMemberNameForType(Type type)
{
var builder = new StringBuilder("T:");
builder.Append(QualifiedNameFor(type));
return builder.ToString();
}
/// <summary>
/// 获取字段或者属性的节点名称
/// </summary>
/// <param name="fieldOrPropertyInfo"></param>
/// <returns></returns>
public string GetMemberNameForFieldOrProperty(MemberInfo fieldOrPropertyInfo)
{
var builder = new StringBuilder((fieldOrPropertyInfo.MemberType & MemberTypes.Field) != 0 ? "F:" : "P:");
builder.Append(QualifiedNameFor(fieldOrPropertyInfo.DeclaringType));
builder.Append($".{fieldOrPropertyInfo.Name}");
return builder.ToString();
}
private string QualifiedNameFor(Type type, bool expandGenericArgs = false)
{
if (type.IsArray)
return $"{QualifiedNameFor(type.GetElementType(), expandGenericArgs)}[]";
var builder = new StringBuilder();
if (!string.IsNullOrEmpty(type.Namespace))
builder.Append($"{type.Namespace}.");
if (type.IsNested)
{
builder.Append($"{string.Join(".", GetNestedTypeNames(type))}.");
}
if (type.IsConstructedGenericType && expandGenericArgs)
{
var nameSansGenericArgs = type.Name.Split('`').First();
builder.Append(nameSansGenericArgs);
var genericArgsNames = type.GetGenericArguments().Select(t =>
{
return t.IsGenericParameter
? $"`{t.GenericParameterPosition}"
: QualifiedNameFor(t, true);
});
builder.Append($"{{{string.Join(",", genericArgsNames)}}}");
}
else
{
builder.Append(type.Name);
}
return builder.ToString();
}
private IEnumerable<string> GetNestedTypeNames(Type type)
{
if (!type.IsNested || type.DeclaringType == null) yield break;
foreach (var nestedTypeName in GetNestedTypeNames(type.DeclaringType))
{
yield return nestedTypeName;
}
yield return type.DeclaringType.Name;
}
private string Humanize(string text)
{
if (text == null)
throw new ArgumentNullException("text");
//Call DecodeXml at last to avoid entities like &lt and &gt to break valid xml
text = NormalizeIndentation(text);
text = HumanizeRefTags(text);
text = HumanizeCodeTags(text);
text = HumanizeParaTags(text);
text = DecodeXml(text);
return text;
}
private string NormalizeIndentation(string text)
{
string[] lines = text.Split('\n');
string padding = GetCommonLeadingWhitespace(lines);
int padLen = padding == null ? 0 : padding.Length;
// remove leading padding from each line
for (int i = 0, l = lines.Length; i < l; ++i)
{
string line = lines[i].TrimEnd('\r'); // remove trailing '\r'
if (padLen != 0 && line.Length >= padLen && line.Substring(0, padLen) == padding)
line = line.Substring(padLen);
lines[i] = line;
}
// remove leading empty lines, but not all leading padding
// remove all trailing whitespace, regardless
return string.Join("\r\n", lines.SkipWhile(x => string.IsNullOrWhiteSpace(x))).TrimEnd();
}
private string GetCommonLeadingWhitespace(string[] lines)
{
if (null == lines)
throw new ArgumentException("lines");
if (lines.Length == 0)
return null;
string[] nonEmptyLines = lines
.Where(x => !string.IsNullOrWhiteSpace(x))
.ToArray();
if (nonEmptyLines.Length < 1)
return null;
int padLen = 0;
// use the first line as a seed, and see what is shared over all nonEmptyLines
string seed = nonEmptyLines[0];
for (int i = 0, l = seed.Length; i < l; ++i)
{
if (!char.IsWhiteSpace(seed, i))
break;
if (nonEmptyLines.Any(line => line[i] != seed[i]))
break;
++padLen;
}
if (padLen > 0)
return seed.Substring(0, padLen);
return null;
}
private string HumanizeRefTags(string text)
{
return RefTagPattern.Replace(text, (match) => match.Groups["display"].Value);
}
private string HumanizeCodeTags(string text)
{
return CodeTagPattern.Replace(text, (match) => "{" + match.Groups["display"].Value + "}");
}
private string HumanizeParaTags(string text)
{
return ParaTagPattern.Replace(text, (match) => "<br>" + match.Groups["display"].Value);
}
private string DecodeXml(string text)
{
return System.Net.WebUtility.HtmlDecode(text);
}
}
}

View File

@@ -18,6 +18,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MiddleWare", "MiddleWare",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AntSK.BackgroundTask", "MiddleWare\AntSK.BackgroundTask\AntSK.BackgroundTask.csproj", "{DF87E829-99C5-44A7-9718-B3E67DC801F6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AntSK.LLM", "AntSk.LLM\AntSK.LLM.csproj", "{19529BFA-152F-4A8C-8254-F2D4896AB739}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -36,6 +38,10 @@ Global
{DF87E829-99C5-44A7-9718-B3E67DC801F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DF87E829-99C5-44A7-9718-B3E67DC801F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DF87E829-99C5-44A7-9718-B3E67DC801F6}.Release|Any CPU.Build.0 = Release|Any CPU
{19529BFA-152F-4A8C-8254-F2D4896AB739}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19529BFA-152F-4A8C-8254-F2D4896AB739}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19529BFA-152F-4A8C-8254-F2D4896AB739}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19529BFA-152F-4A8C-8254-F2D4896AB739}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -8,13 +8,14 @@
<NoWarn>CA1050,CA1707,CA2007,VSTHRD111,CS1591,RCS1110,CA5394,SKEXP0001,SKEXP0002,SKEXP0003,SKEXP0004,SKEXP0010,SKEXP0011,,SKEXP0012,SKEXP0020,SKEXP0021,SKEXP0022,SKEXP0023,SKEXP0024,SKEXP0025,SKEXP0026,SKEXP0027,SKEXP0028,SKEXP0029,SKEXP0030,SKEXP0031,SKEXP0032,SKEXP0040,SKEXP0041,SKEXP0042,SKEXP0050,SKEXP0051,SKEXP0052,SKEXP0053,SKEXP0054,SKEXP0055,SKEXP0060,SKEXP0061,SKEXP0101,SKEXP0102</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AntDesign.Charts" Version="0.5.1" />
<PackageReference Include="AntDesign.ProLayout" Version="0.17.3" />
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="8.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="8.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="8.0.2" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="System.Net.Http.Json" Version="8.0.0" />
<PackageReference Include="Downloader" Version="3.0.6" />
</ItemGroup>
<ItemGroup>

View File

@@ -1,148 +0,0 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>AntSK</name>
</assembly>
<members>
<member name="M:AntSK.Controllers.FileController.UploadFile(Microsoft.AspNetCore.Http.IFormFile)">
<summary>
Upload FileName
</summary>
<returns></returns>
</member>
<member name="M:AntSK.Controllers.InitController.InitTable">
<summary>
初始化DB 和表
</summary>
<returns></returns>
</member>
<member name="T:AntSK.Controllers.KMSController">
<summary>
</summary>
<param name="_taskBroker"></param>
</member>
<member name="M:AntSK.Controllers.LLamaSharpController.chat(AntSK.Models.OpenAIModel)">
<summary>
本地会话接口
</summary>
<returns></returns>
</member>
<member name="M:AntSK.Controllers.LLamaSharpController.embedding(AntSK.Models.OpenAIEmbeddingModel)">
<summary>
本地嵌入接口
</summary>
<param name="model"></param>
<returns></returns>
</member>
<member name="T:AntSK.Controllers.OpenController">
<summary>
对外接口
</summary>
</member>
<member name="M:AntSK.Controllers.OpenController.#ctor(AntSK.Services.OpenApi.IOpenApiService)">
<summary>
对外接口
</summary>
</member>
<member name="M:AntSK.Controllers.OpenController.chat(AntSK.Models.OpenAIModel)">
<summary>
对话接口
</summary>
<returns></returns>
</member>
<member name="M:AntSK.Pages.ChatPage.Chat.SendKms(System.String,System.String,AntSK.Domain.Repositories.Apps)">
<summary>
发送知识库问答
</summary>
<param name="questions"></param>
<param name="msg"></param>
<param name="app"></param>
<returns></returns>
</member>
<member name="M:AntSK.Pages.ChatPage.Chat.SendChat(System.String,System.String,AntSK.Domain.Repositories.Apps)">
<summary>
发送普通对话
</summary>
<param name="questions"></param>
<param name="msg"></param>
<param name="app"></param>
<returns></returns>
</member>
<member name="M:AntSK.Pages.ChatPage.Chat.HistorySummarize(AntSK.Domain.Repositories.Apps,System.String)">
<summary>
历史会话的会话总结
</summary>
<param name="questions"></param>
<returns></returns>
</member>
<member name="M:AntSK.Pages.ChatPage.OpenChat.SendKms(System.String,System.String,AntSK.Domain.Repositories.Apps)">
<summary>
发送知识库问答
</summary>
<param name="questions"></param>
<param name="msg"></param>
<param name="app"></param>
<returns></returns>
</member>
<member name="M:AntSK.Pages.ChatPage.OpenChat.SendChat(System.String,System.String,AntSK.Domain.Repositories.Apps)">
<summary>
发送普通对话
</summary>
<param name="questions"></param>
<param name="msg"></param>
<param name="app"></param>
<returns></returns>
</member>
<member name="M:AntSK.Pages.ChatPage.OpenChat.HistorySummarize(AntSK.Domain.Repositories.Apps,System.String)">
<summary>
历史会话的会话总结
</summary>
<param name="questions"></param>
<returns></returns>
</member>
<member name="T:AntSK.Pages.KmsPage.KmsDetail.UrlModel">
<summary>
根据文档ID获取文档
</summary>
<param name="fileid"></param>
<returns></returns>
</member>
<member name="T:AntSK.Services.LLamaSharp.LLamaChatService">
<summary>
</summary>
</member>
<member name="T:AntSK.Services.LLamaSharp.LLamaEmbeddingService">
<summary>
本地Embedding
</summary>
</member>
<member name="M:AntSK.Services.OpenApi.OpenApiService.SendChat(System.String,AntSK.Domain.Repositories.Apps)">
<summary>
发送普通对话
</summary>
<param name="questions"></param>
<param name="msg"></param>
<param name="app"></param>
<returns></returns>
</member>
<member name="M:AntSK.Services.OpenApi.OpenApiService.SendKms(System.String,AntSK.Domain.Repositories.Apps)">
<summary>
发送知识库问答
</summary>
<param name="questions"></param>
<param name="msg"></param>
<param name="app"></param>
<returns></returns>
</member>
<member name="M:AntSK.Services.OpenApi.OpenApiService.HistorySummarize(AntSK.Domain.Repositories.Apps,AntSK.Models.OpenAIModel)">
<summary>
历史会话的会话总结
</summary>
<param name="questions"></param>
<param name="msg"></param>
<returns></returns>
</member>
</members>
</doc>

View File

@@ -1,16 +1,24 @@
@inject NavigationManager NavigationManager
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Authorization
<CascadingAuthenticationState>
<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
<CascadingValue Value="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(BasicLayout)" />
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(BasicLayout)" >
<NotAuthorized>
您没有权限访问此页面
</NotAuthorized>
<Authorizing>
<RouteView RouteData="@routeData" DefaultLayout="@typeof(BasicLayout)" />
</Authorizing>
</AuthorizeRouteView>
</CascadingValue>
</Found>
<NotFound>
<LayoutView Layout="@typeof(BasicLayout)">
<AntSK.Pages.Exception._404/>
<AntSK.Pages.Exception._404 />
</LayoutView>
</NotFound>
</Router>
<AntContainer />

View File

@@ -0,0 +1,26 @@
@namespace AntSK.Components
@inherits AntDomComponentBase
<Card>
<div class="chartCard">
<div class="chartTop">
<div class="avatar">@Avatar</div>
<div class="metaWrap">
<div class="meta">
<span>@Title</span>
<span class="action"><Icon Type="@Icon" /></span>
</div>
<div class="total">
<span>@Total</span>
</div>
</div>
</div>
<div class="content" style="height: @(string.IsNullOrEmpty(ContentHeight) ? "auto" : ContentHeight+"px")">
<div class="@(string.IsNullOrEmpty(ContentHeight) ? "" : "contentFixed")">@ChildContent</div>
</div>
<div class="footer">
@Footer
</div>
</div>
</Card>

View File

@@ -0,0 +1,31 @@
using Microsoft.AspNetCore.Components;
namespace AntSK.Components
{
public partial class ChartCard
{
[Parameter]
public string Avatar { get; set; }
[Parameter]
public string Title { get; set; }
[Parameter]
public RenderFragment Action { get; set; }
[Parameter]
public string Total { get; set; }
[Parameter]
public RenderFragment ChildContent { get; set; }
[Parameter]
public RenderFragment Footer { get; set; }
[Parameter]
public string ContentHeight { get; set; }
[Parameter]
public string Icon { get; set; }
}
}

View File

@@ -0,0 +1,77 @@
/* stylelint-disable at-rule-empty-line-before,at-rule-name-space-after,at-rule-no-unknown */
/* stylelint-disable no-duplicate-selectors */
/* stylelint-disable */
/* stylelint-disable declaration-bang-space-before,no-duplicate-selectors,string-no-newline */
.chartCard {
position: relative;
}
.chartCard .chartTop {
position: relative;
width: 100%;
overflow: hidden;
}
.chartCard .chartTopMargin {
margin-bottom: 12px;
}
.chartCard .chartTopHasMargin {
margin-bottom: 20px;
}
.chartCard .metaWrap {
float: left;
}
.chartCard .avatar {
position: relative;
top: 4px;
float: left;
margin-right: 20px;
}
.chartCard .avatar img {
border-radius: 100%;
}
.chartCard .meta {
height: 22px;
color: rgba(0, 0, 0, 0.45);
font-size: 14px;
line-height: 22px;
}
.chartCard .action {
position: absolute;
top: 4px;
right: 0;
line-height: 1;
cursor: pointer;
}
.chartCard .total {
height: 38px;
margin-top: 4px;
margin-bottom: 0;
overflow: hidden;
color: rgba(0, 0, 0, 0.85);
font-size: 30px;
line-height: 38px;
white-space: nowrap;
text-overflow: ellipsis;
word-break: break-all;
}
.chartCard .content {
position: relative;
width: 100%;
margin-bottom: 12px;
}
.chartCard .contentFixed {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
}
.chartCard .footer {
margin-top: 8px;
padding-top: 9px;
border-top: 1px solid #f0f0f0;
}
.chartCard .footer > * {
position: relative;
}
.chartCard .footerMargin {
margin-top: 20px;
}

View File

@@ -3,7 +3,8 @@
@inherits AntDomComponentBase
<Space Class="@ClassMapper.Class" Size="@("26")">
<SpaceItem>
<Image Src="http://img.shields.io/github/stars/aidotnet/antsk?style=social" Width="88px" Height="20px;"></Image>
<SpaceItem Style="margin-left:20px;">
<AvatarDropdown Name="@context.Identity.Name"
Avatar="@_currentUser.Avatar"
MenuItems="@AvatarMenuItems"

View File

@@ -1,15 +1,12 @@
using AntDesign;
using AntDesign.ProLayout;
using Microsoft.AspNetCore.Components;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AntSK.Domain.Options;
using AntSK.Models;
using AntSK.Services;
using AntSK.Services.Auth;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using System.Security.Claims;
using AntSK.Services.Auth;
using AntSK.Domain.Options;
namespace AntSK.Components
{
@@ -56,7 +53,7 @@ namespace AntSK.Components
[Inject] public AuthenticationStateProvider AuthenticationStateProvider { get; set; }
[Inject] protected MessageService? Message { get; set; }
private ClaimsPrincipal context => ((AntSKAuthProvider)AuthenticationStateProvider).GetCurrentUser();
private ClaimsPrincipal context => ((AntSKAuthProvider)AuthenticationStateProvider).GetCurrentUser();
protected override async Task OnInitializedAsync()
{
@@ -86,7 +83,7 @@ namespace AntSK.Components
{
NavigationManager.NavigateTo("/setting/user/info/" + context.Identity.Name);
}
else
else
{
_ = Message.Info("管理员无需设置", 2);
}

View File

@@ -1,7 +1,4 @@
using AntDesign;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Net.NetworkInformation;
using Microsoft.AspNetCore.Mvc;
namespace AntSK.Controllers
{
@@ -32,10 +29,10 @@ namespace AntSK.Controllers
}
string extension = Path.GetExtension(file.FileName);
string fileid=Guid.NewGuid().ToString();
string fileid = Guid.NewGuid().ToString();
// 组合目标路径
var uploads = Path.Combine(uploadsFolderPath, fileid+extension);
var uploads = Path.Combine(uploadsFolderPath, fileid + extension);
// 保存文件至目标路径
using var fileStream = System.IO.File.Create(uploads);
using var uploadStream = file.OpenReadStream();

View File

@@ -1,6 +1,5 @@
using Microsoft.AspNetCore.Http;
using AntSK.Domain.Repositories;
using Microsoft.AspNetCore.Mvc;
using AntSK.Domain.Repositories;
namespace AntSK.Controllers
{

View File

@@ -1,14 +1,10 @@
using AntSK.Domain.Model;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using static AntSK.Pages.KmsPage.KmsDetail;
using System;
using AntSK.Domain.Repositories;
using AntSK.BackgroundTask;
using AntSK.Domain.Common.Map;
using AntSK.Domain.Domain.Interface;
using Microsoft.KernelMemory.Configuration;
using AntSK.Domain.Model.Enum;
using AntSK.Domain.Map;
using AntSK.BackgroundTask;
using AntSK.Domain.Domain.Model;
using AntSK.Domain.Domain.Model.Enum;
using AntSK.Domain.Repositories;
using Microsoft.AspNetCore.Mvc;
namespace AntSK.Controllers
{
@@ -27,14 +23,14 @@ namespace AntSK.Controllers
IKmsDetails_Repositories kmsDetails_Repositories,
IKMService iKMService,
BackgroundTaskBroker<ImportKMSTaskReq> taskBroker
)
)
{
_kmsDetails_Repositories = kmsDetails_Repositories;
_iKMService = iKMService;
_taskBroker = taskBroker;
}
[HttpPost]
public async Task<IActionResult> ImportKMSTask(ImportKMSTaskDTO model)
public async Task<IActionResult> ImportKMSTask(ImportKMSTaskDTO model)
{
Console.WriteLine("api/kms/ImportKMSTask 开始");
ImportKMSTaskReq req = model.ToDTO<ImportKMSTaskReq>();

View File

@@ -1,8 +1,6 @@
using AntSK.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using AntSK.Domain.Utils;
using AntSK.Domain.Domain.Model.Dto.OpenAPI;
using AntSK.Services.LLamaSharp;
using Microsoft.AspNetCore.Mvc;
namespace AntSK.Controllers
{
@@ -39,7 +37,7 @@ namespace AntSK.Controllers
public async Task embedding(OpenAIEmbeddingModel model)
{
Console.WriteLine("开始llama/v1/embeddings");
await _lLamaSharpService.Embedding(model,HttpContext);
await _lLamaSharpService.Embedding(model, HttpContext);
Console.WriteLine("结束llama/v1/embeddings");
}

View File

@@ -1,10 +1,6 @@
using AntSK.Domain.Model;
using AntSK.Domain.Repositories;
using AntSK.Domain.Domain.Model.Dto.OpenAPI;
using AntSK.Domain.Utils;
using AntSK.Models;
using AntSK.Models.OpenAPI;
using AntSK.Services.OpenApi;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace AntSK.Controllers
@@ -25,7 +21,7 @@ namespace AntSK.Controllers
public async Task chat(OpenAIModel model)
{
string sk = HttpContext.Request.Headers["Authorization"].ConvertToString();
await _openApiService.Chat(model,sk, HttpContext);
await _openApiService.Chat(model, sk, HttpContext);
}
}
}

View File

@@ -1,6 +1,4 @@
using System;
namespace AntSK
namespace AntSK
{
public static class DateTimeExtension
{

View File

@@ -5,16 +5,25 @@
@using AntSK.Domain.Options
@using AntSK.Domain.Repositories
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@inject INotificationService _notice
@inherits LayoutComponentBase
<AntDesign.ProLayout.BasicLayout
Logo="@("https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg")"
MenuData="_menuData">
<AntDesign.ProLayout.BasicLayout Logo="@("https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg")"
MenuData="_menuData">
<RightContentRender>
<AntSK.Components.RightContent />
</RightContentRender>
<ChildContent>
@Body
<ErrorBoundary @ref="errorBoundary">
<ChildContent>
@Body
</ChildContent>
<ErrorContent Context="ex">
@{
ShowNotification(ex);
}
</ErrorContent>
</ErrorBoundary>
</ChildContent>
<FooterRender>
<FooterView Copyright="2024 许泽宇的技术分享" Links="Links"></FooterView>
@@ -24,6 +33,7 @@
@code
{
ErrorBoundary errorBoundary;
private MenuDataItem[] _menuData = { };
[Inject] public HttpClient HttpClient { get; set; }
@@ -36,7 +46,7 @@
{
await base.OnInitializedAsync();
//菜单权限控制
var menuList = await HttpClient.GetFromJsonAsync<MenuDataItem[]>("data/menu.json");
var menuList = await HttpClient.GetFromJsonAsync<MenuDataItem[]>("data/menu.json");
var userSessionStorageResult = await _protectedSessionStore.GetAsync<UserSession>("UserSession");
var userSession = userSessionStorageResult.Success ? userSessionStorageResult.Value : null;
@@ -54,7 +64,7 @@
}
if (username == LoginOption.User )
if (username == LoginOption.User)
{
_menuData = menuList;
}
@@ -68,6 +78,17 @@
}
void ShowNotification(Exception ex)
{
_ = _notice.Error(new()
{
Message = ex.Message,
Description = ex.StackTrace
});
errorBoundary.Recover();
}
public LinkItem[] Links { get; set; } =
{
new LinkItem
@@ -81,9 +102,9 @@
{
Key = "github",
Title = (RenderFragment)(@<Icon Type="github" />),
Href = "https://github.com/xuzeyu91/Xzy.AntSK.KnowledgeBase",
Href = "https://github.com/AIDotNet/AntSK",
BlankTarget = true,
}
};
}

View File

@@ -1,6 +1,7 @@
@namespace AntSK
@inherits LayoutComponentBase
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
@Body
@code {

View File

@@ -36,7 +36,7 @@
{
Key = "github",
Title = (RenderFragment)(@<Icon Type="github" />),
Href = "https://github.com/xuzeyu91/Xzy.AntSK.KnowledgeBase",
Href = "https://github.com/AIDotNet/AntSK",
BlankTarget = true,
}
};

View File

@@ -0,0 +1,8 @@
namespace AntSK.Models
{
public class FileInfoModel
{
public string FileName { get; set; }
public string FilePath { get; set; }
}
}

Some files were not shown because too many files have changed in this diff Show More