mirror of
https://github.com/AIDotNet/AntSK.git
synced 2026-02-19 15:39:18 +08:00
Compare commits
102 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 |
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,41 +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 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,86 +0,0 @@
|
||||
@namespace AntSK.Pages.ChatPage
|
||||
@using AntSK.Domain.Repositories
|
||||
@using AntSK.Models
|
||||
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
||||
@page "/Chat"
|
||||
@page "/Chat/{AppId}"
|
||||
@using AntSK.Services.Auth
|
||||
@inherits AuthComponentBase
|
||||
|
||||
<GridRow Gutter="(16, 16)">
|
||||
<GridCol Span="12">
|
||||
<Spin Size="large" Tip="请稍等..." Spinning="@(_loading)">
|
||||
<Card Style="height:700px;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())" Disabled="@Sendding">
|
||||
<Suffix>
|
||||
<Button Icon="send" Type="@(ButtonType.Link)" OnClick="@(async () => await OnSendAsync())" Disabled="@Sendding"></Button>
|
||||
</Suffix>
|
||||
</AntDesign.Input>
|
||||
</Body>
|
||||
</Card>
|
||||
</Spin>
|
||||
</GridCol>
|
||||
<GridCol Span="12">
|
||||
<Card Style="height: 700px;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>
|
||||
<Body>
|
||||
@((MarkupString)(@item.Text))
|
||||
</Body>
|
||||
</ChildContent>
|
||||
</AntList>
|
||||
</Body>
|
||||
</Card>
|
||||
</GridCol>
|
||||
</GridRow>
|
||||
|
||||
|
||||
@code {
|
||||
|
||||
}
|
||||
@@ -1,244 +0,0 @@
|
||||
using AntDesign;
|
||||
using AntSK.Domain.Model;
|
||||
using AntSK.Domain.Repositories;
|
||||
using AntSK.Domain.Utils;
|
||||
using Azure.AI.OpenAI;
|
||||
using Azure.Core;
|
||||
using DocumentFormat.OpenXml.EMMA;
|
||||
using MarkdownSharp;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.KernelMemory;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.SemanticKernel;
|
||||
using Microsoft.SemanticKernel.ChatCompletion;
|
||||
using Microsoft.SemanticKernel.Connectors.OpenAI;
|
||||
using Newtonsoft.Json;
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
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 = "";
|
||||
protected bool Sendding = false;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Sendding = true;
|
||||
await SendAsync(_messageInput);
|
||||
_messageInput = "";
|
||||
Sendding = false;
|
||||
|
||||
}
|
||||
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)
|
||||
{
|
||||
string msg = questions;
|
||||
//处理多轮会话
|
||||
if (MessageList.Count > 0)
|
||||
{
|
||||
msg = await HistorySummarize(questions);
|
||||
}
|
||||
|
||||
Apps app=_apps_Repositories.GetFirst(p => p.Id == AppId);
|
||||
switch (app.Type)
|
||||
{
|
||||
case "chat":
|
||||
//普通会话
|
||||
await SendChat(questions, msg, app);
|
||||
break;
|
||||
case "kms":
|
||||
//知识库问答
|
||||
await SendKms(questions, msg, app);
|
||||
break;
|
||||
}
|
||||
|
||||
return await Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送知识库问答
|
||||
/// </summary>
|
||||
/// <param name="questions"></param>
|
||||
/// <param name="msg"></param>
|
||||
/// <param name="app"></param>
|
||||
/// <returns></returns>
|
||||
private async Task SendKms(string questions, string msg, Apps app)
|
||||
{
|
||||
//知识库问答
|
||||
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(msg, 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 info1 = new MessageInfo()
|
||||
{
|
||||
ID = Guid.NewGuid().ToString(),
|
||||
Questions = questions,
|
||||
Answers = answers,
|
||||
HtmlAnswers = htmlAnswers,
|
||||
CreateTime = DateTime.Now,
|
||||
};
|
||||
MessageList.Add(info1);
|
||||
}
|
||||
|
||||
foreach (var x in kmsResult.RelevantSources)
|
||||
{
|
||||
foreach (var xsd in x.Partitions)
|
||||
{
|
||||
var markdown = new Markdown();
|
||||
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 = markdown.Transform(xsd.Text), Relevance = xsd.Relevance });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送普通对话
|
||||
/// </summary>
|
||||
/// <param name="questions"></param>
|
||||
/// <param name="msg"></param>
|
||||
/// <param name="app"></param>
|
||||
/// <returns></returns>
|
||||
private async Task SendChat(string questions, string msg, Apps app)
|
||||
{
|
||||
if (string.IsNullOrEmpty(app.Prompt))
|
||||
{
|
||||
//如果模板为空,给默认提示词
|
||||
app.Prompt = "{{$input}}";
|
||||
}
|
||||
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 = _kernel.InvokeStreamingAsync<StreamingChatMessageContent>(function: func, arguments: new KernelArguments() { ["input"] = msg });
|
||||
MessageInfo info = null;
|
||||
var markdown = new Markdown();
|
||||
await foreach (var content in chatResult)
|
||||
{
|
||||
if (info == null)
|
||||
{
|
||||
info = new MessageInfo();
|
||||
info.ID = Guid.NewGuid().ToString();
|
||||
info.Questions = questions;
|
||||
info.Answers = content.Content!;
|
||||
info.HtmlAnswers = content.Content!;
|
||||
info.CreateTime = DateTime.Now;
|
||||
|
||||
MessageList.Add(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
info.HtmlAnswers += content.Content;
|
||||
await Task.Delay(50);
|
||||
}
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
//全部处理完后再处理一次Markdown
|
||||
info!.HtmlAnswers = markdown.Transform(info.HtmlAnswers);
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 历史会话的会话总结
|
||||
/// </summary>
|
||||
/// <param name="questions"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<string> HistorySummarize(string questions)
|
||||
{
|
||||
StringBuilder history = new StringBuilder();
|
||||
foreach (var item in MessageList)
|
||||
{
|
||||
history.Append($"user:{item.Questions}{Environment.NewLine}");
|
||||
history.Append($"assistant:{item.Answers}{Environment.NewLine}");
|
||||
}
|
||||
|
||||
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 = $"历史对话:{his}{Environment.NewLine} 用户问题:{Environment.NewLine}{questions}"; ;
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
||||
public class RelevantSource
|
||||
{
|
||||
public string SourceName { get; set; }
|
||||
|
||||
public string Text { get; set; }
|
||||
public float Relevance { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
@namespace AntSK.Pages.ChatPage
|
||||
@using AntSK.Domain.Repositories
|
||||
@using AntSK.Models
|
||||
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
||||
@page "/OpenChat/{AppId}"
|
||||
@layout OpenLayout
|
||||
|
||||
<div id="chat" style="display:flex; flex-direction:column; height:100%; overflow-x:hidden;">
|
||||
<PageHeader Class="site-page-header" Title="@app.Name" Subtitle="@app.Describe" />
|
||||
<div id="scrollDiv" style="flex:1; width:100%; overflow-y:auto; overflow-x:hidden;padding:10px;">
|
||||
<Virtualize Items="@(MessageList.OrderByDescending(o => o.CreateTime).ToList())" Context="item">
|
||||
<GridCol Span="24">
|
||||
<Card>
|
||||
<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>
|
||||
</div>
|
||||
<div style="flex-shrink:0;margin:10px;">
|
||||
<AntDesign.Input @bind-Value="@(_messageInput)" DebounceMilliseconds="@(-1)" Placeholder="输入消息回车发送" OnPressEnter="@(async () => await OnSendAsync())" Disabled="@Sendding">
|
||||
<Suffix>
|
||||
<Button Icon="send" Type="@(ButtonType.Link)" OnClick="@(async () => await OnSendAsync())" Disabled="@Sendding"></Button>
|
||||
</Suffix>
|
||||
</AntDesign.Input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
using AntDesign;
|
||||
using AntSK.Domain.Repositories;
|
||||
using AntSK.Models;
|
||||
using AntSK.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace AntSK.Pages.Setting.User
|
||||
{
|
||||
public partial class UserList
|
||||
{
|
||||
private readonly BasicListFormModel _model = new BasicListFormModel();
|
||||
|
||||
private readonly IDictionary<string, ProgressStatus> _pStatus = new Dictionary<string, ProgressStatus>
|
||||
{
|
||||
{"active", ProgressStatus.Active},
|
||||
{"exception", ProgressStatus.Exception},
|
||||
{"normal", ProgressStatus.Normal},
|
||||
{"success", ProgressStatus.Success}
|
||||
};
|
||||
|
||||
private List<Users> _data;
|
||||
|
||||
private string _searchKeyword;
|
||||
|
||||
[Inject]
|
||||
protected IUsers_Repositories _users_Repositories { get; set; }
|
||||
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
_data = _users_Repositories.GetList();
|
||||
}
|
||||
|
||||
public void AddUser() {
|
||||
NavigationManager.NavigateTo("/setting/user/add");
|
||||
}
|
||||
|
||||
public void Edit(string userid)
|
||||
{
|
||||
NavigationManager.NavigateTo("/setting/user/add/"+userid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,195 +0,0 @@
|
||||
using AntSK.Domain.Common.DependencyInjection;
|
||||
using AntSK.Domain.Model;
|
||||
using AntSK.Domain.Repositories;
|
||||
using AntSK.Domain.Utils;
|
||||
using AntSK.Models;
|
||||
using AntSK.Models.OpenAPI;
|
||||
using AntSK.Pages.ChatPage;
|
||||
using MarkdownSharp;
|
||||
using Microsoft.KernelMemory;
|
||||
using Microsoft.SemanticKernel.Connectors.OpenAI;
|
||||
using Microsoft.SemanticKernel;
|
||||
using System.Text;
|
||||
using System;
|
||||
using ServiceLifetime = AntSK.Domain.Common.DependencyInjection.ServiceLifetime;
|
||||
using AntDesign.Core.Extensions;
|
||||
using Azure.AI.OpenAI;
|
||||
using Azure;
|
||||
using Azure.Core;
|
||||
using Microsoft.AspNetCore.Http.HttpResults;
|
||||
using AntDesign;
|
||||
using Newtonsoft.Json;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace AntSK.Services.OpenApi
|
||||
{
|
||||
public interface IOpenApiService
|
||||
{
|
||||
Task Chat(OpenAIModel model, string sk, HttpContext HttpContext);
|
||||
}
|
||||
|
||||
[ServiceDescription(typeof(IOpenApiService), ServiceLifetime.Scoped)]
|
||||
public class OpenApiService(
|
||||
IApps_Repositories _apps_Repositories,
|
||||
IKmss_Repositories _kmss_Repositories,
|
||||
IKmsDetails_Repositories _kmsDetails_Repositories,
|
||||
Kernel _kernel,
|
||||
MemoryServerless _memory
|
||||
) : IOpenApiService
|
||||
{
|
||||
public async Task Chat(OpenAIModel model,string sk, HttpContext HttpContext)
|
||||
{
|
||||
OpenAIResult result = new OpenAIResult();
|
||||
result.created= DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||
result.choices=new List<ChoicesModel>() { new ChoicesModel() { message=new OpenAIMessage() { role= "assistant" } } };
|
||||
Apps app = _apps_Repositories.GetFirst(p => p.SecretKey == sk);
|
||||
|
||||
if (app.IsNotNull())
|
||||
{
|
||||
string msg= await HistorySummarize(model);
|
||||
switch (app.Type)
|
||||
{
|
||||
case "chat":
|
||||
//普通会话
|
||||
if (model.stream)
|
||||
{
|
||||
await SendChatStream( HttpContext, result, app, msg);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.choices[0].message.content = await SendChat(msg, app);
|
||||
}
|
||||
break;
|
||||
case "kms":
|
||||
//知识库问答
|
||||
result.choices[0].message.content = await SendKms( msg, app);
|
||||
break;
|
||||
}
|
||||
}
|
||||
HttpContext.Response.ContentType = "application/json";
|
||||
await HttpContext.Response.WriteAsync(JsonConvert.SerializeObject(result));
|
||||
await HttpContext.Response.CompleteAsync();
|
||||
}
|
||||
|
||||
private async Task SendChatStream( HttpContext HttpContext, OpenAIResult result, Apps app, string msg)
|
||||
{
|
||||
HttpContext.Response.Headers.Add("Content-Type", "text/event-stream");
|
||||
|
||||
if (string.IsNullOrEmpty(app.Prompt))
|
||||
{
|
||||
//如果模板为空,给默认提示词
|
||||
app.Prompt = "{{$input}}";
|
||||
}
|
||||
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 = _kernel.InvokeStreamingAsync<StreamingChatMessageContent>(function: func, arguments: new KernelArguments() { ["input"] = msg });
|
||||
int i = 0;
|
||||
|
||||
await foreach (var content in chatResult)
|
||||
{
|
||||
result.choices[0].message.content = content.Content.ConvertToString();
|
||||
string message = $"data: {JsonConvert.SerializeObject(result)}\n\n";
|
||||
await HttpContext.Response.WriteAsync(message, Encoding.UTF8);
|
||||
await HttpContext.Response.Body.FlushAsync();
|
||||
//模拟延迟。
|
||||
await Task.Delay(TimeSpan.FromMilliseconds(50));
|
||||
}
|
||||
|
||||
await HttpContext.Response.WriteAsync("data: [DONE]");
|
||||
await HttpContext.Response.Body.FlushAsync();
|
||||
|
||||
await HttpContext.Response.CompleteAsync();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 发送知识库问答
|
||||
/// </summary>
|
||||
/// <param name="questions"></param>
|
||||
/// <param name="msg"></param>
|
||||
/// <param name="app"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<string> SendKms( string msg, Apps app)
|
||||
{
|
||||
string result = "";
|
||||
//知识库问答
|
||||
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(msg, index: "kms", filters: filters);
|
||||
if (kmsResult != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(kmsResult.Result))
|
||||
{
|
||||
string answers = kmsResult.Result;
|
||||
result = answers;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 发送普通对话
|
||||
/// </summary>
|
||||
/// <param name="questions"></param>
|
||||
/// <param name="msg"></param>
|
||||
/// <param name="app"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<string> SendChat( string msg, Apps app)
|
||||
{
|
||||
string result = "";
|
||||
if (string.IsNullOrEmpty(app.Prompt))
|
||||
{
|
||||
//如果模板为空,给默认提示词
|
||||
app.Prompt = "{{$input}}";
|
||||
}
|
||||
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(function: func, arguments: new KernelArguments() { ["input"] = msg });
|
||||
if (chatResult.IsNotNull())
|
||||
{
|
||||
string answers = chatResult.GetValue<string>();
|
||||
result = answers;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 历史会话的会话总结
|
||||
/// </summary>
|
||||
/// <param name="questions"></param>
|
||||
/// <param name="msg"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<string> HistorySummarize(OpenAIModel model)
|
||||
{
|
||||
|
||||
StringBuilder history = new StringBuilder();
|
||||
string questions = model.messages[model.messages.Count-1].content;
|
||||
for(int i=0;i<model.messages.Count()-1;i++)
|
||||
{
|
||||
var item = model.messages[i];
|
||||
history.Append($"{item.role}:{item.content}{Environment.NewLine}");
|
||||
}
|
||||
|
||||
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 = $"历史对话:{his}{Environment.NewLine}用户问题:{Environment.NewLine}{questions}"; ;
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
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"]
|
||||
|
||||
18
README.en.md
18
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
|
||||
@@ -157,7 +159,23 @@ Postgres:{
|
||||
|
||||
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.
|
||||
|
||||
50
README.md
50
README.md
@@ -18,6 +18,8 @@
|
||||
|
||||
- **API接口发布**:将内部功能以API的形式对外提供,便于开发者将AntSK 集成进其他应用,增强应用智慧。
|
||||
|
||||
- **模型管理**:适配和管理集成不同厂商的不同模型。
|
||||
|
||||
## 应用场景
|
||||
|
||||
AntSK 适用于多种业务场景,例如:
|
||||
@@ -60,20 +62,36 @@ AntSK 适用于多种业务场景,例如:
|
||||
## 如何开始?
|
||||
|
||||
在这里我使用的是Postgres 作为数据存储和向量存储,因为Semantic Kernel和Kernel Memory都支持他,当然你也可以换成其他的。
|
||||
模型默认支持openai,如果需要使用azure openai需要调整SK的依赖注入,也可以使用one-api进行集成。
|
||||
Login是默认的登陆账号和密码
|
||||
需要配置如下的配置文件
|
||||
### 需要注意的是PostgreSQL需要安装扩展vector
|
||||
|
||||
模型默认支持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=",
|
||||
@@ -89,18 +107,18 @@ Login是默认的登陆账号和密码
|
||||
如果想使用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": "D:\\Code\\AI\\AntBlazor\\model\\tinyllama-1.1b-chat.gguf",//本地会话模型的磁盘路径
|
||||
"Embedding": "D:\\Code\\AI\\AntBlazor\\model\\tinyllama-1.1b-chat.gguf"//本地向量模型的磁盘路径
|
||||
},
|
||||
```
|
||||
|
||||
需要配置Chat和Embedding模型的地址,然后修改EndPoint为本地:
|
||||
需要配置Chat和Embedding模型的地址,然后修改EndPoint为本地,使用本地模型时并没有用到Key、Model、EmbeddingModel这些参数,所以这几个你可以随意填写:
|
||||
```
|
||||
"OpenAIOption": {
|
||||
"EndPoint": "https://ip:port/llama/",
|
||||
"Key": "",
|
||||
"Model": "",
|
||||
"EmbeddingModel": ""
|
||||
"EndPoint": "http://ip:port/llama/",//如果使用本地模型这个ip端口是AntSK服务启动的ip和端口
|
||||
"Key": "",//接口秘钥,如果使用本地模型可以随意填写一个但不能为空
|
||||
"Model": "",//会话模型,使用接口时需要,使用本地模型可以随意填写
|
||||
"EmbeddingModel": ""//向量模型,使用接口时需要,使用本地模型可以随意填写
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
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:
|
||||
@@ -5,25 +5,33 @@
|
||||
<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="LLamaSharp.kernel-memory" Version="0.10.0" />
|
||||
<PackageReference Include="LLamaSharp.semantic-kernel" Version="0.10.0" />
|
||||
<PackageReference Include="MarkdownSharp" Version="2.0.5" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.137" />
|
||||
<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.29.240219.2" />
|
||||
<PackageReference Include="Microsoft.KernelMemory.MemoryDb.Postgres" Version="0.29.240219.2" />
|
||||
<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,11 +198,31 @@
|
||||
描述
|
||||
</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列表
|
||||
@@ -132,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>
|
||||
图标
|
||||
@@ -147,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
|
||||
@@ -399,11 +545,31 @@
|
||||
<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>
|
||||
工号,用于登陆
|
||||
@@ -424,6 +590,11 @@
|
||||
备注
|
||||
</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
|
||||
@@ -514,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; }
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ namespace AntSK.Domain.Options
|
||||
{
|
||||
public class LLamaSharpOption
|
||||
{
|
||||
public static string RunType { get; set; }
|
||||
public static string Chat { get; set; }
|
||||
|
||||
public static string Embedding { get; set; }
|
||||
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>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -25,16 +25,35 @@ namespace AntSK.Domain.Repositories
|
||||
/// </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>
|
||||
@@ -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>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,11 @@ namespace AntSK.Domain.Repositories
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Describe { get; set; }
|
||||
/// <summary>
|
||||
/// 菜单权限
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string MenuRole { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
{
|
||||
@@ -15,7 +15,12 @@ namespace AntSK.Domain.Utils
|
||||
UriBuilder uriBuilder;
|
||||
Regex regex = new Regex(@"(https?)://([^/:]+)(:\d+)?/(.*)");
|
||||
Match match = regex.Match(OpenAIOption.EndPoint);
|
||||
|
||||
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;
|
||||
@@ -35,10 +40,14 @@ namespace AntSK.Domain.Utils
|
||||
{
|
||||
// 这里是你要修改的 URL
|
||||
Scheme = $"{xieyi}://{hostnew}/",
|
||||
Host = host,
|
||||
Port=port.ConvertToInt32(),
|
||||
Host = host,
|
||||
Path = route + "v1/chat/completions",
|
||||
};
|
||||
if (port.ConvertToInt32() != 0)
|
||||
{
|
||||
uriBuilder.Port = port.ConvertToInt32();
|
||||
}
|
||||
|
||||
request.RequestUri = uriBuilder.Uri;
|
||||
|
||||
break;
|
||||
@@ -48,9 +57,12 @@ namespace AntSK.Domain.Utils
|
||||
// 这里是你要修改的 URL
|
||||
Scheme = $"{xieyi}://{host}/",
|
||||
Host = host,
|
||||
Port = port.ConvertToInt32(),
|
||||
Path = route + "v1/embeddings",
|
||||
};
|
||||
if (port.ConvertToInt32() != 0)
|
||||
{
|
||||
uriBuilder.Port = port.ConvertToInt32();
|
||||
}
|
||||
request.RequestUri = uriBuilder.Uri;
|
||||
break;
|
||||
}
|
||||
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
|
||||
@@ -20,5 +20,11 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AntSK.Domain\AntSK.Domain.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="plugins\KMSPlugin\Ask\skprompt.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -16,6 +16,12 @@
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:AntSK.Controllers.KMSController">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="_taskBroker"></param>
|
||||
</member>
|
||||
<member name="M:AntSK.Controllers.LLamaSharpController.chat(AntSK.Models.OpenAIModel)">
|
||||
<summary>
|
||||
本地会话接口
|
||||
@@ -112,18 +118,18 @@
|
||||
本地Embedding
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:AntSK.Services.OpenApi.OpenApiService.SendKms(System.String,AntSK.Domain.Repositories.Apps)">
|
||||
<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.SendChat(System.String,AntSK.Domain.Repositories.Apps)">
|
||||
<member name="M:AntSK.Services.OpenApi.OpenApiService.SendKms(System.String,AntSK.Domain.Repositories.Apps)">
|
||||
<summary>
|
||||
发送普通对话
|
||||
发送知识库问答
|
||||
</summary>
|
||||
<param name="questions"></param>
|
||||
<param name="msg"></param>
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ namespace AntSK.Controllers
|
||||
[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);
|
||||
@@ -25,6 +26,7 @@ namespace AntSK.Controllers
|
||||
{
|
||||
await _lLamaSharpService.Chat(model, HttpContext);
|
||||
}
|
||||
Console.WriteLine("结束:llama/v1/chat/completions");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -36,8 +38,9 @@ namespace AntSK.Controllers
|
||||
[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");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace AntSK.Models.OpenAPI
|
||||
public long created { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class ChoicesModel
|
||||
{
|
||||
public string finish_reason { get; set; } = "stop";
|
||||
@@ -46,4 +47,21 @@ namespace AntSK.Models.OpenAPI
|
||||
|
||||
public List<float> embedding { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class OpenAIStreamResult
|
||||
{
|
||||
public string id { get; set; } = Guid.NewGuid().ToString();
|
||||
[JsonProperty("object")]
|
||||
public string obj { get; set; } = "chat.completion";
|
||||
public List<StreamChoicesModel> choices { get; set; }
|
||||
public long created { get; set; }
|
||||
}
|
||||
public class StreamChoicesModel
|
||||
{
|
||||
public int index { get; set; } = 0;
|
||||
|
||||
public OpenAIMessage delta { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user