Compare commits

...

53 Commits
0.1.4 ... 0.1.6

Author SHA1 Message Date
zyxucp
bee2c56382 Merge branch 'main' of https://github.com/xuzeyu91/AntSK 2024-03-08 22:29:55 +08:00
zyxucp
b05a4f51b7 add 增加清理聊天记录 2024-03-08 22:22:18 +08:00
zyxucp
608794b600 add 增加描述 2024-03-08 22:08:11 +08:00
zyxucp
ce8829ae69 add 新增知识库修改 2024-03-08 22:04:52 +08:00
zyxucp
1fb27f8d5a add 增加应用配置校验 2024-03-08 21:54:53 +08:00
zyxucp
caf8777290 add 增加模型管理配置 2024-03-08 21:47:51 +08:00
zyxucp
7dacdab2b5 fix 修改LLamaSharp本地调用 2024-03-08 21:12:42 +08:00
zyxucp
f6a8660144 fix 修改KMS删除 2024-03-08 20:25:25 +08:00
zyxucp
1e51631eba add 增加LLamaSharp本地执行 2024-03-08 19:53:13 +08:00
zyxucp
91048dc9c1 add 增加应用和知识库使用配置模型
fix 删除openai配置文件
2024-03-08 18:46:26 +08:00
zyxucp
9f8dc39e2f add 增加会话的模型和知识库模型配置 2024-03-08 17:06:35 +08:00
zyxucp
07aa8f4829 Update README.md 2024-03-08 16:55:13 +08:00
zyxucp
b504615b6d add 增加模型配置 2024-03-08 15:20:57 +08:00
zyxucp
3b1811a5ff add 增加模型配置 2024-03-08 14:50:46 +08:00
zyxucp
71be6d4a5a Merge branch 'main' of https://github.com/xuzeyu91/AntSK 2024-03-08 10:04:01 +08:00
zyxucp
ae04d20a82 add 增加session 登陆记录 2024-03-08 00:48:41 +08:00
zyxucp
2ad3953d3f add session 2024-03-08 00:28:27 +08:00
zyxucp
c536f1d74b Update README.md 2024-03-07 21:46:06 +08:00
zyxucp
d8c1695ac9 Update README.en.md 2024-03-07 21:26:17 +08:00
zyxucp
b39912d08b Merge branch 'main' of https://github.com/xuzeyu91/AntSK 2024-03-07 18:27:26 +08:00
zyxucp
8f5dd08836 Update README.md 2024-03-07 17:52:59 +08:00
zyxucp
6a27e61321 fix 删除appsetting注释 2024-03-07 17:32:59 +08:00
zyxucp
34fa19cf1e fix 修改docker file 2024-03-07 16:46:14 +08:00
zyxucp
a97cc538f6 fix 修改dockerfile路径 2024-03-07 16:37:19 +08:00
zyxucp
45471c9bf4 add 增加精简版docker-compose 2024-03-07 16:29:33 +08:00
zyxucp
7145192988 Merge branch 'feature_appsetting' 2024-03-07 16:24:51 +08:00
zyxucp
0935becf70 fix 增加注释 2024-03-07 16:21:33 +08:00
zyxucp
a155c906b3 fix 修改为异步请求 2024-03-07 16:04:23 +08:00
zyxucp
fa8e82224a fix 导入问题修复 2024-03-07 13:08:26 +08:00
zyxucp
7088e26e09 add 调整项目结构 2024-03-07 12:39:12 +08:00
zyxucp
f471bdb607 fix 变量错误bug修复 2024-03-07 11:59:07 +08:00
zyxucp
0a0bd67834 fix 1 2024-03-07 11:57:36 +08:00
zyxucp
e91f8331de fix 修改忽略本地目录 2024-03-07 11:52:53 +08:00
zyxucp
2e90a7fe90 fix 修改目录增加src 2024-03-07 11:52:09 +08:00
zyxucp
3fb3c5bad5 fix 调整 2024-03-06 23:53:46 +08:00
zyxucp
a6753ee888 add 增加导入后台队列模式 2024-03-06 23:18:41 +08:00
zyxucp
9b04d3a758 add 增加CPU和GPU的选择 2024-03-06 22:21:10 +08:00
zyxucp
68e2b2ff9b fix 修改默认切片数和保存校验 2024-03-06 21:54:52 +08:00
zyxucp
464baa6125 add 修改仓储多库兼容,和注释 2024-03-06 19:22:23 +08:00
zyxucp
78083a0b68 fix 更新配置文件 2024-03-06 19:14:24 +08:00
zyxucp
681e248bdf del 删除不要的历史文件 2024-03-06 19:12:40 +08:00
zyxucp
1ca9493ce9 忽略本地内存配置 2024-03-06 19:09:38 +08:00
zyxucp
5537a8796f 忽略本地内存配置 2024-03-06 19:09:25 +08:00
zyxucp
e2a1ab80b0 删除本地文件 2024-03-06 19:06:48 +08:00
zyxucp
74db9e425f add 支持不同的业务数据库和向量数据库 2024-03-06 19:05:12 +08:00
zyxucp
3e2152a979 fix httpheader 中文异常 2024-03-06 16:09:05 +08:00
zyxucp
930c6c88ae Merge branch 'main' of https://github.com/xuzeyu91/AntSK 2024-03-06 14:44:46 +08:00
zyxucp
24bc276732 fix 处理mysql api实体长度问题 2024-03-06 14:42:02 +08:00
zyxucp
17cab5c51b Update docker-compose.yml 2024-03-06 14:29:40 +08:00
zyxucp
96dbc8e9e6 增加新增字段默认值 2024-03-06 14:20:50 +08:00
zyxucp
56a0d51794 忽略本地db 2024-03-06 14:19:15 +08:00
zyxucp
1cdbd969ba add 增加init api新增表的初始化 2024-03-06 13:36:41 +08:00
zyxucp
d77ece2aa6 Update docker-compose.yml 2024-03-06 12:55:19 +08:00
226 changed files with 2131 additions and 1082 deletions

10
.gitignore vendored
View File

@@ -330,13 +330,13 @@ ASALocalRun/
*.pdb
# MFractors (Xamarin productivity tool) working folder
.mfractor/
/.semantic-kernel/results/src/ISS.IPSA.AiAgent.Api/plugins/BasePlugin/YesNo
**/bin/
**/obj/
**/.vs/
/Xzy.KnowledgeBase/appsettings.Development.json
/Xzy.KnowledgeBase/XzyAgent.db
/Xzy.KnowledgeBase/AntSK.db
/AntSK/AntSK.db
/AntSK/appsettings.Development.json
/AntSK.db
**/tmp-memory-files/*
/src/AntSK/AntSK.db
/src/AntSK/appsettings.Development.json
/src/AntSK.db

View File

@@ -1,98 +0,0 @@
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.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;
namespace AntSK.Domain.Domain.Service
{
[ServiceDescription(typeof(IKMService), ServiceLifetime.Scoped)]
public class KMService(
IOptions<PostgresConfig> postgresOptions
) : IKMService
{
public MemoryServerless GetMemory(SearchClientConfig searchClientConfig=null, TextPartitioningOptions textPartitioningOptions=null)
{
var handler = new OpenAIHttpClientHandler();
var httpClient = new HttpClient(handler);
if (searchClientConfig.IsNull())
{
searchClientConfig = new SearchClientConfig
{
MaxAskPromptSize = 2048,
MaxMatchesCount = 3,
AnswerTokens = 1000,
EmptyAnswer = "知识库未搜索到相关内容"
};
}
if (textPartitioningOptions.IsNull())
{
textPartitioningOptions = new TextPartitioningOptions
{
MaxTokensPerLine = 99,
MaxTokensPerParagraph = 299,
OverlappingTokens = 47
};
}
var memory = new KernelMemoryBuilder()
.WithPostgresMemoryDb(postgresOptions.Value)
.WithSimpleFileStorage(new SimpleFileStorageConfig { StorageType = FileSystemTypes.Volatile, Directory = "_files" })
.WithSearchClientConfig(searchClientConfig)
//如果用本地模型需要设置token小一点。
.WithCustomTextPartitioningOptions(textPartitioningOptions)
.WithOpenAITextGeneration(new OpenAIConfig()
{
APIKey = OpenAIOption.Key,
TextModel = OpenAIOption.Model
}, null, httpClient)
.WithOpenAITextEmbeddingGeneration(new OpenAIConfig()
{
APIKey = OpenAIOption.Key,
EmbeddingModel = OpenAIOption.EmbeddingModel
}, null, false, httpClient)
.Build<MemoryServerless>();
return memory;
}
public async Task<List<KMFile>> GetDocumentByFileID(string fileid)
{
var _memory = GetMemory();
var memories = await _memory.ListIndexesAsync();
var memoryDbs = _memory.Orchestrator.GetMemoryDbs();
List<KMFile> 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)
{
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);
}
}
}
return docTextList;
}
}
}

View File

@@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Options
{
public class OpenAIOption
{
public static string EndPoint { get; set; }
public static string Key { get; set; }
public static string Model { get; set; }
public static string EmbeddingModel { get; set; }
}
}

View File

@@ -1,51 +0,0 @@
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 System.Reflection;
namespace AntSK.Domain.Repositories.Base
{
public class SqlSugarHelper
{
/// <summary>
/// sqlserver连接
/// </summary>
public static SqlSugarScope Sqlite = new SqlSugarScope(new ConnectionConfig()
{
ConnectionString = ConnectionOption.Postgres,
DbType = DbType.PostgreSQL,
InitKeyType = InitKeyType.Attribute,//从特性读取主键和自增列信息
IsAutoCloseConnection = true,
ConfigureExternalServices = new ConfigureExternalServices
{
//注意: 这儿AOP设置不能少
EntityService = (c, p) =>
{
/***高版C#写法***/
//支持string?和string
if (p.IsPrimarykey == false && new NullabilityInfoContext()
.Create(c).WriteState is NullabilityState.Nullable)
{
p.IsNullable = true;
}
}
}
}, Db =>
{
Db.Aop.OnLogExecuting = (sql, pars) =>
{
if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT").ConvertToString() == "Development")
{
Console.WriteLine(sql + "\r\n" +
Sqlite.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)));
Console.WriteLine();
}
};
});
}
}

