mirror of
https://github.com/AIDotNet/AntSK.git
synced 2026-02-23 18:49:28 +08:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e754b4732 | ||
|
|
48a9fcfabf | ||
|
|
7ae2b9ac3b | ||
|
|
a6bfe3c69b | ||
|
|
6b146f4750 | ||
|
|
1387e716d1 | ||
|
|
fadc350047 | ||
|
|
8af4994a7d | ||
|
|
b505b61bfe | ||
|
|
5d086c9383 | ||
|
|
dd0e367dc8 | ||
|
|
7110eea912 | ||
|
|
154e67ef98 | ||
|
|
4a04423373 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -337,8 +337,9 @@ ASALocalRun/
|
||||
/AntSK/appsettings.Development.json
|
||||
/AntSK.db
|
||||
**/tmp-memory-files/*
|
||||
**/tmp-memory-vectors/*
|
||||
/src/AntSK/AntSK.db
|
||||
/src/AntSK/appsettings.Development.json
|
||||
/src/AntSK.db
|
||||
/src/AntSK/llama_models
|
||||
/src/AntSK/AntSK.xml
|
||||
/src/AntSK/AntSK.xml
|
||||
@@ -231,6 +231,11 @@
|
||||
会话模型ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apps.EmbeddingModelID">
|
||||
<summary>
|
||||
Embedding 模型Id
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apps.Temperature">
|
||||
<summary>
|
||||
温度
|
||||
|
||||
@@ -13,6 +13,6 @@ namespace AntSK.Domain.Domain.Interface
|
||||
{
|
||||
IAsyncEnumerable<StreamingKernelContent> SendChatByAppAsync(Apps app, string questions, string history);
|
||||
|
||||
IAsyncEnumerable<StreamingKernelContent> SendKmsByAppAsync(Apps app, string questions, string history, List<RelevantSource> relevantSources = null);
|
||||
IAsyncEnumerable<StreamingKernelContent> SendKmsByAppAsync(Apps app, string questions, string history, string filePath, List<RelevantSource> relevantSources = null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,24 @@
|
||||
using AntSK.Domain.Domain.Model.Dto;
|
||||
using AntDesign;
|
||||
using AntSK.Domain.Domain.Model.Dto;
|
||||
using AntSK.Domain.Repositories;
|
||||
using Microsoft.KernelMemory;
|
||||
|
||||
namespace AntSK.Domain.Domain.Interface
|
||||
{
|
||||
public interface IKMService
|
||||
{
|
||||
MemoryServerless GetMemory(Apps app);
|
||||
|
||||
MemoryServerless GetMemoryByKMS(string kmsID, SearchClientConfig searchClientConfig = null);
|
||||
|
||||
Task<List<KMFile>> GetDocumentByFileID(string kmsId, string fileId);
|
||||
|
||||
Task<List<RelevantSource>> GetRelevantSourceList(string kmsIdListStr, string msg);
|
||||
|
||||
List<UploadFileItem> FileList { get; }
|
||||
|
||||
bool BeforeUpload(UploadFileItem file);
|
||||
|
||||
void OnSingleCompleted(UploadInfo fileinfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,29 @@
|
||||
namespace AntSK.Domain.Domain.Model.Enum
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AntSK.Domain.Domain.Model.Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// AI类型
|
||||
/// </summary>
|
||||
public enum AIType
|
||||
{
|
||||
[Display(Name = "Open AI")]
|
||||
OpenAI = 1,
|
||||
|
||||
[Display(Name = "Azure Open AI")]
|
||||
AzureOpenAI = 2,
|
||||
|
||||
[Display(Name = "LLama本地模型")]
|
||||
LLamaSharp = 3,
|
||||
|
||||
[Display(Name = "星火大模型")]
|
||||
SparkDesk = 4,
|
||||
Mock = 5,
|
||||
|
||||
[Display(Name = "灵积大模型")]
|
||||
DashScope = 5,
|
||||
|
||||
[Display(Name = "模拟输出")]
|
||||
Mock = 100,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -10,7 +10,11 @@
|
||||
/// 发送是true 接收是false
|
||||
/// </summary>
|
||||
public bool IsSend { get; set; } = false;
|
||||
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
public string? FilePath { get; set; }
|
||||
|
||||
public string? FileName { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,11 @@ using System.Text;
|
||||
using AntSK.Domain.Utils;
|
||||
using AntSK.Domain.Domain.Model.Dto;
|
||||
using AntSK.Domain.Domain.Model.Constant;
|
||||
using DocumentFormat.OpenXml.Drawing;
|
||||
using System.Reflection.Metadata;
|
||||
using Microsoft.KernelMemory;
|
||||
using System.Collections.Generic;
|
||||
using Markdig;
|
||||
|
||||
namespace AntSK.Domain.Domain.Service
|
||||
{
|
||||
@@ -34,7 +39,7 @@ namespace AntSK.Domain.Domain.Service
|
||||
var _kernel = _kernelService.GetKernelByApp(app);
|
||||
var temperature = app.Temperature / 100;//存的是0~100需要缩小
|
||||
OpenAIPromptExecutionSettings settings = new() { Temperature = temperature };
|
||||
if (!string.IsNullOrEmpty(app.ApiFunctionList)|| !string.IsNullOrEmpty(app.NativeFunctionList))//这里还需要加上本地插件的
|
||||
if (!string.IsNullOrEmpty(app.ApiFunctionList) || !string.IsNullOrEmpty(app.NativeFunctionList))//这里还需要加上本地插件的
|
||||
{
|
||||
_kernelService.ImportFunctionsByApp(app, _kernel);
|
||||
settings.ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions;
|
||||
@@ -47,12 +52,29 @@ namespace AntSK.Domain.Domain.Service
|
||||
}
|
||||
}
|
||||
|
||||
public async IAsyncEnumerable<StreamingKernelContent> SendKmsByAppAsync(Apps app, string questions, string history, List<RelevantSource> relevantSources = null)
|
||||
public async IAsyncEnumerable<StreamingKernelContent> SendKmsByAppAsync(Apps app, string questions, string history, string filePath, List<RelevantSource> relevantSources = null)
|
||||
{
|
||||
var _kernel = _kernelService.GetKernelByApp(app);
|
||||
|
||||
|
||||
var relevantSourceList = await _kMService.GetRelevantSourceList(app.KmsIdList, questions);
|
||||
var _kernel = _kernelService.GetKernelByApp(app);
|
||||
if (!string.IsNullOrWhiteSpace(filePath))
|
||||
{
|
||||
var memory = _kMService.GetMemory(app);
|
||||
var fileId = Guid.NewGuid().ToString();
|
||||
var result = await memory.ImportDocumentAsync(new Microsoft.KernelMemory.Document(fileId).AddFile(filePath)
|
||||
.AddTag(KmsConstantcs.KmsIdTag, app.Id)
|
||||
, index: KmsConstantcs.KmsIndex);
|
||||
|
||||
var filters = new MemoryFilter().ByTag(KmsConstantcs.KmsIdTag, app.Id);
|
||||
|
||||
var searchResult = await memory.SearchAsync(questions, index: KmsConstantcs.KmsIndex, filters: [filters]);
|
||||
relevantSourceList.AddRange(searchResult.Results.SelectMany(item => item.Partitions.Select(part => new RelevantSource()
|
||||
{
|
||||
SourceName = item.SourceName,
|
||||
Text = Markdown.ToHtml(part.Text),
|
||||
Relevance = part.Relevance
|
||||
})));
|
||||
}
|
||||
|
||||
var dataMsg = new StringBuilder();
|
||||
if (relevantSourceList.Any())
|
||||
{
|
||||
@@ -61,7 +83,7 @@ namespace AntSK.Domain.Domain.Service
|
||||
{
|
||||
dataMsg.AppendLine(item.ToString());
|
||||
}
|
||||
|
||||
|
||||
KernelFunction jsonFun = _kernel.Plugins.GetFunction("KMSPlugin", "Ask");
|
||||
var chatResult = _kernel.InvokeStreamingAsync(function: jsonFun,
|
||||
arguments: new KernelArguments() { ["doc"] = dataMsg, ["history"] = history, ["questions"] = questions });
|
||||
@@ -73,7 +95,7 @@ namespace AntSK.Domain.Domain.Service
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return new StreamingTextContent(KmsConstantcs.KmsSearchNull);
|
||||
yield return new StreamingTextContent(KmsConstantcs.KmsSearchNull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
using AntSK.Domain.Common.DependencyInjection;
|
||||
using AntDesign;
|
||||
using AntSK.Domain.Common.DependencyInjection;
|
||||
using AntSK.Domain.Domain.Interface;
|
||||
using AntSK.Domain.Domain.Model.Constant;
|
||||
using AntSK.Domain.Domain.Model.Dto;
|
||||
using AntSK.Domain.Domain.Other;
|
||||
using AntSK.Domain.Options;
|
||||
using AntSK.Domain.Repositories;
|
||||
using AntSK.Domain.Utils;
|
||||
using DocumentFormat.OpenXml.Drawing.Diagrams;
|
||||
using LLama;
|
||||
using LLamaSharp.KernelMemory;
|
||||
using Markdig;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.KernelMemory;
|
||||
using Microsoft.KernelMemory.Configuration;
|
||||
@@ -20,13 +24,52 @@ namespace AntSK.Domain.Domain.Service
|
||||
{
|
||||
[ServiceDescription(typeof(IKMService), ServiceLifetime.Scoped)]
|
||||
public class KMService(
|
||||
IConfiguration _config,
|
||||
IKmss_Repositories _kmss_Repositories,
|
||||
IAIModels_Repositories _aIModels_Repositories
|
||||
IAIModels_Repositories _aIModels_Repositories,
|
||||
IMessageService? _message
|
||||
) : IKMService
|
||||
{
|
||||
private MemoryServerless _memory;
|
||||
|
||||
private List<UploadFileItem> _fileList = [];
|
||||
|
||||
public List<UploadFileItem> FileList => _fileList;
|
||||
|
||||
public MemoryServerless GetMemory(Apps app)
|
||||
{
|
||||
var chatModel = _aIModels_Repositories.GetFirst(p => p.Id == app.ChatModelID);
|
||||
var embedModel = _aIModels_Repositories.GetFirst(p => p.Id == app.EmbeddingModelID);
|
||||
var chatHttpClient = OpenAIHttpClientHandlerUtil.GetHttpClient(chatModel.EndPoint);
|
||||
var embeddingHttpClient = OpenAIHttpClientHandlerUtil.GetHttpClient(embedModel.EndPoint);
|
||||
|
||||
var searchClientConfig = new SearchClientConfig
|
||||
{
|
||||
MaxAskPromptSize = 2048,
|
||||
MaxMatchesCount = 3,
|
||||
AnswerTokens = 1000,
|
||||
EmptyAnswer = KmsConstantcs.KmsSearchNull
|
||||
};
|
||||
|
||||
var memoryBuild = new KernelMemoryBuilder()
|
||||
.WithSearchClientConfig(searchClientConfig)
|
||||
//.WithCustomTextPartitioningOptions(new TextPartitioningOptions
|
||||
//{
|
||||
// MaxTokensPerLine = app.MaxTokensPerLine,
|
||||
// MaxTokensPerParagraph = kms.MaxTokensPerParagraph,
|
||||
// OverlappingTokens = kms.OverlappingTokens
|
||||
//})
|
||||
;
|
||||
//加载会话模型
|
||||
WithTextGenerationByAIType(memoryBuild, chatModel, chatHttpClient);
|
||||
//加载向量模型
|
||||
WithTextEmbeddingGenerationByAIType(memoryBuild, embedModel, embeddingHttpClient);
|
||||
//加载向量库
|
||||
WithMemoryDbByVectorDB(memoryBuild);
|
||||
|
||||
_memory = memoryBuild.Build<MemoryServerless>();
|
||||
return _memory;
|
||||
}
|
||||
|
||||
public MemoryServerless GetMemoryByKMS(string kmsID, SearchClientConfig searchClientConfig = null)
|
||||
{
|
||||
//if (_memory.IsNull())
|
||||
@@ -65,7 +108,7 @@ namespace AntSK.Domain.Domain.Service
|
||||
//加载向量模型
|
||||
WithTextEmbeddingGenerationByAIType(memoryBuild, embedModel, embeddingHttpClient);
|
||||
//加载向量库
|
||||
WithMemoryDbByVectorDB(memoryBuild, _config);
|
||||
WithMemoryDbByVectorDB(memoryBuild);
|
||||
|
||||
_memory = memoryBuild.Build<MemoryServerless>();
|
||||
return _memory;
|
||||
@@ -87,6 +130,7 @@ namespace AntSK.Domain.Domain.Service
|
||||
EmbeddingModel = embedModel.ModelName
|
||||
}, null, false, embeddingHttpClient);
|
||||
break;
|
||||
|
||||
case Model.Enum.AIType.AzureOpenAI:
|
||||
memory.WithAzureOpenAITextEmbeddingGeneration(new AzureOpenAIConfig()
|
||||
{
|
||||
@@ -97,11 +141,15 @@ namespace AntSK.Domain.Domain.Service
|
||||
APIType = AzureOpenAIConfig.APITypes.EmbeddingGeneration,
|
||||
});
|
||||
break;
|
||||
|
||||
case Model.Enum.AIType.LLamaSharp:
|
||||
var (weights, parameters) = LLamaConfig.GetLLamaConfig(embedModel.ModelName);
|
||||
var embedder = new LLamaEmbedder(weights, parameters);
|
||||
memory.WithLLamaSharpTextEmbeddingGeneration(new LLamaSharpTextEmbeddingGenerator(embedder));
|
||||
break;
|
||||
case Model.Enum.AIType.DashScope:
|
||||
memory.WithDashScopeDefaults(embedModel.ModelKey);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,6 +165,7 @@ namespace AntSK.Domain.Domain.Service
|
||||
TextModel = chatModel.ModelName
|
||||
}, null, chatHttpClient);
|
||||
break;
|
||||
|
||||
case Model.Enum.AIType.AzureOpenAI:
|
||||
memory.WithAzureOpenAITextGeneration(new AzureOpenAIConfig()
|
||||
{
|
||||
@@ -127,20 +176,27 @@ namespace AntSK.Domain.Domain.Service
|
||||
APIType = AzureOpenAIConfig.APITypes.TextCompletion,
|
||||
});
|
||||
break;
|
||||
|
||||
case Model.Enum.AIType.LLamaSharp:
|
||||
var (weights, parameters) = LLamaConfig.GetLLamaConfig(chatModel.ModelName);
|
||||
var context = weights.CreateContext(parameters);
|
||||
var executor = new StatelessExecutor(weights, parameters);
|
||||
memory.WithLLamaSharpTextGeneration(new LlamaSharpTextGenerator(weights, context, executor));
|
||||
break;
|
||||
case Model.Enum.AIType.DashScope:
|
||||
memory.WithDashScopeTextGeneration(new Cnblogs.KernelMemory.AI.DashScope.DashScopeConfig
|
||||
{
|
||||
ApiKey = chatModel.ModelKey,
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void WithMemoryDbByVectorDB(IKernelMemoryBuilder memory, IConfiguration _config)
|
||||
private void WithMemoryDbByVectorDB(IKernelMemoryBuilder memory)
|
||||
{
|
||||
string VectorDb = _config["KernelMemory:VectorDb"].ConvertToString();
|
||||
string ConnectionString = _config["KernelMemory:ConnectionString"].ConvertToString();
|
||||
string TableNamePrefix = _config["KernelMemory:TableNamePrefix"].ConvertToString();
|
||||
string VectorDb = KernelMemoryOption.VectorDb.ConvertToString();
|
||||
string ConnectionString = KernelMemoryOption.ConnectionString.ConvertToString();
|
||||
string TableNamePrefix = KernelMemoryOption.TableNamePrefix.ConvertToString();
|
||||
switch (VectorDb)
|
||||
{
|
||||
case "Postgres":
|
||||
@@ -150,12 +206,14 @@ namespace AntSK.Domain.Domain.Service
|
||||
TableNamePrefix = TableNamePrefix
|
||||
});
|
||||
break;
|
||||
|
||||
case "Disk":
|
||||
memory.WithSimpleVectorDb(new SimpleVectorDbConfig()
|
||||
{
|
||||
StorageType = FileSystemTypes.Disk,
|
||||
});
|
||||
break;
|
||||
|
||||
case "Memory":
|
||||
memory.WithSimpleVectorDb(new SimpleVectorDbConfig()
|
||||
{
|
||||
@@ -194,6 +252,8 @@ namespace AntSK.Domain.Domain.Service
|
||||
public async Task<List<RelevantSource>> GetRelevantSourceList(string kmsIdListStr, string msg)
|
||||
{
|
||||
var result = new List<RelevantSource>();
|
||||
if (string.IsNullOrWhiteSpace(kmsIdListStr))
|
||||
return result;
|
||||
var kmsIdList = kmsIdListStr.Split(",");
|
||||
if (!kmsIdList.Any()) return result;
|
||||
|
||||
@@ -202,7 +262,7 @@ namespace AntSK.Domain.Domain.Service
|
||||
var filters = kmsIdList.Select(kmsId => new MemoryFilter().ByTag(KmsConstantcs.KmsIdTag, kmsId)).ToList();
|
||||
|
||||
var searchResult = await memory.SearchAsync(msg, index: KmsConstantcs.KmsIndex, filters: filters);
|
||||
if (!searchResult.NoResult)
|
||||
if (!searchResult.NoResult)
|
||||
{
|
||||
foreach (var item in searchResult.Results)
|
||||
{
|
||||
@@ -217,5 +277,49 @@ namespace AntSK.Domain.Domain.Service
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool BeforeUpload(UploadFileItem file)
|
||||
{
|
||||
List<string> types = new List<string>() {
|
||||
"text/plain",
|
||||
"application/msword",
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
"application/vnd.ms-excel",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"application/vnd.ms-powerpoint",
|
||||
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
||||
"application/pdf",
|
||||
"application/json",
|
||||
"text/x-markdown",
|
||||
"text/markdown"
|
||||
};
|
||||
|
||||
string[] exceptExts = [".md", ".pdf"];
|
||||
var validTypes = types.Contains(file.Type) || exceptExts.Contains(file.Ext);
|
||||
if (!validTypes && file.Ext != ".md")
|
||||
{
|
||||
_message.Error("文件格式错误,请重新选择!");
|
||||
}
|
||||
var IsLt500K = file.Size < 1024 * 1024 * 100;
|
||||
if (!IsLt500K)
|
||||
{
|
||||
_message.Error("文件需不大于100MB!");
|
||||
}
|
||||
|
||||
return validTypes && IsLt500K;
|
||||
}
|
||||
|
||||
public void OnSingleCompleted(UploadInfo fileinfo)
|
||||
{
|
||||
if (fileinfo.File.State == UploadState.Success)
|
||||
{
|
||||
//文件列表
|
||||
_fileList.Add(new UploadFileItem()
|
||||
{
|
||||
FileName = fileinfo.File.FileName,
|
||||
Url = fileinfo.File.Url = fileinfo.File.Response
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,6 +97,11 @@ namespace AntSK.Domain.Domain.Service
|
||||
var options = new SparkDeskOptions { AppId = chatModel.EndPoint, ApiSecret = chatModel.ModelKey, ApiKey = chatModel.ModelName, ModelVersion = Sdcb.SparkDesk.ModelVersion.V3_5 };
|
||||
builder.Services.AddKeyedSingleton<ITextGenerationService>("spark-desk", new SparkDeskTextCompletion(options, app.Id));
|
||||
break;
|
||||
|
||||
case Model.Enum.AIType.DashScope:
|
||||
builder.Services.AddDashScopeChatCompletion(chatModel.ModelKey, chatModel.ModelName);
|
||||
break;
|
||||
|
||||
case Model.Enum.AIType.Mock:
|
||||
builder.Services.AddKeyedSingleton<ITextGenerationService>("mock", new MockTextCompletion());
|
||||
break;
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace AntSK.Domain.Repositories
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Describe { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 图标
|
||||
/// </summary>
|
||||
@@ -38,6 +39,11 @@ namespace AntSK.Domain.Repositories
|
||||
[Required]
|
||||
public string? ChatModelID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Embedding 模型Id
|
||||
/// </summary>
|
||||
public string? EmbeddingModelID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 温度
|
||||
/// </summary>
|
||||
@@ -61,14 +67,14 @@ namespace AntSK.Domain.Repositories
|
||||
[SugarColumn(ColumnDataType = "varchar(1000)")]
|
||||
public string? NativeFunctionList { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 知识库ID列表
|
||||
/// </summary>
|
||||
public string? KmsIdList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// API调用秘钥
|
||||
/// </summary>
|
||||
public string? SecretKey { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,9 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="plugins\KMSPlugin\Ask1\skprompt.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="plugins\KMSPlugin\Ask\skprompt.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
||||
@@ -38,6 +38,14 @@
|
||||
</Select>
|
||||
<Button Type="@ButtonType.Link" OnClick="NavigateModelList">去创建</Button>
|
||||
</FormItem>
|
||||
<FormItem Label="Embedding模型" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<Select DataSource="@_embedignList"
|
||||
@bind-Value="@context.EmbeddingModelID"
|
||||
ValueProperty="c=>c.Id"
|
||||
LabelProperty="c=>'【'+c.AIType.ToString()+'】'+c.ModelDescription">
|
||||
</Select>
|
||||
<Button Type="@ButtonType.Link" OnClick="NavigateModelList">去创建</Button>
|
||||
</FormItem>
|
||||
@if (@context.Type == AppType.chat.ToString())
|
||||
{
|
||||
|
||||
|
||||
@@ -44,15 +44,17 @@ namespace AntSK.Pages.AppPage
|
||||
|
||||
public Dictionary<string, string> _funList = new Dictionary<string, string>();
|
||||
|
||||
private List<AIModels> _chatList { get; set; }
|
||||
|
||||
private List<AIModels> _chatList;
|
||||
private List<AIModels> _embedignList;
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
_kmsList = _kmss_Repositories.GetList();
|
||||
_apiList = _apis_Repositories.GetList();
|
||||
var models=_aimodels_Repositories.GetList();
|
||||
_chatList = models.Where(p => p.AIModelType == AIModelType.Chat).ToList();
|
||||
_embedignList = models.Where(p => p.AIModelType == AIModelType.Embedding).ToList();
|
||||
|
||||
_chatList = _aimodels_Repositories.GetList(p => p.AIModelType == AIModelType.Chat);
|
||||
_functionService.SearchMarkedMethods();
|
||||
foreach (var func in _functionService.Functions)
|
||||
{
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace AntSK.Pages.AppPage
|
||||
|
||||
private void GetDesc()
|
||||
{
|
||||
_desc = @$"为了方便其他应用对接,接口符合openai规范,省略了温度TopP等参数。{Environment.NewLine}BaseUrl:{Environment.NewLine}{_openApiUrl} {Environment.NewLine}headers:{Environment.NewLine}Authorization: ""{_appModel.SecretKey}"" {Environment.NewLine}Body: {Environment.NewLine}{JsonConvert.SerializeObject(new OpenAIModel() { messages = new List<OpenAIMessage>() { new OpenAIMessage() { role = "user", content = "你好,你是谁" } } }, Formatting.Indented)}";
|
||||
_desc = @$"为了方便其他应用对接,接口符合openai规范,省略了温度TopP等参数。{Environment.NewLine}BaseUrl:{Environment.NewLine}{_openApiUrl} {Environment.NewLine}headers:{Environment.NewLine}Authorization:Bearer ""{_appModel.SecretKey}"" {Environment.NewLine}Body: {Environment.NewLine}{JsonConvert.SerializeObject(new OpenAIModel() { messages = new List<OpenAIMessage>() { new OpenAIMessage() { role = "user", content = "你好,你是谁" } } }, Formatting.Indented)}";
|
||||
}
|
||||
|
||||
private void GetScript()
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<a href="@( NavigationManager.BaseUri + "openchat/" + AppId)" target="_blank">分享使用</a>
|
||||
</TitleTemplate>
|
||||
<Body>
|
||||
<div id="scrollDiv" style="height: calc(75vh - 170px); overflow-y: auto; overflow-x: hidden;">
|
||||
<div id="scrollDiv" style="height: calc(75vh - 190px); overflow-y: auto; overflow-x: hidden;">
|
||||
<GridRow Gutter="(8, 8)" Style="margin:0">
|
||||
<Virtualize Items="@(MessageList.OrderBy(o => o.CreateTime).ToList())" Context="item">
|
||||
@if (item.IsSend)
|
||||
@@ -32,7 +32,17 @@
|
||||
<GridCol Span="23">
|
||||
<div class="chat-bubble sent">
|
||||
<Popover Title="@item.CreateTime.ToString()">
|
||||
@(item.Context)
|
||||
<Unbound>
|
||||
<Flex Vertical RefBack="context">
|
||||
@if (item.FileName != null)
|
||||
{
|
||||
<p class="message-file">
|
||||
<Upload DefaultFileList="[new(){ FileName= item.FileName }]" />
|
||||
</p>
|
||||
}
|
||||
<p>@(item.Context)</p>
|
||||
</Flex>
|
||||
</Unbound>
|
||||
</Popover>
|
||||
</div>
|
||||
<Icon Style="float:right;margin-top:10px;" Type="copy" Theme="outline" OnClick="async () =>await OnCopyAsync(item)" />
|
||||
@@ -58,13 +68,27 @@
|
||||
</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="clear" Type="@(ButtonType.Link)" OnClick="@(async () => await OnClearAsync())" Disabled="@Sendding"></Button>
|
||||
<Button Icon="send" Type="@(ButtonType.Link)" OnClick="@(async () => await OnSendAsync())" Disabled="@Sendding"></Button>
|
||||
</Suffix>
|
||||
</AntDesign.Input>
|
||||
|
||||
<Flex Vertical>
|
||||
@if (fileList.Count > 0)
|
||||
{
|
||||
<Upload DefaultFileList="fileList" OnRemove="HandleFileRemove" />
|
||||
}
|
||||
<AntDesign.Input @bind-Value="@(_messageInput)" DebounceMilliseconds="@(-1)" Placeholder="输入消息回车发送" OnPressEnter="@(async () => await OnSendAsync())" Disabled="@Sendding"></AntDesign.Input>
|
||||
</Flex>
|
||||
<Flex Justify="end">
|
||||
<Upload Action="@("api/File/UploadFile")"
|
||||
Name="file"
|
||||
Accept="*/*"
|
||||
ShowUploadList="false"
|
||||
BeforeUpload="_kMService.BeforeUpload"
|
||||
OnSingleCompleted="OnSingleCompleted">
|
||||
<Button Icon="@IconType.Outline.Upload" Type="@(ButtonType.Link)" />
|
||||
</Upload>
|
||||
<Button Icon="clear" Type="@(ButtonType.Link)" OnClick="@(async () => await OnClearAsync())" Disabled="@Sendding"></Button>
|
||||
<Button Icon="send" Type="@(ButtonType.Link)" OnClick="@(async () => await OnSendAsync())" Disabled="@Sendding"></Button>
|
||||
</Flex>
|
||||
|
||||
</Body>
|
||||
</Card>
|
||||
</Spin>
|
||||
@@ -79,61 +103,61 @@
|
||||
</Extra>
|
||||
<Body>
|
||||
<AntList Bordered DataSource="@_relevantSources" Style="padding:10px;">
|
||||
<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>
|
||||
<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>
|
||||
|
||||
<style>
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
margin: 0;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
height: 100vh;
|
||||
}
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
margin: 0;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.chat-container {
|
||||
width: 350px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #fff;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
.chat-container {
|
||||
width: 350px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #fff;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
.chat-bubble {
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
margin-bottom: 0;
|
||||
border-radius: 5px;
|
||||
max-width: 70%;
|
||||
position: relative;
|
||||
}
|
||||
.chat-bubble {
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
margin-bottom: 0;
|
||||
border-radius: 5px;
|
||||
max-width: 70%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.received {
|
||||
background-color: #f0f0f0;
|
||||
align-self: flex-start;
|
||||
float: left;
|
||||
}
|
||||
.received {
|
||||
background-color: #f0f0f0;
|
||||
align-self: flex-start;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.sent {
|
||||
background-color: #daf8cb;
|
||||
align-self: flex-end;
|
||||
float: right;
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
@code {
|
||||
.sent {
|
||||
background-color: #daf8cb;
|
||||
align-self: flex-end;
|
||||
float: right;
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
@code {
|
||||
|
||||
}
|
||||
|
||||
@@ -19,12 +19,12 @@ namespace AntSK.Pages.ChatPage
|
||||
[Inject] protected IApis_Repositories _apis_Repositories { get; set; }
|
||||
[Inject] protected IKmss_Repositories _kmss_Repositories { get; set; }
|
||||
[Inject] protected IKmsDetails_Repositories _kmsDetails_Repositories { get; set; }
|
||||
[Inject] IJSRuntime _JSRuntime { get; set; }
|
||||
[Inject] private IJSRuntime _JSRuntime { get; set; }
|
||||
|
||||
[Inject] protected IKernelService _kernelService { get; set; }
|
||||
[Inject] protected IKMService _kMService { get; set; }
|
||||
[Inject] IConfirmService _confirmService { get; set; }
|
||||
[Inject] IChatService _chatService { get; set; }
|
||||
[Inject] private IConfirmService _confirmService { get; set; }
|
||||
[Inject] private IChatService _chatService { get; set; }
|
||||
|
||||
[Inject] private ILogger<Chat> Logger { get; set; }
|
||||
|
||||
@@ -34,10 +34,14 @@ namespace AntSK.Pages.ChatPage
|
||||
protected string _json = "";
|
||||
protected bool Sendding = false;
|
||||
|
||||
List<RelevantSource> _relevantSources = new List<RelevantSource>();
|
||||
private List<RelevantSource> _relevantSources = new List<RelevantSource>();
|
||||
|
||||
protected List<Apps> _list = new List<Apps>();
|
||||
|
||||
private List<UploadFileItem> fileList = [];
|
||||
|
||||
private Upload _uploadRef;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
@@ -60,17 +64,27 @@ namespace AntSK.Pages.ChatPage
|
||||
return;
|
||||
}
|
||||
|
||||
var filePath = fileList.FirstOrDefault()?.Url;
|
||||
var fileName = fileList.FirstOrDefault()?.FileName;
|
||||
|
||||
MessageList.Add(new MessageInfo()
|
||||
{
|
||||
ID = Guid.NewGuid().ToString(),
|
||||
Context = _messageInput,
|
||||
CreateTime = DateTime.Now,
|
||||
IsSend = true
|
||||
IsSend = true,
|
||||
FilePath = filePath,
|
||||
FileName = fileName
|
||||
});
|
||||
|
||||
Sendding = true;
|
||||
await SendAsync(_messageInput);
|
||||
var prompt = _messageInput;
|
||||
_messageInput = "";
|
||||
fileList.Clear();
|
||||
|
||||
Sendding = true;
|
||||
|
||||
await SendAsync(prompt, filePath);
|
||||
|
||||
Sendding = false;
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
@@ -105,7 +119,7 @@ namespace AntSK.Pages.ChatPage
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task<bool> SendAsync(string questions)
|
||||
protected async Task<bool> SendAsync(string questions, string? filePath)
|
||||
{
|
||||
string msg = "";
|
||||
//处理多轮会话
|
||||
@@ -117,13 +131,14 @@ namespace AntSK.Pages.ChatPage
|
||||
|
||||
switch (app.Type)
|
||||
{
|
||||
case "chat":
|
||||
case "chat" when filePath == null:
|
||||
//普通会话
|
||||
await SendChat(questions, msg, app);
|
||||
break;
|
||||
case "kms":
|
||||
|
||||
default:
|
||||
//知识库问答
|
||||
await SendKms(questions, msg, app);
|
||||
await SendKms(questions, msg, filePath, app);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -135,12 +150,13 @@ namespace AntSK.Pages.ChatPage
|
||||
/// </summary>
|
||||
/// <param name="questions"></param>
|
||||
/// <param name="msg"></param>
|
||||
/// <param name="filePath"></param>
|
||||
/// <param name="app"></param>
|
||||
/// <returns></returns>
|
||||
private async Task SendKms(string questions, string msg, Apps app)
|
||||
private async Task SendKms(string questions, string msg, string filePath, Apps app)
|
||||
{
|
||||
MessageInfo info = null;
|
||||
var chatResult = _chatService.SendKmsByAppAsync(app, questions, msg, _relevantSources);
|
||||
var chatResult = _chatService.SendKmsByAppAsync(app, questions, msg, filePath, _relevantSources);
|
||||
await foreach (var content in chatResult)
|
||||
{
|
||||
if (info == null)
|
||||
@@ -256,5 +272,24 @@ namespace AntSK.Pages.ChatPage
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSingleCompleted(UploadInfo fileInfo)
|
||||
{
|
||||
fileList.Add(new()
|
||||
{
|
||||
FileName = fileInfo.File.FileName,
|
||||
Url = fileInfo.File.Url = fileInfo.File.Response,
|
||||
Ext = fileInfo.File.Ext,
|
||||
State = UploadState.Success,
|
||||
});
|
||||
_kMService.OnSingleCompleted(fileInfo);
|
||||
}
|
||||
|
||||
private async Task<bool> HandleFileRemove(UploadFileItem file)
|
||||
{
|
||||
fileList.RemoveAll(x => x.FileName == file.FileName);
|
||||
await Task.Yield();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,7 +152,7 @@ namespace AntSK.Pages.ChatPage
|
||||
private async Task SendKms(string questions, string msg, Apps app)
|
||||
{
|
||||
MessageInfo info = null;
|
||||
var chatResult=_chatService.SendKmsByAppAsync(app, questions, msg);
|
||||
var chatResult=_chatService.SendKmsByAppAsync(app, questions, "" ,msg);
|
||||
await foreach (var content in chatResult)
|
||||
{
|
||||
if (info == null)
|
||||
|
||||
@@ -141,8 +141,8 @@
|
||||
Drag
|
||||
Multiple
|
||||
Accept="*/*"
|
||||
BeforeUpload="BeforeUpload"
|
||||
OnSingleCompleted="OnSingleCompleted">
|
||||
BeforeUpload="iKMService.BeforeUpload"
|
||||
OnSingleCompleted="iKMService.OnSingleCompleted">
|
||||
<p class="ant-upload-drag-icon">
|
||||
<Icon Type="inbox" />
|
||||
</p>
|
||||
|
||||
@@ -21,16 +21,16 @@ namespace AntSK.Pages.KmsPage
|
||||
|
||||
private readonly KmsDetails _model = new KmsDetails();
|
||||
|
||||
bool _urlVisible = false;
|
||||
bool _urlConfirmLoading = false;
|
||||
private bool _urlVisible = false;
|
||||
private bool _urlConfirmLoading = false;
|
||||
|
||||
bool _fileVisible = false;
|
||||
bool _fileConfirmLoading = false;
|
||||
private bool _fileVisible = false;
|
||||
private bool _fileConfirmLoading = false;
|
||||
|
||||
bool _textVisible = false;
|
||||
bool _textConfirmLoading = false;
|
||||
private bool _textVisible = false;
|
||||
private bool _textConfirmLoading = false;
|
||||
|
||||
List<FileInfoModel> fileList = new List<FileInfoModel>();
|
||||
private List<FileInfoModel> fileList = new List<FileInfoModel>();
|
||||
|
||||
private Form<UrlModel> _urlForm;
|
||||
private UrlModel urlModel = new UrlModel();
|
||||
@@ -50,6 +50,7 @@ namespace AntSK.Pages.KmsPage
|
||||
|
||||
[Inject]
|
||||
protected IConfirmService _confirmService { get; set; }
|
||||
|
||||
[Inject]
|
||||
protected IKmsDetails_Repositories _kmsDetails_Repositories { get; set; }
|
||||
|
||||
@@ -57,16 +58,19 @@ namespace AntSK.Pages.KmsPage
|
||||
protected IKmss_Repositories _kmss_Repositories { get; set; }
|
||||
|
||||
private MemoryServerless _memory { get; set; }
|
||||
|
||||
[Inject]
|
||||
protected IKMService iKMService { get; set; }
|
||||
|
||||
[Inject]
|
||||
protected MessageService? _message { get; set; }
|
||||
|
||||
[Inject]
|
||||
protected BackgroundTaskBroker<ImportKMSTaskReq> _taskBroker { get; set; }
|
||||
|
||||
[Inject]
|
||||
protected IHttpService _httpService { get; set; }
|
||||
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
@@ -81,6 +85,7 @@ namespace AntSK.Pages.KmsPage
|
||||
{
|
||||
_data = await _kmsDetails_Repositories.GetListAsync(p => p.KmsId == KmsId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据文档ID获取文档
|
||||
/// </summary>
|
||||
@@ -88,11 +93,13 @@ namespace AntSK.Pages.KmsPage
|
||||
/// <returns></returns>
|
||||
|
||||
#region Url
|
||||
|
||||
public class UrlModel
|
||||
{
|
||||
[Required]
|
||||
public string Url { get; set; }
|
||||
}
|
||||
|
||||
private async Task UrlHandleOk(MouseEventArgs e)
|
||||
{
|
||||
try
|
||||
@@ -106,22 +113,25 @@ namespace AntSK.Pages.KmsPage
|
||||
_data = await _kmsDetails_Repositories.GetListAsync(p => p.KmsId == KmsId);
|
||||
_urlVisible = false;
|
||||
urlModel.Url = "";
|
||||
_ = _message.Info("加入队列,进入后台处理中!", 2);
|
||||
_ = _message.Info("加入队列,进入后台处理中!", 2);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message + " ---- " + ex.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
private void UrlHandleCancel(MouseEventArgs e)
|
||||
{
|
||||
_urlVisible = false;
|
||||
}
|
||||
|
||||
private void UrlShowModal()
|
||||
{
|
||||
_urlVisible = true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#endregion Url
|
||||
|
||||
#region Text
|
||||
|
||||
@@ -130,6 +140,7 @@ namespace AntSK.Pages.KmsPage
|
||||
[Required]
|
||||
public string Text { get; set; }
|
||||
}
|
||||
|
||||
private async Task TextHandleOk(MouseEventArgs e)
|
||||
{
|
||||
try
|
||||
@@ -144,26 +155,27 @@ namespace AntSK.Pages.KmsPage
|
||||
_textVisible = false;
|
||||
textModel.Text = "";
|
||||
_ = _message.Info("加入队列,进入后台处理中!", 2);
|
||||
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message + " ---- " + ex.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
private void TextHandleCancel(MouseEventArgs e)
|
||||
{
|
||||
_textVisible = false;
|
||||
}
|
||||
|
||||
private void TextShowModal()
|
||||
{
|
||||
_textVisible = true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#endregion Text
|
||||
|
||||
#region File
|
||||
|
||||
|
||||
private async Task FileHandleOk(MouseEventArgs e)
|
||||
{
|
||||
try
|
||||
@@ -177,7 +189,7 @@ namespace AntSK.Pages.KmsPage
|
||||
FilePath = item.FilePath,
|
||||
FileName = item.FileName
|
||||
});
|
||||
}
|
||||
}
|
||||
_data = await _kmsDetails_Repositories.GetListAsync(p => p.KmsId == KmsId);
|
||||
//上传文档
|
||||
_fileVisible = false;
|
||||
@@ -189,56 +201,17 @@ namespace AntSK.Pages.KmsPage
|
||||
Console.WriteLine(ex.Message + " ---- " + ex.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
private void FileHandleCancel(MouseEventArgs e)
|
||||
{
|
||||
_fileVisible = false;
|
||||
}
|
||||
|
||||
private void FileShowModal()
|
||||
{
|
||||
_fileVisible = true;
|
||||
}
|
||||
|
||||
bool BeforeUpload(UploadFileItem file)
|
||||
{
|
||||
List<string> types = new List<string>() {
|
||||
"text/plain",
|
||||
"application/msword",
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
"application/vnd.ms-excel",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"application/vnd.ms-powerpoint",
|
||||
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
||||
"application/pdf",
|
||||
"application/json",
|
||||
"text/x-markdown",
|
||||
"text/markdown"
|
||||
};
|
||||
var IsType = types.Contains(file.Type);
|
||||
if (!IsType && file.Ext != ".md")
|
||||
{
|
||||
_message.Error("文件格式错误,请重新选择!");
|
||||
}
|
||||
var IsLt500K = file.Size < 1024 * 1024 * 100;
|
||||
if (!IsLt500K)
|
||||
{
|
||||
_message.Error("文件需不大于100MB!");
|
||||
}
|
||||
|
||||
return IsType && IsLt500K;
|
||||
}
|
||||
private void OnSingleCompleted(UploadInfo fileinfo)
|
||||
{
|
||||
if (fileinfo.File.State == UploadState.Success)
|
||||
{
|
||||
//文件列表
|
||||
fileList.Add(new FileInfoModel()
|
||||
{
|
||||
FileName = fileinfo.File.FileName,
|
||||
FilePath = fileinfo.File.Url = fileinfo.File.Response
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void FileDetail(string fileid)
|
||||
{
|
||||
NavigationManager.NavigateTo($"/kms/detaillist/{KmsId}/{fileid}");
|
||||
@@ -271,6 +244,6 @@ namespace AntSK.Pages.KmsPage
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion File
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,6 +72,15 @@
|
||||
<InputPassword @bind-Value="@context.ModelKey" Placeholder="APISecret" Size="@InputSize.Large" />
|
||||
</FormItem>
|
||||
}
|
||||
@if (context.AIType == AIType.DashScope)
|
||||
{
|
||||
<FormItem Label="API KEY" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<Input Placeholder="请输入API KEY" @bind-Value="@context.ModelKey" />
|
||||
</FormItem>
|
||||
<FormItem Label="模型名称" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<Input Placeholder="请输入模型名称" @bind-Value="@context.ModelName" />
|
||||
</FormItem>
|
||||
}
|
||||
@if (context.AIType == AIType.LLamaSharp)
|
||||
{
|
||||
<FormItem Label="模型路径" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
@@ -79,7 +88,6 @@
|
||||
<AutoComplete Options="_modelFiles" Placeholder="请输入模型路径" @bind-Value="@context.ModelName" />
|
||||
<Button OnClick="()=>_downloadModalVisible=true">从Haggingface下载</Button>
|
||||
</InputGroup>
|
||||
|
||||
</FormItem>
|
||||
}
|
||||
@if (context.AIType == AIType.Mock)
|
||||
|
||||
@@ -13,6 +13,7 @@ using LLama.Native;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
using System.Reflection;
|
||||
using System.Text.Encodings.Web;
|
||||
@@ -70,6 +71,26 @@ builder.Services.AddSwaggerGen(c =>
|
||||
return actionVersion.Any(v => v == docName);
|
||||
return version.Any(v => v == docName);
|
||||
});
|
||||
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
|
||||
{
|
||||
Description = "Directly enter bearer {token} in the box below (note that there is a space between bearer and token)",
|
||||
Name = "Authorization",
|
||||
In = ParameterLocation.Header,
|
||||
Type = SecuritySchemeType.ApiKey,
|
||||
});
|
||||
c.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||
{
|
||||
{
|
||||
new OpenApiSecurityScheme
|
||||
{
|
||||
Reference = new OpenApiReference()
|
||||
{
|
||||
Id = "Bearer",
|
||||
Type = ReferenceType.SecurityScheme
|
||||
}
|
||||
}, Array.Empty<string>()
|
||||
}
|
||||
});
|
||||
});
|
||||
//Mapper
|
||||
builder.Services.AddMapper();
|
||||
@@ -80,6 +101,7 @@ builder.Services.AddBackgroundTaskBroker().AddHandler<ImportKMSTaskReq, BackGrou
|
||||
builder.Configuration.GetSection("DBConnection").Get<DBConnectionOption>();
|
||||
builder.Configuration.GetSection("Login").Get<LoginOption>();
|
||||
builder.Configuration.GetSection("LLamaSharp").Get<LLamaSharpOption>();
|
||||
builder.Configuration.GetSection("KernelMemory").Get<KernelMemoryOption>();
|
||||
if (LLamaSharpOption.RunType.ToUpper() == "CPU")
|
||||
{
|
||||
NativeLibraryConfig
|
||||
|
||||
@@ -134,16 +134,14 @@ namespace AntSK.Services.OpenApi
|
||||
var _kernel = _kernelService.GetKernelByApp(app);
|
||||
var temperature = app.Temperature / 100; //存的是0~100需要缩小
|
||||
OpenAIPromptExecutionSettings settings = new() { Temperature = temperature };
|
||||
|
||||
_kernelService.ImportFunctionsByApp(app, _kernel);
|
||||
settings.ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions;
|
||||
|
||||
var promptTemplateFactory = new KernelPromptTemplateFactory();
|
||||
var promptTemplate = promptTemplateFactory.Create(new PromptTemplateConfig(app.Prompt));
|
||||
if (!string.IsNullOrEmpty(app.ApiFunctionList) || !string.IsNullOrEmpty(app.NativeFunctionList))//这里还需要加上本地插件的
|
||||
{
|
||||
_kernelService.ImportFunctionsByApp(app, _kernel);
|
||||
settings.ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions;
|
||||
}
|
||||
|
||||
var func = _kernel.CreateFunctionFromPrompt(app.Prompt, settings);
|
||||
var chatResult =
|
||||
await _kernel.InvokeAsync(function: func, arguments: new KernelArguments() { ["input"] = msg });
|
||||
var chatResult =await _kernel.InvokeAsync(function: func, arguments: new KernelArguments() { ["input"] = msg });
|
||||
if (chatResult.IsNotNull())
|
||||
{
|
||||
string answers = chatResult.GetValue<string>();
|
||||
@@ -156,7 +154,7 @@ namespace AntSK.Services.OpenApi
|
||||
private async Task SendKmsStream(HttpContext HttpContext, OpenAIStreamResult result, Apps app, string msg)
|
||||
{
|
||||
HttpContext.Response.Headers.Add("Content-Type", "text/event-stream");
|
||||
var chatResult = _chatService.SendKmsByAppAsync(app, msg, "");
|
||||
var chatResult = _chatService.SendKmsByAppAsync(app, msg,"", "");
|
||||
int i = 0;
|
||||
await foreach (var content in chatResult)
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"urls":"http://*:5000",
|
||||
"ProSettings": {
|
||||
"NavTheme": "light",
|
||||
"Layout": "side",
|
||||
@@ -34,9 +35,9 @@
|
||||
},
|
||||
"LLamaSharp": {
|
||||
"RunType": "GPU",
|
||||
"Chat": "D:\\Code\\AI\\AntBlazor\\model\\qwen1_5-1_8b-chat-q8_0.gguf",
|
||||
"Embedding": "D:\\Code\\AI\\AntBlazor\\model\\qwen1_5-1_8b-chat-q8_0.gguf",
|
||||
"FileDirectory": "D:\\Code\\AI\\AntBlazor\\model\\"
|
||||
"Chat": "D:\\git\\AntBlazor\\model\\qwen1_5-1_8b-chat-q8_0.gguf",
|
||||
"Embedding": "D:\\git\\AntBlazor\\model\\qwen1_5-1_8b-chat-q8_0.gguf",
|
||||
"FileDirectory": "D:\\git\\AntBlazor\\model\\\\"
|
||||
},
|
||||
"Login": {
|
||||
"User": "admin",
|
||||
|
||||
30
src/AntSK/plugins/KMSPlugin/Ask1/config.json
Normal file
30
src/AntSK/plugins/KMSPlugin/Ask1/config.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"type": "completion",
|
||||
"description": "知识库问答",
|
||||
"completion": {
|
||||
"temperature": 0.0,
|
||||
"top_p": 0.0,
|
||||
"presence_penalty": 0.0,
|
||||
"frequency_penalty": 0.0
|
||||
},
|
||||
"input": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "doc",
|
||||
"description": "背景文档。",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"name": "history",
|
||||
"description": "历史聊天记录。",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"name": "questions",
|
||||
"description": "用户问题。",
|
||||
"defaultValue": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
17
src/AntSK/plugins/KMSPlugin/Ask1/skprompt.txt
Normal file
17
src/AntSK/plugins/KMSPlugin/Ask1/skprompt.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
使用<data></data>标记的内容作为你的知识:
|
||||
<data>
|
||||
{{$doc}}
|
||||
</data>
|
||||
--------------------------
|
||||
回答要求:
|
||||
- 如果你不清楚答案,你需要澄清
|
||||
- 避免提及你是从<data></data>获取的知识
|
||||
- 保持答案与<data></data>众描述一致
|
||||
- 使用Markdown语法优化回答格式。
|
||||
- 如果Markdown有图片则正常显示
|
||||
--------------------------
|
||||
|
||||
历史聊天记录:{{$history}}
|
||||
--------------------------
|
||||
用户问题: {{$questions}}
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.SemanticKernel" Version="1.4.0" />
|
||||
<PackageReference Include="Cnblogs.KernelMemory.AI.DashScope" Version="0.1.0" />
|
||||
<PackageReference Include="Cnblogs.SemanticKernel.Connectors.DashScope" Version="0.2.0" />
|
||||
<PackageReference Include="Microsoft.SemanticKernel" Version="1.6.2" />
|
||||
<PackageReference Include="Sdcb.SparkDesk" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user