Compare commits
132 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e754b4732 | ||
|
|
48a9fcfabf | ||
|
|
7ae2b9ac3b | ||
|
|
a6bfe3c69b | ||
|
|
6b146f4750 | ||
|
|
1387e716d1 | ||
|
|
fadc350047 | ||
|
|
8af4994a7d | ||
|
|
b505b61bfe | ||
|
|
5d086c9383 | ||
|
|
dd0e367dc8 | ||
|
|
7110eea912 | ||
|
|
154e67ef98 | ||
|
|
4a04423373 | ||
|
|
470ea50ebb | ||
|
|
2a30f3f221 | ||
|
|
315f58fdba | ||
|
|
f027682175 | ||
|
|
2618dffcd6 | ||
|
|
ee42d5870b | ||
|
|
27500b1e08 | ||
|
|
4d71a98724 | ||
|
|
b8ba0ab391 | ||
|
|
b589612913 | ||
|
|
ec4b440469 | ||
|
|
adbecb3b25 | ||
|
|
277aacc34d | ||
|
|
dba98f7968 | ||
|
|
a2b0f3f3c2 | ||
|
|
b5e527afdb | ||
|
|
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 |
3
.gitignore
vendored
@@ -337,6 +337,9 @@ ASALocalRun/
|
||||
/AntSK/appsettings.Development.json
|
||||
/AntSK.db
|
||||
**/tmp-memory-files/*
|
||||
**/tmp-memory-vectors/*
|
||||
/src/AntSK/AntSK.db
|
||||
/src/AntSK/appsettings.Development.json
|
||||
/src/AntSK.db
|
||||
/src/AntSK/llama_models
|
||||
/src/AntSK/AntSK.xml
|
||||
118
README.en.md
@@ -1,41 +1,42 @@
|
||||
[简体中文](./README.md) | English
|
||||
# AntSK
|
||||
|
||||
## Based on AI knowledge base/agent created by Net8+AntBlazor+SemanticKernel
|
||||
## An AI knowledge base/intelligent agent built with .Net 8+AntBlazor+SemanticKernel
|
||||
|
||||
|
||||
|
||||
## Core functions
|
||||
## Core Features
|
||||
|
||||
|
||||
|
||||
- **Semantic Kernel**: It uses advanced natural language processing technology to accurately understand, process and respond to complex semantic queries, and provides users with accurate information retrieval and recommendation services.
|
||||
- **Semantic Kernel**: Utilizes advanced natural language processing technologies to accurately understand, process, and respond to complex semantic queries, providing users with precise information retrieval and recommendation services.
|
||||
|
||||
|
||||
|
||||
- **Kernel Memory**: It has the ability to continuously learn and store knowledge points. AntSK has a long-term memory function to accumulate experience and provide a more personalized interactive experience.
|
||||
- **Kernel Memory**: Capable of continuous learning and knowledge storage, AntSK has a long-term memory function, accumulating experience to offer more personalized interaction experiences.
|
||||
|
||||
|
||||
|
||||
- **Knowledge base**: Knowledge base documents can be created by importing knowledge base documents (Word, PDF, Excel, Txt, Markdown, Json, PPT) and other forms.
|
||||
- **Knowledge base**: Import knowledge into the database through documents (Word, PDF, Excel, Txt, Markdown, Json, PPT) and manage knowledge base documents.
|
||||
|
||||
|
||||
|
||||
- **API plug-in system**: an open API plug-in system that allows third-party developers or service providers to easily integrate their services into AntSK and continuously enhance application functions.
|
||||
- **GPTs Generation**:The platform supports the creation of personalized GPT models, try building your own GPT model.
|
||||
|
||||
|
||||
|
||||
- **Online search**: AntSK can obtain the latest information in real time to ensure that the information received by users is always the most timely and relevant.
|
||||
- **API Interface Release**: Internal functions are provided as APIs for developers to integrate AntSK into other applications, enhancing application intelligence.
|
||||
|
||||
|
||||
|
||||
- **GPTs generation**: This platform supports the creation of personalized GPT models and attempts to build your own GPT models.
|
||||
- **API Plugin System**: An open API plugin system allows third-party developers or service providers to easily integrate their services into AntSK, continuously enhancing application functions.
|
||||
|
||||
|
||||
- **.Net Plugin System**: An open dll plugin system allows third-party developers or service providers to integrate their business functions into AntSK by generating dlls with the standard format codes, continuously enhancing application functions.
|
||||
|
||||
- **API interface publishing**: internal functions are provided externally in the form of API, so that developers can easily translate Xzy AntSK KnowledgeBase is integrated into other applications to enhance application intelligence.
|
||||
|
||||
- **Model management**: Adapt and manage different models from different vendors.
|
||||
- **Internet Search**: AntSK can retrieve the latest information in real-time, ensuring that the information users receive is always timely and relevant.
|
||||
|
||||
|
||||
- **Model management**: Adapts and manages different models from various manufacturers. It also supports offline running of models in 'gguf' format supported by llama.cpp.
|
||||
|
||||
|
||||
- **National Information Creation**: AntSK supports domestic models and databases, and can operate under information creation conditions.
|
||||
|
||||
|
||||
|
||||
@@ -43,11 +44,11 @@
|
||||
|
||||
|
||||
|
||||
AntSK is applicable to a variety of business scenarios, such as:
|
||||
AntSK is suitable for various business scenarios, such as:
|
||||
|
||||
- Enterprise level knowledge management system
|
||||
- Corporate knowledge management systems
|
||||
|
||||
- Automatic customer service and chat robot
|
||||
- Automated customer service and chatbots
|
||||
|
||||
- Enterprise Search Engine
|
||||
|
||||
@@ -57,7 +58,7 @@ AntSK is applicable to a variety of business scenarios, such as:
|
||||
|
||||
- Education and online learning platform
|
||||
|
||||
- Other interesting AI Apps
|
||||
- Other interesting AI applications
|
||||
|
||||
|
||||
|
||||
@@ -115,25 +116,71 @@ Let's see the effect
|
||||
|
||||
## How do I get started?
|
||||
|
||||
Login is the default login account and password
|
||||
Here I am using Postgres as a data and vector store, because the Semantic Kernel and Kernel Memory both support it, though you can switch to others.
|
||||
|
||||
Here I use Postgres as data storage and vector storage, because both the Semantic Kernel and Kernel Memory support it. Of course, you can switch to other ones.
|
||||
The model by default supports local models in 'gguf' format from openai, azure openai, and llama. If you need to use other models, you can integrate them using the one-api.
|
||||
|
||||
The model supports openai by default. If you need to use azure openai and need to adjust the dependency injection of SK, you can also use one api for integration.
|
||||
The login configuration in the configuration file is the default account and password.
|
||||
|
||||
The following configuration files need to be configured
|
||||
The following configuration files are needed:
|
||||
|
||||
## 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
|
||||
A appsettings.json for the pg version and a simplified version (Sqlite+disk) docker-compose.simple.yml are provided.
|
||||
|
||||
Download docker-compose.yml from the project root directory, then place the configuration file appsettings.json in the same directory,
|
||||
|
||||
The pg image has already been prepared. You can modify the default account and password in the docker-compose.yml, and then your appsettings.json database connection needs to be consistent.
|
||||
|
||||
Then you can enter the directory and execute
|
||||
```
|
||||
docker compose up - d
|
||||
```
|
||||
To start AntSK
|
||||
to start AntSK.
|
||||
|
||||
Some meanings of configuration files
|
||||
How to mount local models and model download directories in docker
|
||||
|
||||
```
|
||||
# Non-host version, does not use local proxy
|
||||
version: '3.8'
|
||||
services:
|
||||
antsk:
|
||||
container_name: antsk
|
||||
image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.2.1
|
||||
ports:
|
||||
- 5000:5000
|
||||
networks:
|
||||
- antsk
|
||||
depends_on:
|
||||
- antskpg
|
||||
restart: always
|
||||
environment:
|
||||
- ASPNETCORE_URLS=http://*:5000
|
||||
volumes:
|
||||
- ./appsettings.json:/app/appsettings.json # local configuration file must be placed in the same directory
|
||||
- D://model:/app/model
|
||||
networks:
|
||||
antsk:
|
||||
|
||||
```
|
||||
Using this as an example, the meaning is to mount the local folder D://model from Windows into the container /app/model. If so, your appsettings.json model directory should be configured as
|
||||
|
||||
```
|
||||
model/xxx.gguf
|
||||
```
|
||||
Some meanings of the configuration file
|
||||
// (The rest of the information is omitted as it's unnecessary for the translation example context.)
|
||||
|
||||
Solving the missing style issue:
|
||||
Execute under AntSK/src/AntSK:
|
||||
```
|
||||
dotnet clean
|
||||
dotnet build
|
||||
dotnet publish "AntSK.csproj"
|
||||
```
|
||||
Then go to AntSK/src/AntSK/bin/Release/net8.0/publish
|
||||
```
|
||||
dotnet AntSK.dll
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
@@ -142,12 +189,6 @@ Some meanings of configuration files
|
||||
"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=",
|
||||
@@ -156,7 +197,8 @@ Some meanings of configuration files
|
||||
"LLamaSharp": {
|
||||
"RunType": "GPU",
|
||||
"Chat": "D:\\Code\\AI\\AntBlazor\\model\\qwen1_5-1_8b-chat-q8_0.gguf",
|
||||
"Embedding": "D:\\Code\\AI\\AntBlazor\\model\\qwen1_5-1_8b-chat-q8_0.gguf"
|
||||
"Embedding": "D:\\Code\\AI\\AntBlazor\\model\\qwen1_5-1_8b-chat-q8_0.gguf",
|
||||
"FileDirectory": "D:\\Code\\AI\\AntBlazor\\model\\"
|
||||
},
|
||||
"Login": {
|
||||
"User": "admin",
|
||||
@@ -176,10 +218,6 @@ Some meanings of configuration files
|
||||
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
|
||||
|
||||
38
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,9 +67,9 @@ AntSK 适用于多种业务场景,例如:
|
||||
|
||||
在这里我使用的是Postgres 作为数据存储和向量存储,因为Semantic Kernel和Kernel Memory都支持他,当然你也可以换成其他的。
|
||||
|
||||
模型默认支持openai,如果需要使用azure openai需要调整SK的依赖注入,也可以使用one-api进行集成。
|
||||
模型默认支持openai、azure openai 和llama支持的gguf本地模型,如果需要使用其他模型,可以使用one-api进行集成。
|
||||
|
||||
Login是默认的登陆账号和密码
|
||||
配置文件中的Login配置是默认的登陆账号和密码
|
||||
|
||||
需要配置如下的配置文件
|
||||
|
||||
@@ -83,7 +87,7 @@ docker-compose up -d
|
||||
```
|
||||
来启动AntSK
|
||||
|
||||
## 如何在docker中挂载本地模型
|
||||
## 如何在docker中挂载本地模型,和模型下载的目录
|
||||
```
|
||||
# 非 host 版本, 不使用本机代理
|
||||
version: '3.8'
|
||||
@@ -118,12 +122,6 @@ model/xxx.gguf
|
||||
"DbType": "Sqlite",
|
||||
"ConnectionStrings": "Data Source=AntSK.db;"
|
||||
},
|
||||
"OpenAIOption": {
|
||||
"EndPoint": "http://localhost:5000/llama/",
|
||||
"Key": "NotNull",
|
||||
"Model": "gpt4-turbo",
|
||||
"EmbeddingModel": "text-embedding-ada-002"
|
||||
},
|
||||
"KernelMemory": {
|
||||
"VectorDb": "Disk",
|
||||
"ConnectionString": "Host=;Port=;Database=antsk;Username=;Password=",
|
||||
@@ -132,7 +130,8 @@ model/xxx.gguf
|
||||
"LLamaSharp": {
|
||||
"RunType": "GPU",
|
||||
"Chat": "D:\\Code\\AI\\AntBlazor\\model\\qwen1_5-1_8b-chat-q8_0.gguf",
|
||||
"Embedding": "D:\\Code\\AI\\AntBlazor\\model\\qwen1_5-1_8b-chat-q8_0.gguf"
|
||||
"Embedding": "D:\\Code\\AI\\AntBlazor\\model\\qwen1_5-1_8b-chat-q8_0.gguf",
|
||||
"FileDirectory": "D:\\Code\\AI\\AntBlazor\\model\\"
|
||||
},
|
||||
"Login": {
|
||||
"User": "admin",
|
||||
@@ -150,18 +149,19 @@ model/xxx.gguf
|
||||
DBConnection.DbType
|
||||
//连接字符串,需要根据不同DB类型,用对应的字符串
|
||||
DBConnection.ConnectionStrings
|
||||
//可以使用符合openai格式的在线API(国产模型使用one-api转接) ,也可以使用AntSK自带的llama api,ip和端口是AntSK启动地址
|
||||
OpenAIOption.EndPoint
|
||||
//模型秘钥,如果使用本地模型可以默认NotNull 这里不能用中文
|
||||
OpenAIOption.Key
|
||||
|
||||
//向量存储的类型,支持 Postgres Disk Memory ,其中Postgres需要配置 ConnectionString
|
||||
KernelMemory.VectorDb
|
||||
|
||||
//本地模型使用的运行方式 GUP CPU ,如果用在线API 这个随意使用一个即可
|
||||
LLamaSharp.RunType
|
||||
//本地会话模型的模型路径 注意区分linux和windows盘符不同
|
||||
LLamaSharp.Chat
|
||||
//本地向量模型的模型路径 注意区分linux和windows盘符不同
|
||||
LLamaSharp.Embedding
|
||||
//本地模型路径,用于在选择llama时可以快速选择目录下的模型,以及保存下载的模型
|
||||
LLamaSharp.FileDirectory
|
||||
|
||||
//默认管理员账号密码
|
||||
Login
|
||||
//导入异步处理的线程数,使用在线API可以高一点,本地模型建议1 否则容易内存溢出崩掉
|
||||
|
||||
@@ -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.2.1
|
||||
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.2.1
|
||||
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,6 +48,55 @@
|
||||
<param name="value"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:AntSK.Domain.Domain.Model.Enum.AIType">
|
||||
<summary>
|
||||
AI类型
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:AntSK.Domain.Domain.Model.Enum.AIModelType">
|
||||
<summary>
|
||||
模型类型
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Domain.Model.MessageInfo.IsSend">
|
||||
<summary>
|
||||
发送是true 接收是false
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Domain.Model.PageList`1.PageIndex">
|
||||
<summary>
|
||||
当前页,从1开始
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Domain.Model.PageList`1.PageSize">
|
||||
<summary>
|
||||
每页数量
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Domain.Model.PageList`1.TotalCount">
|
||||
<summary>
|
||||
总数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:AntSK.Domain.Domain.Other.LLamaConfig.dicLLamaWeights">
|
||||
<summary>
|
||||
避免模型重复加载,本地缓存
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.Domain.Service.ChatService.SendChatByAppAsync(AntSK.Domain.Repositories.Apps,System.String,System.String)">
|
||||
<summary>
|
||||
发送消息
|
||||
</summary>
|
||||
<param name="app"></param>
|
||||
<param name="questions"></param>
|
||||
<param name="history"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.Domain.Service.FunctionService.SearchMarkedMethods">
|
||||
<summary>
|
||||
查询程序集中的方法委托,后续利用Source Generators生成
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.Domain.Service.KernelService.GetKernelByApp(AntSK.Domain.Repositories.Apps)">
|
||||
<summary>
|
||||
获取kernel实例,依赖注入不好按每个用户去Import不同的插件,所以每次new一个新的kernel
|
||||
@@ -63,6 +112,20 @@
|
||||
<param name="app"></param>
|
||||
<param name="_kernel"></param>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.Domain.Service.KernelService.ImportApiFunction(AntSK.Domain.Repositories.Apps,System.Collections.Generic.List{Microsoft.SemanticKernel.KernelFunction})">
|
||||
<summary>
|
||||
导入API插件
|
||||
</summary>
|
||||
<param name="app"></param>
|
||||
<param name="functions"></param>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.Domain.Service.KernelService.ImportNativeFunction(AntSK.Domain.Repositories.Apps,System.Collections.Generic.List{Microsoft.SemanticKernel.KernelFunction})">
|
||||
<summary>
|
||||
导入原生插件
|
||||
</summary>
|
||||
<param name="app"></param>
|
||||
<param name="functions"></param>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.Domain.Service.KernelService.RegisterPluginsWithKernel(Microsoft.SemanticKernel.Kernel)">
|
||||
<summary>
|
||||
注册默认插件
|
||||
@@ -78,66 +141,6 @@
|
||||
<param name="history"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="F:AntSK.Domain.Domain.Service.LLamaConfig.dicLLamaWeights">
|
||||
<summary>
|
||||
避免模型重复加载,本地缓存
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.Map.MapperExtend.ToDTOList``1(System.Object)">
|
||||
<summary>
|
||||
Entity集合转DTO集合
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<param name="value"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.Map.MapperExtend.ToDTO``1(System.Object)">
|
||||
<summary>
|
||||
Entity转DTO
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<param name="value"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.Map.MapperExtend.MapTo``1(System.Object,``0)">
|
||||
<summary>
|
||||
给已有对象map,适合update场景,如需过滤空值需要在AutoMapProfile 设置
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<param name="self"></param>
|
||||
<param name="result"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:AntSK.Domain.Model.Enum.AIType">
|
||||
<summary>
|
||||
AI类型
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:AntSK.Domain.Model.Enum.AIModelType">
|
||||
<summary>
|
||||
模型类型
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Model.MessageInfo.IsSend">
|
||||
<summary>
|
||||
发送是true 接收是false
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Model.PageList`1.PageIndex">
|
||||
<summary>
|
||||
当前页,从1开始
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Model.PageList`1.PageSize">
|
||||
<summary>
|
||||
每页数量
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Model.PageList`1.TotalCount">
|
||||
<summary>
|
||||
总数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Options.DBConnectionOption.DbType">
|
||||
<summary>
|
||||
sqlite连接字符串
|
||||
@@ -228,6 +231,11 @@
|
||||
会话模型ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apps.EmbeddingModelID">
|
||||
<summary>
|
||||
Embedding 模型Id
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apps.Temperature">
|
||||
<summary>
|
||||
温度
|
||||
@@ -243,6 +251,11 @@
|
||||
插件列表
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apps.NativeFunctionList">
|
||||
<summary>
|
||||
本地函数列表
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apps.KmsIdList">
|
||||
<summary>
|
||||
知识库ID列表
|
||||
@@ -253,6 +266,11 @@
|
||||
API调用秘钥
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Funs.Path">
|
||||
<summary>
|
||||
接口描述
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.KmsDetails.FileName">
|
||||
<summary>
|
||||
文件名称
|
||||
@@ -725,11 +743,143 @@
|
||||
<param name="stream"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.Utils.ConvertUtils.ToQueryString(System.Collections.Generic.Dictionary{System.String,System.String})">
|
||||
<summary>
|
||||
json参数转化querystring参数
|
||||
</summary>
|
||||
<param name="parameters"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.Utils.RepoFiles.SamplePluginsPath">
|
||||
<summary>
|
||||
Scan the local folders from the repo, looking for "samples/plugins" folder.
|
||||
</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
|
||||
{
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AntSK.Domain.Domain.Dto
|
||||
{
|
||||
public class KMFile
|
||||
{
|
||||
public string Text { get; set; }
|
||||
|
||||
public string Url { get; set; }
|
||||
|
||||
public string LastUpdate { get; set; }
|
||||
|
||||
public string Schema { get; set; }
|
||||
|
||||
public string File { get; set; }
|
||||
}
|
||||
}
|
||||
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, string filePath, 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,24 @@
|
||||
using AntSK.Domain.Domain.Dto;
|
||||
using Microsoft.KernelMemory.Configuration;
|
||||
using AntDesign;
|
||||
using AntSK.Domain.Domain.Model.Dto;
|
||||
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.Domain.Interface
|
||||
{
|
||||
public interface IKMService
|
||||
{
|
||||
MemoryServerless GetMemory(Apps app);
|
||||
|
||||
MemoryServerless GetMemoryByKMS(string kmsID, SearchClientConfig searchClientConfig = null);
|
||||
Task<List<KMFile>> GetDocumentByFileID(string kmsid, string fileid);
|
||||
|
||||
Task<List<KMFile>> GetDocumentByFileID(string kmsId, string fileId);
|
||||
|
||||
Task<List<RelevantSource>> GetRelevantSourceList(string kmsIdListStr, string msg);
|
||||
|
||||
List<UploadFileItem> FileList { get; }
|
||||
|
||||
bool BeforeUpload(UploadFileItem file);
|
||||
|
||||
void OnSingleCompleted(UploadInfo fileinfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,5 @@
|
||||
using AntSK.Domain.Repositories;
|
||||
using Microsoft.SemanticKernel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AntSK.Domain.Domain.Interface
|
||||
{
|
||||
|
||||
15
src/AntSK.Domain/Domain/Model/Constant/KmsConstantcs.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AntSK.Domain.Domain.Model.Constant
|
||||
{
|
||||
public class KmsConstantcs
|
||||
{
|
||||
public const string KmsIdTag = "kmsid";
|
||||
public const string KmsIndex = "kms";
|
||||
public const string KmsSearchNull="知识库未搜索到相关内容";
|
||||
}
|
||||
}
|
||||
14
src/AntSK.Domain/Domain/Model/Dto/KMFile.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace AntSK.Domain.Domain.Model.Dto
|
||||
{
|
||||
public class KMFile
|
||||
{
|
||||
public string DocumentId { get; set; }
|
||||
public string Text { get; set; }
|
||||
|
||||
public string? Url { get; set; }
|
||||
|
||||
public string LastUpdate { get; set; }
|
||||
|
||||
public string File { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -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 @@
|
||||
|
||||
namespace AntSK.Domain.Domain.Model.Dto
|
||||
{
|
||||
public class RelevantSource
|
||||
{
|
||||
public string SourceName { get; set; }
|
||||
|
||||
public string Text { get; set; }
|
||||
public float Relevance { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"[file:{SourceName};Relevance:{(Relevance * 100):F2}%]:{Text}";
|
||||
}
|
||||
}
|
||||
}
|
||||
37
src/AntSK.Domain/Domain/Model/Enum/AIModelType.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AntSK.Domain.Domain.Model.Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// AI类型
|
||||
/// </summary>
|
||||
public enum AIType
|
||||
{
|
||||
[Display(Name = "Open AI")]
|
||||
OpenAI = 1,
|
||||
|
||||
[Display(Name = "Azure Open AI")]
|
||||
AzureOpenAI = 2,
|
||||
|
||||
[Display(Name = "LLama本地模型")]
|
||||
LLamaSharp = 3,
|
||||
|
||||
[Display(Name = "星火大模型")]
|
||||
SparkDesk = 4,
|
||||
|
||||
[Display(Name = "灵积大模型")]
|
||||
DashScope = 5,
|
||||
|
||||
[Display(Name = "模拟输出")]
|
||||
Mock = 100,
|
||||
}
|
||||
|
||||
/// <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
|
||||
}
|
||||
}
|
||||
23
src/AntSK.Domain/Domain/Model/Fun/FunDto.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AntSK.Domain.Domain.Model.Fun
|
||||
{
|
||||
public class FunDto
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Description { get; set; }
|
||||
|
||||
public FunType FunType { get; set; }
|
||||
}
|
||||
|
||||
public enum FunType
|
||||
{
|
||||
System=1,
|
||||
Import=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
|
||||
{
|
||||
@@ -16,7 +10,11 @@ namespace AntSK.Domain.Model
|
||||
/// 发送是true 接收是false
|
||||
/// </summary>
|
||||
public bool IsSend { get; set; } = false;
|
||||
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
public string? FilePath { get; set; }
|
||||
|
||||
public string? FileName { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.后台任务执行完成");
|
||||
@@ -1,13 +1,8 @@
|
||||
using LLama.Common;
|
||||
using LLama;
|
||||
using LLama;
|
||||
using LLama.Common;
|
||||
using LLamaSharp.KernelMemory;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AntSK.Domain.Domain.Service
|
||||
namespace AntSK.Domain.Domain.Other
|
||||
{
|
||||
public static class LLamaConfig
|
||||
{
|
||||
@@ -16,7 +11,7 @@ namespace AntSK.Domain.Domain.Service
|
||||
/// 避免模型重复加载,本地缓存
|
||||
/// </summary>
|
||||
static Dictionary<string, (LLamaWeights, ModelParams)> dicLLamaWeights = new Dictionary<string, (LLamaWeights, ModelParams)>();
|
||||
public static (LLamaWeights, ModelParams) GetLLamaConfig(string modelPath, LLamaSharpConfig config =null)
|
||||
public static (LLamaWeights, ModelParams) GetLLamaConfig(string modelPath, LLamaSharpConfig config = null)
|
||||
{
|
||||
lock (lockobj)
|
||||
{
|
||||
@@ -28,7 +23,7 @@ namespace AntSK.Domain.Domain.Service
|
||||
{
|
||||
InferenceParams infParams = new() { AntiPrompts = ["\n\n"] };
|
||||
LLamaSharpConfig lsConfig = new(modelPath) { DefaultInferenceParams = infParams };
|
||||
if (config!=null)
|
||||
if (config != null)
|
||||
{
|
||||
lsConfig = config;
|
||||
}
|
||||
@@ -36,14 +31,14 @@ namespace AntSK.Domain.Domain.Service
|
||||
{
|
||||
ContextSize = lsConfig?.ContextSize ?? 2048,
|
||||
Seed = lsConfig?.Seed ?? 0,
|
||||
GpuLayerCount = lsConfig?.GpuLayerCount ?? 20,
|
||||
GpuLayerCount = lsConfig?.GpuLayerCount ?? 10,
|
||||
EmbeddingMode = true
|
||||
};
|
||||
var weights = LLamaWeights.LoadFromFile(parameters);
|
||||
dicLLamaWeights.Add(modelPath, (weights, parameters));
|
||||
return (weights, parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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.Text;
|
||||
using AntSK.Domain.Utils;
|
||||
using AntSK.Domain.Domain.Model.Dto;
|
||||
using AntSK.Domain.Domain.Model.Constant;
|
||||
using DocumentFormat.OpenXml.Drawing;
|
||||
using System.Reflection.Metadata;
|
||||
using Microsoft.KernelMemory;
|
||||
using System.Collections.Generic;
|
||||
using Markdig;
|
||||
|
||||
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, string filePath, List<RelevantSource> relevantSources = null)
|
||||
{
|
||||
var relevantSourceList = await _kMService.GetRelevantSourceList(app.KmsIdList, questions);
|
||||
var _kernel = _kernelService.GetKernelByApp(app);
|
||||
if (!string.IsNullOrWhiteSpace(filePath))
|
||||
{
|
||||
var memory = _kMService.GetMemory(app);
|
||||
var fileId = Guid.NewGuid().ToString();
|
||||
var result = await memory.ImportDocumentAsync(new Microsoft.KernelMemory.Document(fileId).AddFile(filePath)
|
||||
.AddTag(KmsConstantcs.KmsIdTag, app.Id)
|
||||
, index: KmsConstantcs.KmsIndex);
|
||||
|
||||
var filters = new MemoryFilter().ByTag(KmsConstantcs.KmsIdTag, app.Id);
|
||||
|
||||
var searchResult = await memory.SearchAsync(questions, index: KmsConstantcs.KmsIndex, filters: [filters]);
|
||||
relevantSourceList.AddRange(searchResult.Results.SelectMany(item => item.Partitions.Select(part => new RelevantSource()
|
||||
{
|
||||
SourceName = item.SourceName,
|
||||
Text = Markdown.ToHtml(part.Text),
|
||||
Relevance = part.Relevance
|
||||
})));
|
||||
}
|
||||
|
||||
var dataMsg = new StringBuilder();
|
||||
if (relevantSourceList.Any())
|
||||
{
|
||||
relevantSources?.AddRange(relevantSourceList);
|
||||
foreach (var item in relevantSources)
|
||||
{
|
||||
dataMsg.AppendLine(item.ToString());
|
||||
}
|
||||
|
||||
KernelFunction jsonFun = _kernel.Plugins.GetFunction("KMSPlugin", "Ask");
|
||||
var chatResult = _kernel.InvokeStreamingAsync(function: jsonFun,
|
||||
arguments: new KernelArguments() { ["doc"] = dataMsg, ["history"] = history, ["questions"] = questions });
|
||||
|
||||
await foreach (var content in chatResult)
|
||||
{
|
||||
yield return content;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return new StreamingTextContent(KmsConstantcs.KmsSearchNull);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
122
src/AntSK.Domain/Domain/Service/FunctionService.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Loader;
|
||||
using System.Xml;
|
||||
using AntSK.Domain.Common;
|
||||
using AntSK.Domain.Utils;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.SemanticKernel;
|
||||
using HtmlAgilityPack;
|
||||
using System.Collections.Generic;
|
||||
|
||||
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 Assembly[] _assemblies;
|
||||
private readonly AssemblyLoadContext loadContext;
|
||||
|
||||
public FunctionService(IServiceProvider serviceProvider, Assembly[] assemblies)
|
||||
{
|
||||
_methodCache = [];
|
||||
_methodInfos = [];
|
||||
_serviceProvider = serviceProvider;
|
||||
_assemblies = assemblies;
|
||||
loadContext = new AssemblyLoadContext("AntSKLoadContext", true);
|
||||
}
|
||||
|
||||
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.Contains( "AntSK");
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
//动态加载部分
|
||||
var loadedAssemblies = loadContext.Assemblies.ToList();
|
||||
foreach (var assembly in loadedAssemblies)
|
||||
{
|
||||
// 从缓存中获取标记了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.Contains("AntSK");
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
// 构建方法调用
|
||||
foreach (var method in markedMethods)
|
||||
{
|
||||
var key = $"{method.DeclaringType.Assembly.GetName().Name}_{method.DeclaringType.Name}_{method.Name}";
|
||||
string pattern = "[^a-zA-Z0-9_]";
|
||||
// 使用 '-' 替换非ASCII的正则表达式的字符
|
||||
key = Regex.Replace(key, pattern, "_");
|
||||
_methodCache.TryAdd(key, method);
|
||||
|
||||
var description= method.GetCustomAttribute<DescriptionAttribute>().Description.ConvertToString().Replace("AntSK:","");
|
||||
var returnType = method.ReturnParameter.GetCustomAttribute<DescriptionAttribute>().Description.ConvertToString();
|
||||
var parameters = method.GetParameters().Select(x => (x.Name, x.ParameterType,x.GetCustomAttribute<DescriptionAttribute>()?.Description)).ToArray();
|
||||
// 假设 _methodInfos 是一个已经定义好的字典,用来保存方法的相关信息
|
||||
_methodInfos.TryAdd(key, (description, (method.ReflectedType, returnType), parameters));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void FuncLoad(string pluginPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(pluginPath))
|
||||
{
|
||||
string directory = Path.GetDirectoryName(pluginPath);
|
||||
string fileName = Path.GetFileName(pluginPath);
|
||||
var resolver = new AssemblyDependencyResolver(directory);
|
||||
|
||||
// Create a custom AssemblyLoadContext
|
||||
|
||||
loadContext.Resolving += (context, assemblyName) =>
|
||||
{
|
||||
string assemblyPath = resolver.ResolveAssemblyToPath(assemblyName);
|
||||
if (assemblyPath != null)
|
||||
{
|
||||
return context.LoadFromAssemblyPath(assemblyPath);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
// Load your assembly
|
||||
Assembly pluginAssembly = loadContext.LoadFromAssemblyPath(pluginPath);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message + " ---- " + ex.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,9 @@
|
||||
using AntSK.Domain.Common.DependencyInjection;
|
||||
using AntSK.Domain.Domain.Interface;
|
||||
using AntSK.Domain.Model;
|
||||
using AntSK.Domain.Domain.Model;
|
||||
using AntSK.Domain.Domain.Model.Constant;
|
||||
using AntSK.Domain.Repositories;
|
||||
using Microsoft.KernelMemory;
|
||||
using Microsoft.KernelMemory.Configuration;
|
||||
using Microsoft.SemanticKernel.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AntSK.Domain.Domain.Service
|
||||
{
|
||||
@@ -34,12 +28,12 @@ namespace AntSK.Domain.Domain.Service
|
||||
case ImportType.File:
|
||||
//导入文件
|
||||
{
|
||||
var importResult= _memory.ImportDocumentAsync(new Document(fileid)
|
||||
.AddFile(req.FilePath)
|
||||
.AddTag("kmsid", req.KmsId)
|
||||
, index: "kms").Result;
|
||||
var importResult = _memory.ImportDocumentAsync(new Document(fileid)
|
||||
.AddFile(req.FilePath)
|
||||
.AddTag(KmsConstantcs.KmsIdTag, req.KmsId)
|
||||
, index: KmsConstantcs.KmsIndex).Result;
|
||||
//查询文档数量
|
||||
var docTextList = _kMService.GetDocumentByFileID(km.Id,fileid).Result;
|
||||
var docTextList = _kMService.GetDocumentByFileID(km.Id, fileid).Result;
|
||||
string fileGuidName = Path.GetFileName(req.FilePath);
|
||||
req.KmsDetail.FileName = req.FileName;
|
||||
req.KmsDetail.FileGuidName = fileGuidName;
|
||||
@@ -50,10 +44,10 @@ namespace AntSK.Domain.Domain.Service
|
||||
case ImportType.Url:
|
||||
{
|
||||
//导入url
|
||||
var importResult = _memory.ImportWebPageAsync(req.Url, fileid, new TagCollection() { { "kmsid", req.KmsId } }
|
||||
, index: "kms").Result;
|
||||
var importResult = _memory.ImportWebPageAsync(req.Url, fileid, new TagCollection() { { KmsConstantcs.KmsIdTag, req.KmsId } }
|
||||
, index: KmsConstantcs.KmsIndex).Result;
|
||||
//查询文档数量
|
||||
var docTextList = _kMService.GetDocumentByFileID(km.Id,fileid).Result;
|
||||
var docTextList = _kMService.GetDocumentByFileID(km.Id, fileid).Result;
|
||||
req.KmsDetail.Url = req.Url;
|
||||
req.KmsDetail.DataCount = docTextList.Count;
|
||||
}
|
||||
@@ -61,10 +55,10 @@ namespace AntSK.Domain.Domain.Service
|
||||
case ImportType.Text:
|
||||
//导入文本
|
||||
{
|
||||
var importResult = _memory.ImportTextAsync(req.Text, fileid, new TagCollection() { { "kmsid", req.KmsId } }
|
||||
, index: "kms").Result;
|
||||
var importResult = _memory.ImportTextAsync(req.Text, fileid, new TagCollection() { { KmsConstantcs.KmsIdTag, req.KmsId } }
|
||||
, index: KmsConstantcs.KmsIndex).Result;
|
||||
//查询文档数量
|
||||
var docTextList = _kMService.GetDocumentByFileID(km.Id,fileid).Result;
|
||||
var docTextList = _kMService.GetDocumentByFileID(km.Id, fileid).Result;
|
||||
req.KmsDetail.Url = req.Url;
|
||||
req.KmsDetail.DataCount = docTextList.Count;
|
||||
|
||||
@@ -72,14 +66,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,75 +1,125 @@
|
||||
using AntSK.Domain.Common.DependencyInjection;
|
||||
using AntDesign;
|
||||
using AntSK.Domain.Common.DependencyInjection;
|
||||
using AntSK.Domain.Domain.Interface;
|
||||
using Microsoft.KernelMemory;
|
||||
using AntSK.Domain.Utils;
|
||||
using AntSK.Domain.Domain.Dto;
|
||||
using AntSK.Domain.Domain.Model.Constant;
|
||||
using AntSK.Domain.Domain.Model.Dto;
|
||||
using AntSK.Domain.Domain.Other;
|
||||
using AntSK.Domain.Options;
|
||||
using Microsoft.KernelMemory.ContentStorage.DevTools;
|
||||
using Microsoft.KernelMemory.FileSystem.DevTools;
|
||||
using Microsoft.KernelMemory.Postgres;
|
||||
using System.Net.Http;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.KernelMemory.Configuration;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using AntSK.Domain.Repositories;
|
||||
using LLamaSharp.KernelMemory;
|
||||
using LLama.Common;
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using AntSK.Domain.Utils;
|
||||
using DocumentFormat.OpenXml.Drawing.Diagrams;
|
||||
using LLama;
|
||||
using LLamaSharp.KernelMemory;
|
||||
using Markdig;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.KernelMemory;
|
||||
using Microsoft.KernelMemory.Configuration;
|
||||
using Microsoft.KernelMemory.FileSystem.DevTools;
|
||||
using Microsoft.KernelMemory.MemoryStorage;
|
||||
using Microsoft.KernelMemory.MemoryStorage.DevTools;
|
||||
using Microsoft.KernelMemory.Postgres;
|
||||
|
||||
namespace AntSK.Domain.Domain.Service
|
||||
{
|
||||
[ServiceDescription(typeof(IKMService), ServiceLifetime.Scoped)]
|
||||
public class KMService(
|
||||
IConfiguration _config,
|
||||
IKmss_Repositories _kmss_Repositories,
|
||||
IAIModels_Repositories _aIModels_Repositories
|
||||
) : IKMService
|
||||
IKmss_Repositories _kmss_Repositories,
|
||||
IAIModels_Repositories _aIModels_Repositories,
|
||||
IMessageService? _message
|
||||
) : IKMService
|
||||
{
|
||||
public MemoryServerless GetMemoryByKMS(string kmsID, SearchClientConfig searchClientConfig = null)
|
||||
{
|
||||
//获取KMS配置
|
||||
var kms = _kmss_Repositories.GetFirst(p => p.Id == kmsID);
|
||||
var chatModel = _aIModels_Repositories.GetFirst(p => p.Id == kms.ChatModelID);
|
||||
var embedModel = _aIModels_Repositories.GetFirst(p => p.Id == kms.EmbeddingModelID);
|
||||
private MemoryServerless _memory;
|
||||
|
||||
//http代理
|
||||
private List<UploadFileItem> _fileList = [];
|
||||
|
||||
public List<UploadFileItem> FileList => _fileList;
|
||||
|
||||
public MemoryServerless GetMemory(Apps app)
|
||||
{
|
||||
var chatModel = _aIModels_Repositories.GetFirst(p => p.Id == app.ChatModelID);
|
||||
var embedModel = _aIModels_Repositories.GetFirst(p => p.Id == app.EmbeddingModelID);
|
||||
var chatHttpClient = OpenAIHttpClientHandlerUtil.GetHttpClient(chatModel.EndPoint);
|
||||
var embeddingHttpClient = OpenAIHttpClientHandlerUtil.GetHttpClient(embedModel.EndPoint);
|
||||
|
||||
//搜索配置
|
||||
if (searchClientConfig.IsNull())
|
||||
var searchClientConfig = new SearchClientConfig
|
||||
{
|
||||
searchClientConfig = new SearchClientConfig
|
||||
{
|
||||
MaxAskPromptSize = 2048,
|
||||
MaxMatchesCount = 3,
|
||||
AnswerTokens = 1000,
|
||||
EmptyAnswer = "知识库未搜索到相关内容"
|
||||
};
|
||||
}
|
||||
MaxAskPromptSize = 2048,
|
||||
MaxMatchesCount = 3,
|
||||
AnswerTokens = 1000,
|
||||
EmptyAnswer = KmsConstantcs.KmsSearchNull
|
||||
};
|
||||
|
||||
var memory = new KernelMemoryBuilder()
|
||||
.WithSearchClientConfig(searchClientConfig)
|
||||
.WithCustomTextPartitioningOptions(new TextPartitioningOptions
|
||||
{
|
||||
MaxTokensPerLine = kms.MaxTokensPerLine,
|
||||
MaxTokensPerParagraph = kms.MaxTokensPerParagraph,
|
||||
OverlappingTokens = kms.OverlappingTokens
|
||||
});
|
||||
//加载huihu 模型
|
||||
WithTextGenerationByAIType(memory, chatModel, chatHttpClient);
|
||||
var memoryBuild = new KernelMemoryBuilder()
|
||||
.WithSearchClientConfig(searchClientConfig)
|
||||
//.WithCustomTextPartitioningOptions(new TextPartitioningOptions
|
||||
//{
|
||||
// MaxTokensPerLine = app.MaxTokensPerLine,
|
||||
// MaxTokensPerParagraph = kms.MaxTokensPerParagraph,
|
||||
// OverlappingTokens = kms.OverlappingTokens
|
||||
//})
|
||||
;
|
||||
//加载会话模型
|
||||
WithTextGenerationByAIType(memoryBuild, chatModel, chatHttpClient);
|
||||
//加载向量模型
|
||||
WithTextEmbeddingGenerationByAIType(memory,embedModel, embeddingHttpClient);
|
||||
WithTextEmbeddingGenerationByAIType(memoryBuild, embedModel, embeddingHttpClient);
|
||||
//加载向量库
|
||||
WithMemoryDbByVectorDB(memory, _config);
|
||||
|
||||
var result = memory.Build<MemoryServerless>();
|
||||
return result;
|
||||
WithMemoryDbByVectorDB(memoryBuild);
|
||||
|
||||
_memory = memoryBuild.Build<MemoryServerless>();
|
||||
return _memory;
|
||||
}
|
||||
|
||||
private void WithTextEmbeddingGenerationByAIType(IKernelMemoryBuilder memory,AIModels embedModel, HttpClient embeddingHttpClient )
|
||||
public MemoryServerless GetMemoryByKMS(string kmsID, SearchClientConfig searchClientConfig = null)
|
||||
{
|
||||
//if (_memory.IsNull())
|
||||
{
|
||||
//获取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())
|
||||
{
|
||||
searchClientConfig = new SearchClientConfig
|
||||
{
|
||||
MaxAskPromptSize = 2048,
|
||||
MaxMatchesCount = 3,
|
||||
AnswerTokens = 1000,
|
||||
EmptyAnswer = KmsConstantcs.KmsSearchNull
|
||||
};
|
||||
}
|
||||
|
||||
var memoryBuild = new KernelMemoryBuilder()
|
||||
.WithSearchClientConfig(searchClientConfig)
|
||||
.WithCustomTextPartitioningOptions(new TextPartitioningOptions
|
||||
{
|
||||
MaxTokensPerLine = kms.MaxTokensPerLine,
|
||||
MaxTokensPerParagraph = kms.MaxTokensPerParagraph,
|
||||
OverlappingTokens = kms.OverlappingTokens
|
||||
});
|
||||
//加载会话模型
|
||||
WithTextGenerationByAIType(memoryBuild, chatModel, chatHttpClient);
|
||||
//加载向量模型
|
||||
WithTextEmbeddingGenerationByAIType(memoryBuild, embedModel, embeddingHttpClient);
|
||||
//加载向量库
|
||||
WithMemoryDbByVectorDB(memoryBuild);
|
||||
|
||||
_memory = memoryBuild.Build<MemoryServerless>();
|
||||
return _memory;
|
||||
}
|
||||
//else {
|
||||
// return _memory;
|
||||
//}
|
||||
}
|
||||
|
||||
private void WithTextEmbeddingGenerationByAIType(IKernelMemoryBuilder memory, AIModels embedModel,
|
||||
HttpClient embeddingHttpClient)
|
||||
{
|
||||
switch (embedModel.AIType)
|
||||
{
|
||||
@@ -80,23 +130,31 @@ namespace AntSK.Domain.Domain.Service
|
||||
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()
|
||||
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;
|
||||
case Model.Enum.AIType.DashScope:
|
||||
memory.WithDashScopeDefaults(embedModel.ModelKey);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void WithTextGenerationByAIType(IKernelMemoryBuilder memory,AIModels chatModel, HttpClient chatHttpClient )
|
||||
private void WithTextGenerationByAIType(IKernelMemoryBuilder memory, AIModels chatModel,
|
||||
HttpClient chatHttpClient)
|
||||
{
|
||||
switch (chatModel.AIType)
|
||||
{
|
||||
@@ -107,28 +165,38 @@ namespace AntSK.Domain.Domain.Service
|
||||
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()
|
||||
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;
|
||||
case Model.Enum.AIType.DashScope:
|
||||
memory.WithDashScopeTextGeneration(new Cnblogs.KernelMemory.AI.DashScope.DashScopeConfig
|
||||
{
|
||||
ApiKey = chatModel.ModelKey,
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void WithMemoryDbByVectorDB(IKernelMemoryBuilder memory,IConfiguration _config)
|
||||
private void WithMemoryDbByVectorDB(IKernelMemoryBuilder memory)
|
||||
{
|
||||
string VectorDb = _config["KernelMemory:VectorDb"].ConvertToString();
|
||||
string ConnectionString = _config["KernelMemory:ConnectionString"].ConvertToString();
|
||||
string TableNamePrefix = _config["KernelMemory:TableNamePrefix"].ConvertToString();
|
||||
string VectorDb = KernelMemoryOption.VectorDb.ConvertToString();
|
||||
string ConnectionString = KernelMemoryOption.ConnectionString.ConvertToString();
|
||||
string TableNamePrefix = KernelMemoryOption.TableNamePrefix.ConvertToString();
|
||||
switch (VectorDb)
|
||||
{
|
||||
case "Postgres":
|
||||
@@ -138,14 +206,16 @@ namespace AntSK.Domain.Domain.Service
|
||||
TableNamePrefix = TableNamePrefix
|
||||
});
|
||||
break;
|
||||
|
||||
case "Disk":
|
||||
memory.WithSimpleFileStorage(new SimpleFileStorageConfig()
|
||||
memory.WithSimpleVectorDb(new SimpleVectorDbConfig()
|
||||
{
|
||||
StorageType = FileSystemTypes.Disk
|
||||
StorageType = FileSystemTypes.Disk,
|
||||
});
|
||||
break;
|
||||
|
||||
case "Memory":
|
||||
memory.WithSimpleFileStorage(new SimpleFileStorageConfig()
|
||||
memory.WithSimpleVectorDb(new SimpleVectorDbConfig()
|
||||
{
|
||||
StorageType = FileSystemTypes.Volatile
|
||||
});
|
||||
@@ -153,36 +223,103 @@ namespace AntSK.Domain.Domain.Service
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<KMFile>> GetDocumentByFileID(string kmsid,string fileid)
|
||||
public async Task<List<KMFile>> GetDocumentByFileID(string kmsId, string fileId)
|
||||
{
|
||||
var _memory = GetMemoryByKMS(kmsid);
|
||||
var memories = await _memory.ListIndexesAsync();
|
||||
var memoryDbs = _memory.Orchestrator.GetMemoryDbs();
|
||||
List<KMFile> docTextList = new List<KMFile>();
|
||||
var memory = GetMemoryByKMS(kmsId);
|
||||
var memories = await memory.ListIndexesAsync();
|
||||
var memoryDbs = memory.Orchestrator.GetMemoryDbs();
|
||||
var docTextList = new List<KMFile>();
|
||||
|
||||
foreach (var memoryIndex in memories)
|
||||
{
|
||||
foreach (var memoryDb in memoryDbs)
|
||||
{
|
||||
|
||||
var items = await memoryDb.GetListAsync(memoryIndex.Name, new List<MemoryFilter>() { new MemoryFilter().ByDocument(fileid) }, 100, true).ToListAsync();
|
||||
foreach (var item in items)
|
||||
var items = await memoryDb.GetListAsync(memoryIndex.Name, new List<MemoryFilter>() { new MemoryFilter().ByDocument(fileId) }, 100, true).ToListAsync();
|
||||
docTextList.AddRange(items.Select(item => new KMFile()
|
||||
{
|
||||
KMFile file = new KMFile()
|
||||
{
|
||||
Text = item.Payload.FirstOrDefault(p => p.Key == "text").Value.ConvertToString(),
|
||||
Url = item.Payload.FirstOrDefault(p => p.Key == "url").Value.ConvertToString(),
|
||||
LastUpdate = item.Payload.FirstOrDefault(p => p.Key == "last_update").Value.ConvertToString(),
|
||||
Schema = item.Payload.FirstOrDefault(p => p.Key == "schema").Value.ConvertToString(),
|
||||
File = item.Payload.FirstOrDefault(p => p.Key == "file").Value.ConvertToString(),
|
||||
};
|
||||
docTextList.Add(file);
|
||||
}
|
||||
DocumentId = item.GetDocumentId(),
|
||||
Text = item.GetPartitionText(),
|
||||
Url = item.GetWebPageUrl(),
|
||||
LastUpdate = item.GetLastUpdate().LocalDateTime.ToString("yyyy-MM-dd HH:mm:ss"),
|
||||
File = item.GetFileName()
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
return docTextList;
|
||||
}
|
||||
|
||||
|
||||
public async Task<List<RelevantSource>> GetRelevantSourceList(string kmsIdListStr, string msg)
|
||||
{
|
||||
var result = new List<RelevantSource>();
|
||||
if (string.IsNullOrWhiteSpace(kmsIdListStr))
|
||||
return result;
|
||||
var kmsIdList = kmsIdListStr.Split(",");
|
||||
if (!kmsIdList.Any()) return result;
|
||||
|
||||
var memory = GetMemoryByKMS(kmsIdList.FirstOrDefault()!);
|
||||
|
||||
var filters = kmsIdList.Select(kmsId => new MemoryFilter().ByTag(KmsConstantcs.KmsIdTag, kmsId)).ToList();
|
||||
|
||||
var searchResult = await memory.SearchAsync(msg, index: KmsConstantcs.KmsIndex, filters: filters);
|
||||
if (!searchResult.NoResult)
|
||||
{
|
||||
foreach (var item in searchResult.Results)
|
||||
{
|
||||
result.AddRange(item.Partitions.Select(part => new RelevantSource()
|
||||
{
|
||||
SourceName = item.SourceName,
|
||||
Text = Markdown.ToHtml(part.Text),
|
||||
Relevance = part.Relevance
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool BeforeUpload(UploadFileItem file)
|
||||
{
|
||||
List<string> types = new List<string>() {
|
||||
"text/plain",
|
||||
"application/msword",
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
"application/vnd.ms-excel",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"application/vnd.ms-powerpoint",
|
||||
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
||||
"application/pdf",
|
||||
"application/json",
|
||||
"text/x-markdown",
|
||||
"text/markdown"
|
||||
};
|
||||
|
||||
string[] exceptExts = [".md", ".pdf"];
|
||||
var validTypes = types.Contains(file.Type) || exceptExts.Contains(file.Ext);
|
||||
if (!validTypes && file.Ext != ".md")
|
||||
{
|
||||
_message.Error("文件格式错误,请重新选择!");
|
||||
}
|
||||
var IsLt500K = file.Size < 1024 * 1024 * 100;
|
||||
if (!IsLt500K)
|
||||
{
|
||||
_message.Error("文件需不大于100MB!");
|
||||
}
|
||||
|
||||
return validTypes && IsLt500K;
|
||||
}
|
||||
|
||||
public void OnSingleCompleted(UploadInfo fileinfo)
|
||||
{
|
||||
if (fileinfo.File.State == UploadState.Success)
|
||||
{
|
||||
//文件列表
|
||||
_fileList.Add(new UploadFileItem()
|
||||
{
|
||||
FileName = fileinfo.File.FileName,
|
||||
Url = fileinfo.File.Url = fileinfo.File.Response
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,43 +1,46 @@
|
||||
using AntSK.Domain.Common.DependencyInjection;
|
||||
using AntSK.LLM.SparkDesk;
|
||||
using AntSK.Domain.Common.DependencyInjection;
|
||||
using AntSK.Domain.Domain.Interface;
|
||||
using AntSK.Domain.Model;
|
||||
using AntSK.Domain.Options;
|
||||
using AntSK.Domain.Domain.Other;
|
||||
using AntSK.Domain.Repositories;
|
||||
using AntSK.Domain.Utils;
|
||||
using DocumentFormat.OpenXml.EMMA;
|
||||
using LLama;
|
||||
using LLamaSharp.KernelMemory;
|
||||
using LLamaSharp.SemanticKernel.TextCompletion;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.KernelMemory;
|
||||
using Microsoft.SemanticKernel;
|
||||
using Microsoft.SemanticKernel.Plugins.Core;
|
||||
using Microsoft.SemanticKernel.TextGeneration;
|
||||
using RestSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ServiceLifetime = AntSK.Domain.Common.DependencyInjection.ServiceLifetime;
|
||||
using AntSK.LLM.Mock;
|
||||
using AntSK.Domain.Domain.Model.Enum;
|
||||
using System.Reflection;
|
||||
using DocumentFormat.OpenXml.Drawing;
|
||||
|
||||
namespace AntSK.Domain.Domain.Service
|
||||
{
|
||||
[ServiceDescription(typeof(IKernelService), ServiceLifetime.Scoped)]
|
||||
public class KernelService: IKernelService
|
||||
public class KernelService : IKernelService
|
||||
{
|
||||
private readonly IApis_Repositories _apis_Repositories;
|
||||
private readonly IAIModels_Repositories _aIModels_Repositories;
|
||||
private readonly FunctionService _functionService;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private Kernel _kernel;
|
||||
|
||||
public KernelService(
|
||||
IApis_Repositories apis_Repositories,
|
||||
IAIModels_Repositories aIModels_Repositories
|
||||
)
|
||||
IAIModels_Repositories aIModels_Repositories,
|
||||
FunctionService functionService,
|
||||
IServiceProvider serviceProvider)
|
||||
{
|
||||
_apis_Repositories = apis_Repositories;
|
||||
_aIModels_Repositories = aIModels_Repositories;
|
||||
|
||||
_functionService = functionService;
|
||||
_serviceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取kernel实例,依赖注入不好按每个用户去Import不同的插件,所以每次new一个新的kernel
|
||||
/// </summary>
|
||||
@@ -46,20 +49,26 @@ namespace AntSK.Domain.Domain.Service
|
||||
/// <returns></returns>
|
||||
public Kernel GetKernelByApp(Apps app)
|
||||
{
|
||||
var chatModel= _aIModels_Repositories.GetFirst(p => p.Id == app.ChatModelID);
|
||||
//if (_kernel.IsNull())
|
||||
{
|
||||
var chatModel = _aIModels_Repositories.GetFirst(p => p.Id == app.ChatModelID);
|
||||
|
||||
var chatHttpClient = OpenAIHttpClientHandlerUtil.GetHttpClient(chatModel.EndPoint);
|
||||
var chatHttpClient = OpenAIHttpClientHandlerUtil.GetHttpClient(chatModel.EndPoint);
|
||||
|
||||
var builder = Kernel.CreateBuilder();
|
||||
WithTextGenerationByAIType(builder, chatModel, chatHttpClient);
|
||||
var builder = Kernel.CreateBuilder();
|
||||
WithTextGenerationByAIType(builder, app, chatModel, chatHttpClient);
|
||||
|
||||
|
||||
var kernel= builder.Build();
|
||||
RegisterPluginsWithKernel(kernel);
|
||||
return kernel;
|
||||
_kernel = builder.Build();
|
||||
RegisterPluginsWithKernel(_kernel);
|
||||
return _kernel;
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// return _kernel;
|
||||
//}
|
||||
}
|
||||
|
||||
private void WithTextGenerationByAIType(IKernelBuilder builder, AIModels chatModel, HttpClient chatHttpClient)
|
||||
private void WithTextGenerationByAIType(IKernelBuilder builder, Apps app, AIModels chatModel, HttpClient chatHttpClient)
|
||||
{
|
||||
switch (chatModel.AIType)
|
||||
{
|
||||
@@ -69,18 +78,33 @@ namespace AntSK.Domain.Domain.Service
|
||||
apiKey: chatModel.ModelKey,
|
||||
httpClient: chatHttpClient);
|
||||
break;
|
||||
|
||||
case Model.Enum.AIType.AzureOpenAI:
|
||||
builder.AddAzureOpenAIChatCompletion(
|
||||
deploymentName:chatModel.ModelName,
|
||||
deploymentName: chatModel.ModelName,
|
||||
apiKey: chatModel.ModelKey,
|
||||
endpoint: chatModel.EndPoint
|
||||
);
|
||||
break;
|
||||
|
||||
case Model.Enum.AIType.LLamaSharp:
|
||||
var (weights, parameters) = LLamaConfig.GetLLamaConfig(chatModel.ModelName);
|
||||
var ex = new StatelessExecutor(weights, parameters);
|
||||
builder.Services.AddKeyedSingleton<ITextGenerationService>("local-llama", new LLamaSharpTextCompletion(ex));
|
||||
break;
|
||||
|
||||
case Model.Enum.AIType.SparkDesk:
|
||||
var options = new SparkDeskOptions { AppId = chatModel.EndPoint, ApiSecret = chatModel.ModelKey, ApiKey = chatModel.ModelName, ModelVersion = Sdcb.SparkDesk.ModelVersion.V3_5 };
|
||||
builder.Services.AddKeyedSingleton<ITextGenerationService>("spark-desk", new SparkDeskTextCompletion(options, app.Id));
|
||||
break;
|
||||
|
||||
case Model.Enum.AIType.DashScope:
|
||||
builder.Services.AddDashScopeChatCompletion(chatModel.ModelKey, chatModel.ModelName);
|
||||
break;
|
||||
|
||||
case Model.Enum.AIType.Mock:
|
||||
builder.Services.AddKeyedSingleton<ITextGenerationService>("mock", new MockTextCompletion());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,25 +115,57 @@ 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> functions = new List<KernelFunction>();
|
||||
|
||||
//API插件
|
||||
ImportApiFunction(app, functions);
|
||||
//本地函数插件
|
||||
ImportNativeFunction(app, functions);
|
||||
|
||||
_kernel.ImportPluginFromFunctions("AntSkFunctions", functions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导入API插件
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <param name="functions"></param>
|
||||
private void ImportApiFunction(Apps app, List<KernelFunction> functions)
|
||||
{
|
||||
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)
|
||||
{
|
||||
var returnType = new KernelReturnParameterMetadata() { Description = api.OutputPrompt };
|
||||
switch (api.Method)
|
||||
{
|
||||
case HttpMethodType.Get:
|
||||
functions.Add(_kernel.CreateFunctionFromMethod((string msg) =>
|
||||
|
||||
var getParametes = new List<KernelParameterMetadata>() {
|
||||
new KernelParameterMetadata("jsonbody"){
|
||||
Name="json参数字符串",
|
||||
ParameterType=typeof(string),
|
||||
Description=$"需要根据背景文档:{Environment.NewLine}{api.InputPrompt} {Environment.NewLine}提取出对应的json格式字符串,参考如下格式:{Environment.NewLine}{api.Query}"
|
||||
}
|
||||
};
|
||||
functions.Add(_kernel.CreateFunctionFromMethod((string jsonbody) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.WriteLine(msg);
|
||||
//将json 转换为query参数
|
||||
var queryString = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonbody);
|
||||
RestClient client = new RestClient();
|
||||
RestRequest request = new RestRequest(api.Url, Method.Get);
|
||||
foreach (var header in api.Header.Split("\n"))
|
||||
foreach (var header in api.Header.ConvertToString().Split("\n"))
|
||||
{
|
||||
var headerArray = header.Split(":");
|
||||
if (headerArray.Length == 2)
|
||||
@@ -118,13 +174,9 @@ namespace AntSK.Domain.Domain.Service
|
||||
}
|
||||
}
|
||||
//这里应该还要处理一次参数提取,等后面再迭代
|
||||
foreach (var query in api.Query.Split("\n"))
|
||||
foreach (var q in queryString)
|
||||
{
|
||||
var queryArray = query.Split("=");
|
||||
if (queryArray.Length == 2)
|
||||
{
|
||||
request.AddQueryParameter(queryArray[0], queryArray[1]);
|
||||
}
|
||||
request.AddQueryParameter(q.Key, q.Value);
|
||||
}
|
||||
var result = client.Execute(request);
|
||||
return result.Content;
|
||||
@@ -133,17 +185,25 @@ namespace AntSK.Domain.Domain.Service
|
||||
{
|
||||
return "调用失败:" + ex.Message;
|
||||
}
|
||||
}, api.Name, $"{api.Describe}"));
|
||||
}, api.Name, api.Describe, getParametes, returnType));
|
||||
break;
|
||||
case HttpMethodType.Post:
|
||||
functions.Add(_kernel.CreateFunctionFromMethod((string msg) =>
|
||||
//处理json body
|
||||
var postParametes = new List<KernelParameterMetadata>() {
|
||||
new KernelParameterMetadata("jsonbody"){
|
||||
Name="json参数字符串",
|
||||
ParameterType=typeof(string),
|
||||
Description=$"需要根据背景文档:{Environment.NewLine}{api.InputPrompt} {Environment.NewLine}提取出对应的json格式字符串,参考如下格式:{Environment.NewLine}{api.JsonBody}"
|
||||
}
|
||||
};
|
||||
functions.Add(_kernel.CreateFunctionFromMethod((string jsonBody) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.WriteLine(msg);
|
||||
Console.WriteLine(jsonBody);
|
||||
RestClient client = new RestClient();
|
||||
RestRequest request = new RestRequest(api.Url, Method.Post);
|
||||
foreach (var header in api.Header.Split("\n"))
|
||||
foreach (var header in api.Header.ConvertToString().Split("\n"))
|
||||
{
|
||||
var headerArray = header.Split(":");
|
||||
if (headerArray.Length == 2)
|
||||
@@ -152,7 +212,7 @@ namespace AntSK.Domain.Domain.Service
|
||||
}
|
||||
}
|
||||
//这里应该还要处理一次参数提取,等后面再迭代
|
||||
request.AddJsonBody(api.JsonBody);
|
||||
request.AddJsonBody(jsonBody.ConvertToString());
|
||||
var result = client.Execute(request);
|
||||
return result.Content;
|
||||
}
|
||||
@@ -160,24 +220,51 @@ namespace AntSK.Domain.Domain.Service
|
||||
{
|
||||
return "调用失败:" + ex.Message;
|
||||
}
|
||||
}, api.Name, $"{api.Describe}"));
|
||||
}, api.Name, api.Describe, postParametes, returnType));
|
||||
break;
|
||||
}
|
||||
}
|
||||
_kernel.ImportPluginFromFunctions("ApiFunctions", functions);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导入原生插件
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <param name="functions"></param>
|
||||
private void ImportNativeFunction(Apps app, List<KernelFunction> 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);
|
||||
functions.Add(_kernel.CreateFunctionFromMethod(func.Value, target, func.Key, methodInfo.Description, parameters, returnType));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <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.ImportPluginFromPromptDirectory(Path.Combine(RepoFiles.SamplePluginsPath(), "KMSPlugin"));
|
||||
//kernel.ImportPluginFromObject(new TimePlugin(), "TimePlugin");
|
||||
kernel.ImportPluginFromPromptDirectory(System.IO.Path.Combine(RepoFiles.SamplePluginsPath(), "KMSPlugin"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -187,13 +274,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,27 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AntSK.Domain.Model.Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// AI类型
|
||||
/// </summary>
|
||||
public enum AIType
|
||||
{
|
||||
OpenAI = 1,
|
||||
AzureOpenAI = 2,
|
||||
LLamaSharp=3
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 模型类型
|
||||
/// </summary>
|
||||
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,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
|
||||
{
|
||||
@@ -25,6 +20,7 @@ namespace AntSK.Domain.Repositories
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Describe { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 图标
|
||||
/// </summary>
|
||||
@@ -43,11 +39,16 @@ namespace AntSK.Domain.Repositories
|
||||
[Required]
|
||||
public string? ChatModelID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Embedding 模型Id
|
||||
/// </summary>
|
||||
public string? EmbeddingModelID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 温度
|
||||
/// </summary>
|
||||
[SugarColumn(DefaultValue = "70")]
|
||||
public double Temperature { get; set; }=70f;
|
||||
public double Temperature { get; set; } = 70f;
|
||||
|
||||
/// <summary>
|
||||
/// 提示词
|
||||
@@ -57,16 +58,23 @@ 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列表
|
||||
/// </summary>
|
||||
public string? KmsIdList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// API调用秘钥
|
||||
/// </summary>
|
||||
public string? SecretKey { 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
|
||||
{
|
||||
|
||||
20
src/AntSK.Domain/Repositories/AI/Fun/Funs.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using AntSK.Domain.Domain.Model.Enum;
|
||||
using SqlSugar;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AntSK.Domain.Repositories
|
||||
{
|
||||
[SugarTable("Funs")]
|
||||
public partial class Funs
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 接口描述
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Path { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
11
src/AntSK.Domain/Repositories/AI/Fun/Funs_Repositories.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
using AntSK.Domain.Common.DependencyInjection;
|
||||
using AntSK.Domain.Repositories.Base;
|
||||
|
||||
namespace AntSK.Domain.Repositories
|
||||
{
|
||||
[ServiceDescription(typeof(IFuns_Repositories), ServiceLifetime.Scoped)]
|
||||
public class Funs_Repositories : Repository<Funs>, IFuns_Repositories
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using AntSK.Domain.Repositories.Base;
|
||||
|
||||
namespace AntSK.Domain.Repositories
|
||||
{
|
||||
public interface IFuns_Repositories : IRepository<Funs>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
@@ -60,6 +55,6 @@ namespace AntSK.Domain.Repositories
|
||||
[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
|
||||
{
|
||||
@@ -25,7 +20,7 @@ namespace AntSK.Domain.Repositories
|
||||
/// 模型类型
|
||||
/// </summary>
|
||||
[Required]
|
||||
public AIModelType AIModelType { get; set; }= AIModelType.Chat;
|
||||
public AIModelType AIModelType { get; set; } = AIModelType.Chat;
|
||||
/// <summary>
|
||||
/// 模型地址
|
||||
/// </summary>
|
||||
|
||||
@@ -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,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
|
||||
namespace AntSK.Domain.Utils
|
||||
{
|
||||
@@ -237,5 +233,22 @@ namespace AntSK.Domain.Utils
|
||||
{
|
||||
return $"{Environment.NewLine}```json{Environment.NewLine}{s}{Environment.NewLine}```{Environment.NewLine}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// json参数转化querystring参数
|
||||
/// </summary>
|
||||
/// <param name="parameters"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToQueryString(this Dictionary<string, string> parameters)
|
||||
{
|
||||
var nameValueCollection = HttpUtility.ParseQueryString(string.Empty);
|
||||
|
||||
foreach (var param in parameters)
|
||||
{
|
||||
nameValueCollection[param.Key] = param.Value;
|
||||
}
|
||||
|
||||
return nameValueCollection.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,11 +1,4 @@
|
||||
using AntSK.Domain.Options;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace AntSK.Domain.Utils
|
||||
{
|
||||
@@ -23,7 +16,7 @@ namespace AntSK.Domain.Utils
|
||||
Regex regex = new Regex(@"(https?)://([^/:]+)(:\d+)?/(.*)");
|
||||
Match match = regex.Match(_endPoint);
|
||||
if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development" && request.Content != null)
|
||||
{
|
||||
{
|
||||
string requestBody = await request.Content.ReadAsStringAsync();
|
||||
//便于调试查看请求prompt
|
||||
Console.WriteLine(requestBody);
|
||||
@@ -47,14 +40,14 @@ namespace AntSK.Domain.Utils
|
||||
{
|
||||
// 这里是你要修改的 URL
|
||||
Scheme = $"{xieyi}://{hostnew}/",
|
||||
Host = host,
|
||||
Host = host,
|
||||
Path = route + "v1/chat/completions",
|
||||
};
|
||||
if (port.ConvertToInt32() != 0)
|
||||
{
|
||||
uriBuilder.Port = port.ConvertToInt32();
|
||||
}
|
||||
|
||||
|
||||
request.RequestUri = uriBuilder.Uri;
|
||||
|
||||
break;
|
||||
@@ -83,9 +76,9 @@ namespace AntSK.Domain.Utils
|
||||
}
|
||||
|
||||
|
||||
public class OpenAIHttpClientHandlerUtil
|
||||
public class OpenAIHttpClientHandlerUtil
|
||||
{
|
||||
public static HttpClient GetHttpClient( string endPoint)
|
||||
public static HttpClient GetHttpClient(string endPoint)
|
||||
{
|
||||
var handler = new OpenAIHttpClientHandler(endPoint.ConvertToString());
|
||||
var httpClient = new HttpClient(handler);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
8
src/AntSK.Test/AntSK.Test.csproj
Normal file
@@ -0,0 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
22
src/AntSK.Test/Class1.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace AntSK.Test
|
||||
{
|
||||
/// <summary>
|
||||
/// 测试插件导入
|
||||
/// </summary>
|
||||
public class TestFunctionImport
|
||||
{
|
||||
//导入的Function Call插件请安此格式书写,函数描述需要以AntSK:开头,返回值描述需要以return:Description,参数描述需要使用Description
|
||||
[Description("AntSK:获取产品详情")]
|
||||
[return: Description("返回信息详情")]
|
||||
public string GetInfo([Description("产品名称")] string Name)
|
||||
{
|
||||
return $"""
|
||||
我的名字是{Name},
|
||||
我的作者是许泽宇
|
||||
我是一个AI 知识库/智能体项目
|
||||
""";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,10 @@ 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
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AntSK.Test", "AntSK.Test\AntSK.Test.csproj", "{6AD71410-127F-4C83-95A8-F699C39B44FF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -36,6 +40,14 @@ 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
|
||||
{6AD71410-127F-4C83-95A8-F699C39B44FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6AD71410-127F-4C83-95A8-F699C39B44FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6AD71410-127F-4C83-95A8-F699C39B44FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6AD71410-127F-4C83-95A8-F699C39B44FF}.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>
|
||||
@@ -22,6 +23,9 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="plugins\KMSPlugin\Ask1\skprompt.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="plugins\KMSPlugin\Ask\skprompt.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>AntSK</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="M:AntSK.Controllers.FileController.UploadFile(Microsoft.AspNetCore.Http.IFormFile)">
|
||||
<summary>
|
||||
Upload FileName
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Controllers.InitController.InitTable">
|
||||
<summary>
|
||||
初始化DB 和表
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:AntSK.Controllers.KMSController">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="_taskBroker"></param>
|
||||
</member>
|
||||
<member name="M:AntSK.Controllers.LLamaSharpController.chat(AntSK.Models.OpenAIModel)">
|
||||
<summary>
|
||||
本地会话接口
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Controllers.LLamaSharpController.embedding(AntSK.Models.OpenAIEmbeddingModel)">
|
||||
<summary>
|
||||
本地嵌入接口
|
||||
</summary>
|
||||
<param name="model"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:AntSK.Controllers.OpenController">
|
||||
<summary>
|
||||
对外接口
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:AntSK.Controllers.OpenController.#ctor(AntSK.Services.OpenApi.IOpenApiService)">
|
||||
<summary>
|
||||
对外接口
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:AntSK.Controllers.OpenController.chat(AntSK.Models.OpenAIModel)">
|
||||
<summary>
|
||||
对话接口
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Pages.ChatPage.Chat.SendKms(System.String,System.String,AntSK.Domain.Repositories.Apps)">
|
||||
<summary>
|
||||
发送知识库问答
|
||||
</summary>
|
||||
<param name="questions"></param>
|
||||
<param name="msg"></param>
|
||||
<param name="app"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Pages.ChatPage.Chat.SendChat(System.String,System.String,AntSK.Domain.Repositories.Apps)">
|
||||
<summary>
|
||||
发送普通对话
|
||||
</summary>
|
||||
<param name="questions"></param>
|
||||
<param name="msg"></param>
|
||||
<param name="app"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Pages.ChatPage.Chat.HistorySummarize(AntSK.Domain.Repositories.Apps,System.String)">
|
||||
<summary>
|
||||
历史会话的会话总结
|
||||
</summary>
|
||||
<param name="questions"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Pages.ChatPage.OpenChat.SendKms(System.String,System.String,AntSK.Domain.Repositories.Apps)">
|
||||
<summary>
|
||||
发送知识库问答
|
||||
</summary>
|
||||
<param name="questions"></param>
|
||||
<param name="msg"></param>
|
||||
<param name="app"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Pages.ChatPage.OpenChat.SendChat(System.String,System.String,AntSK.Domain.Repositories.Apps)">
|
||||
<summary>
|
||||
发送普通对话
|
||||
</summary>
|
||||
<param name="questions"></param>
|
||||
<param name="msg"></param>
|
||||
<param name="app"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Pages.ChatPage.OpenChat.HistorySummarize(AntSK.Domain.Repositories.Apps,System.String)">
|
||||
<summary>
|
||||
历史会话的会话总结
|
||||
</summary>
|
||||
<param name="questions"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:AntSK.Pages.KmsPage.KmsDetail.UrlModel">
|
||||
<summary>
|
||||
根据文档ID获取文档
|
||||
</summary>
|
||||
<param name="fileid"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:AntSK.Services.LLamaSharp.LLamaChatService">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:AntSK.Services.LLamaSharp.LLamaEmbeddingService">
|
||||
<summary>
|
||||
本地Embedding
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:AntSK.Services.OpenApi.OpenApiService.SendChat(System.String,AntSK.Domain.Repositories.Apps)">
|
||||
<summary>
|
||||
发送普通对话
|
||||
</summary>
|
||||
<param name="questions"></param>
|
||||
<param name="msg"></param>
|
||||
<param name="app"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Services.OpenApi.OpenApiService.SendKms(System.String,AntSK.Domain.Repositories.Apps)">
|
||||
<summary>
|
||||
发送知识库问答
|
||||
</summary>
|
||||
<param name="questions"></param>
|
||||
<param name="msg"></param>
|
||||
<param name="app"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Services.OpenApi.OpenApiService.HistorySummarize(AntSK.Domain.Repositories.Apps,AntSK.Models.OpenAIModel)">
|
||||
<summary>
|
||||
历史会话的会话总结
|
||||
</summary>
|
||||
<param name="questions"></param>
|
||||
<param name="msg"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||