View File

@@ -1,473 +0,0 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>AntSK.Domain</name>
</assembly>
<members>
<member name="T:AntSK.Domain.Common.DependencyInjection.ServiceCollectionExtensions">
<summary>
容器扩展
</summary>
</member>
<member name="M:AntSK.Domain.Common.DependencyInjection.ServiceCollectionExtensions.AddServicesFromAssemblies(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.String[])">
<summary>
从程序集中加载类型并添加到容器中
</summary>
<param name="services">容器</param>
<param name="assemblies">程序集集合</param>
<returns></returns>
</member>
<member name="F:AntSK.Domain.Common.DependencyInjection.ServiceLifetime.Scoped">
<summary>
作用域
</summary>
</member>
<member name="F:AntSK.Domain.Common.DependencyInjection.ServiceLifetime.Singleton">
<summary>
单例
</summary>
</member>
<member name="F:AntSK.Domain.Common.DependencyInjection.ServiceLifetime.Transient">
<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="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.ConnectionOption.Sqlite">
<summary>
sqlite连接字符串
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Apps.Name">
<summary>
名称
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Apps.Describe">
<summary>
描述
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.KmsDetails.FileName">
<summary>
文件名称
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.KmsDetails.DataCount">
<summary>
数据数量
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.KmsDetails.Status">
<summary>
状态
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.KmsDetails.CreateTime">
<summary>
创建时间
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Kmss.Name">
<summary>
名称
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Kmss.ChatModel">
<summary>
会话模型
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Kmss.EmbeddingModel">
<summary>
向量模型
</summary>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.GetList">
<summary>
获取所有list
</summary>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.GetListAsync">
<summary>
获取所有list-异步
</summary>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.GetList(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
<summary>
根据lambda查询
</summary>
<param name="whereExpression"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.GetListAsync(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
<summary>
根据lambda查询-异步
</summary>
<param name="whereExpression"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.Count(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
<summary>
根据lambda表达式获取数量
</summary>
<param name="whereExpression"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.CountAsync(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
<summary>
根据lambda表达式获取数量-异步
</summary>
<param name="whereExpression"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.GetPageList(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}},SqlSugar.PageModel)">
<summary>
获取分页
</summary>
<param name="whereExpression"></param>
<param name="page"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.GetPageListAsync(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}},SqlSugar.PageModel)">
<summary>
获取分页-异步
</summary>
<param name="whereExpression"></param>
<param name="page"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.GetById(System.Object)">
<summary>
根据id获取实体
</summary>
<param name="id"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.GetByIdAsync(System.Object)">
<summary>
根据id获取实体-异步
</summary>
<param name="id"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.GetSingle(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
<summary>
根据lambda获取单个对象 注意需要确保唯一如果获取到2个会报错这种场景需要使用GetFirst
</summary>
<param name="whereExpression"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.GetSingleAsync(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
<summary>
根据lambda获取单个对象-异步 注意需要确保唯一如果获取到2个会报错这种场景需要使用GetFirst
</summary>
<param name="whereExpression"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.GetFirst(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
<summary>
根据lambda获取单个对象
</summary>
<param name="whereExpression"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.GetFirstAsync(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
<summary>
根据lambda获取单个对象 --异步
</summary>
<param name="whereExpression"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.Insert(`0)">
<summary>
实体插入
</summary>
<param name="obj"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.InsertAsync(`0)">
<summary>
实体插入-异步
</summary>
<param name="obj"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.InsertRange(System.Collections.Generic.List{`0})">
<summary>
批量插入
</summary>
<param name="objs"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.InsertRangeAsync(System.Collections.Generic.List{`0})">
<summary>
批量插入-异步
</summary>
<param name="objs"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.InsertReturnIdentity(`0)">
<summary>
插入返回自增列
</summary>
<param name="obj"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.InsertReturnIdentityAsync(`0)">
<summary>
插入返回自增列-异步
</summary>
<param name="obj"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.InsertReturnBigIdentity(`0)">
<summary>
插入返回longid
</summary>
<param name="obj"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.InsertReturnBigIdentityAsync(`0)">
<summary>
插入返回longid-异步
</summary>
<param name="obj"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.DeleteByIds(System.Object[])">
<summary>
批量删除
</summary>
<param name="ids"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.DeleteByIdsAsync(System.Object[])">
<summary>
批量删除-异步
</summary>
<param name="ids"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.Delete(System.Object)">
<summary>
根据主键删除
</summary>
<param name="id"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.DeleteAsync(System.Object)">
<summary>
根据主键删除-异步
</summary>
<param name="id"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.Delete(`0)">
<summary>
根据实体删除
</summary>
<param name="obj"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.DeleteAsync(`0)">
<summary>
根据实体删除-异步
</summary>
<param name="obj"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.Delete(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
<summary>
根据表达式删除
</summary>
<param name="whereExpression"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.DeleteAsync(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
<summary>
根据表达式删除-异步
</summary>
<param name="whereExpression"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.Update(`0)">
<summary>
更新
</summary>
<param name="obj"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.UpdateAsync(`0)">
<summary>
更新-异步
</summary>
<param name="obj"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.UpdateRange(System.Collections.Generic.List{`0})">
<summary>
批量更新
</summary>
<param name="objs"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.UpdateRangeAsync(System.Collections.Generic.List{`0})">
<summary>
批量更新-异步
</summary>
<param name="objs"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.IsAny(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
<summary>
是否包含元素
</summary>
<param name="whereExpression"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.IsAnyAsync(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
<summary>
是否包含元素-异步
</summary>
<param name="whereExpression"></param>
<returns></returns>
</member>
<member name="F:AntSK.Domain.Repositories.Base.SqlSugarHelper.Sqlite">
<summary>
sqlserver连接
</summary>
</member>
<member name="M:AntSK.Domain.Utils.ConvertUtils.IsNull(System.Object)">
<summary>
判断是否为空为空返回true
</summary>
<param name="data"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.ConvertUtils.IsNotNull(System.Object)">
<summary>
判断是否为空为空返回true
</summary>
<param name="data"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.ConvertUtils.IsNull(System.String)">
<summary>
判断是否为空为空返回true
</summary>
<param name="data"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.ConvertUtils.ConvertToString(System.Object)">
<summary>
将obj类型转换为string
</summary>
<param name="s"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.ConvertUtils.ConvertToInt32(System.Object)">
<summary>
object 转int32
</summary>
<param name="s"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.ConvertUtils.ConvertToInt64(System.Object)">
<summary>
object 转int32
</summary>
<param name="s"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.ConvertUtils.ConvertToDouble(System.Object)">
<summary>
将字符串转double
</summary>
<param name="s"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.ConvertUtils.ConvertToDateTime(System.String)">
<summary>
转换为datetime类型
</summary>
<param name="s"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.ConvertUtils.ConvertToDateTime(System.String,System.String)">
<summary>
转换为datetime类型的格式字符串
</summary>
<param name="s">要转换的对象</param>
<param name="y">格式化字符串</param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.ConvertUtils.ConvertToDecimal(System.Object)">
<summary>
将字符串转换成decimal
</summary>
<param name="s"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.ConvertUtils.DecimalFraction(System.Decimal)">
<summary>
decimal保留2位小数
</summary>
</member>
<member name="M:AntSK.Domain.Utils.ConvertUtils.ReplaceHtml(System.String)">
<summary>
替换html种的特殊字符
</summary>
<param name="s"></param>
<returns></returns>
</member>
<member name="M:AntSK.Domain.Utils.ConvertUtils.StreamToByte(System.IO.Stream)">
<summary>
流转byte
</summary>
<param name="stream"></param>
<returns></returns>
</member>
</members>
</doc>

View File

@@ -1,36 +0,0 @@
using AntDesign;
using Microsoft.AspNetCore.Components;
using AntSK.Domain.Repositories;
using AntSK.Models;
using System.IO;
namespace AntSK.Pages.KmsPage
{
public partial class AddKms
{
[Inject]
protected IKmss_Repositories _kmss_Repositories { get; set; }
[Inject]
protected NavigationManager NavigationManager { get; set; }
[Inject]
protected MessageService? Message { get; set; }
private readonly Kmss _kmsModel = new Kmss() ;
private void HandleSubmit()
{
_kmsModel.Id = Guid.NewGuid().ToString();
if (_kmss_Repositories.IsAny(p => p.Name == _kmsModel.Name))
{
_ = Message.Error("名称已存在!", 2);
return;
}
_kmss_Repositories.Insert(_kmsModel);
NavigationManager.NavigateTo("/kmslist");
}
}
}

View File

@@ -1,52 +0,0 @@
@namespace AntSK.Pages.Setting.AIModel
@using AntSK.Domain.Repositories
@using AntSK.Models
@using AntSK.Domain.Model.Enum
@page "/setting/model/add"
@page "/setting/model/add/{ModelId}"
@using AntSK.Services.Auth
@inherits AuthComponentBase
<PageContainer Title="新增模型">
<ChildContent>
<Card>
<Form Model="@_aiModel"
Style="margin-top: 8px;"
OnFinish="HandleSubmit">
<FormItem Label="模型描述" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
<Input Placeholder="请输入模型描述" @bind-Value="@context.ModelDescription" />
</FormItem>
<FormItem Label="模型类型" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
<RadioGroup @bind-Value="context.AIModelType">
<Radio RadioButton Value="@(AIModelType.Chat)">会话模型</Radio>
<Radio RadioButton Value="@(AIModelType.Embedding)">向量模型</Radio>
</RadioGroup>
</FormItem>
<FormItem Label="模型地址" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
<Input Placeholder="请输入模型地址" @bind-Value="@context.EndPoint" />
</FormItem>
<FormItem Label="模型名称" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
<Input Placeholder="请输入模型名称" @bind-Value="@context.ModelName" />
</FormItem>
<FormItem Label="模型秘钥" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
<InputPassword @bind-Value="@context.ModelKey" Placeholder="请输入模型秘钥" Size="@InputSize.Large" />
</FormItem>
<FormItem Label=" " Style="margin-top:32px" WrapperCol="LayoutModel._submitFormLayout.WrapperCol">
<Button Type="primary" OnClick="HandleSubmit">
保存
</Button>
<Button OnClick="Back">
返回
</Button>
</FormItem>
</Form>
</Card>
</ChildContent>
</PageContainer>
@code {
}

View File

@@ -1,14 +0,0 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>AntSK</name>
</assembly>
<members>
<member name="M:AntSK.Controllers.InitController.InitTable">
<summary>
初始化DB 和表
</summary>
<returns></returns>
</member>
</members>
</doc>

View File

@@ -3,11 +3,11 @@ FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
# Copy csproj and restore as distinct layers
COPY ["AntSK/AntSK.csproj", "AntSK/"]
COPY ["src/AntSK/AntSK.csproj", "AntSK/"]
RUN dotnet restore "AntSK/AntSK.csproj"
# Copy everything else and build
COPY . .
COPY src/ .
WORKDIR "/src/AntSK"
RUN dotnet build "AntSK.csproj" -c Release -o /app/build
RUN dotnet publish "AntSK.csproj" -c Release -o /app/publish

View File

@@ -123,58 +123,76 @@ The model supports openai by default. If you need to use azure openai and need t
The following configuration files need to be configured
## Using Docker Compose
Provided pg version appsettings. json and simplified version (Sqlite+disk) Docker Compose. simple. yml
Download Docker Compose.yml from the project root directory, and then place the configuration file appsettings.json and it in a unified directory,
The image of PG has been prepared here. You can modify the default account password in Docker Compose.yml, and your appsettings. json database connection needs to be consistent.
Then you can enter the directory and execute it
```
docker compose up - d
```
To start AntSK
Some meanings of configuration files
```
"ConnectionStrings":{
"Postgres": "Host=; Port=; Database=antsk; Username=; Password="
},
"OpenAIOption":{
"EndPoint": "",
"Key": "",
"Model": "",
"Embedding Model": """""
},
Postgres:{
"ConnectionString": "Host=; Port=; Database=antsk; Username=; Password=",
"TableNamePrefix": "km -"
},
"Login": {
"User": "admin",
"Password": "xuzeyu"
{
"DBConnection": {
"DbType": "Sqlite",
"ConnectionStrings": "Data Source=AntSK.db;"
},
"OpenAIOption": {
"EndPoint": "http://localhost:5000/llama/",
"Key": "NotNull",
"Model": "gpt4-turbo",
"EmbeddingModel": "text-embedding-ada-002"
},
"KernelMemory": {
"VectorDb": "Disk",
"ConnectionString": "Host=;Port=;Database=antsk;Username=;Password=",
"TableNamePrefix": "km-"
},
"LLamaSharp": {
"RunType": "GPU",
"Chat": "D:\\Code\\AI\\AntBlazor\\model\\qwen1_5-1_8b-chat-q8_0.gguf",
"Embedding": "D:\\Code\\AI\\AntBlazor\\model\\qwen1_5-1_8b-chat-q8_0.gguf"
},
"Login": {
"User": "admin",
"Password": "xuzeyu"
},
"BackgroundTaskBroker": {
"ImportKMSTask": {
"WorkerCount": 1
}
}
}
```
I use CodeFirst mode. As long as the database link is configured, the table structure is automatically created
```
//Supports multiple databases, including SqlSugar, MySql, SqlServer, Sqlite, Oracle, PostgreSQL, Dm, Kdbndp, Oscar, MySqlConnector, Access, OpenGaussian, QuestDB, HG, ClickHouse, GBase, Odbc, OceanBaseForOracle, TDengine, GaussDB, OceanBase, Tidb, Vastbase, PolarDB, Custom
DBConnection DbType
//Connection string, corresponding strings need to be used according to different DB types
DBConnection ConnectionStrings
//You can use an online API that conforms to the OpenAI format (domestic models use one API adapter), or you can use AntSK's built-in llama API, with the IP and port being the AntSK startup address
OpenAIOption EndPoint
//Model key, if using a local model, it can default to Notnull. Chinese cannot be used here
OpenAIOption Key
//The type of vector storage supports Postgres Disk Memory, where Postgres requires the configuration of ConnectionString
KernelMemory VectorDb
//The running mode used by the local model is GUP CPU. If using an online API, you can freely use one
LLamaSharp RunType
//The model path of the local session model should pay attention to distinguishing between Linux and Windows drive letters
LLamaSharp Chat
//The model path of the local vector model should pay attention to distinguishing between Linux and Windows drive letters
LLamaSharp Embedding
//Default administrator account password
Login
//The number of threads for importing asynchronous processing can be higher when using online APIs. Local models suggest 1, otherwise memory overflow and crash may occur
BackgroundTaskBroker ImportKMSTask WorkerCount
If you want to use LLamaSharp to run the local model, you also need to set the following configuration:
```
"LLamaSharp": {
"Chat": "D:\\Code\\AI\\AntBlazor\\model\\tinyllama-1.1b-chat.gguf",
"Embedding": "D:\\Code\\AI\\AntBlazor\\model\\tinyllama-1.1b-chat.gguf"
},
```
You need to configure the addresses of the Chat and Embedding models, and then modify EndPoint to local. When using the local model, parameters such as Key, Model, and Embedding Model are not used, so you can freely fill in these parameters:
```
"OpenAIOption": {
"EndPoint": "https://ip:port/llama/",
"Key": "",
"Model": "",
"EmbeddingModel": ""
},
```

109
README.md
View File

@@ -71,9 +71,11 @@ Login是默认的登陆账号和密码
## 使用docker-compose
从项目根目录下载docker-compose.yml,然后把配置文件appsettings.json和它放在统一目录
提供了pg版本 **appsettings.json** 和 简化版本Sqlite+disk **docker-compose.simple.yml**
这里已经把pg的镜像做好了。在docker-compose.yml中可以修改默认账号密码,然后你的appsettings.json的数据库连接需要保持一致。
从项目根目录下载**docker-compose.yml**,然后把配置文件**appsettings.json**和它放在统一目录,
这里已经把pg的镜像做好了。在docker-compose.yml中可以修改默认账号密码然后你的**appsettings.json**的数据库连接需要保持一致。
然后你可以进入到目录后执行
```
@@ -81,46 +83,106 @@ docker-compose up -d
```
来启动AntSK
## 如何在docker中挂载本地模型
```
# 非 host 版本, 不使用本机代理
version: '3.8'
services:
antsk:
container_name: antsk
image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.1.5
ports:
- 5000:5000
networks:
- antsk
depends_on:
- antskpg
restart: always
environment:
- ASPNETCORE_URLS=http://*:5000
volumes:
- ./appsettings.json:/app/appsettings.json # 本地配置文件 需要放在同级目录
- D://model:/app/model
networks:
antsk:
```
以这个为示例意思是把windows本地D://model的文件夹挂载进 容器内/app/model 如果是这样你的appsettings.json中的模型地址应该配置为
```
model/xxx.gguf
```
## 配置文件的一些含义
```
"ConnectionStrings": {
"Postgres": "Host=;Port=;Database=antsk;Username=;Password="//这个是业务数据的连接字符串
{
"DBConnection": {
"DbType": "Sqlite",
"ConnectionStrings": "Data Source=AntSK.db;"
},
"OpenAIOption": {
"EndPoint": "", //openai协议的接口写到v1之前
"Key": "",//接口秘钥,如果使用本地模型可以随意填写一个但不能为空
"Model": "",//会话模型,使用接口时需要,使用本地模型可以随意填写
"EmbeddingModel": ""//向量模型,使用接口时需要,使用本地模型可以随意填写
"EndPoint": "http://localhost:5000/llama/",
"Key": "NotNull",
"Model": "gpt4-turbo",
"EmbeddingModel": "text-embedding-ada-002"
},
"Postgres": {
"KernelMemory": {
"VectorDb": "Disk",
"ConnectionString": "Host=;Port=;Database=antsk;Username=;Password=",
"TableNamePrefix": "km-"
},
"LLamaSharp": {
"RunType": "GPU",
"Chat": "D:\\Code\\AI\\AntBlazor\\model\\qwen1_5-1_8b-chat-q8_0.gguf",
"Embedding": "D:\\Code\\AI\\AntBlazor\\model\\qwen1_5-1_8b-chat-q8_0.gguf"
},
"Login": {
"User": "admin",
"Password": "xuzeyu"
},
"BackgroundTaskBroker": {
"ImportKMSTask": {
"WorkerCount": 1
}
}
}
```
我使用的是CodeFirst模式只要配置好数据库链接表结构是自动创建的
如果想使用LLamaSharp运行本地模型还需要设置如下配置
```
"LLamaSharp": {
"Chat": "D:\\Code\\AI\\AntBlazor\\model\\tinyllama-1.1b-chat.gguf",//本地会话模型的磁盘路径
"Embedding": "D:\\Code\\AI\\AntBlazor\\model\\tinyllama-1.1b-chat.gguf"//本地向量模型的磁盘路径
},
//支持多种数据库具体可以查看SqlSugarMySqlSqlServerSqliteOraclePostgreSQLDmKdbndpOscarMySqlConnectorAccessOpenGaussQuestDBHGClickHouseGBaseOdbcOceanBaseForOracleTDengineGaussDBOceanBaseTidbVastbasePolarDBCustom
DBConnection.DbType
//连接字符串需要根据不同DB类型用对应的字符串
DBConnection.ConnectionStrings
//可以使用符合openai格式的在线API国产模型使用one-api转接 也可以使用AntSK自带的llama apiip和端口是AntSK启动地址
OpenAIOption.EndPoint
//模型秘钥如果使用本地模型可以默认NotNull 这里不能用中文
OpenAIOption.Key
//向量存储的类型,支持 Postgres Disk Memory 其中Postgres需要配置 ConnectionString
KernelMemory.VectorDb
//本地模型使用的运行方式 GUP CPU ,如果用在线API 这个随意使用一个即可
LLamaSharp.RunType
//本地会话模型的模型路径 注意区分linux和windows盘符不同
LLamaSharp.Chat
//本地向量模型的模型路径 注意区分linux和windows盘符不同
LLamaSharp.Embedding
//默认管理员账号密码
Login
//导入异步处理的线程数使用在线API可以高一点本地模型建议1 否则容易内存溢出崩掉
BackgroundTaskBroker.ImportKMSTask.WorkerCount
```
需要配置Chat和Embedding模型的地址然后修改EndPoint为本地使用本地模型时并没有用到Key、Model、EmbeddingModel这些参数所以这几个你可以随意填写
## 找不到样式问题解决
AntSK/src/AntSK下执行:
```
"OpenAIOption": {
"EndPoint": "http://ip:port/llama/",//如果使用本地模型这个ip端口是AntSK服务启动的ip和端口
"Key": "",//接口秘钥,如果使用本地模型可以随意填写一个但不能为空
"Model": "",//会话模型,使用接口时需要,使用本地模型可以随意填写
"EmbeddingModel": ""//向量模型,使用接口时需要,使用本地模型可以随意填写
},
dotnet clean
dotnet build
dotnet publish "AntSK.csproj"
```
再去AntSK/src/AntSK/bin/Release/net8.0/publish下
```
dotnet AntSK.dll
```
然后启动就有样式了
DB我使用的是CodeFirst模式只要配置好数据库链接表结构是自动创建的
想了解更多信息或开始使用 **AntSK**,可以关注我的公众号以及加入交流群。
@@ -132,3 +194,4 @@ docker-compose up -d
---
我们对您在**AntSK**的兴趣表示感谢,并期待与您携手共创智能化的未来!

17
docker-compose.simple.yml Normal file
View File

@@ -0,0 +1,17 @@
# 非 host 版本, 不使用本机代理
version: '3.8'
services:
antsk:
container_name: antsk
image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.1.5
ports:
- 5000:5000
networks:
- antsk
restart: always
environment:
- ASPNETCORE_URLS=http://*:5000
volumes:
- ./appsettings.json:/app/appsettings.json # 本地配置文件 需要放在同级目录
networks:
antsk:

View File

@@ -18,7 +18,7 @@ services:
- ./pg/data:/var/lib/postgresql/data
antsk:
container_name: antsk
image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.1.3
image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/antsk:v0.1.5
ports:
- 5000:5000
networks:
@@ -31,4 +31,4 @@ services:
volumes:
- ./appsettings.json:/app/appsettings.json # 本地配置文件 需要放在同级目录
networks:
antsk:
antsk:

View File

@@ -10,8 +10,6 @@
<ItemGroup>
<PackageReference Include="AutoMapper" Version="8.1.0" />
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
<PackageReference Include="LLamaSharp.kernel-memory" Version="0.10.0" />
<PackageReference Include="LLamaSharp.semantic-kernel" Version="0.10.0" />
<PackageReference Include="MarkdownSharp" Version="2.0.5" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.143" />
@@ -26,8 +24,14 @@
<PackageReference Include="LLamaSharp" Version="0.10.0" />
<PackageReference Include="LLamaSharp.Backend.Cpu" Version="0.10.0" />
<PackageReference Include="LLamaSharp.Backend.Cuda12" Version="0.10.0" />
<PackageReference Include="LLamaSharp.kernel-memory" Version="0.10.0" />
<PackageReference Include="LLamaSharp.semantic-kernel" Version="0.10.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MiddleWare\AntSK.BackgroundTask\AntSK.BackgroundTask.csproj" />
</ItemGroup>
</Project>

View File

@@ -32,7 +32,23 @@
瞬时
</summary>
</member>
<member name="M:AntSK.Domain.Domain.Service.KernelService.GetKernel(System.String,System.String)">
<member name="M:AntSK.Domain.Common.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.Common.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.Domain.Service.KernelService.GetKernelByApp(AntSK.Domain.Repositories.Apps)">
<summary>
获取kernel实例依赖注入不好按每个用户去Import不同的插件所以每次new一个新的kernel
</summary>
@@ -62,6 +78,11 @@
<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集合
@@ -87,6 +108,16 @@
<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
@@ -107,16 +138,31 @@
总数
</summary>
</member>
<member name="P:AntSK.Domain.Options.ConnectionOption.Sqlite">
<member name="P:AntSK.Domain.Options.DBConnectionOption.DbType">
<summary>
sqlite连接字符串
</summary>
</member>
<member name="P:AntSK.Domain.Options.ConnectionOption.Postgres">
<member name="P:AntSK.Domain.Options.DBConnectionOption.ConnectionStrings">
<summary>
pg链接字符串
</summary>
</member>
<member name="P:AntSK.Domain.Options.KernelMemoryOption.VectorDb">
<summary>
向量库
</summary>
</member>
<member name="P:AntSK.Domain.Options.KernelMemoryOption.ConnectionString">
<summary>
连接字符串
</summary>
</member>
<member name="P:AntSK.Domain.Options.KernelMemoryOption.TableNamePrefix">
<summary>
表前缀
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Apis.Name">
<summary>
接口名称
@@ -177,6 +223,11 @@
类型
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Apps.ChatModelID">
<summary>
会话模型ID
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Apps.Temperature">
<summary>
温度
@@ -227,6 +278,11 @@
创建时间
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.KmsDetails.Status">
<summary>
状态
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Kmss.Icon">
<summary>
图标
@@ -242,6 +298,16 @@
会话模型
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Kmss.ChatModelID">
<summary>
会话模型ID
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Kmss.EmbeddingModelID">
<summary>
向量模型ID
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Kmss.MaxTokensPerParagraph">
<summary>
每个段落的最大标记数。
@@ -509,11 +575,16 @@
<param name="whereExpression"></param>
<returns></returns>
</member>
<member name="F:AntSK.Domain.Repositories.Base.SqlSugarHelper.Sqlite">
<member name="M:AntSK.Domain.Repositories.Base.SqlSugarHelper.SqlScope">
<summary>
sqlserver连接
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.AIModels.AIType">
<summary>
AI类型
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.AIModels.AIModelType">
<summary>
模型类型
@@ -534,6 +605,11 @@
模型秘钥
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.AIModels.ModelDescription">
<summary>
部署名azure需要使用
</summary>
</member>
<member name="P:AntSK.Domain.Repositories.Users.No">
<summary>
工号,用于登陆

View File

@@ -0,0 +1,15 @@
using AutoMapper;
using System;
using System.Collections.Generic;
using System.Text;
namespace AntSK.Domain.Common.Map
{
public class AutoMapProfile : Profile
{
public AutoMapProfile()
{
//CreateMap<PMP_BizCase_Main_Max, BizcaseQueryDTO>();
}
}
}

View File

@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace AntSK.Domain.Common.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 AutoMapper.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 AutoMapper.Mapper.Map<T>(value);
}
}
}

View File

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

View File

@@ -0,0 +1,14 @@
using RestSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Domain.Interface
{
public interface IHttpService
{
Task<RestResponse> PostAsync(string url, Object jsonBody);
}
}

View File

@@ -0,0 +1,14 @@
using AntSK.Domain.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Domain.Interface
{
public interface IImportKMSService
{
void ImportKMSTask(ImportKMSTaskReq req);
}
}

View File

@@ -11,7 +11,7 @@ namespace AntSK.Domain.Domain.Interface
{
public interface IKMService
{
MemoryServerless GetMemory(SearchClientConfig searchClientConfig = null, TextPartitioningOptions textPartitioningOptions = null);
Task<List<KMFile>> GetDocumentByFileID(string fileid);
MemoryServerless GetMemoryByKMS(string kmsID, SearchClientConfig searchClientConfig = null);
Task<List<KMFile>> GetDocumentByFileID(string kmsid, string fileid);
}
}

View File

@@ -10,7 +10,7 @@ namespace AntSK.Domain.Domain.Interface
{
public interface IKernelService
{
Kernel GetKernel(string modelId = null, string apiKey = null);
Kernel GetKernelByApp(Apps app);
void ImportFunctionsByApp(Apps app, Kernel _kernel);
Task<string> HistorySummarize(Kernel _kernel, string questions, string history);
}

View File

@@ -0,0 +1,46 @@
using AntSK.BackgroundTask;
using AntSK.Domain.Domain.Interface;
using AntSK.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
{
public class BackGroundTaskHandler : IBackgroundTaskHandler<ImportKMSTaskReq>
{
private readonly IServiceScopeFactory _scopeFactory;
public BackGroundTaskHandler(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task ExecuteAsync(ImportKMSTaskReq item)
{
using (var scope = _scopeFactory.CreateScope())
{
Console.WriteLine("ExecuteAsync.开始执行后台任务");
var importKMSService = scope.ServiceProvider.GetRequiredService<IImportKMSService>();
//不能使用异步
importKMSService.ImportKMSTask(item);
Console.WriteLine("ExecuteAsync.后台任务执行完成");
}
}
public Task OnFailed()
{
return Task.CompletedTask;
}
public Task OnSuccess()
{
return Task.CompletedTask;
}
}
}

View File

@@ -0,0 +1,30 @@
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 async Task< RestResponse> PostAsync(string url ,Object jsonBody)
{
RestClient client = new RestClient();
RestRequest request= new RestRequest(url, Method.Post);
string josn = JsonConvert.SerializeObject(jsonBody);
request.AddJsonBody(jsonBody);
var result =await client.ExecuteAsync(request);
return result;
}
}
}

View File

@@ -0,0 +1,87 @@
using AntSK.Domain.Common.DependencyInjection;
using AntSK.Domain.Domain.Interface;
using AntSK.Domain.Model;
using AntSK.Domain.Repositories;
using Microsoft.KernelMemory;
using Microsoft.KernelMemory.Configuration;
using Microsoft.SemanticKernel.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AntSK.Domain.Domain.Service
{
[ServiceDescription(typeof(IImportKMSService), ServiceLifetime.Scoped)]
public class ImportKMSService(
IKMService _kMService,
IKmsDetails_Repositories _kmsDetails_Repositories,
IKmss_Repositories _kmss_Repositories
) : IImportKMSService
{
public void ImportKMSTask(ImportKMSTaskReq req)
{
try
{
var km = _kmss_Repositories.GetFirst(p => p.Id == req.KmsId);
var _memory = _kMService.GetMemoryByKMS(km.Id);
string fileid = req.KmsDetail.Id;
switch (req.ImportType)
{
case ImportType.File:
//导入文件
{
var importResult= _memory.ImportDocumentAsync(new Document(fileid)
.AddFile(req.FilePath)
.AddTag("kmsid", req.KmsId)
, index: "kms").Result;
//查询文档数量
var docTextList = _kMService.GetDocumentByFileID(km.Id,fileid).Result;
string fileGuidName = Path.GetFileName(req.FilePath);
req.KmsDetail.FileName = req.FileName;
req.KmsDetail.FileGuidName = fileGuidName;
req.KmsDetail.DataCount = docTextList.Count;
}
break;
case ImportType.Url:
{
//导入url
var importResult = _memory.ImportWebPageAsync(req.Url, fileid, new TagCollection() { { "kmsid", req.KmsId } }
, index: "kms").Result;
//查询文档数量
var docTextList = _kMService.GetDocumentByFileID(km.Id,fileid).Result;
req.KmsDetail.Url = req.Url;
req.KmsDetail.DataCount = docTextList.Count;
}
break;
case ImportType.Text:
//导入文本
{
var importResult = _memory.ImportTextAsync(req.Text, fileid, new TagCollection() { { "kmsid", req.KmsId } }
, index: "kms").Result;
//查询文档数量
var docTextList = _kMService.GetDocumentByFileID(km.Id,fileid).Result;
req.KmsDetail.Url = req.Url;
req.KmsDetail.DataCount = docTextList.Count;
}
break;
}
req.KmsDetail.Status = Model.Enum.ImportKmsStatus.Success;
_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);
Console.WriteLine("后台导入任务异常:" + ex.Message);
}
}
}
}

View File

@@ -0,0 +1,188 @@
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.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 LLama;
namespace AntSK.Domain.Domain.Service
{
[ServiceDescription(typeof(IKMService), ServiceLifetime.Scoped)]
public class KMService(
IConfiguration _config,
IKmss_Repositories _kmss_Repositories,
IAIModels_Repositories _aIModels_Repositories
) : 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);
//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 = "知识库未搜索到相关内容"
};
}
var memory = new KernelMemoryBuilder()
.WithSearchClientConfig(searchClientConfig)
.WithCustomTextPartitioningOptions(new TextPartitioningOptions
{
MaxTokensPerLine = kms.MaxTokensPerLine,
MaxTokensPerParagraph = kms.MaxTokensPerParagraph,
OverlappingTokens = kms.OverlappingTokens
});
//加载huihu 模型
WithTextGenerationByAIType(memory, chatModel, chatHttpClient);
//加载向量模型
WithTextEmbeddingGenerationByAIType(memory,embedModel, embeddingHttpClient);
//加载向量库
WithMemoryDbByVectorDB(memory, _config);
var result = memory.Build<MemoryServerless>();
return result;
}
private void WithTextEmbeddingGenerationByAIType(IKernelMemoryBuilder memory,AIModels embedModel, HttpClient embeddingHttpClient )
{
switch (embedModel.AIType)
{
case Model.Enum.AIType.OpenAI:
memory.WithOpenAITextEmbeddingGeneration(new OpenAIConfig()
{
APIKey = embedModel.ModelKey,
EmbeddingModel = embedModel.ModelName
}, null, false, embeddingHttpClient);
break;
case Model.Enum.AIType.AzureOpenAI:
memory.WithAzureOpenAITextEmbeddingGeneration(new AzureOpenAIConfig()
{
APIKey = embedModel.ModelKey,
Deployment = embedModel.ModelName.ConvertToString(),
Endpoint = embedModel.EndPoint.ConvertToString()
});
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;
}
}
private void WithTextGenerationByAIType(IKernelMemoryBuilder memory,AIModels chatModel, HttpClient chatHttpClient )
{
switch (chatModel.AIType)
{
case Model.Enum.AIType.OpenAI:
memory.WithOpenAITextGeneration(new OpenAIConfig()
{
APIKey = chatModel.ModelKey,
TextModel = chatModel.ModelName
}, null, chatHttpClient);
break;
case Model.Enum.AIType.AzureOpenAI:
memory.WithAzureOpenAITextGeneration(new AzureOpenAIConfig()
{
APIKey = chatModel.ModelKey,
Deployment = chatModel.ModelName.ConvertToString(),
Endpoint = chatModel.EndPoint.ConvertToString()
});
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;
}
}
private void WithMemoryDbByVectorDB(IKernelMemoryBuilder memory,IConfiguration _config)
{
string VectorDb = _config["KernelMemory:VectorDb"].ConvertToString();
string ConnectionString = _config["KernelMemory:ConnectionString"].ConvertToString();
string TableNamePrefix = _config["KernelMemory:TableNamePrefix"].ConvertToString();
switch (VectorDb)
{
case "Postgres":
memory.WithPostgresMemoryDb(new PostgresConfig()
{
ConnectionString = ConnectionString,
TableNamePrefix = TableNamePrefix
});
break;
case "Disk":
memory.WithSimpleFileStorage(new SimpleFileStorageConfig()
{
StorageType = FileSystemTypes.Disk
});
break;
case "Memory":
memory.WithSimpleFileStorage(new SimpleFileStorageConfig()
{
StorageType = FileSystemTypes.Volatile
});
break;
}
}
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>();
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)
{
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);
}
}
}
return docTextList;
}
}
}

View File

@@ -4,8 +4,15 @@ using AntSK.Domain.Model;
using AntSK.Domain.Options;
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;
@@ -13,35 +20,70 @@ using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using ServiceLifetime = AntSK.Domain.Common.DependencyInjection.ServiceLifetime;
namespace AntSK.Domain.Domain.Service
{
[ServiceDescription(typeof(IKernelService), ServiceLifetime.Scoped)]
public class KernelService(
IApis_Repositories _apis_Repositories
) : IKernelService
public class KernelService: IKernelService
{
private readonly IApis_Repositories _apis_Repositories;
private readonly IAIModels_Repositories _aIModels_Repositories;
public KernelService(
IApis_Repositories apis_Repositories,
IAIModels_Repositories aIModels_Repositories
)
{
_apis_Repositories = apis_Repositories;
_aIModels_Repositories = aIModels_Repositories;
}
/// <summary>
/// 获取kernel实例依赖注入不好按每个用户去Import不同的插件所以每次new一个新的kernel
/// </summary>
/// <param name="modelId"></param>
/// <param name="apiKey"></param>
/// <returns></returns>
public Kernel GetKernel(string modelId=null,string apiKey=null)
public Kernel GetKernelByApp(Apps app)
{
var handler = new OpenAIHttpClientHandler();
var httpClient = new HttpClient(handler);
httpClient.Timeout = TimeSpan.FromMinutes(5);
var kernel = Kernel.CreateBuilder()
.AddOpenAIChatCompletion(
modelId: modelId!=null? modelId : OpenAIOption.Model,
apiKey: apiKey!=null? apiKey: OpenAIOption.Key,
httpClient: httpClient)
.Build();
var chatModel= _aIModels_Repositories.GetFirst(p => p.Id == app.ChatModelID);
var chatHttpClient = OpenAIHttpClientHandlerUtil.GetHttpClient(chatModel.EndPoint);
var builder = Kernel.CreateBuilder();
WithTextGenerationByAIType(builder, chatModel, chatHttpClient);
var kernel= builder.Build();
RegisterPluginsWithKernel(kernel);
return kernel;
}
private void WithTextGenerationByAIType(IKernelBuilder builder, AIModels chatModel, HttpClient chatHttpClient)
{
switch (chatModel.AIType)
{
case Model.Enum.AIType.OpenAI:
builder.AddOpenAIChatCompletion(
modelId: chatModel.ModelName,
apiKey: chatModel.ModelKey,
httpClient: chatHttpClient);
break;
case Model.Enum.AIType.AzureOpenAI:
builder.AddAzureOpenAIChatCompletion(
deploymentName:chatModel.ModelName,
apiKey: chatModel.ModelKey,
endpoint: chatModel.EndPoint
);
break;
case Model.Enum.AIType.LLamaSharp:
var (weights, parameters) = LLamaConfig.GetLLamaConfig(chatModel.ModelName);
var ex = new StatelessExecutor(weights, parameters);
builder.Services.AddKeyedSingleton<ITextGenerationService>("local-llama", new LLamaSharpTextCompletion(ex));
break;
}
}
/// <summary>
/// 根据app配置的插件导入插件
/// </summary>

View File

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

View File

@@ -0,0 +1,27 @@
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,
}
}

View File

@@ -6,9 +6,10 @@ using System.Threading.Tasks;
namespace AntSK.Domain.Model.Enum
{
public enum AIModelType
public enum ImportKmsStatus
{
Chat = 1,
Embedding = 2,
Loadding=0,
Success=1,
Fail=2
}
}

View File

@@ -0,0 +1,39 @@
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
{
public class ImportKMSTaskDTO
{
public ImportType ImportType { get; set; }
public string KmsId { get; set; }
public string Url { get; set; } = "";
public string Text { get; set; } = "";
public string FilePath { get; set; } = "";
public string FileName { get; set; } = "";
}
public class ImportKMSTaskReq: ImportKMSTaskDTO
{
public KmsDetails KmsDetail { get; set; } = new KmsDetails();
}
public enum ImportType {
File=1,
Url=2,
Text=3
}
}

View File

@@ -6,15 +6,15 @@ using System.Threading.Tasks;
namespace AntSK.Domain.Options
{
public class ConnectionOption
public class DBConnectionOption
{
/// <summary>
/// sqlite连接字符串
/// </summary>
public static string Sqlite { get; set; }
public static string DbType { get; set; }
/// <summary>
/// pg链接字符串
/// </summary>
public static string Postgres { get; set; }
public static string ConnectionStrings { get; set; }
}
}

View File

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

View File

@@ -8,6 +8,7 @@ namespace AntSK.Domain.Options
{
public class LLamaSharpOption
{
public static string RunType { get; set; }
public static string Chat { get; set; }
public static string Embedding { get; set; }

View File

@@ -37,31 +37,31 @@ namespace AntSK.Domain.Repositories
[Required]
public HttpMethodType Method { get; set; }
[SugarColumn(ColumnDataType = "varchar(2000)")]
[SugarColumn(ColumnDataType = "varchar(1000)")]
public string? Header { get; set; }
/// <summary>
/// QueryString参数
/// </summary>
[SugarColumn(ColumnDataType = "varchar(2000)")]
[SugarColumn(ColumnDataType = "varchar(1000)")]
public string? Query { get; set; }
/// <summary>
/// jsonBody 实体
/// </summary>
[SugarColumn(ColumnDataType = "varchar(8000)")]
[SugarColumn(ColumnDataType = "varchar(7000)")]
public string? JsonBody { get; set; }
/// <summary>
/// 入参提示词
/// </summary>
[Required]
[SugarColumn(ColumnDataType = "varchar(2000)")]
[SugarColumn(ColumnDataType = "varchar(1500)")]
public string InputPrompt { get; set; }
/// <summary>
/// 返回提示词
/// </summary>
[Required]
[SugarColumn(ColumnDataType = "varchar(2000)")]
[SugarColumn(ColumnDataType = "varchar(1500)")]
public string OutputPrompt { get; set; }
}
}

View File

@@ -37,9 +37,16 @@ namespace AntSK.Domain.Repositories
[Required]
public string Type { get; set; }
/// <summary>
/// 会话模型ID
/// </summary>
[Required]
public string? ChatModelID { get; set; }
/// <summary>
/// 温度
/// </summary>
[SugarColumn(DefaultValue = "70")]
public double Temperature { get; set; }=70f;
/// <summary>

View File

@@ -28,22 +28,38 @@ namespace AntSK.Domain.Repositories
/// </summary>
[Required]
public string Describe { get; set; }
/// <summary>
/// 会话模型ID
/// </summary>
[Required]
public string? ChatModelID { get; set; }
/// <summary>
/// 向量模型ID
/// </summary>
[Required]
public string? EmbeddingModelID { get; set; }
/// <summary>
/// 每个段落的最大标记数。
/// </summary>
public int MaxTokensPerParagraph { get; set; } = 1000;
[SugarColumn(DefaultValue = "299")]
public int MaxTokensPerParagraph { get; set; } = 299;
/// <summary>
/// 每行,也就是每句话的最大标记数
/// </summary>
public int MaxTokensPerLine { get; set; } = 300;
[SugarColumn(DefaultValue = "99")]
public int MaxTokensPerLine { get; set; } = 99;
/// <summary>
/// 段落之间重叠标记的数量。
/// </summary>
public int OverlappingTokens { get; set; } = 100;
[SugarColumn(DefaultValue = "49")]
public int OverlappingTokens { get; set; } = 49;
}
}

View File

@@ -1,4 +1,5 @@
using SqlSugar;
using AntSK.Domain.Model.Enum;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -32,9 +33,14 @@ namespace AntSK.Domain.Repositories
/// </summary>
public int? DataCount { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime { get; set; }
/// <summary>
/// 状态
/// </summary>
public ImportKmsStatus? Status { get; set; } = ImportKmsStatus.Loadding;
}
}

View File

@@ -7,31 +7,34 @@ using System.Text;
using System.Threading.Tasks;
using AntSK.Domain.Map;
using AntSK.Domain.Model;
using Microsoft.Extensions.Configuration;
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)
{
}
//Sqlite.DbMaintenance.CreateDatabase();
//Sqlite.CodeFirst.InitTables(typeof(CodeFirstTable1));
}
//注意如果使用Client不能写成静态的Scope并发更高
public static SqlSugarScope Sqlite = SqlSugarHelper.Sqlite;
public static SqlSugarScope SqlScope = SqlSugarHelper.SqlScope();
public SimpleClient<T> CurrentDb
{ get { return new SimpleClient<T>(Sqlite); } }//用来处理T表的常用操作
{ get { return new SimpleClient<T>(SqlScope); } }//用来处理T表的常用操作
#region
public virtual SqlSugarScope GetDB()
{
return Sqlite;
return SqlScope;
}
/// <summary>

View File

@@ -0,0 +1,54 @@
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 System.Reflection;
using Microsoft.Extensions.Configuration;
namespace AntSK.Domain.Repositories.Base
{
public class SqlSugarHelper()
{
/// <summary>
/// sqlserver连接
/// </summary>
public static SqlSugarScope SqlScope() {
string DBType = DBConnectionOption.DbType;
string ConnectionString = DBConnectionOption.ConnectionStrings;
var config = new ConnectionConfig()
{
ConnectionString = ConnectionString,
InitKeyType = InitKeyType.Attribute,//从特性读取主键和自增列信息
IsAutoCloseConnection = true,
ConfigureExternalServices = new ConfigureExternalServices
{
//注意: 这儿AOP设置不能少
EntityService = (c, p) =>
{
/***高版C#写法***/
//支持string?和string
if (p.IsPrimarykey == false && new NullabilityInfoContext()
.Create(c).WriteState is NullabilityState.Nullable)
{
p.IsNullable = true;
}
}
}
};
DbType dbType = (DbType)Enum.Parse(typeof(DbType), DBType);
config.DbType = dbType;
var scope= new SqlSugarScope(config, Db =>
{
});
return scope;
}
}
}

View File

@@ -15,25 +15,36 @@ namespace AntSK.Domain.Repositories
[SugarColumn(IsPrimaryKey = true)]
public string Id { get; set; }
/// <summary>
/// AI类型
/// </summary>
[Required]
[SugarColumn(DefaultValue = "1")]
public AIType AIType { get; set; } = AIType.OpenAI;
/// <summary>
/// 模型类型
/// </summary>
[Required]
public AIModelType AIModelType { get; set; }
public AIModelType AIModelType { get; set; }= AIModelType.Chat;
/// <summary>
/// 模型地址
/// </summary>
[Required]
public string EndPoint { get; set; }
public string EndPoint { get; set; } = "";
/// <summary>
/// 模型名称
/// </summary>
[Required]
public string ModelName { get; set; }
public string ModelName { get; set; } = "";
/// <summary>
/// 模型秘钥
/// </summary>
[Required]
public string ModelKey { get; set; }
public string ModelKey { get; set; } = "";
/// <summary>
/// 部署名azure需要使用
/// </summary>
[Required]
public string ModelDescription { get; set; }
}

View File

@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
@@ -10,11 +11,17 @@ namespace AntSK.Domain.Utils
{
public class OpenAIHttpClientHandler : HttpClientHandler
{
private string _endPoint { get; set; }
public OpenAIHttpClientHandler(string endPoint)
{
this._endPoint = endPoint;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
UriBuilder uriBuilder;
Regex regex = new Regex(@"(https?)://([^/:]+)(:\d+)?/(.*)");
Match match = regex.Match(OpenAIOption.EndPoint);
Match match = regex.Match(_endPoint);
if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development" && request.Content != null)
{
string requestBody = await request.Content.ReadAsStringAsync();
@@ -74,4 +81,16 @@ namespace AntSK.Domain.Utils
return response;
}
}
public class OpenAIHttpClientHandlerUtil
{
public static HttpClient GetHttpClient( string endPoint)
{
var handler = new OpenAIHttpClientHandler(endPoint.ConvertToString());
var httpClient = new HttpClient(handler);
httpClient.Timeout = TimeSpan.FromMinutes(5);
return httpClient;
}
}
}

View File

@@ -9,10 +9,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AntSK.Domain", "AntSK.Domai
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docker", "Docker", "{9F2E193A-5F9D-4C82-B591-CB133EEB59F0}"
ProjectSection(SolutionItems) = preProject
docker-compose.yml = docker-compose.yml
Dockerfile = Dockerfile
..\docker-compose.simple.yml = ..\docker-compose.simple.yml
..\docker-compose.yml = ..\docker-compose.yml
..\Dockerfile = ..\Dockerfile
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MiddleWare", "MiddleWare", "{40DDB1DC-571B-4A95-9F34-47F52981C511}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AntSK.BackgroundTask", "MiddleWare\AntSK.BackgroundTask\AntSK.BackgroundTask.csproj", "{DF87E829-99C5-44A7-9718-B3E67DC801F6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -27,10 +32,17 @@ Global
{64F17C9A-97C2-46FA-9345-86C5289288AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{64F17C9A-97C2-46FA-9345-86C5289288AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{64F17C9A-97C2-46FA-9345-86C5289288AD}.Release|Any CPU.Build.0 = Release|Any CPU
{DF87E829-99C5-44A7-9718-B3E67DC801F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{DF87E829-99C5-44A7-9718-B3E67DC801F6} = {40DDB1DC-571B-4A95-9F34-47F52981C511}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2076B7C9-2E5B-4580-9712-03F0D56BC1AF}
EndGlobalSection

View File

@@ -16,6 +16,12 @@
</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>
本地会话接口
@@ -63,7 +69,7 @@
<param name="app"></param>
<returns></returns>
</member>
<member name="M:AntSK.Pages.ChatPage.Chat.HistorySummarize(System.String)">
<member name="M:AntSK.Pages.ChatPage.Chat.HistorySummarize(AntSK.Domain.Repositories.Apps,System.String)">
<summary>
历史会话的会话总结
</summary>
@@ -88,7 +94,7 @@
<param name="app"></param>
<returns></returns>
</member>
<member name="M:AntSK.Pages.ChatPage.OpenChat.HistorySummarize(System.String)">
<member name="M:AntSK.Pages.ChatPage.OpenChat.HistorySummarize(AntSK.Domain.Repositories.Apps,System.String)">
<summary>
历史会话的会话总结
</summary>
@@ -130,7 +136,7 @@
<param name="app"></param>
<returns></returns>
</member>
<member name="M:AntSK.Services.OpenApi.OpenApiService.HistorySummarize(AntSK.Models.OpenAIModel)">
<member name="M:AntSK.Services.OpenApi.OpenApiService.HistorySummarize(AntSK.Domain.Repositories.Apps,AntSK.Models.OpenAIModel)">
<summary>
历史会话的会话总结
</summary>

View File

@@ -25,6 +25,11 @@ namespace AntSK.Controllers
_repository.GetDB().CodeFirst.InitTables(typeof(Apps));
_repository.GetDB().CodeFirst.InitTables(typeof(Kmss));
_repository.GetDB().CodeFirst.InitTables(typeof(KmsDetails));
_repository.GetDB().CodeFirst.InitTables(typeof(Users));
_repository.GetDB().CodeFirst.InitTables(typeof(Apis));
_repository.GetDB().CodeFirst.InitTables(typeof(AIModels));
//创建vector插件如果数据库没有则需要提供支持向量的数据库
_repository.GetDB().Ado.ExecuteCommandAsync($"CREATE EXTENSION IF NOT EXISTS vector;");
return Ok();
}
}

View File

@@ -0,0 +1,57 @@
using AntSK.Domain.Model;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using static AntSK.Pages.KmsPage.KmsDetail;
using System;
using AntSK.Domain.Repositories;
using AntSK.Domain.Domain.Interface;
using Microsoft.KernelMemory.Configuration;
using AntSK.Domain.Model.Enum;
using AntSK.Domain.Map;
using AntSK.BackgroundTask;
namespace AntSK.Controllers
{
/// <summary>
///
/// </summary>
/// <param name="_taskBroker"></param>
[Route("api/[controller]/[action]")]
[ApiController]
public class KMSController : ControllerBase
{
private readonly IKmsDetails_Repositories _kmsDetails_Repositories;
private readonly IKMService _iKMService;
private readonly BackgroundTaskBroker<ImportKMSTaskReq> _taskBroker;
public KMSController(
IKmsDetails_Repositories kmsDetails_Repositories,
IKMService iKMService,
BackgroundTaskBroker<ImportKMSTaskReq> taskBroker
)
{
_kmsDetails_Repositories = kmsDetails_Repositories;
_iKMService = iKMService;
_taskBroker = taskBroker;
}
[HttpPost]
public async Task<IActionResult> ImportKMSTask(ImportKMSTaskDTO model)
{
Console.WriteLine("api/kms/ImportKMSTask 开始");
ImportKMSTaskReq req = model.ToDTO<ImportKMSTaskReq>();
KmsDetails detail = new KmsDetails()
{
Id = Guid.NewGuid().ToString(),
KmsId = req.KmsId,
CreateTime = DateTime.Now,
Status = ImportKmsStatus.Loadding,
Type = model.ImportType.ToString().ToLower()
};
_kmsDetails_Repositories.Insert(detail);
req.KmsDetail = detail;
_taskBroker.QueueWorkItem(req);
Console.WriteLine("api/kms/ImportKMSTask 结束");
return Ok();
}
}
}

View File

@@ -4,6 +4,7 @@
@using Microsoft.AspNetCore.Components.Authorization
@using AntSK.Domain.Options
@using AntSK.Domain.Repositories
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@inherits LayoutComponentBase
<AntDesign.ProLayout.BasicLayout
@@ -28,6 +29,7 @@
[Inject] public HttpClient HttpClient { get; set; }
[Inject] public AuthenticationStateProvider AuthenticationStateProvider { get; set; }
[Inject] protected IUsers_Repositories _users_Repositories { get; set; }
[Inject] protected ProtectedSessionStorage _protectedSessionStore { get; set; }
private ClaimsPrincipal context => ((AntSKAuthProvider)AuthenticationStateProvider).GetCurrentUser();
protected override async Task OnInitializedAsync()
@@ -35,15 +37,30 @@
await base.OnInitializedAsync();
//菜单权限控制
var menuList = await HttpClient.GetFromJsonAsync<MenuDataItem[]>("data/menu.json");
if ((bool)context?.Identity.IsAuthenticated)
var userSessionStorageResult = await _protectedSessionStore.GetAsync<UserSession>("UserSession");
var userSession = userSessionStorageResult.Success ? userSessionStorageResult.Value : null;
if (userSession != null || (bool)context?.Identity.IsAuthenticated)
{
if (context.Identity.Name == LoginOption.User)
string username = "";
if (userSession != null)
{
username = userSession.UserName;
}
else
{
username = context.Identity.Name;
}
if (username == LoginOption.User )
{
_menuData = menuList;
}
else
{
var userMenuList = _users_Repositories.GetFirst(p => p.No == context.Identity.Name).MenuRole.Split(",").ToList();
var userMenuList = _users_Repositories.GetFirst(p => p.No == username).MenuRole.Split(",").ToList();
//非管理员用户不允许操作系统设置
_menuData = menuList.Where(p => p.Key != "setting" && userMenuList.Contains(p.Key)).ToArray();
}

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