Compare commits
125 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e84b05a39b | ||
|
|
631c563e71 | ||
|
|
47b304e46f | ||
|
|
27ccfc5e88 | ||
|
|
69441167d3 | ||
|
|
4b97594217 | ||
|
|
9ee601f88c | ||
|
|
75b1a299e3 | ||
|
|
2613c463a1 | ||
|
|
78e0350d36 | ||
|
|
bc2425fc3f | ||
|
|
3e861bc72f | ||
|
|
b41c464753 | ||
|
|
2817275091 | ||
|
|
e76b0cf326 | ||
|
|
cf34103e15 | ||
|
|
1588fd7d7a | ||
|
|
4507ccde6c | ||
|
|
73fffd766f | ||
|
|
e529146c5b | ||
|
|
7050e52009 | ||
|
|
4f3238c4f6 | ||
|
|
b7d27c5d50 | ||
|
|
fe94aa0564 | ||
|
|
ae60a9aced | ||
|
|
4f686b0871 | ||
|
|
c61840b7e8 | ||
|
|
9adce95367 | ||
|
|
eef943458e | ||
|
|
f5c80689d4 | ||
|
|
5eaee3130a | ||
|
|
5846473f28 | ||
|
|
94c019b484 | ||
|
|
7e1140c022 | ||
|
|
ea9044719a | ||
|
|
8a96095448 | ||
|
|
fcc8f8751b | ||
|
|
af09ae7c3e | ||
|
|
e8e6a36d7b | ||
|
|
4f89d54ef0 | ||
|
|
2f9e2fb114 | ||
|
|
b6098024b8 | ||
|
|
1700131066 | ||
|
|
189536471a | ||
|
|
f534e0bcc3 | ||
|
|
e203a18e92 | ||
|
|
575a69bf4d | ||
|
|
69fd3a0367 | ||
|
|
8f7e70298e | ||
|
|
0fa3f5a554 | ||
|
|
f420012752 | ||
|
|
c1ca916549 | ||
|
|
dfcf2bdc85 | ||
|
|
72e7acfb7d | ||
|
|
9d06c127dc | ||
|
|
0460b388ab | ||
|
|
45b84ae898 | ||
|
|
41b1cb6f2d | ||
|
|
159aaab38e | ||
|
|
dc351238f6 | ||
|
|
e6491b39c6 | ||
|
|
91b4ed8940 | ||
|
|
ab99098afd | ||
|
|
d14ce2faa0 | ||
|
|
ca293691a8 | ||
|
|
cf8955b9b6 | ||
|
|
512828fdc9 | ||
|
|
91299a96e7 | ||
|
|
4876d9e727 | ||
|
|
a856f2a0e3 | ||
|
|
0e8113e7b0 | ||
|
|
34a953589d | ||
|
|
504ea5a238 | ||
|
|
3b5997fce6 | ||
|
|
7b0f6c3e75 | ||
|
|
099b85619c | ||
|
|
0129cd3f39 | ||
|
|
84f3cbf9a9 | ||
|
|
a7af462a44 | ||
|
|
fdca08eb3d | ||
|
|
c3eeefe9fe | ||
|
|
2f6990320c | ||
|
|
ef83450425 | ||
|
|
f2f10ec9f4 | ||
|
|
7346ff2e78 | ||
|
|
1dc274ce82 | ||
|
|
2be438f9c3 | ||
|
|
1f7f51ff1e | ||
|
|
338a7ae083 | ||
|
|
04d7896a92 | ||
|
|
4b8c8c0f96 | ||
|
|
8296476d94 | ||
|
|
38b3fc26ed | ||
|
|
6852b458fa | ||
|
|
cdb41023d4 | ||
|
|
8e00e681f0 | ||
|
|
577d6dd3a6 | ||
|
|
eeecd15d9e | ||
|
|
e39b26bcc3 | ||
|
|
6b5a77f8c1 | ||
|
|
0dc9736c35 | ||
|
|
bbe2471815 | ||
|
|
bee2c56382 | ||
|
|
b05a4f51b7 | ||
|
|
608794b600 | ||
|
|
ce8829ae69 | ||
|
|
1fb27f8d5a | ||
|
|
caf8777290 | ||
|
|
7dacdab2b5 | ||
|
|
f6a8660144 | ||
|
|
1e51631eba | ||
|
|
91048dc9c1 | ||
|
|
9f8dc39e2f | ||
|
|
07aa8f4829 | ||
|
|
b504615b6d | ||
|
|
3b1811a5ff | ||
|
|
71be6d4a5a | ||
|
|
ae04d20a82 | ||
|
|
2ad3953d3f | ||
|
|
c536f1d74b | ||
|
|
d8c1695ac9 | ||
|
|
b39912d08b | ||
|
|
8f5dd08836 | ||
|
|
6a27e61321 | ||
|
|
34fa19cf1e |
2
.gitignore
vendored
@@ -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
|
||||
|
||||
@@ -7,7 +7,7 @@ COPY ["src/AntSK/AntSK.csproj", "AntSK/"]
|
||||
RUN dotnet restore "AntSK/AntSK.csproj"
|
||||
|
||||
# Copy everything else and build
|
||||
COPY . .
|
||||
COPY src/ .
|
||||
WORKDIR "/src/AntSK"
|
||||
RUN dotnet build "AntSK.csproj" -c Release -o /app/build
|
||||
RUN dotnet publish "AntSK.csproj" -c Release -o /app/publish
|
||||
|
||||
108
README.en.md
@@ -123,58 +123,76 @@ The model supports openai by default. If you need to use azure openai and need t
|
||||
|
||||
The following configuration files need to be configured
|
||||
|
||||
## Using Docker Compose
|
||||
Provided pg version appsettings. json and simplified version (Sqlite+disk) Docker Compose. simple. yml
|
||||
Download Docker Compose.yml from the project root directory, and then place the configuration file appsettings.json and it in a unified directory,
|
||||
The image of PG has been prepared here. You can modify the default account password in Docker Compose.yml, and your appsettings. json database connection needs to be consistent.
|
||||
Then you can enter the directory and execute it
|
||||
```
|
||||
docker compose up - d
|
||||
```
|
||||
To start AntSK
|
||||
|
||||
Some meanings of configuration files
|
||||
|
||||
```
|
||||
|
||||
"ConnectionStrings":{
|
||||
|
||||
"Postgres": "Host=; Port=; Database=antsk; Username=; Password="
|
||||
|
||||
},
|
||||
|
||||
"OpenAIOption":{
|
||||
|
||||
"EndPoint": "",
|
||||
|
||||
"Key": "",
|
||||
|
||||
"Model": "",
|
||||
|
||||
"Embedding Model": """""
|
||||
|
||||
},
|
||||
|
||||
Postgres:{
|
||||
|
||||
"ConnectionString": "Host=; Port=; Database=antsk; Username=; Password=",
|
||||
|
||||
"TableNamePrefix": "km -"
|
||||
|
||||
},
|
||||
"Login": {
|
||||
"User": "admin",
|
||||
"Password": "xuzeyu"
|
||||
{
|
||||
"DBConnection": {
|
||||
"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=",
|
||||
"TableNamePrefix": "km-"
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"Login": {
|
||||
"User": "admin",
|
||||
"Password": "xuzeyu"
|
||||
},
|
||||
"BackgroundTaskBroker": {
|
||||
"ImportKMSTask": {
|
||||
"WorkerCount": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
I use CodeFirst mode. As long as the database link is configured, the table structure is automatically created
|
||||
```
|
||||
//Supports multiple databases, including SqlSugar, MySql, SqlServer, Sqlite, Oracle, PostgreSQL, Dm, Kdbndp, Oscar, MySqlConnector, Access, OpenGaussian, QuestDB, HG, ClickHouse, GBase, Odbc, OceanBaseForOracle, TDengine, GaussDB, OceanBase, Tidb, Vastbase, PolarDB, Custom
|
||||
DBConnection DbType
|
||||
//Connection string, corresponding strings need to be used according to different DB types
|
||||
DBConnection ConnectionStrings
|
||||
//You can use an online API that conforms to the OpenAI format (domestic models use one API adapter), or you can use AntSK's built-in llama API, with the IP and port being the AntSK startup address
|
||||
OpenAIOption EndPoint
|
||||
//Model key, if using a local model, it can default to Notnull. Chinese cannot be used here
|
||||
OpenAIOption Key
|
||||
//The type of vector storage supports Postgres Disk Memory, where Postgres requires the configuration of ConnectionString
|
||||
KernelMemory VectorDb
|
||||
//The running mode used by the local model is GUP CPU. If using an online API, you can freely use one
|
||||
LLamaSharp RunType
|
||||
//The model path of the local session model should pay attention to distinguishing between Linux and Windows drive letters
|
||||
LLamaSharp Chat
|
||||
//The model path of the local vector model should pay attention to distinguishing between Linux and Windows drive letters
|
||||
LLamaSharp Embedding
|
||||
//Default administrator account password
|
||||
Login
|
||||
//The number of threads for importing asynchronous processing can be higher when using online APIs. Local models suggest 1, otherwise memory overflow and crash may occur
|
||||
BackgroundTaskBroker ImportKMSTask WorkerCount
|
||||
|
||||
If you want to use LLamaSharp to run the local model, you also need to set the following configuration:
|
||||
```
|
||||
"LLamaSharp": {
|
||||
"Chat": "D:\\Code\\AI\\AntBlazor\\model\\tinyllama-1.1b-chat.gguf",
|
||||
"Embedding": "D:\\Code\\AI\\AntBlazor\\model\\tinyllama-1.1b-chat.gguf"
|
||||
},
|
||||
```
|
||||
|
||||
You need to configure the addresses of the Chat and Embedding models, and then modify EndPoint to local. When using the local model, parameters such as Key, Model, and Embedding Model are not used, so you can freely fill in these parameters:
|
||||
```
|
||||
"OpenAIOption": {
|
||||
"EndPoint": "https://ip:port/llama/",
|
||||
"Key": "",
|
||||
"Model": "",
|
||||
"EmbeddingModel": ""
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
|
||||
127
README.md
@@ -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,17 +67,19 @@ AntSK 适用于多种业务场景,例如:
|
||||
|
||||
在这里我使用的是Postgres 作为数据存储和向量存储,因为Semantic Kernel和Kernel Memory都支持他,当然你也可以换成其他的。
|
||||
|
||||
模型默认支持openai,如果需要使用azure openai需要调整SK的依赖注入,也可以使用one-api进行集成。
|
||||
模型默认支持openai、azure openai 和llama支持的gguf本地模型,如果需要使用其他模型,可以使用one-api进行集成。
|
||||
|
||||
Login是默认的登陆账号和密码
|
||||
配置文件中的Login配置是默认的登陆账号和密码
|
||||
|
||||
需要配置如下的配置文件
|
||||
|
||||
## 使用docker-compose
|
||||
|
||||
从项目根目录下载docker-compose.yml,然后把配置文件appsettings.json和它放在统一目录,
|
||||
提供了pg版本 **appsettings.json** 和 简化版本(Sqlite+disk) **docker-compose.simple.yml**
|
||||
|
||||
这里已经把pg的镜像做好了。在docker-compose.yml中可以修改默认账号密码,然后你的appsettings.json的数据库连接需要保持一致。
|
||||
从项目根目录下载**docker-compose.yml**,然后把配置文件**appsettings.json**和它放在统一目录,
|
||||
|
||||
这里已经把pg的镜像做好了。在docker-compose.yml中可以修改默认账号密码,然后你的**appsettings.json**的数据库连接需要保持一致。
|
||||
|
||||
然后你可以进入到目录后执行
|
||||
```
|
||||
@@ -81,46 +87,102 @@ docker-compose up -d
|
||||
```
|
||||
来启动AntSK
|
||||
|
||||
## 如何在docker中挂载本地模型,和模型下载的目录
|
||||
```
|
||||
# 非 host 版本, 不使用本机代理
|
||||
version: '3.8'
|
||||
services:
|
||||
antsk:
|
||||
container_name: antsk
|
||||
image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.1.5
|
||||
ports:
|
||||
- 5000:5000
|
||||
networks:
|
||||
- antsk
|
||||
depends_on:
|
||||
- antskpg
|
||||
restart: always
|
||||
environment:
|
||||
- ASPNETCORE_URLS=http://*:5000
|
||||
volumes:
|
||||
- ./appsettings.json:/app/appsettings.json # 本地配置文件 需要放在同级目录
|
||||
- D://model:/app/model
|
||||
networks:
|
||||
antsk:
|
||||
```
|
||||
以这个为示例,意思是把windows本地D://model的文件夹挂载进 容器内/app/model 如果是这样你的appsettings.json中的模型地址应该配置为
|
||||
```
|
||||
model/xxx.gguf
|
||||
```
|
||||
|
||||
## 配置文件的一些含义
|
||||
```
|
||||
"ConnectionStrings": {
|
||||
"Postgres": "Host=;Port=;Database=antsk;Username=;Password="//这个是业务数据的连接字符串
|
||||
{
|
||||
"DBConnection": {
|
||||
"DbType": "Sqlite",
|
||||
"ConnectionStrings": "Data Source=AntSK.db;"
|
||||
},
|
||||
"OpenAIOption": {
|
||||
"EndPoint": "", //openai协议的接口,写到v1之前
|
||||
"Key": "",//接口秘钥,如果使用本地模型可以随意填写一个但不能为空
|
||||
"Model": "",//会话模型,使用接口时需要,使用本地模型可以随意填写
|
||||
"EmbeddingModel": ""//向量模型,使用接口时需要,使用本地模型可以随意填写
|
||||
},
|
||||
"Postgres": {
|
||||
"KernelMemory": {
|
||||
"VectorDb": "Disk",
|
||||
"ConnectionString": "Host=;Port=;Database=antsk;Username=;Password=",
|
||||
"TableNamePrefix": "km-"
|
||||
},
|
||||
"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",
|
||||
"FileDirectory": "D:\\Code\\AI\\AntBlazor\\model\\"
|
||||
},
|
||||
"Login": {
|
||||
"User": "admin",
|
||||
"Password": "xuzeyu"
|
||||
},
|
||||
"BackgroundTaskBroker": {
|
||||
"ImportKMSTask": {
|
||||
"WorkerCount": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
我使用的是CodeFirst模式,只要配置好数据库链接,表结构是自动创建的
|
||||
```
|
||||
//支持多种数据库,具体可以查看SqlSugar,MySql,SqlServer,Sqlite,Oracle,PostgreSQL,Dm,Kdbndp,Oscar,MySqlConnector,Access,OpenGauss,QuestDB,HG,ClickHouse,GBase,Odbc,OceanBaseForOracle,TDengine,GaussDB,OceanBase,Tidb,Vastbase,PolarDB,Custom
|
||||
DBConnection.DbType
|
||||
//连接字符串,需要根据不同DB类型,用对应的字符串
|
||||
DBConnection.ConnectionStrings
|
||||
|
||||
如果想使用LLamaSharp运行本地模型还需要设置如下配置:
|
||||
```
|
||||
"LLamaSharp": {
|
||||
"Chat": "D:\\Code\\AI\\AntBlazor\\model\\tinyllama-1.1b-chat.gguf",//本地会话模型的磁盘路径
|
||||
"Embedding": "D:\\Code\\AI\\AntBlazor\\model\\tinyllama-1.1b-chat.gguf"//本地向量模型的磁盘路径
|
||||
},
|
||||
//向量存储的类型,支持 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 否则容易内存溢出崩掉
|
||||
BackgroundTaskBroker.ImportKMSTask.WorkerCount
|
||||
```
|
||||
|
||||
需要配置Chat和Embedding模型的地址,然后修改EndPoint为本地,使用本地模型时并没有用到Key、Model、EmbeddingModel这些参数,所以这几个你可以随意填写:
|
||||
## 找不到样式问题解决:
|
||||
AntSK/src/AntSK下执行:
|
||||
```
|
||||
"OpenAIOption": {
|
||||
"EndPoint": "http://ip:port/llama/",//如果使用本地模型这个ip端口是AntSK服务启动的ip和端口
|
||||
"Key": "",//接口秘钥,如果使用本地模型可以随意填写一个但不能为空
|
||||
"Model": "",//会话模型,使用接口时需要,使用本地模型可以随意填写
|
||||
"EmbeddingModel": ""//向量模型,使用接口时需要,使用本地模型可以随意填写
|
||||
},
|
||||
dotnet clean
|
||||
dotnet build
|
||||
dotnet publish "AntSK.csproj"
|
||||
```
|
||||
再去AntSK/src/AntSK/bin/Release/net8.0/publish下
|
||||
```
|
||||
dotnet AntSK.dll
|
||||
```
|
||||
然后启动就有样式了
|
||||
|
||||
DB我使用的是CodeFirst模式,只要配置好数据库链接,表结构是自动创建的
|
||||
|
||||
|
||||
|
||||
想了解更多信息或开始使用 **AntSK**,可以关注我的公众号以及加入交流群。
|
||||
@@ -132,3 +194,4 @@ docker-compose up -d
|
||||
---
|
||||
|
||||
我们对您在**AntSK**的兴趣表示感谢,并期待与您携手共创智能化的未来!
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
BIN
images/对话效果.png
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 101 KiB |
BIN
images/应用.png
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 54 KiB |
BIN
images/应用配置.png
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 53 KiB |
BIN
images/知识库.png
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 47 KiB |
BIN
images/简单对话.png
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 55 KiB |
BIN
images/问答.png
|
Before Width: | Height: | Size: 174 KiB After Width: | Height: | Size: 170 KiB |
@@ -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>
|
||||
|
||||
|
||||
@@ -48,7 +48,56 @@
|
||||
<param name="value"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.Domain.Service.KernelService.GetKernel(System.String,System.String)">
|
||||
<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
|
||||
</summary>
|
||||
@@ -78,51 +127,6 @@
|
||||
<param name="history"></param>
|
||||
<returns></returns>
|
||||
</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="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连接字符串
|
||||
@@ -208,6 +212,11 @@
|
||||
类型
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apps.ChatModelID">
|
||||
<summary>
|
||||
会话模型ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apps.Temperature">
|
||||
<summary>
|
||||
温度
|
||||
@@ -223,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列表
|
||||
@@ -278,6 +292,16 @@
|
||||
会话模型
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Kmss.ChatModelID">
|
||||
<summary>
|
||||
会话模型ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Kmss.EmbeddingModelID">
|
||||
<summary>
|
||||
向量模型ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Kmss.MaxTokensPerParagraph">
|
||||
<summary>
|
||||
每个段落的最大标记数。
|
||||
@@ -550,6 +574,11 @@
|
||||
sqlserver连接
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.AIModels.AIType">
|
||||
<summary>
|
||||
AI类型
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.AIModels.AIModelType">
|
||||
<summary>
|
||||
模型类型
|
||||
@@ -570,6 +599,11 @@
|
||||
模型秘钥
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.AIModels.ModelDescription">
|
||||
<summary>
|
||||
部署名,azure需要使用
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Users.No">
|
||||
<summary>
|
||||
工号,用于登陆
|
||||
@@ -691,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>
|
||||
|
||||
8
src/AntSK.Domain/Common/AntSkFunctionAttribute.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace AntSK.Domain.Common
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class AntSkFunctionAttribute : Attribute
|
||||
{
|
||||
// 自定义的ActionAttribute
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using AutoMapper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace AntSK.Domain.Common.Map
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
using AutoMapper;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace AntSK.Domain.Common.Map
|
||||
{
|
||||
|
||||
18
src/AntSK.Domain/Domain/Interface/IChatService.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -1,17 +1,11 @@
|
||||
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
|
||||
{
|
||||
public interface IKMService
|
||||
{
|
||||
MemoryServerless GetMemory(SearchClientConfig searchClientConfig = null, TextPartitioningOptions textPartitioningOptions = null);
|
||||
Task<List<KMFile>> GetDocumentByFileID(string fileid);
|
||||
MemoryServerless GetMemoryByKMS(string kmsID, SearchClientConfig searchClientConfig = null);
|
||||
Task<List<KMFile>> GetDocumentByFileID(string kmsid, string fileid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
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 IKernelService
|
||||
{
|
||||
Kernel GetKernel(string modelId = null, string apiKey = null);
|
||||
Kernel GetKernelByApp(Apps app);
|
||||
void ImportFunctionsByApp(Apps app, Kernel _kernel);
|
||||
Task<string> HistorySummarize(Kernel _kernel, string questions, string history);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -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
|
||||
{
|
||||
@@ -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";
|
||||
16
src/AntSK.Domain/Domain/Model/Dto/RelevantSource.cs
Normal 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; }
|
||||
}
|
||||
}
|
||||
23
src/AntSK.Domain/Domain/Model/Enum/AIModelType.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
namespace AntSK.Domain.Domain.Model.Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// AI类型
|
||||
/// </summary>
|
||||
public enum AIType
|
||||
{
|
||||
OpenAI = 1,
|
||||
AzureOpenAI = 2,
|
||||
LLamaSharp = 3,
|
||||
SparkDesk = 4,
|
||||
Mock = 5,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 模型类型
|
||||
/// </summary>
|
||||
public enum AIModelType
|
||||
{
|
||||
Chat = 1,
|
||||
Embedding = 2,
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
8
src/AntSK.Domain/Domain/Model/Enum/HttpMethodType.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace AntSK.Domain.Domain.Model.Enum
|
||||
{
|
||||
public enum HttpMethodType
|
||||
{
|
||||
Get = 1,
|
||||
Post = 2,
|
||||
}
|
||||
}
|
||||
9
src/AntSK.Domain/Domain/Model/Enum/ImportKmsStatus.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace AntSK.Domain.Domain.Model.Enum
|
||||
{
|
||||
public enum ImportKmsStatus
|
||||
{
|
||||
Loadding = 0,
|
||||
Success = 1,
|
||||
Fail = 2
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
@@ -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>
|
||||
{
|
||||
40
src/AntSK.Domain/Domain/Model/hfmirror/HfModel.cs
Normal 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; }
|
||||
}
|
||||
}
|
||||
17
src/AntSK.Domain/Domain/Model/hfmirror/HfModelDetail.cs
Normal 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; }
|
||||
}
|
||||
}
|
||||
@@ -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.后台任务执行完成");
|
||||
44
src/AntSK.Domain/Domain/Other/LLamaConfig.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using LLama;
|
||||
using LLama.Common;
|
||||
using LLamaSharp.KernelMemory;
|
||||
|
||||
namespace AntSK.Domain.Domain.Other
|
||||
{
|
||||
public static class LLamaConfig
|
||||
{
|
||||
static object lockobj = new object();
|
||||
/// <summary>
|
||||
/// 避免模型重复加载,本地缓存
|
||||
/// </summary>
|
||||
static Dictionary<string, (LLamaWeights, ModelParams)> dicLLamaWeights = new Dictionary<string, (LLamaWeights, ModelParams)>();
|
||||
public static (LLamaWeights, ModelParams) GetLLamaConfig(string modelPath, LLamaSharpConfig config = null)
|
||||
{
|
||||
lock (lockobj)
|
||||
{
|
||||
if (dicLLamaWeights.ContainsKey(modelPath))
|
||||
{
|
||||
return dicLLamaWeights.GetValueOrDefault(modelPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
InferenceParams infParams = new() { AntiPrompts = ["\n\n"] };
|
||||
LLamaSharpConfig lsConfig = new(modelPath) { DefaultInferenceParams = infParams };
|
||||
if (config != null)
|
||||
{
|
||||
lsConfig = config;
|
||||
}
|
||||
var parameters = new ModelParams(lsConfig.ModelPath)
|
||||
{
|
||||
ContextSize = lsConfig?.ContextSize ?? 2048,
|
||||
Seed = lsConfig?.Seed ?? 0,
|
||||
GpuLayerCount = lsConfig?.GpuLayerCount ?? 10,
|
||||
EmbeddingMode = true
|
||||
};
|
||||
var weights = LLamaWeights.LoadFromFile(parameters);
|
||||
dicLLamaWeights.Add(modelPath, (weights, parameters));
|
||||
return (weights, parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
102
src/AntSK.Domain/Domain/Service/ChatService.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
70
src/AntSK.Domain/Domain/Service/FunctionService.cs
Normal 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -26,24 +19,20 @@ namespace AntSK.Domain.Domain.Service
|
||||
try
|
||||
{
|
||||
var km = _kmss_Repositories.GetFirst(p => p.Id == req.KmsId);
|
||||
var _memory = _kMService.GetMemory(textPartitioningOptions: new TextPartitioningOptions()
|
||||
{
|
||||
MaxTokensPerLine = km.MaxTokensPerLine,
|
||||
MaxTokensPerParagraph = km.MaxTokensPerParagraph,
|
||||
OverlappingTokens = km.OverlappingTokens
|
||||
});
|
||||
|
||||
var _memory = _kMService.GetMemoryByKMS(km.Id);
|
||||
string fileid = req.KmsDetail.Id;
|
||||
switch (req.ImportType)
|
||||
{
|
||||
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(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;
|
||||
@@ -57,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(fileid).Result;
|
||||
var docTextList = _kMService.GetDocumentByFileID(km.Id, fileid).Result;
|
||||
req.KmsDetail.Url = req.Url;
|
||||
req.KmsDetail.DataCount = docTextList.Count;
|
||||
}
|
||||
@@ -68,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(fileid).Result;
|
||||
var docTextList = _kMService.GetDocumentByFileID(km.Id, fileid).Result;
|
||||
req.KmsDetail.Url = req.Url;
|
||||
req.KmsDetail.DataCount = docTextList.Count;
|
||||
|
||||
@@ -76,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,66 +1,139 @@
|
||||
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;
|
||||
|
||||
namespace AntSK.Domain.Domain.Service
|
||||
{
|
||||
[ServiceDescription(typeof(IKMService), ServiceLifetime.Scoped)]
|
||||
public class KMService(
|
||||
IConfiguration _config
|
||||
IConfiguration _config,
|
||||
IKmss_Repositories _kmss_Repositories,
|
||||
IAIModels_Repositories _aIModels_Repositories
|
||||
) : IKMService
|
||||
{
|
||||
public MemoryServerless GetMemory(SearchClientConfig searchClientConfig = null, TextPartitioningOptions textPartitioningOptions = null)
|
||||
private MemoryServerless _memory;
|
||||
|
||||
public MemoryServerless GetMemoryByKMS(string kmsID, SearchClientConfig searchClientConfig = null)
|
||||
{
|
||||
var handler = new OpenAIHttpClientHandler();
|
||||
var httpClient = new HttpClient(handler);
|
||||
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 = "知识库未搜索到相关内容"
|
||||
};
|
||||
}
|
||||
|
||||
if (textPartitioningOptions.IsNull())
|
||||
{
|
||||
textPartitioningOptions = new TextPartitioningOptions
|
||||
var memoryBuild = new KernelMemoryBuilder()
|
||||
.WithSearchClientConfig(searchClientConfig)
|
||||
.WithCustomTextPartitioningOptions(new TextPartitioningOptions
|
||||
{
|
||||
MaxTokensPerLine = 99,
|
||||
MaxTokensPerParagraph = 299,
|
||||
OverlappingTokens = 47
|
||||
};
|
||||
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;
|
||||
}
|
||||
//else {
|
||||
// return _memory;
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
var memory = new KernelMemoryBuilder()
|
||||
.WithSimpleFileStorage(new SimpleFileStorageConfig { StorageType = FileSystemTypes.Volatile, Directory = "_files" })
|
||||
.WithSearchClientConfig(searchClientConfig)
|
||||
.WithCustomTextPartitioningOptions(textPartitioningOptions)
|
||||
.WithOpenAITextGeneration(new OpenAIConfig()
|
||||
private void WithTextEmbeddingGenerationByAIType(IKernelMemoryBuilder memory, AIModels embedModel, HttpClient embeddingHttpClient)
|
||||
{
|
||||
switch (embedModel.AIType)
|
||||
{
|
||||
APIKey = OpenAIOption.Key,
|
||||
TextModel = OpenAIOption.Model
|
||||
case Model.Enum.AIType.OpenAI:
|
||||
memory.WithOpenAITextEmbeddingGeneration(new OpenAIConfig()
|
||||
{
|
||||
APIKey = embedModel.ModelKey,
|
||||
EmbeddingModel = embedModel.ModelName
|
||||
}, null, false, embeddingHttpClient);
|
||||
break;
|
||||
case Model.Enum.AIType.AzureOpenAI:
|
||||
memory.WithAzureOpenAITextEmbeddingGeneration(new AzureOpenAIConfig()
|
||||
{
|
||||
APIKey = embedModel.ModelKey,
|
||||
Deployment = embedModel.ModelName.ConvertToString(),
|
||||
Endpoint = embedModel.EndPoint.ConvertToString(),
|
||||
Auth = AzureOpenAIConfig.AuthTypes.APIKey,
|
||||
APIType = AzureOpenAIConfig.APITypes.EmbeddingGeneration,
|
||||
});
|
||||
break;
|
||||
case Model.Enum.AIType.LLamaSharp:
|
||||
var (weights, parameters) = LLamaConfig.GetLLamaConfig(embedModel.ModelName);
|
||||
var embedder = new LLamaEmbedder(weights, parameters);
|
||||
memory.WithLLamaSharpTextEmbeddingGeneration(new LLamaSharpTextEmbeddingGenerator(embedder));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}, null, httpClient)
|
||||
.WithOpenAITextEmbeddingGeneration(new OpenAIConfig()
|
||||
private void WithTextGenerationByAIType(IKernelMemoryBuilder memory, AIModels chatModel, HttpClient chatHttpClient)
|
||||
{
|
||||
switch (chatModel.AIType)
|
||||
{
|
||||
APIKey = OpenAIOption.Key,
|
||||
EmbeddingModel = OpenAIOption.EmbeddingModel
|
||||
case Model.Enum.AIType.OpenAI:
|
||||
memory.WithOpenAITextGeneration(new OpenAIConfig()
|
||||
{
|
||||
APIKey = chatModel.ModelKey,
|
||||
TextModel = chatModel.ModelName
|
||||
}, null, chatHttpClient);
|
||||
break;
|
||||
case Model.Enum.AIType.AzureOpenAI:
|
||||
memory.WithAzureOpenAITextGeneration(new AzureOpenAIConfig()
|
||||
{
|
||||
APIKey = chatModel.ModelKey,
|
||||
Deployment = chatModel.ModelName.ConvertToString(),
|
||||
Endpoint = chatModel.EndPoint.ConvertToString(),
|
||||
Auth = AzureOpenAIConfig.AuthTypes.APIKey,
|
||||
APIType = AzureOpenAIConfig.APITypes.TextCompletion,
|
||||
});
|
||||
break;
|
||||
case Model.Enum.AIType.LLamaSharp:
|
||||
var (weights, parameters) = LLamaConfig.GetLLamaConfig(chatModel.ModelName);
|
||||
var context = weights.CreateContext(parameters);
|
||||
var executor = new StatelessExecutor(weights, parameters);
|
||||
memory.WithLLamaSharpTextGeneration(new LlamaSharpTextGenerator(weights, context, executor));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}, null, false, httpClient);
|
||||
private void WithMemoryDbByVectorDB(IKernelMemoryBuilder memory, IConfiguration _config)
|
||||
{
|
||||
string VectorDb = _config["KernelMemory:VectorDb"].ConvertToString();
|
||||
string ConnectionString = _config["KernelMemory:ConnectionString"].ConvertToString();
|
||||
string TableNamePrefix = _config["KernelMemory:TableNamePrefix"].ConvertToString();
|
||||
@@ -86,14 +159,11 @@ namespace AntSK.Domain.Domain.Service
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
var result = memory.Build<MemoryServerless>();
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<List<KMFile>> GetDocumentByFileID(string fileid)
|
||||
public async Task<List<KMFile>> GetDocumentByFileID(string kmsid, string fileid)
|
||||
{
|
||||
var _memory = GetMemory();
|
||||
var _memory = GetMemoryByKMS(kmsid);
|
||||
var memories = await _memory.ListIndexesAsync();
|
||||
var memoryDbs = _memory.Orchestrator.GetMemoryDbs();
|
||||
List<KMFile> docTextList = new List<KMFile>();
|
||||
@@ -120,5 +190,7 @@ namespace AntSK.Domain.Domain.Service
|
||||
}
|
||||
return docTextList;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +1,104 @@
|
||||
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 LLama;
|
||||
using LLamaSharp.SemanticKernel.TextCompletion;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
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(
|
||||
IApis_Repositories _apis_Repositories
|
||||
) : 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,
|
||||
FunctionService functionService,
|
||||
IServiceProvider serviceProvider)
|
||||
{
|
||||
_apis_Repositories = apis_Repositories;
|
||||
_aIModels_Repositories = aIModels_Repositories;
|
||||
_functionService = functionService;
|
||||
_serviceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取kernel实例,依赖注入不好按每个用户去Import不同的插件,所以每次new一个新的kernel
|
||||
/// </summary>
|
||||
/// <param name="modelId"></param>
|
||||
/// <param name="apiKey"></param>
|
||||
/// <returns></returns>
|
||||
public Kernel GetKernel(string modelId=null,string apiKey=null)
|
||||
public Kernel GetKernelByApp(Apps app)
|
||||
{
|
||||
var handler = new OpenAIHttpClientHandler();
|
||||
var httpClient = new HttpClient(handler);
|
||||
httpClient.Timeout = TimeSpan.FromMinutes(5);
|
||||
var kernel = Kernel.CreateBuilder()
|
||||
.AddOpenAIChatCompletion(
|
||||
modelId: modelId!=null? modelId : OpenAIOption.Model,
|
||||
apiKey: apiKey!=null? apiKey: OpenAIOption.Key,
|
||||
httpClient: httpClient)
|
||||
.Build();
|
||||
RegisterPluginsWithKernel(kernel);
|
||||
return kernel;
|
||||
//if (_kernel.IsNull())
|
||||
{
|
||||
var chatModel = _aIModels_Repositories.GetFirst(p => p.Id == app.ChatModelID);
|
||||
|
||||
var chatHttpClient = OpenAIHttpClientHandlerUtil.GetHttpClient(chatModel.EndPoint);
|
||||
|
||||
var builder = Kernel.CreateBuilder();
|
||||
WithTextGenerationByAIType(builder, app, chatModel, chatHttpClient);
|
||||
|
||||
_kernel = builder.Build();
|
||||
RegisterPluginsWithKernel(_kernel);
|
||||
return _kernel;
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// return _kernel;
|
||||
//}
|
||||
}
|
||||
|
||||
private void WithTextGenerationByAIType(IKernelBuilder builder, Apps app, AIModels chatModel, HttpClient chatHttpClient)
|
||||
{
|
||||
switch (chatModel.AIType)
|
||||
{
|
||||
case Model.Enum.AIType.OpenAI:
|
||||
builder.AddOpenAIChatCompletion(
|
||||
modelId: chatModel.ModelName,
|
||||
apiKey: chatModel.ModelKey,
|
||||
httpClient: chatHttpClient);
|
||||
break;
|
||||
|
||||
case Model.Enum.AIType.AzureOpenAI:
|
||||
builder.AddAzureOpenAIChatCompletion(
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -49,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)
|
||||
@@ -76,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)
|
||||
@@ -93,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)
|
||||
@@ -110,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;
|
||||
}
|
||||
@@ -122,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"));
|
||||
}
|
||||
|
||||
@@ -145,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +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 AIModelType
|
||||
{
|
||||
Chat = 1,
|
||||
Embedding = 2,
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
/// 连接字符串
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AntSK.Domain.Options
|
||||
{
|
||||
public class OpenAIOption
|
||||
{
|
||||
public static string EndPoint { get; set; }
|
||||
public static string Key { get; set; }
|
||||
public static string Model { get; set; }
|
||||
|
||||
public static string EmbeddingModel { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -37,11 +32,17 @@ namespace AntSK.Domain.Repositories
|
||||
[Required]
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 会话模型ID
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string? ChatModelID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 温度
|
||||
/// </summary>
|
||||
[SugarColumn(DefaultValue = "70")]
|
||||
public double Temperature { get; set; }=70f;
|
||||
public double Temperature { get; set; } = 70f;
|
||||
|
||||
/// <summary>
|
||||
/// 提示词
|
||||
@@ -51,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列表
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -28,6 +23,17 @@ namespace AntSK.Domain.Repositories
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Describe { get; set; }
|
||||
/// <summary>
|
||||
/// 会话模型ID
|
||||
/// </summary>
|
||||
[Required]
|
||||
|
||||
public string? ChatModelID { get; set; }
|
||||
/// <summary>
|
||||
/// 向量模型ID
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string? EmbeddingModelID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 每个段落的最大标记数。
|
||||
@@ -48,5 +54,7 @@ namespace AntSK.Domain.Repositories
|
||||
/// </summary>
|
||||
[SugarColumn(DefaultValue = "49")]
|
||||
public int OverlappingTokens { get; set; } = 49;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -15,25 +10,36 @@ namespace AntSK.Domain.Repositories
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public string Id { get; set; }
|
||||
/// <summary>
|
||||
/// AI类型
|
||||
/// </summary>
|
||||
|
||||
[Required]
|
||||
[SugarColumn(DefaultValue = "1")]
|
||||
public AIType AIType { get; set; } = AIType.OpenAI;
|
||||
/// <summary>
|
||||
/// 模型类型
|
||||
/// </summary>
|
||||
[Required]
|
||||
public AIModelType AIModelType { get; set; }
|
||||
public AIModelType AIModelType { get; set; } = AIModelType.Chat;
|
||||
/// <summary>
|
||||
/// 模型地址
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string EndPoint { get; set; }
|
||||
public string EndPoint { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 模型名称
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string ModelName { get; set; }
|
||||
public string ModelName { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 模型秘钥
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string ModelKey { get; set; }
|
||||
public string ModelKey { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 部署名,azure需要使用
|
||||
/// </summary>
|
||||
|
||||
[Required]
|
||||
public string ModelDescription { get; set; }
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
17
src/AntSK.Domain/Utils/JSUtils.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Buffers.Text;
|
||||
using System.Buffers.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
using AntSK.Domain.Options;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace AntSK.Domain.Utils
|
||||
{
|
||||
public class OpenAIHttpClientHandler : HttpClientHandler
|
||||
{
|
||||
private string _endPoint { get; set; }
|
||||
public OpenAIHttpClientHandler(string endPoint)
|
||||
{
|
||||
this._endPoint = endPoint;
|
||||
}
|
||||
|
||||
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
UriBuilder uriBuilder;
|
||||
Regex regex = new Regex(@"(https?)://([^/:]+)(:\d+)?/(.*)");
|
||||
Match match = regex.Match(OpenAIOption.EndPoint);
|
||||
Match match = regex.Match(_endPoint);
|
||||
if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development" && request.Content != null)
|
||||
{
|
||||
{
|
||||
string requestBody = await request.Content.ReadAsStringAsync();
|
||||
//便于调试查看请求prompt
|
||||
Console.WriteLine(requestBody);
|
||||
@@ -40,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;
|
||||
@@ -74,4 +74,16 @@ namespace AntSK.Domain.Utils
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class OpenAIHttpClientHandlerUtil
|
||||
{
|
||||
public static HttpClient GetHttpClient(string endPoint)
|
||||
{
|
||||
var handler = new OpenAIHttpClientHandler(endPoint.ConvertToString());
|
||||
var httpClient = new HttpClient(handler);
|
||||
httpClient.Timeout = TimeSpan.FromMinutes(5);
|
||||
return httpClient;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using BCrypt.Net;
|
||||
|
||||
namespace AntSK.Domain.Utils
|
||||
namespace AntSK.Domain.Utils
|
||||
{
|
||||
public class PasswordUtil
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
375
src/AntSK.Domain/Utils/XmlCommentHelper.cs
Normal 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 < and > 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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(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(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.Models.OpenAIModel)">
|
||||
<summary>
|
||||
历史会话的会话总结
|
||||
</summary>
|
||||
<param name="questions"></param>
|
||||
<param name="msg"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
||||
@@ -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 />
|
||||
|
||||
26
src/AntSK/Components/ChartCard/ChartCard.razor
Normal 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>
|
||||
|
||||
31
src/AntSK/Components/ChartCard/ChartCard.razor.cs
Normal 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; }
|
||||
}
|
||||
}
|
||||
77
src/AntSK/Components/ChartCard/ChartCard.razor.css
Normal 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;
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using AntSK.Domain.Repositories;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using AntSK.Domain.Repositories;
|
||||
|
||||
namespace AntSK.Controllers
|
||||
{
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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");
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System;
|
||||
|
||||
namespace AntSK
|
||||
namespace AntSK
|
||||
{
|
||||
public static class DateTimeExtension
|
||||
{
|
||||
|
||||