mirror of
https://github.com/AIDotNet/AntSK.git
synced 2026-02-21 09:05:35 +08:00
Compare commits
161 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a97cc538f6 | ||
|
|
45471c9bf4 | ||
|
|
7145192988 | ||
|
|
0935becf70 | ||
|
|
a155c906b3 | ||
|
|
fa8e82224a | ||
|
|
7088e26e09 | ||
|
|
f471bdb607 | ||
|
|
0a0bd67834 | ||
|
|
e91f8331de | ||
|
|
2e90a7fe90 | ||
|
|
3fb3c5bad5 | ||
|
|
a6753ee888 | ||
|
|
9b04d3a758 | ||
|
|
68e2b2ff9b | ||
|
|
464baa6125 | ||
|
|
78083a0b68 | ||
|
|
681e248bdf | ||
|
|
1ca9493ce9 | ||
|
|
5537a8796f | ||
|
|
e2a1ab80b0 | ||
|
|
74db9e425f | ||
|
|
3e2152a979 | ||
|
|
930c6c88ae | ||
|
|
24bc276732 | ||
|
|
17cab5c51b | ||
|
|
96dbc8e9e6 | ||
|
|
56a0d51794 | ||
|
|
1cdbd969ba | ||
|
|
d77ece2aa6 | ||
|
|
d4c804c4ac | ||
|
|
c3003f8c3a | ||
|
|
66a2e45029 | ||
|
|
b0c889c336 | ||
|
|
f470b1e555 | ||
|
|
4965983ae1 | ||
|
|
2f2b4e2f3c | ||
|
|
16c739e37f | ||
|
|
f4d51a73cd | ||
|
|
6cc29e4167 | ||
|
|
324e1de84f | ||
|
|
551bdf4802 | ||
|
|
761d9069f6 | ||
|
|
7a15b0f444 | ||
|
|
a185ee4841 | ||
|
|
7213a75212 | ||
|
|
4823977098 | ||
|
|
fa74b84ce3 | ||
|
|
7423b23d3c | ||
|
|
033ded08c7 | ||
|
|
6b397c86d2 | ||
|
|
9730f12c56 | ||
|
|
92c7a80c2e | ||
|
|
64029de11a | ||
|
|
ae363ebad6 | ||
|
|
7b6478b7f5 | ||
|
|
aef7f58c6d | ||
|
|
52450efeb3 | ||
|
|
74d218d2d5 | ||
|
|
f4a60b28ec | ||
|
|
798593bad3 | ||
|
|
778e76b00b | ||
|
|
55778562ae | ||
|
|
66b5b42952 | ||
|
|
3ff8a4f51b | ||
|
|
b2a46db524 | ||
|
|
8d66f4f34d | ||
|
|
199b546d56 | ||
|
|
bea6e5ef53 | ||
|
|
3c17dc9943 | ||
|
|
6d693ed340 | ||
|
|
f86b7aee95 | ||
|
|
fca2d98d51 | ||
|
|
2f3d3d7b55 | ||
|
|
5250817d21 | ||
|
|
6f966590d9 | ||
|
|
da16cf73c9 | ||
|
|
999cda2fc2 | ||
|
|
28f5be071a | ||
|
|
4ad8fb69c7 | ||
|
|
2cb5ab7f98 | ||
|
|
97b87f2adb | ||
|
|
d23c263f9f | ||
|
|
7f003afa2b | ||
|
|
53d52dd17f | ||
|
|
036d57ef05 | ||
|
|
b25e429687 | ||
|
|
a3f87bf123 | ||
|
|
2cab253c4a | ||
|
|
ed119f02e2 | ||
|
|
f178fc16e9 | ||
|
|
e4b2071689 | ||
|
|
146df7ed1d | ||
|
|
7e8db0a3f8 | ||
|
|
e098922219 | ||
|
|
16ca024c22 | ||
|
|
a886e9dfb3 | ||
|
|
5d6114c9ec | ||
|
|
e3b2e1f434 | ||
|
|
6145347d9b | ||
|
|
49e694cbdc | ||
|
|
f860229993 | ||
|
|
f5d93baa17 | ||
|
|
76f58c43b0 | ||
|
|
db29fcc867 | ||
|
|
2f361c23c7 | ||
|
|
4e7ac6eb4b | ||
|
|
58bca689c8 | ||
|
|
e1b2aee33c | ||
|
|
7a6e8525c5 | ||
|
|
b8db68bed1 | ||
|
|
1072f47467 | ||
|
|
cfb1d858c6 | ||
|
|
8e0e75aee6 | ||
|
|
1479c942e2 | ||
|
|
63b02b889c | ||
|
|
5a1de0e2cf | ||
|
|
ad2a402521 | ||
|
|
a14af93afc | ||
|
|
90630bca1d | ||
|
|
bf1db38e2e | ||
|
|
88e23768c6 | ||
|
|
ea8366ca92 | ||
|
|
8e1f07415f | ||
|
|
0b62e773eb | ||
|
|
1c4b1e2d2f | ||
|
|
0e53dd3854 | ||
|
|
c2fa13b6ab | ||
|
|
837c9a1444 | ||
|
|
08ec4f6b7e | ||
|
|
f5a8076da3 | ||
|
|
cf8c935694 | ||
|
|
67fd7d952a | ||
|
|
b7a3ad6fe7 | ||
|
|
0dabd2ee58 | ||
|
|
e841fc6282 | ||
|
|
ab45a46fc0 | ||
|
|
34c06b1dd1 | ||
|
|
50415b12c0 | ||
|
|
61509154c6 | ||
|
|
3d5be56089 | ||
|
|
a0da9c223b | ||
|
|
172755081f | ||
|
|
1da43f2cee | ||
|
|
8b77ea4438 | ||
|
|
b6039c0da3 | ||
|
|
1cda01d5b3 | ||
|
|
6bd2ef4131 | ||
|
|
96e1ca6b34 | ||
|
|
6620a74447 | ||
|
|
fb7a85b9cf | ||
|
|
b7532676c5 | ||
|
|
8cd6940311 | ||
|
|
2de851f5b1 | ||
|
|
e8fd055349 | ||
|
|
7b92373f54 | ||
|
|
03b937432f | ||
|
|
bd9798ad17 | ||
|
|
030abf1059 | ||
|
|
91e633700a | ||
|
|
6eb034967c |
10
.gitignore
vendored
10
.gitignore
vendored
@@ -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
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<DocumentationFile>AntSK.Domain.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper" Version="8.1.0" />
|
||||
<PackageReference Include="MarkdownSharp" Version="2.0.5" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.137" />
|
||||
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.118" />
|
||||
|
||||
<PackageReference Include="Microsoft.SemanticKernel" Version="1.3.0" />
|
||||
<PackageReference Include="Microsoft.SemanticKernel.Core" Version="1.3.0" />
|
||||
<PackageReference Include="Microsoft.KernelMemory.Core" Version="0.26.240121.1" />
|
||||
<PackageReference Include="Microsoft.KernelMemory.MemoryDb.Postgres" Version="0.26.240121.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,45 +0,0 @@
|
||||
using AntSK.Domain.Common.DependencyInjection;
|
||||
using AntSK.Domain.Domain.Interface;
|
||||
using Microsoft.KernelMemory;
|
||||
using AntSK.Domain.Utils;
|
||||
using AntSK.Domain.Domain.Dto;
|
||||
|
||||
namespace AntSK.Domain.Domain.Service
|
||||
{
|
||||
[ServiceDescription(typeof(IKMService), ServiceLifetime.Scoped)]
|
||||
public class KMService(MemoryServerless _memory) : IKMService
|
||||
{
|
||||
public async Task<List<KMFile>> GetDocumentByFileID(string fileid)
|
||||
{
|
||||
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 list = memoryDb.GetListAsync(memoryIndex.Name, null, 100, true);
|
||||
|
||||
await foreach (var item in list)
|
||||
{
|
||||
if (item.Id.Contains(fileid))
|
||||
{
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -1,25 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<DocumentationFile>AntSK.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AntDesign.Charts" Version="0.5.1" />
|
||||
<PackageReference Include="AntDesign.ProLayout" Version="0.17.3" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||
<PackageReference Include="System.Net.Http.Json" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AntSK.Domain\AntSK.Domain.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Pages\Setting\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,27 +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.Pages.KmsPage.KmsDetail.UrlModel">
|
||||
<summary>
|
||||
根据文档ID获取文档
|
||||
</summary>
|
||||
<param name="fileid"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
||||
@@ -1,13 +0,0 @@
|
||||
<Router AppAssembly="@typeof(Program).Assembly">
|
||||
<Found Context="routeData">
|
||||
<CascadingValue Value="routeData">
|
||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(BasicLayout)" />
|
||||
</CascadingValue>
|
||||
</Found>
|
||||
<NotFound>
|
||||
<LayoutView Layout="@typeof(BasicLayout)">
|
||||
<p>Sorry, there's nothing at this address.</p>
|
||||
</LayoutView>
|
||||
</NotFound>
|
||||
</Router>
|
||||
<AntContainer />
|
||||
@@ -1,80 +0,0 @@
|
||||
@namespace AntSK.Pages.AppPage
|
||||
@using AntSK.Domain.Repositories
|
||||
@using AntSK.Models
|
||||
@page "/App/Add"
|
||||
@page "/App/Add/{AppId}"
|
||||
|
||||
<PageContainer Title="新增应用">
|
||||
<ChildContent>
|
||||
<Card>
|
||||
<Form Model="@_appModel"
|
||||
Style="margin-top: 8px;"
|
||||
OnFinish="HandleSubmit">
|
||||
<FormItem Label="知识库名称" LabelCol="_formItemLayout.LabelCol" WrapperCol="_formItemLayout.WrapperCol">
|
||||
<Input Placeholder="请输入知识库名称" @bind-Value="@context.Name" />
|
||||
</FormItem>
|
||||
<FormItem Label="图标" LabelCol="_formItemLayout.LabelCol" WrapperCol="_formItemLayout.WrapperCol">
|
||||
<Input Placeholder="请输入图标" @bind-Value="@context.Icon" />
|
||||
<a href="https://antblazor.com/zh-CN/components/icon" target="_blank">图标库</a>
|
||||
</FormItem>
|
||||
<FormItem Label="类型" LabelCol="_formItemLayout.LabelCol" WrapperCol="_formItemLayout.WrapperCol">
|
||||
<RadioGroup @bind-Value="context.Type">
|
||||
<Radio RadioButton Value="@("chat")">简单对话</Radio>
|
||||
<Radio RadioButton Value="@("kms")" >知识库</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
<FormItem Label="描述" LabelCol="_formItemLayout.LabelCol" WrapperCol="_formItemLayout.WrapperCol">
|
||||
<Input Placeholder="请输入描述" @bind-Value="@context.Describe" />
|
||||
</FormItem>
|
||||
@if (@context.Type == "chat")
|
||||
{
|
||||
<FormItem Label="提示词" LabelCol="_formItemLayout.LabelCol" WrapperCol="_formItemLayout.WrapperCol">
|
||||
<TextArea MinRows="4" Placeholder="请输入提示词,用户输入使用{{$input}} 来做占位符" @bind-Value="@context.Prompt" />
|
||||
</FormItem>
|
||||
}
|
||||
@if (@context.Type == "kms")
|
||||
{
|
||||
<FormItem Label="知识库" LabelCol="_formItemLayout.LabelCol" WrapperCol="_formItemLayout.WrapperCol">
|
||||
<Select Mode="multiple"
|
||||
@bind-Values="kmsIds"
|
||||
Placeholder="选择知识库"
|
||||
TItemValue="string"
|
||||
TItem="string"
|
||||
Size="@AntSizeLDSType.Default"
|
||||
>
|
||||
<SelectOptions>
|
||||
@foreach (var kms in _kmsList)
|
||||
{
|
||||
<SelectOption TItem="string" TItemValue="string" Value="@kms.Id" Label="@kms.Name" />
|
||||
}
|
||||
</SelectOptions>
|
||||
</Select>
|
||||
</FormItem>
|
||||
}
|
||||
<FormItem Label=" " Style="margin-top:32px" WrapperCol="_submitFormLayout.WrapperCol">
|
||||
<Button Type="primary" HtmlType="submit">
|
||||
保存
|
||||
</Button>
|
||||
<Button OnClick="Back">
|
||||
返回
|
||||
</Button>
|
||||
</FormItem>
|
||||
@if (!string.IsNullOrEmpty(_errorMsg))
|
||||
{
|
||||
<Alert Type="@AlertType.Error"
|
||||
Message="错误"
|
||||
Description="@_errorMsg"
|
||||
ShowIcon="true" />
|
||||
}
|
||||
</Form>
|
||||
</Card>
|
||||
</ChildContent>
|
||||
</PageContainer>
|
||||
|
||||
|
||||
<style>
|
||||
.avatar-uploader > .ant-upload {
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,11 +0,0 @@
|
||||
@namespace AntSK.Pages.AppPage
|
||||
@using AntSK.Domain.Repositories
|
||||
@using System.ComponentModel.DataAnnotations
|
||||
@page "/App/Detail/{AppID}"
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
<h3>AppDetail</h3>
|
||||
|
||||
@code {
|
||||
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace AntSK.Pages.AppPage
|
||||
{
|
||||
public partial class AppDetail
|
||||
{
|
||||
[Parameter]
|
||||
public string AppId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
@namespace AntSK.Pages.ChatPage
|
||||
@using AntSK.Domain.Repositories
|
||||
@using AntSK.Models
|
||||
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
||||
@page "/Chat"
|
||||
@page "/Chat/{AppId}"
|
||||
|
||||
<GridRow Gutter="(16, 16)">
|
||||
<GridCol Span="12">
|
||||
<Spin Size="large" Tip="请稍等..." Spinning="@(_loading)">
|
||||
<Card Style="height:800px;overflow: auto;">
|
||||
<TitleTemplate>
|
||||
<Icon Type="setting" /> 选择应用
|
||||
<Select DataSource="@_list"
|
||||
@bind-Value="@AppId"
|
||||
DefaultValue="@("lucy")"
|
||||
ValueProperty="c=>c.Id"
|
||||
LabelProperty="c=>c.Name"
|
||||
Style="width:200px">
|
||||
</Select>
|
||||
</TitleTemplate>
|
||||
<Body>
|
||||
<div id="scrollDiv" style="height: 530px; overflow-y: auto; overflow-x: hidden;">
|
||||
<GridRow Gutter="(8, 8)">
|
||||
<Virtualize Items="@(MessageList.OrderByDescending(o => o.CreateTime).ToList())" Context="item">
|
||||
<GridCol Span="24">
|
||||
<Card Size="small">
|
||||
<TitleTemplate>
|
||||
<Text Strong><Icon Type="bulb" /> @(item.Questions)</Text>
|
||||
</TitleTemplate>
|
||||
<Extra>
|
||||
<Space>
|
||||
<SpaceItem>
|
||||
<a style="color: gray;" @onclick="@(() => OnCopyAsync(item))"><Icon Type="copy" /></a>
|
||||
</SpaceItem>
|
||||
<SpaceItem>
|
||||
<a style="color: gray;" @onclick="@(() => OnClearAsync(item.ID))"><Icon Type="rest" /></a>
|
||||
</SpaceItem>
|
||||
</Space>
|
||||
</Extra>
|
||||
<Body>
|
||||
@((MarkupString)(item.HtmlAnswers))
|
||||
</Body>
|
||||
</Card>
|
||||
</GridCol>
|
||||
</Virtualize>
|
||||
</GridRow>
|
||||
</div>
|
||||
<div style="height: 10px;"></div>
|
||||
<AntDesign.Input @bind-Value="@(_messageInput)" DebounceMilliseconds="@(-1)" Placeholder="输入消息回车发送" OnPressEnter="@(async () => await OnSendAsync())">
|
||||
<Suffix>
|
||||
<Button Icon="send" Type="@(ButtonType.Link)" OnClick="@(async () => await OnSendAsync())"></Button>
|
||||
</Suffix>
|
||||
</AntDesign.Input>
|
||||
</Body>
|
||||
</Card>
|
||||
</Spin>
|
||||
</GridCol>
|
||||
<GridCol Span="12">
|
||||
<Card Style="height: 800px;overflow: auto;">
|
||||
<TitleTemplate>
|
||||
<Icon Type="search" /> 调试结果
|
||||
</TitleTemplate>
|
||||
<Extra>
|
||||
|
||||
</Extra>
|
||||
<Body>
|
||||
<AntList Bordered DataSource="@RelevantSources">
|
||||
<ChildContent Context="item">
|
||||
<span> <b>@item.SourceName </b> 相似度:<Text Mark> @item.Relevance</Text></span>
|
||||
<ListItem>
|
||||
@item.Text
|
||||
</ListItem>
|
||||
</ChildContent>
|
||||
</AntList>
|
||||
</Body>
|
||||
</Card>
|
||||
</GridCol>
|
||||
</GridRow>
|
||||
|
||||
|
||||
@code {
|
||||
|
||||
}
|
||||
@@ -1,170 +0,0 @@
|
||||
using AntDesign;
|
||||
using AntSK.Domain.Model;
|
||||
using AntSK.Domain.Repositories;
|
||||
using AntSK.Domain.Utils;
|
||||
using Azure.AI.OpenAI;
|
||||
using Azure.Core;
|
||||
using MarkdownSharp;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.KernelMemory;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.SemanticKernel;
|
||||
using Microsoft.SemanticKernel.Connectors.OpenAI;
|
||||
using Newtonsoft.Json;
|
||||
using SqlSugar;
|
||||
using System;
|
||||
|
||||
namespace AntSK.Pages.ChatPage
|
||||
{
|
||||
public partial class Chat
|
||||
{
|
||||
[Parameter]
|
||||
public string AppId { get; set; }
|
||||
[Inject]
|
||||
protected MessageService? Message { get; set; }
|
||||
[Inject]
|
||||
protected IApps_Repositories _apps_Repositories { get; set; }
|
||||
[Inject]
|
||||
protected IKmss_Repositories _kmss_Repositories { get; set; }
|
||||
[Inject]
|
||||
protected IKmsDetails_Repositories _kmsDetails_Repositories { get; set; }
|
||||
[Inject]
|
||||
protected MemoryServerless _memory { get; set; }
|
||||
[Inject]
|
||||
protected Kernel _kernel { get; set; }
|
||||
|
||||
protected bool _loading = false;
|
||||
protected List<MessageInfo> MessageList = [];
|
||||
protected string? _messageInput;
|
||||
protected string _json = "";
|
||||
|
||||
List<RelevantSource> RelevantSources = new List<RelevantSource>();
|
||||
|
||||
protected List<Apps> _list = new List<Apps>();
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
_list= _apps_Repositories.GetList();
|
||||
}
|
||||
protected async Task OnSendAsync()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(_messageInput))
|
||||
{
|
||||
_ = Message.Info("请输入消息", 2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(AppId))
|
||||
{
|
||||
_ = Message.Info("请选择应用进行测试", 2);
|
||||
return;
|
||||
}
|
||||
|
||||
await SendAsync(_messageInput);
|
||||
_messageInput = "";
|
||||
|
||||
}
|
||||
protected async Task OnCopyAsync(MessageInfo item)
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
_messageInput = item.Questions;
|
||||
});
|
||||
}
|
||||
|
||||
protected async Task OnClearAsync(string id)
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
MessageList = MessageList.Where(w => w.ID != id).ToList();
|
||||
});
|
||||
}
|
||||
|
||||
protected async Task<bool> SendAsync(string questions)
|
||||
{
|
||||
Apps app=_apps_Repositories.GetFirst(p => p.Id == AppId);
|
||||
switch (app.Type)
|
||||
{
|
||||
case "chat":
|
||||
//普通会话
|
||||
var promptTemplateFactory = new KernelPromptTemplateFactory();
|
||||
var promptTemplate = promptTemplateFactory.Create(new PromptTemplateConfig(app.Prompt));
|
||||
var renderedPrompt = await promptTemplate.RenderAsync(_kernel);
|
||||
|
||||
var func = _kernel.CreateFunctionFromPrompt(app.Prompt, new OpenAIPromptExecutionSettings() );
|
||||
var chatResult = await _kernel.InvokeAsync(func,new KernelArguments() { ["input"]=questions});
|
||||
if (chatResult.IsNotNull())
|
||||
{
|
||||
string answers = chatResult.GetValue<string>();
|
||||
var markdown = new Markdown();
|
||||
string htmlAnswers = markdown.Transform(answers);
|
||||
var info = new MessageInfo()
|
||||
{
|
||||
ID = Guid.NewGuid().ToString(),
|
||||
Questions = questions,
|
||||
Answers = answers,
|
||||
HtmlAnswers = htmlAnswers,
|
||||
CreateTime = DateTime.Now,
|
||||
};
|
||||
MessageList.Add(info);
|
||||
}
|
||||
|
||||
break;
|
||||
case "kms":
|
||||
//知识库问答
|
||||
var filters = new List<MemoryFilter>();
|
||||
|
||||
var kmsidList = app.KmsIdList.Split(",");
|
||||
foreach (var kmsid in kmsidList)
|
||||
{
|
||||
filters.Add(new MemoryFilter().ByTag("kmsid", kmsid));
|
||||
}
|
||||
|
||||
var kmsResult = await _memory.AskAsync(questions, index: "kms", filters: filters);
|
||||
if (kmsResult != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(kmsResult.Result))
|
||||
{
|
||||
string answers = kmsResult.Result;
|
||||
var markdown = new Markdown();
|
||||
string htmlAnswers = markdown.Transform(answers);
|
||||
var info = new MessageInfo()
|
||||
{
|
||||
ID = Guid.NewGuid().ToString(),
|
||||
Questions = questions,
|
||||
Answers = answers,
|
||||
HtmlAnswers = htmlAnswers,
|
||||
CreateTime = DateTime.Now,
|
||||
};
|
||||
MessageList.Add(info);
|
||||
}
|
||||
|
||||
foreach (var x in kmsResult.RelevantSources)
|
||||
{
|
||||
foreach (var xsd in x.Partitions)
|
||||
{
|
||||
string sourceName = x.SourceName;
|
||||
var fileDetail = _kmsDetails_Repositories.GetFirst(p => p.FileGuidName == x.SourceName);
|
||||
if (fileDetail.IsNotNull())
|
||||
{
|
||||
sourceName = fileDetail.FileName;
|
||||
}
|
||||
RelevantSources.Add(new RelevantSource() { SourceName = sourceName, Text = xsd.Text, Relevance = xsd.Relevance });
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return await Task.FromResult(true);
|
||||
}
|
||||
}
|
||||
|
||||
public class RelevantSource
|
||||
{
|
||||
public string SourceName { get; set; }
|
||||
|
||||
public string Text { get; set; }
|
||||
public float Relevance { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
@namespace AntSK.Pages.Exception
|
||||
@page "/exception/404"
|
||||
|
||||
<Result Status="404"
|
||||
Title="404"
|
||||
SubTitle="Sorry, the page you visited does not exist.">
|
||||
<Extra>
|
||||
<Button Type="primary">Back Home</Button>
|
||||
</Extra>
|
||||
</Result>
|
||||
@@ -1,48 +0,0 @@
|
||||
@namespace AntSK.Pages.KmsPage
|
||||
@using AntSK.Domain.Repositories
|
||||
@using AntSK.Models
|
||||
@page "/Kms/Add"
|
||||
@inject IMessageService _message
|
||||
|
||||
<PageContainer Title="新增知识库">
|
||||
<ChildContent>
|
||||
<Card>
|
||||
<Form
|
||||
Model="@_kmsModel"
|
||||
Style="margin-top: 8px;"
|
||||
OnFinish="HandleSubmit">
|
||||
<FormItem Label="知识库名称" LabelCol="_formItemLayout.LabelCol" WrapperCol="_formItemLayout.WrapperCol">
|
||||
<Input Placeholder="请输入知识库名称" @bind-Value="@context.Name" />
|
||||
</FormItem>
|
||||
<FormItem Label="图标" LabelCol="_formItemLayout.LabelCol" WrapperCol="_formItemLayout.WrapperCol">
|
||||
<Input Placeholder="请输入图标" @bind-Value="@context.Icon" />
|
||||
<a href="https://antblazor.com/zh-CN/components/icon" target="_blank">图标库</a>
|
||||
</FormItem>
|
||||
<FormItem Label="描述" LabelCol="_formItemLayout.LabelCol" WrapperCol="_formItemLayout.WrapperCol">
|
||||
<Input Placeholder="请输入描述" @bind-Value="@context.Describe" />
|
||||
</FormItem>
|
||||
<FormItem Label=" " Style="margin-top:32px" WrapperCol="_submitFormLayout.WrapperCol">
|
||||
<Button Type="primary" HtmlType="submit">
|
||||
保存
|
||||
</Button>
|
||||
</FormItem>
|
||||
@if ( !string.IsNullOrEmpty(_errorMsg))
|
||||
{
|
||||
<Alert Type="@AlertType.Error"
|
||||
Message="错误"
|
||||
Description="@_errorMsg"
|
||||
ShowIcon="true"
|
||||
/>
|
||||
}
|
||||
</Form>
|
||||
</Card>
|
||||
</ChildContent>
|
||||
</PageContainer>
|
||||
|
||||
|
||||
<style>
|
||||
.avatar-uploader > .ant-upload {
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,60 +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; }
|
||||
|
||||
private string _errorMsg { get; set; }
|
||||
|
||||
private readonly Kmss _kmsModel = new Kmss() ;
|
||||
|
||||
private readonly FormItemLayout _formItemLayout = new FormItemLayout
|
||||
{
|
||||
LabelCol = new ColLayoutParam
|
||||
{
|
||||
Xs = new EmbeddedProperty { Span = 24 },
|
||||
Sm = new EmbeddedProperty { Span = 7 },
|
||||
},
|
||||
|
||||
WrapperCol = new ColLayoutParam
|
||||
{
|
||||
Xs = new EmbeddedProperty { Span = 24 },
|
||||
Sm = new EmbeddedProperty { Span = 12 },
|
||||
Md = new EmbeddedProperty { Span = 10 },
|
||||
}
|
||||
};
|
||||
private readonly FormItemLayout _submitFormLayout = new FormItemLayout
|
||||
{
|
||||
WrapperCol = new ColLayoutParam
|
||||
{
|
||||
Xs = new EmbeddedProperty { Span = 24, Offset = 0 },
|
||||
Sm = new EmbeddedProperty { Span = 10, Offset = 7 },
|
||||
}
|
||||
};
|
||||
|
||||
private void HandleSubmit()
|
||||
{
|
||||
_kmsModel.Id = Guid.NewGuid().ToString();
|
||||
if (_kmss_Repositories.IsAny(p => p.Name == _kmsModel.Name))
|
||||
{
|
||||
_errorMsg = "名称已存在!";
|
||||
return;
|
||||
}
|
||||
|
||||
_kmss_Repositories.Insert(_kmsModel);
|
||||
|
||||
NavigationManager.NavigateTo("/kmslist");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
@namespace AntSK.Pages.User
|
||||
@layout UserLayout
|
||||
@page "/user/login"
|
||||
|
||||
<div class="main__b__0">
|
||||
<div class="login">
|
||||
<Form Model="@_model" OnFinish="HandleSubmit">
|
||||
<Tabs ActiveKey="@context.LoginType">
|
||||
<TabPane Key="1" Tab="Account Login">
|
||||
<FormItem>
|
||||
<AntDesign.Input Placeholder="Username: admin or user" Size="large" @bind-Value="@context.UserName">
|
||||
<Prefix><Icon Type="user" /></Prefix>
|
||||
</AntDesign.Input>
|
||||
</FormItem>
|
||||
<FormItem>
|
||||
<AntDesign.Input Placeholder="Password: ant.design" Size="large" @bind-Value="@context.Password" Type="password">
|
||||
<Prefix><Icon Type="lock" /></Prefix>
|
||||
</AntDesign.Input>
|
||||
</FormItem>
|
||||
</TabPane>
|
||||
<TabPane Key="2" Tab="Mobile Login">
|
||||
<FormItem>
|
||||
<AntDesign.Input Placeholder="Phone Number" Size="large" @bind-Value="@context.Mobile">
|
||||
<Prefix><Icon Type="mobile" /></Prefix>
|
||||
</AntDesign.Input>
|
||||
</FormItem>
|
||||
<FormItem>
|
||||
<Row Gutter="8">
|
||||
<AntDesign.Col Span="16">
|
||||
<AntDesign.Input Placeholder="Verification code" Size="large" @bind-Value="@context.Captcha">
|
||||
<Prefix><Icon Type="mail" /></Prefix>
|
||||
</AntDesign.Input>
|
||||
</AntDesign.Col>
|
||||
<AntDesign.Col Span="8">
|
||||
<Button Size="large" Block OnClick="GetCaptcha">Verify</Button>
|
||||
</AntDesign.Col>
|
||||
</Row>
|
||||
</FormItem>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
<div>
|
||||
<Checkbox Checked="@context.AutoLogin">
|
||||
Auto Login
|
||||
</Checkbox>
|
||||
<a style="float: right;">
|
||||
Forgot Password
|
||||
</a>
|
||||
</div>
|
||||
<Button Type="primary" HtmlType="submit" Class="submit" Size="large" Block>Log in </Button>
|
||||
<div class="other">
|
||||
Other Login Methods
|
||||
<Icon Class="icon" Type="alipay-circle" />
|
||||
<Icon Class="icon" Type="taobao-circle" />
|
||||
<Icon Class="icon" Type="weibo-circle" />
|
||||
<a class="register" href="/user/register">Register Account</a>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,36 +0,0 @@
|
||||
using AntDesign;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using System.Threading.Tasks;
|
||||
using AntSK.Models;
|
||||
using AntSK.Services;
|
||||
|
||||
namespace AntSK.Pages.User
|
||||
{
|
||||
public partial class Login
|
||||
{
|
||||
private readonly LoginParamsType _model = new LoginParamsType();
|
||||
|
||||
[Inject] public NavigationManager NavigationManager { get; set; }
|
||||
|
||||
[Inject] public IAccountService AccountService { get; set; }
|
||||
|
||||
[Inject] public MessageService Message { get; set; }
|
||||
|
||||
public void HandleSubmit()
|
||||
{
|
||||
if (_model.UserName == "admin" && _model.Password == "ant.design")
|
||||
{
|
||||
NavigationManager.NavigateTo("/");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_model.UserName == "user" && _model.Password == "ant.design") NavigationManager.NavigateTo("/");
|
||||
}
|
||||
|
||||
public async Task GetCaptcha()
|
||||
{
|
||||
var captcha = await AccountService.GetCaptchaAsync(_model.Mobile);
|
||||
await Message.Success($"Verification code validated successfully! The verification code is: {captcha}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -1,39 +0,0 @@
|
||||
{
|
||||
"DetailedErrors": true,
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"ProSettings": {
|
||||
"NavTheme": "light",
|
||||
"Layout": "side",
|
||||
"ContentWidth": "Fluid",
|
||||
"FixedHeader": false,
|
||||
"FixSiderbar": true,
|
||||
"Title": "AntSK",
|
||||
"PrimaryColor": "daybreak",
|
||||
"ColorWeak": false,
|
||||
"SplitMenus": false,
|
||||
"HeaderRender": true,
|
||||
"FooterRender": true,
|
||||
"MenuRender": true,
|
||||
"MenuHeaderRender": true,
|
||||
"HeaderHeight": 48
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"Postgres": "Host=;Port=;Database=antsk;Username=;Password="
|
||||
},
|
||||
"OpenAIOption": {
|
||||
"EndPoint": "",
|
||||
"Key": "",
|
||||
"Model": "",
|
||||
"EmbeddingModel": ""
|
||||
},
|
||||
"Postgres": {
|
||||
"ConnectionString": "Host=;Port=;Database=antsk;Username=;Password=",
|
||||
"TableNamePrefix": "km-"
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
[
|
||||
{
|
||||
"path": "/chat",
|
||||
"name": "聊天",
|
||||
"key": "chat",
|
||||
"icon": "wechat"
|
||||
},
|
||||
{
|
||||
"path": "/applist",
|
||||
"name": "应用",
|
||||
"key": "app",
|
||||
"icon": "windows"
|
||||
},
|
||||
{
|
||||
"path": "/kmslist",
|
||||
"name": "知识库",
|
||||
"key": "kms",
|
||||
"icon": "database"
|
||||
},
|
||||
{
|
||||
"path": "/setting",
|
||||
"name": "设置",
|
||||
"key": "setting",
|
||||
"icon": "setting"
|
||||
}
|
||||
]
|
||||
26
Dockerfile
26
Dockerfile
@@ -1,13 +1,25 @@
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
|
||||
# Build stage
|
||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
|
||||
WORKDIR /src
|
||||
|
||||
# Copy csproj and restore as distinct layers
|
||||
COPY ["src/AntSK/AntSK.csproj", "AntSK/"]
|
||||
RUN dotnet restore "AntSK/AntSK.csproj"
|
||||
|
||||
# Copy everything else and build
|
||||
COPY . .
|
||||
WORKDIR "/src/AntSK"
|
||||
RUN dotnet build "AntSK.csproj" -c Release -o /app/build
|
||||
RUN dotnet publish "AntSK.csproj" -c Release -o /app/publish
|
||||
|
||||
# Runtime stage
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
|
||||
WORKDIR /service
|
||||
EXPOSE 5000
|
||||
|
||||
WORKDIR /app
|
||||
COPY ["AntSK/bin/Release/net8.0/publish", "publish"]
|
||||
|
||||
WORKDIR /app/publish
|
||||
|
||||
FROM base AS final
|
||||
WORKDIR /app
|
||||
COPY --from=build /app/publish .
|
||||
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
||||
RUN echo 'Asia/Shanghai' >/etc/timezone
|
||||
ENTRYPOINT ["dotnet", "AntSK.dll"]
|
||||
ENTRYPOINT ["dotnet", "AntSK.dll"]
|
||||
|
||||
24
README.en.md
24
README.en.md
@@ -35,6 +35,8 @@
|
||||
|
||||
- **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.
|
||||
|
||||
|
||||
|
||||
## Application scenarios
|
||||
@@ -113,7 +115,7 @@ Let's see the effect
|
||||
|
||||
## How do I get started?
|
||||
|
||||
|
||||
Login is the default login account and password
|
||||
|
||||
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.
|
||||
|
||||
@@ -147,13 +149,33 @@ Postgres:{
|
||||
|
||||
"TableNamePrefix": "km -"
|
||||
|
||||
},
|
||||
"Login": {
|
||||
"User": "admin",
|
||||
"Password": "xuzeyu"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
I use CodeFirst mode. As long as the database link is configured, the table structure is automatically created
|
||||
|
||||
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": ""
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
To learn more or start using**AntSK**, you can follow my public account and join the exchange group.
|
||||
|
||||
55
README.md
55
README.md
@@ -16,7 +16,9 @@
|
||||
|
||||
- **GPTs 生成**:此平台支持创建个性化的GPT模型,尝试构建您自己的GPT模型。
|
||||
|
||||
- **API接口发布**:将内部功能以API的形式对外提供,便于开发者将Xzy.AntSK.KnowledgeBase 集成进其他应用,增强应用智慧。
|
||||
- **API接口发布**:将内部功能以API的形式对外提供,便于开发者将AntSK 集成进其他应用,增强应用智慧。
|
||||
|
||||
- **模型管理**:适配和管理集成不同厂商的不同模型。
|
||||
|
||||
## 应用场景
|
||||
|
||||
@@ -60,25 +62,66 @@ AntSK 适用于多种业务场景,例如:
|
||||
## 如何开始?
|
||||
|
||||
在这里我使用的是Postgres 作为数据存储和向量存储,因为Semantic Kernel和Kernel Memory都支持他,当然你也可以换成其他的。
|
||||
|
||||
模型默认支持openai,如果需要使用azure openai需要调整SK的依赖注入,也可以使用one-api进行集成。
|
||||
|
||||
Login是默认的登陆账号和密码
|
||||
|
||||
需要配置如下的配置文件
|
||||
|
||||
## 使用docker-compose
|
||||
|
||||
从项目根目录下载docker-compose.yml,然后把配置文件appsettings.json和它放在统一目录,
|
||||
|
||||
这里已经把pg的镜像做好了。在docker-compose.yml中可以修改默认账号密码,然后你的appsettings.json的数据库连接需要保持一致。
|
||||
|
||||
然后你可以进入到目录后执行
|
||||
```
|
||||
docker-compose up -d
|
||||
```
|
||||
来启动AntSK
|
||||
|
||||
|
||||
## 配置文件的一些含义
|
||||
```
|
||||
"ConnectionStrings": {
|
||||
"Postgres": "Host=;Port=;Database=antsk;Username=;Password="
|
||||
"Postgres": "Host=;Port=;Database=antsk;Username=;Password="//这个是业务数据的连接字符串
|
||||
},
|
||||
"OpenAIOption": {
|
||||
"EndPoint": "",
|
||||
"Key": "",
|
||||
"Model": "",
|
||||
"EmbeddingModel": ""
|
||||
"EndPoint": "", //openai协议的接口,写到v1之前
|
||||
"Key": "",//接口秘钥,如果使用本地模型可以随意填写一个但不能为空
|
||||
"Model": "",//会话模型,使用接口时需要,使用本地模型可以随意填写
|
||||
"EmbeddingModel": ""//向量模型,使用接口时需要,使用本地模型可以随意填写
|
||||
},
|
||||
"Postgres": {
|
||||
"ConnectionString": "Host=;Port=;Database=antsk;Username=;Password=",
|
||||
"TableNamePrefix": "km-"
|
||||
},
|
||||
"Login": {
|
||||
"User": "admin",
|
||||
"Password": "xuzeyu"
|
||||
}
|
||||
```
|
||||
我使用的是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"//本地向量模型的磁盘路径
|
||||
},
|
||||
```
|
||||
|
||||
需要配置Chat和Embedding模型的地址,然后修改EndPoint为本地,使用本地模型时并没有用到Key、Model、EmbeddingModel这些参数,所以这几个你可以随意填写:
|
||||
```
|
||||
"OpenAIOption": {
|
||||
"EndPoint": "http://ip:port/llama/",//如果使用本地模型这个ip端口是AntSK服务启动的ip和端口
|
||||
"Key": "",//接口秘钥,如果使用本地模型可以随意填写一个但不能为空
|
||||
"Model": "",//会话模型,使用接口时需要,使用本地模型可以随意填写
|
||||
"EmbeddingModel": ""//向量模型,使用接口时需要,使用本地模型可以随意填写
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
想了解更多信息或开始使用 **AntSK**,可以关注我的公众号以及加入交流群。
|
||||
|
||||
|
||||
17
docker-compose.simple.yml
Normal file
17
docker-compose.simple.yml
Normal 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:
|
||||
34
docker-compose.yml
Normal file
34
docker-compose.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
# 非 host 版本, 不使用本机代理
|
||||
version: '3.8'
|
||||
services:
|
||||
antskpg:
|
||||
image: registry.cn-hangzhou.aliyuncs.com/xuzeyu91/pg:v0.5.0
|
||||
container_name: antskpg
|
||||
restart: always
|
||||
ports: # 生产环境建议不要暴露
|
||||
- 5432:5432
|
||||
networks:
|
||||
- antsk
|
||||
environment:
|
||||
# 这里的配置只有首次运行生效。修改后,重启镜像是不会生效的。需要把持久化数据删除再重启,才有效果
|
||||
- POSTGRES_USER=username
|
||||
- POSTGRES_PASSWORD=password
|
||||
- POSTGRES_DB=antsk
|
||||
volumes:
|
||||
- ./pg/data:/var/lib/postgresql/data
|
||||
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 # 本地配置文件 需要放在同级目录
|
||||
networks:
|
||||
antsk:
|
||||
37
src/AntSK.Domain/AntSK.Domain.csproj
Normal file
37
src/AntSK.Domain/AntSK.Domain.csproj
Normal file
@@ -0,0 +1,37 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<DocumentationFile>AntSK.Domain.xml</DocumentationFile>
|
||||
<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="AutoMapper" Version="8.1.0" />
|
||||
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
|
||||
<PackageReference Include="MarkdownSharp" Version="2.0.5" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.143" />
|
||||
<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="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>
|
||||
@@ -32,6 +32,52 @@
|
||||
瞬时
|
||||
</summary>
|
||||
</member>
|
||||
<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.GetKernel(System.String,System.String)">
|
||||
<summary>
|
||||
获取kernel实例,依赖注入不好按每个用户去Import不同的插件,所以每次new一个新的kernel
|
||||
</summary>
|
||||
<param name="modelId"></param>
|
||||
<param name="apiKey"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.Domain.Service.KernelService.ImportFunctionsByApp(AntSK.Domain.Repositories.Apps,Microsoft.SemanticKernel.Kernel)">
|
||||
<summary>
|
||||
根据app配置的插件,导入插件
|
||||
</summary>
|
||||
<param name="app"></param>
|
||||
<param name="_kernel"></param>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.Domain.Service.KernelService.RegisterPluginsWithKernel(Microsoft.SemanticKernel.Kernel)">
|
||||
<summary>
|
||||
注册默认插件
|
||||
</summary>
|
||||
<param name="kernel"></param>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.Domain.Service.KernelService.HistorySummarize(Microsoft.SemanticKernel.Kernel,System.String,System.String)">
|
||||
<summary>
|
||||
会话总结
|
||||
</summary>
|
||||
<param name="_kernel"></param>
|
||||
<param name="questions"></param>
|
||||
<param name="history"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.Map.MapperExtend.ToDTOList``1(System.Object)">
|
||||
<summary>
|
||||
Entity集合转DTO集合
|
||||
@@ -57,6 +103,11 @@
|
||||
<param name="result"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Model.MessageInfo.IsSend">
|
||||
<summary>
|
||||
发送是true 接收是false
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Model.PageList`1.PageIndex">
|
||||
<summary>
|
||||
当前页,从1开始
|
||||
@@ -72,16 +123,71 @@
|
||||
总数
|
||||
</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>
|
||||
接口名称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apis.Describe">
|
||||
<summary>
|
||||
接口描述
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apis.Url">
|
||||
<summary>
|
||||
接口地址
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apis.Method">
|
||||
<summary>
|
||||
请求方法
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apis.Query">
|
||||
<summary>
|
||||
QueryString参数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apis.JsonBody">
|
||||
<summary>
|
||||
jsonBody 实体
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apis.InputPrompt">
|
||||
<summary>
|
||||
入参提示词
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apis.OutputPrompt">
|
||||
<summary>
|
||||
返回提示词
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apps.Name">
|
||||
<summary>
|
||||
名称
|
||||
@@ -92,16 +198,41 @@
|
||||
描述
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apps.Icon">
|
||||
<summary>
|
||||
图标
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apps.Type">
|
||||
<summary>
|
||||
类型
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apps.Temperature">
|
||||
<summary>
|
||||
温度
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apps.Prompt">
|
||||
<summary>
|
||||
提示词
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apps.ApiFunctionList">
|
||||
<summary>
|
||||
插件列表
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apps.KmsIdList">
|
||||
<summary>
|
||||
知识库ID列表
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apps.SecretKey">
|
||||
<summary>
|
||||
API调用秘钥
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.KmsDetails.FileName">
|
||||
<summary>
|
||||
文件名称
|
||||
@@ -127,6 +258,11 @@
|
||||
创建时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.KmsDetails.Status">
|
||||
<summary>
|
||||
状态
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Kmss.Icon">
|
||||
<summary>
|
||||
图标
|
||||
@@ -142,6 +278,21 @@
|
||||
会话模型
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Kmss.MaxTokensPerParagraph">
|
||||
<summary>
|
||||
每个段落的最大标记数。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Kmss.MaxTokensPerLine">
|
||||
<summary>
|
||||
每行,也就是每句话的最大标记数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Kmss.OverlappingTokens">
|
||||
<summary>
|
||||
段落之间重叠标记的数量。
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.Repositories.Base.Repository`1.GetList">
|
||||
<summary>
|
||||
获取所有list
|
||||
@@ -394,11 +545,56 @@
|
||||
<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.AIModelType">
|
||||
<summary>
|
||||
模型类型
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.AIModels.EndPoint">
|
||||
<summary>
|
||||
模型地址
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.AIModels.ModelName">
|
||||
<summary>
|
||||
模型名称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.AIModels.ModelKey">
|
||||
<summary>
|
||||
模型秘钥
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Users.No">
|
||||
<summary>
|
||||
工号,用于登陆
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Users.Password">
|
||||
<summary>
|
||||
密码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Users.Name">
|
||||
<summary>
|
||||
名称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Users.Describe">
|
||||
<summary>
|
||||
备注
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Users.MenuRole">
|
||||
<summary>
|
||||
菜单权限
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:AntSK.Domain.Utils.ConvertUtils.IsNull(System.Object)">
|
||||
<summary>
|
||||
判断是否为空,为空返回true
|
||||
@@ -489,5 +685,11 @@
|
||||
<param name="stream"></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>
|
||||
</members>
|
||||
</doc>
|
||||
15
src/AntSK.Domain/Common/Map/AutoMapProfile.cs
Normal file
15
src/AntSK.Domain/Common/Map/AutoMapProfile.cs
Normal 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>();
|
||||
}
|
||||
}
|
||||
}
|
||||
36
src/AntSK.Domain/Common/Map/MapperExtend.cs
Normal file
36
src/AntSK.Domain/Common/Map/MapperExtend.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
31
src/AntSK.Domain/Common/Map/MapperRegister.cs
Normal file
31
src/AntSK.Domain/Common/Map/MapperRegister.cs
Normal 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>();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
14
src/AntSK.Domain/Domain/Interface/IHttpService.cs
Normal file
14
src/AntSK.Domain/Domain/Interface/IHttpService.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
14
src/AntSK.Domain/Domain/Interface/IImportKMSService.cs
Normal file
14
src/AntSK.Domain/Domain/Interface/IImportKMSService.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using AntSK.Domain.Domain.Dto;
|
||||
using Microsoft.KernelMemory.Configuration;
|
||||
using Microsoft.KernelMemory;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -9,6 +11,7 @@ namespace AntSK.Domain.Domain.Interface
|
||||
{
|
||||
public interface IKMService
|
||||
{
|
||||
MemoryServerless GetMemory(SearchClientConfig searchClientConfig = null, TextPartitioningOptions textPartitioningOptions = null);
|
||||
Task<List<KMFile>> GetDocumentByFileID(string fileid);
|
||||
}
|
||||
}
|
||||
17
src/AntSK.Domain/Domain/Interface/IKernelService.cs
Normal file
17
src/AntSK.Domain/Domain/Interface/IKernelService.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using AntSK.Domain.Repositories;
|
||||
using Microsoft.SemanticKernel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AntSK.Domain.Domain.Interface
|
||||
{
|
||||
public interface IKernelService
|
||||
{
|
||||
Kernel GetKernel(string modelId = null, string apiKey = null);
|
||||
void ImportFunctionsByApp(Apps app, Kernel _kernel);
|
||||
Task<string> HistorySummarize(Kernel _kernel, string questions, string history);
|
||||
}
|
||||
}
|
||||
46
src/AntSK.Domain/Domain/Service/BackGroundTaskHandler.cs
Normal file
46
src/AntSK.Domain/Domain/Service/BackGroundTaskHandler.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
30
src/AntSK.Domain/Domain/Service/HttpService.cs
Normal file
30
src/AntSK.Domain/Domain/Service/HttpService.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
91
src/AntSK.Domain/Domain/Service/ImportKMSService.cs
Normal file
91
src/AntSK.Domain/Domain/Service/ImportKMSService.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
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.GetMemory(textPartitioningOptions: new TextPartitioningOptions()
|
||||
{
|
||||
MaxTokensPerLine = km.MaxTokensPerLine,
|
||||
MaxTokensPerParagraph = km.MaxTokensPerParagraph,
|
||||
OverlappingTokens = km.OverlappingTokens
|
||||
});
|
||||
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(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(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(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
124
src/AntSK.Domain/Domain/Service/KMService.cs
Normal file
124
src/AntSK.Domain/Domain/Service/KMService.cs
Normal file
@@ -0,0 +1,124 @@
|
||||
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;
|
||||
|
||||
namespace AntSK.Domain.Domain.Service
|
||||
{
|
||||
[ServiceDescription(typeof(IKMService), ServiceLifetime.Scoped)]
|
||||
public class KMService(
|
||||
IConfiguration _config
|
||||
) : 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()
|
||||
.WithSimpleFileStorage(new SimpleFileStorageConfig { StorageType = FileSystemTypes.Volatile, Directory = "_files" })
|
||||
.WithSearchClientConfig(searchClientConfig)
|
||||
.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);
|
||||
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;
|
||||
}
|
||||
|
||||
var result = memory.Build<MemoryServerless>();
|
||||
return result;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
157
src/AntSK.Domain/Domain/Service/KernelService.cs
Normal file
157
src/AntSK.Domain/Domain/Service/KernelService.cs
Normal file
@@ -0,0 +1,157 @@
|
||||
using AntSK.Domain.Common.DependencyInjection;
|
||||
using AntSK.Domain.Domain.Interface;
|
||||
using AntSK.Domain.Model;
|
||||
using AntSK.Domain.Options;
|
||||
using AntSK.Domain.Repositories;
|
||||
using AntSK.Domain.Utils;
|
||||
using Microsoft.SemanticKernel;
|
||||
using Microsoft.SemanticKernel.Plugins.Core;
|
||||
using RestSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AntSK.Domain.Domain.Service
|
||||
{
|
||||
[ServiceDescription(typeof(IKernelService), ServiceLifetime.Scoped)]
|
||||
public class KernelService(
|
||||
IApis_Repositories _apis_Repositories
|
||||
) : IKernelService
|
||||
{
|
||||
/// <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)
|
||||
{
|
||||
var handler = new OpenAIHttpClientHandler();
|
||||
var httpClient = new HttpClient(handler);
|
||||
httpClient.Timeout = TimeSpan.FromMinutes(5);
|
||||
var kernel = Kernel.CreateBuilder()
|
||||
.AddOpenAIChatCompletion(
|
||||
modelId: modelId!=null? modelId : OpenAIOption.Model,
|
||||
apiKey: apiKey!=null? apiKey: OpenAIOption.Key,
|
||||
httpClient: httpClient)
|
||||
.Build();
|
||||
RegisterPluginsWithKernel(kernel);
|
||||
return kernel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据app配置的插件,导入插件
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <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");
|
||||
{
|
||||
foreach (var api in apiList)
|
||||
{
|
||||
switch (api.Method)
|
||||
{
|
||||
case HttpMethodType.Get:
|
||||
functions.Add(_kernel.CreateFunctionFromMethod((string msg) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.WriteLine(msg);
|
||||
RestClient client = new RestClient();
|
||||
RestRequest request = new RestRequest(api.Url, Method.Get);
|
||||
foreach (var header in api.Header.Split("\n"))
|
||||
{
|
||||
var headerArray = header.Split(":");
|
||||
if (headerArray.Length == 2)
|
||||
{
|
||||
request.AddHeader(headerArray[0], headerArray[1]);
|
||||
}
|
||||
}
|
||||
//这里应该还要处理一次参数提取,等后面再迭代
|
||||
foreach (var query in api.Query.Split("\n"))
|
||||
{
|
||||
var queryArray = query.Split("=");
|
||||
if (queryArray.Length == 2)
|
||||
{
|
||||
request.AddQueryParameter(queryArray[0], queryArray[1]);
|
||||
}
|
||||
}
|
||||
var result = client.Execute(request);
|
||||
return result.Content;
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
return "调用失败:" + ex.Message;
|
||||
}
|
||||
}, api.Name, $"{api.Describe}"));
|
||||
break;
|
||||
case HttpMethodType.Post:
|
||||
functions.Add(_kernel.CreateFunctionFromMethod((string msg) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.WriteLine(msg);
|
||||
RestClient client = new RestClient();
|
||||
RestRequest request = new RestRequest(api.Url, Method.Post);
|
||||
foreach (var header in api.Header.Split("\n"))
|
||||
{
|
||||
var headerArray = header.Split(":");
|
||||
if (headerArray.Length == 2)
|
||||
{
|
||||
request.AddHeader(headerArray[0], headerArray[1]);
|
||||
}
|
||||
}
|
||||
//这里应该还要处理一次参数提取,等后面再迭代
|
||||
request.AddJsonBody(api.JsonBody);
|
||||
var result = client.Execute(request);
|
||||
return result.Content;
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
return "调用失败:" + ex.Message;
|
||||
}
|
||||
}, api.Name, $"{api.Describe}"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
_kernel.ImportPluginFromFunctions("ApiFunctions", functions);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册默认插件
|
||||
/// </summary>
|
||||
/// <param name="kernel"></param>
|
||||
void RegisterPluginsWithKernel(Kernel kernel)
|
||||
{
|
||||
kernel.ImportPluginFromObject(new ConversationSummaryPlugin(), "ConversationSummaryPlugin");
|
||||
kernel.ImportPluginFromObject(new TimePlugin(), "TimePlugin");
|
||||
kernel.ImportPluginFromPromptDirectory(Path.Combine(RepoFiles.SamplePluginsPath(), "KMSPlugin"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 会话总结
|
||||
/// </summary>
|
||||
/// <param name="_kernel"></param>
|
||||
/// <param name="questions"></param>
|
||||
/// <param name="history"></param>
|
||||
/// <returns></returns>
|
||||
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}"; ;
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
14
src/AntSK.Domain/Model/Enum/AIModelType.cs
Normal file
14
src/AntSK.Domain/Model/Enum/AIModelType.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AntSK.Domain.Model.Enum
|
||||
{
|
||||
public enum AIModelType
|
||||
{
|
||||
Chat = 1,
|
||||
Embedding = 2,
|
||||
}
|
||||
}
|
||||
15
src/AntSK.Domain/Model/Enum/HttpMethodType.cs
Normal file
15
src/AntSK.Domain/Model/Enum/HttpMethodType.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.Model
|
||||
{
|
||||
public enum HttpMethodType
|
||||
{
|
||||
Get = 1,
|
||||
Post = 2,
|
||||
|
||||
}
|
||||
}
|
||||
15
src/AntSK.Domain/Model/Enum/ImportKmsStatus.cs
Normal file
15
src/AntSK.Domain/Model/Enum/ImportKmsStatus.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.Model.Enum
|
||||
{
|
||||
public enum ImportKmsStatus
|
||||
{
|
||||
Loadding=0,
|
||||
Success=1,
|
||||
Fail=2
|
||||
}
|
||||
}
|
||||
39
src/AntSK.Domain/Model/ImportKMSTaskReq.cs
Normal file
39
src/AntSK.Domain/Model/ImportKMSTaskReq.cs
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -9,9 +9,13 @@ namespace AntSK.Domain.Model
|
||||
public class MessageInfo
|
||||
{
|
||||
public string ID { get; set; } = "";
|
||||
public string Questions { get; set; } = "";
|
||||
public string Answers { get; set; } = "";
|
||||
public string Context { get; set; } = "";
|
||||
public string HtmlAnswers { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 发送是true 接收是false
|
||||
/// </summary>
|
||||
public bool IsSend { get; set; } = false;
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
24
src/AntSK.Domain/Options/KernelMemoryOption.cs
Normal file
24
src/AntSK.Domain/Options/KernelMemoryOption.cs
Normal 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; }
|
||||
}
|
||||
}
|
||||
16
src/AntSK.Domain/Options/LLamaSharpOption.cs
Normal file
16
src/AntSK.Domain/Options/LLamaSharpOption.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AntSK.Domain.Options
|
||||
{
|
||||
public class LLamaSharpOption
|
||||
{
|
||||
public static string RunType { get; set; }
|
||||
public static string Chat { get; set; }
|
||||
|
||||
public static string Embedding { get; set; }
|
||||
}
|
||||
}
|
||||
15
src/AntSK.Domain/Options/LoginOption.cs
Normal file
15
src/AntSK.Domain/Options/LoginOption.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.Options
|
||||
{
|
||||
public class LoginOption
|
||||
{
|
||||
public static string User { get; set; }
|
||||
|
||||
public static string Password { get; set; }
|
||||
}
|
||||
}
|
||||
67
src/AntSK.Domain/Repositories/AI/Api/Apis.cs
Normal file
67
src/AntSK.Domain/Repositories/AI/Api/Apis.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using AntSK.Domain.Model;
|
||||
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
|
||||
{
|
||||
[SugarTable("Apis")]
|
||||
public partial class Apis
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 接口名称
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 接口描述
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Describe { get; set; }
|
||||
/// <summary>
|
||||
/// 接口地址
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Url { get; set; }
|
||||
/// <summary>
|
||||
/// 请求方法
|
||||
/// </summary>
|
||||
[Required]
|
||||
public HttpMethodType Method { get; set; }
|
||||
|
||||
[SugarColumn(ColumnDataType = "varchar(1000)")]
|
||||
public string? Header { get; set; }
|
||||
/// <summary>
|
||||
/// QueryString参数
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDataType = "varchar(1000)")]
|
||||
public string? Query { get; set; }
|
||||
/// <summary>
|
||||
/// jsonBody 实体
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDataType = "varchar(7000)")]
|
||||
public string? JsonBody { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 入参提示词
|
||||
/// </summary>
|
||||
[Required]
|
||||
[SugarColumn(ColumnDataType = "varchar(1500)")]
|
||||
public string InputPrompt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回提示词
|
||||
/// </summary>
|
||||
[Required]
|
||||
[SugarColumn(ColumnDataType = "varchar(1500)")]
|
||||
public string OutputPrompt { get; set; }
|
||||
}
|
||||
}
|
||||
16
src/AntSK.Domain/Repositories/AI/Api/Apis_Repositories.cs
Normal file
16
src/AntSK.Domain/Repositories/AI/Api/Apis_Repositories.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
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;
|
||||
|
||||
namespace AntSK.Domain.Repositories
|
||||
{
|
||||
[ServiceDescription(typeof(IApis_Repositories), ServiceLifetime.Scoped)]
|
||||
public class Apis_Repositories : Repository<Apis>, IApis_Repositories
|
||||
{
|
||||
}
|
||||
}
|
||||
13
src/AntSK.Domain/Repositories/AI/Api/IApis_Repositories.cs
Normal file
13
src/AntSK.Domain/Repositories/AI/Api/IApis_Repositories.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
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
|
||||
{
|
||||
public interface IApis_Repositories : IRepository<Apis>
|
||||
{
|
||||
}
|
||||
}
|
||||
66
src/AntSK.Domain/Repositories/AI/App/Apps.cs
Normal file
66
src/AntSK.Domain/Repositories/AI/App/Apps.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
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
|
||||
{
|
||||
[SugarTable("Apps")]
|
||||
public partial class Apps
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 描述
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Describe { get; set; }
|
||||
/// <summary>
|
||||
/// 图标
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Icon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 温度
|
||||
/// </summary>
|
||||
[SugarColumn(DefaultValue = "70")]
|
||||
public double Temperature { get; set; }=70f;
|
||||
|
||||
/// <summary>
|
||||
/// 提示词
|
||||
/// </summary>
|
||||
public string? Prompt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 插件列表
|
||||
/// </summary>
|
||||
public string? ApiFunctionList { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 知识库ID列表
|
||||
/// </summary>
|
||||
public string? KmsIdList { get; set; }
|
||||
/// <summary>
|
||||
/// API调用秘钥
|
||||
/// </summary>
|
||||
public string? SecretKey { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -28,5 +28,25 @@ namespace AntSK.Domain.Repositories
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Describe { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 每个段落的最大标记数。
|
||||
/// </summary>
|
||||
[SugarColumn(DefaultValue = "299")]
|
||||
public int MaxTokensPerParagraph { get; set; } = 299;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 每行,也就是每句话的最大标记数
|
||||
/// </summary>
|
||||
[SugarColumn(DefaultValue = "99")]
|
||||
public int MaxTokensPerLine { get; set; } = 99;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 段落之间重叠标记的数量。
|
||||
/// </summary>
|
||||
[SugarColumn(DefaultValue = "49")]
|
||||
public int OverlappingTokens { get; set; } = 49;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
54
src/AntSK.Domain/Repositories/Base/SqlSugarHelper.cs
Normal file
54
src/AntSK.Domain/Repositories/Base/SqlSugarHelper.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
40
src/AntSK.Domain/Repositories/Setting/AIModel/AIModels.cs
Normal file
40
src/AntSK.Domain/Repositories/Setting/AIModel/AIModels.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using AntSK.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
|
||||
{
|
||||
[SugarTable("AIModels")]
|
||||
public partial class AIModels
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public string Id { get; set; }
|
||||
/// <summary>
|
||||
/// 模型类型
|
||||
/// </summary>
|
||||
[Required]
|
||||
public AIModelType AIModelType { get; set; }
|
||||
/// <summary>
|
||||
/// 模型地址
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string EndPoint { get; set; }
|
||||
/// <summary>
|
||||
/// 模型名称
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string ModelName { get; set; }
|
||||
/// <summary>
|
||||
/// 模型秘钥
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string ModelKey { get; set; }
|
||||
[Required]
|
||||
public string ModelDescription { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
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;
|
||||
|
||||
namespace AntSK.Domain.Repositories
|
||||
{
|
||||
[ServiceDescription(typeof(IAIModels_Repositories), ServiceLifetime.Scoped)]
|
||||
public class AIModels_Repositories : Repository<AIModels>, IAIModels_Repositories
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
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
|
||||
{
|
||||
public interface IAIModels_Repositories : IRepository<AIModels>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
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
|
||||
{
|
||||
public interface IUsers_Repositories : IRepository<Users>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -8,12 +8,24 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace AntSK.Domain.Repositories
|
||||
{
|
||||
[SugarTable("Apps")]
|
||||
public partial class Apps
|
||||
[SugarTable("Users")]
|
||||
public partial class Users
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工号,用于登陆
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string No { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 密码
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
@@ -21,23 +33,15 @@ namespace AntSK.Domain.Repositories
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 描述
|
||||
/// 备注
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Describe { get; set; }
|
||||
[Required]
|
||||
public string Icon { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 提示词
|
||||
/// 菜单权限
|
||||
/// </summary>
|
||||
public string? Prompt { get; set; }
|
||||
/// <summary>
|
||||
/// 知识库ID列表
|
||||
/// </summary>
|
||||
public string? KmsIdList { get; set; }
|
||||
[Required]
|
||||
public string MenuRole { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
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;
|
||||
|
||||
namespace AntSK.Domain.Repositories
|
||||
{
|
||||
[ServiceDescription(typeof(IUsers_Repositories), ServiceLifetime.Scoped)]
|
||||
public class Users_Repositories : Repository<Users>, IUsers_Repositories
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ using System.Buffers.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AntSK.Utils
|
||||
namespace AntSK.Domain.Utils
|
||||
{
|
||||
public class LongToDateTimeConverter : JsonConverter<DateTime>
|
||||
{
|
||||
@@ -13,13 +13,25 @@ namespace AntSK.Domain.Utils
|
||||
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
UriBuilder uriBuilder;
|
||||
Regex regex = new Regex(@"(https?)://([^/]+)/(.*)");
|
||||
Regex regex = new Regex(@"(https?)://([^/:]+)(:\d+)?/(.*)");
|
||||
Match match = regex.Match(OpenAIOption.EndPoint);
|
||||
string xieyi = match.Groups[1].Value;
|
||||
string host = match.Groups[2].Value;
|
||||
string route = match.Groups[3].Value;
|
||||
if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development" && request.Content != null)
|
||||
{
|
||||
string requestBody = await request.Content.ReadAsStringAsync();
|
||||
//便于调试查看请求prompt
|
||||
Console.WriteLine(requestBody);
|
||||
}
|
||||
if (match.Success)
|
||||
{
|
||||
string xieyi = match.Groups[1].Value;
|
||||
string host = match.Groups[2].Value;
|
||||
string port = match.Groups[3].Value; // 可选的端口号
|
||||
string route = match.Groups[4].Value;
|
||||
// 如果port不为空,它将包含冒号,所以你可能需要去除它
|
||||
port = string.IsNullOrEmpty(port) ? port : port.Substring(1);
|
||||
// 拼接host和端口号
|
||||
var hostnew = string.IsNullOrEmpty(port) ? host : $"{host}:{port}";
|
||||
|
||||
switch (request.RequestUri.LocalPath)
|
||||
{
|
||||
case "/v1/chat/completions":
|
||||
@@ -27,10 +39,15 @@ namespace AntSK.Domain.Utils
|
||||
uriBuilder = new UriBuilder(request.RequestUri)
|
||||
{
|
||||
// 这里是你要修改的 URL
|
||||
Scheme = $"{xieyi}://{host}/",
|
||||
Host = host,
|
||||
Scheme = $"{xieyi}://{hostnew}/",
|
||||
Host = host,
|
||||
Path = route + "v1/chat/completions",
|
||||
};
|
||||
if (port.ConvertToInt32() != 0)
|
||||
{
|
||||
uriBuilder.Port = port.ConvertToInt32();
|
||||
}
|
||||
|
||||
request.RequestUri = uriBuilder.Uri;
|
||||
|
||||
break;
|
||||
@@ -42,10 +59,15 @@ namespace AntSK.Domain.Utils
|
||||
Host = host,
|
||||
Path = route + "v1/embeddings",
|
||||
};
|
||||
if (port.ConvertToInt32() != 0)
|
||||
{
|
||||
uriBuilder.Port = port.ConvertToInt32();
|
||||
}
|
||||
request.RequestUri = uriBuilder.Uri;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 接着,调用基类的 SendAsync 方法将你的修改后的请求发出去
|
||||
HttpResponseMessage response = await base.SendAsync(request, cancellationToken);
|
||||
|
||||
19
src/AntSK.Domain/Utils/PasswordUtil.cs
Normal file
19
src/AntSK.Domain/Utils/PasswordUtil.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using BCrypt.Net;
|
||||
|
||||
namespace AntSK.Domain.Utils
|
||||
{
|
||||
public class PasswordUtil
|
||||
{
|
||||
public static string HashPassword(string password)
|
||||
{
|
||||
// 默认的工作因子是10,可以根据你的需求调整以增加散列的复杂度
|
||||
return BCrypt.Net.BCrypt.HashPassword(password);
|
||||
}
|
||||
|
||||
// 验证密码是否匹配散列值
|
||||
public static bool VerifyPassword(string password, string hashedPassword)
|
||||
{
|
||||
return BCrypt.Net.BCrypt.Verify(password, hashedPassword);
|
||||
}
|
||||
}
|
||||
}
|
||||
59
src/AntSK.Domain/Utils/RepoFiles.cs
Normal file
59
src/AntSK.Domain/Utils/RepoFiles.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AntSK.Domain.Utils
|
||||
{
|
||||
public static class RepoFiles
|
||||
{
|
||||
/// <summary>
|
||||
/// Scan the local folders from the repo, looking for "samples/plugins" folder.
|
||||
/// </summary>
|
||||
/// <returns>The full path to samples/plugins</returns>
|
||||
public static string SamplePluginsPath()
|
||||
{
|
||||
string Parent = AppDomain.CurrentDomain.BaseDirectory;
|
||||
string Folder = "plugins";
|
||||
|
||||
bool SearchPath(string pathToFind, out string result, int maxAttempts = 10)
|
||||
{
|
||||
var currDir = Path.GetFullPath(Assembly.GetExecutingAssembly().Location);
|
||||
bool found;
|
||||
do
|
||||
{
|
||||
result = Path.Join(currDir, pathToFind);
|
||||
found = Directory.Exists(result);
|
||||
currDir = Path.GetFullPath(Path.Combine(currDir, ".."));
|
||||
} while (maxAttempts-- > 0 && !found);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
if (!SearchPath(Parent + Path.DirectorySeparatorChar + Folder, out string path)
|
||||
&& !SearchPath(Folder, out path))
|
||||
{
|
||||
throw new YourAppException("Plugins directory not found. The app needs the plugins from the repo to work.");
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
public class YourAppException : Exception
|
||||
{
|
||||
public YourAppException() : base()
|
||||
{
|
||||
}
|
||||
|
||||
public YourAppException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public YourAppException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,9 +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
|
||||
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
|
||||
@@ -26,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
|
||||
30
src/AntSK/AntSK.csproj
Normal file
30
src/AntSK/AntSK.csproj
Normal file
@@ -0,0 +1,30 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<DocumentationFile>AntSK.xml</DocumentationFile>
|
||||
<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" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AntSK.Domain\AntSK.Domain.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="plugins\KMSPlugin\Ask\skprompt.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
148
src/AntSK/AntSK.xml
Normal file
148
src/AntSK/AntSK.xml
Normal file
@@ -0,0 +1,148 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>AntSK</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="M:AntSK.Controllers.FileController.UploadFile(Microsoft.AspNetCore.Http.IFormFile)">
|
||||
<summary>
|
||||
Upload FileName
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Controllers.InitController.InitTable">
|
||||
<summary>
|
||||
初始化DB 和表
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:AntSK.Controllers.KMSController">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="_taskBroker"></param>
|
||||
</member>
|
||||
<member name="M:AntSK.Controllers.LLamaSharpController.chat(AntSK.Models.OpenAIModel)">
|
||||
<summary>
|
||||
本地会话接口
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Controllers.LLamaSharpController.embedding(AntSK.Models.OpenAIEmbeddingModel)">
|
||||
<summary>
|
||||
本地嵌入接口
|
||||
</summary>
|
||||
<param name="model"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:AntSK.Controllers.OpenController">
|
||||
<summary>
|
||||
对外接口
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:AntSK.Controllers.OpenController.#ctor(AntSK.Services.OpenApi.IOpenApiService)">
|
||||
<summary>
|
||||
对外接口
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:AntSK.Controllers.OpenController.chat(AntSK.Models.OpenAIModel)">
|
||||
<summary>
|
||||
对话接口
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Pages.ChatPage.Chat.SendKms(System.String,System.String,AntSK.Domain.Repositories.Apps)">
|
||||
<summary>
|
||||
发送知识库问答
|
||||
</summary>
|
||||
<param name="questions"></param>
|
||||
<param name="msg"></param>
|
||||
<param name="app"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Pages.ChatPage.Chat.SendChat(System.String,System.String,AntSK.Domain.Repositories.Apps)">
|
||||
<summary>
|
||||
发送普通对话
|
||||
</summary>
|
||||
<param name="questions"></param>
|
||||
<param name="msg"></param>
|
||||
<param name="app"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Pages.ChatPage.Chat.HistorySummarize(System.String)">
|
||||
<summary>
|
||||
历史会话的会话总结
|
||||
</summary>
|
||||
<param name="questions"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Pages.ChatPage.OpenChat.SendKms(System.String,System.String,AntSK.Domain.Repositories.Apps)">
|
||||
<summary>
|
||||
发送知识库问答
|
||||
</summary>
|
||||
<param name="questions"></param>
|
||||
<param name="msg"></param>
|
||||
<param name="app"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Pages.ChatPage.OpenChat.SendChat(System.String,System.String,AntSK.Domain.Repositories.Apps)">
|
||||
<summary>
|
||||
发送普通对话
|
||||
</summary>
|
||||
<param name="questions"></param>
|
||||
<param name="msg"></param>
|
||||
<param name="app"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Pages.ChatPage.OpenChat.HistorySummarize(System.String)">
|
||||
<summary>
|
||||
历史会话的会话总结
|
||||
</summary>
|
||||
<param name="questions"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:AntSK.Pages.KmsPage.KmsDetail.UrlModel">
|
||||
<summary>
|
||||
根据文档ID获取文档
|
||||
</summary>
|
||||
<param name="fileid"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:AntSK.Services.LLamaSharp.LLamaChatService">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:AntSK.Services.LLamaSharp.LLamaEmbeddingService">
|
||||
<summary>
|
||||
本地Embedding
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:AntSK.Services.OpenApi.OpenApiService.SendChat(System.String,AntSK.Domain.Repositories.Apps)">
|
||||
<summary>
|
||||
发送普通对话
|
||||
</summary>
|
||||
<param name="questions"></param>
|
||||
<param name="msg"></param>
|
||||
<param name="app"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Services.OpenApi.OpenApiService.SendKms(System.String,AntSK.Domain.Repositories.Apps)">
|
||||
<summary>
|
||||
发送知识库问答
|
||||
</summary>
|
||||
<param name="questions"></param>
|
||||
<param name="msg"></param>
|
||||
<param name="app"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:AntSK.Services.OpenApi.OpenApiService.HistorySummarize(AntSK.Models.OpenAIModel)">
|
||||
<summary>
|
||||
历史会话的会话总结
|
||||
</summary>
|
||||
<param name="questions"></param>
|
||||
<param name="msg"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
||||
32
src/AntSK/App.razor
Normal file
32
src/AntSK/App.razor
Normal file
@@ -0,0 +1,32 @@
|
||||
@inject NavigationManager NavigationManager
|
||||
@using Microsoft.AspNetCore.Components.Authorization
|
||||
<CascadingAuthenticationState>
|
||||
<Router AppAssembly="@typeof(Program).Assembly">
|
||||
<Found Context="routeData">
|
||||
<CascadingValue Value="routeData">
|
||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(BasicLayout)" />
|
||||
</CascadingValue>
|
||||
</Found>
|
||||
<NotFound>
|
||||
<LayoutView Layout="@typeof(BasicLayout)">
|
||||
<AntSK.Pages.Exception._404/>
|
||||
</LayoutView>
|
||||
</NotFound>
|
||||
</Router>
|
||||
<AntContainer />
|
||||
</CascadingAuthenticationState>
|
||||
|
||||
@code {
|
||||
private RenderFragment RedirectToLogin => builder =>
|
||||
{
|
||||
var returnUrl = NavigationManager.ToBaseRelativePath(NavigationManager.Uri);
|
||||
if (string.IsNullOrWhiteSpace(returnUrl))
|
||||
{
|
||||
NavigationManager.NavigateTo("user/login");
|
||||
}
|
||||
else
|
||||
{
|
||||
NavigationManager.NavigateTo($"user/login?returnUrl={Uri.EscapeDataString(returnUrl)}", true);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
@namespace AntSK.Components
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
@inherits AntDomComponentBase
|
||||
|
||||
<Space Class="@ClassMapper.Class" Size="@("24")">
|
||||
<Space Class="@ClassMapper.Class" Size="@("26")">
|
||||
<SpaceItem>
|
||||
<AvatarDropdown Name="@_currentUser.Name"
|
||||
<AvatarDropdown Name="@context.Identity.Name"
|
||||
Avatar="@_currentUser.Avatar"
|
||||
MenuItems="@AvatarMenuItems"
|
||||
OnItemSelected="HandleSelectUser" />
|
||||
|
||||
</SpaceItem>
|
||||
</Space>
|
||||
@@ -6,6 +6,10 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using AntSK.Models;
|
||||
using AntSK.Services;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using System.Security.Claims;
|
||||
using AntSK.Services.Auth;
|
||||
using AntSK.Domain.Options;
|
||||
|
||||
namespace AntSK.Components
|
||||
{
|
||||
@@ -38,7 +42,6 @@ namespace AntSK.Components
|
||||
|
||||
public AvatarMenuItem[] AvatarMenuItems { get; set; } = new AvatarMenuItem[]
|
||||
{
|
||||
new() { Key = "center", IconType = "user", Option = "个人中心"},
|
||||
new() { Key = "setting", IconType = "setting", Option = "个人设置"},
|
||||
new() { IsDivider = true },
|
||||
new() { Key = "logout", IconType = "logout", Option = "退出登录"}
|
||||
@@ -50,6 +53,11 @@ namespace AntSK.Components
|
||||
[Inject] protected IProjectService ProjectService { get; set; }
|
||||
[Inject] protected MessageService MessageService { get; set; }
|
||||
|
||||
[Inject] public AuthenticationStateProvider AuthenticationStateProvider { get; set; }
|
||||
[Inject] protected MessageService? Message { get; set; }
|
||||
|
||||
private ClaimsPrincipal context => ((AntSKAuthProvider)AuthenticationStateProvider).GetCurrentUser();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
@@ -73,11 +81,15 @@ namespace AntSK.Components
|
||||
{
|
||||
switch (item.Key)
|
||||
{
|
||||
case "center":
|
||||
NavigationManager.NavigateTo("/account/center");
|
||||
break;
|
||||
case "setting":
|
||||
NavigationManager.NavigateTo("/account/settings");
|
||||
if (context.Identity.Name != LoginOption.User)
|
||||
{
|
||||
NavigationManager.NavigateTo("/setting/user/info/" + context.Identity.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
_ = Message.Info("管理员无需设置", 2);
|
||||
}
|
||||
break;
|
||||
case "logout":
|
||||
NavigationManager.NavigateTo("/user/login");
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
57
src/AntSK/Controllers/KMSController.cs
Normal file
57
src/AntSK/Controllers/KMSController.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
47
src/AntSK/Controllers/LLamaSharpController.cs
Normal file
47
src/AntSK/Controllers/LLamaSharpController.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using AntSK.Models;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using AntSK.Domain.Utils;
|
||||
using AntSK.Services.LLamaSharp;
|
||||
|
||||
namespace AntSK.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
public class LLamaSharpController(ILLamaSharpService _lLamaSharpService) : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 本地会话接口
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("llama/v1/chat/completions")]
|
||||
public async Task chat(OpenAIModel model)
|
||||
{
|
||||
Console.WriteLine("开始:llama/v1/chat/completions");
|
||||
if (model.stream)
|
||||
{
|
||||
await _lLamaSharpService.ChatStream(model, HttpContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _lLamaSharpService.Chat(model, HttpContext);
|
||||
}
|
||||
Console.WriteLine("结束:llama/v1/chat/completions");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 本地嵌入接口
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("llama/v1/embeddings")]
|
||||
public async Task embedding(OpenAIEmbeddingModel model)
|
||||
{
|
||||
Console.WriteLine("开始:llama/v1/embeddings");
|
||||
await _lLamaSharpService.Embedding(model,HttpContext);
|
||||
Console.WriteLine("结束:llama/v1/embeddings");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
31
src/AntSK/Controllers/OpenController.cs
Normal file
31
src/AntSK/Controllers/OpenController.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using AntSK.Domain.Model;
|
||||
using AntSK.Domain.Repositories;
|
||||
using AntSK.Domain.Utils;
|
||||
using AntSK.Models;
|
||||
using AntSK.Models.OpenAPI;
|
||||
using AntSK.Services.OpenApi;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace AntSK.Controllers
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 对外接口
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
public class OpenController(IOpenApiService _openApiService) : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 对话接口
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Route("api/v1/chat/completions")]
|
||||
public async Task chat(OpenAIModel model)
|
||||
{
|
||||
string sk = HttpContext.Request.Headers["Authorization"].ConvertToString();
|
||||
await _openApiService.Chat(model,sk, HttpContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,9 @@
|
||||
@namespace AntSK
|
||||
@using System.Security.Claims
|
||||
@using AntSK.Services.Auth
|
||||
@using Microsoft.AspNetCore.Components.Authorization
|
||||
@using AntSK.Domain.Options
|
||||
@using AntSK.Domain.Repositories
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
<AntDesign.ProLayout.BasicLayout
|
||||
@@ -21,11 +26,28 @@
|
||||
private MenuDataItem[] _menuData = { };
|
||||
|
||||
[Inject] public HttpClient HttpClient { get; set; }
|
||||
[Inject] public AuthenticationStateProvider AuthenticationStateProvider { get; set; }
|
||||
[Inject] protected IUsers_Repositories _users_Repositories { get; set; }
|
||||
private ClaimsPrincipal context => ((AntSKAuthProvider)AuthenticationStateProvider).GetCurrentUser();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
_menuData = await HttpClient.GetFromJsonAsync<MenuDataItem[]>("data/menu.json");
|
||||
//菜单权限控制
|
||||
var menuList = await HttpClient.GetFromJsonAsync<MenuDataItem[]>("data/menu.json");
|
||||
if ((bool)context?.Identity.IsAuthenticated)
|
||||
{
|
||||
if (context.Identity.Name == LoginOption.User)
|
||||
{
|
||||
_menuData = menuList;
|
||||
}
|
||||
else
|
||||
{
|
||||
var userMenuList = _users_Repositories.GetFirst(p => p.No == context.Identity.Name).MenuRole.Split(",").ToList();
|
||||
//非管理员用户不允许操作系统设置
|
||||
_menuData = menuList.Where(p => p.Key != "setting" && userMenuList.Contains(p.Key)).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
8
src/AntSK/Layouts/OpenLayout.razor
Normal file
8
src/AntSK/Layouts/OpenLayout.razor
Normal file
@@ -0,0 +1,8 @@
|
||||
@namespace AntSK
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
@Body
|
||||
|
||||
@code {
|
||||
|
||||
}
|
||||
@@ -11,14 +11,14 @@
|
||||
<div class="header">
|
||||
<a>
|
||||
<img alt="logo" class="logo" src="assets/logo.svg" />
|
||||
<span class="title">Ant Design</span>
|
||||
<span class="title">AntSK</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="desc">Ant Design Blazor</div>
|
||||
<div class="desc"> </div>
|
||||
</div>
|
||||
@Body
|
||||
</div>
|
||||
<FooterView Copyright="2021 Ant Design Blazor" Links="Links"></FooterView>
|
||||
<FooterView Copyright="许泽宇的技术分享" Links="Links"></FooterView>
|
||||
</div>
|
||||
|
||||
@code
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user