Compare commits

..

16 Commits
0.1.2 ... 0.1.3

Author SHA1 Message Date
zyxucp
b25e429687 fix 修改maxtoken 2024-03-01 12:15:21 +08:00
zyxucp
a3f87bf123 fix 修复维度和maxtoken问题 2024-03-01 12:10:11 +08:00
zyxucp
2cab253c4a fix 修复openai stream接口格式不正确问题 2024-03-01 12:09:27 +08:00
zyxucp
ed119f02e2 fix 修改message实体 2024-02-29 18:28:32 +08:00
zyxucp
f178fc16e9 style 样式调整 2024-02-29 18:23:50 +08:00
zyxucp
e4b2071689 fix SK还原到1.4 2024-02-29 17:49:43 +08:00
zyxucp
146df7ed1d fix 修改SK版本 2024-02-29 17:42:41 +08:00
zyxucp
7e8db0a3f8 add 修改气泡样式 2024-02-29 17:40:43 +08:00
zyxucp
e098922219 fix 修改聊天窗为气泡样式 2024-02-29 17:30:50 +08:00
zyxucp
16ca024c22 Merge branch 'main' into feature_plugin 2024-02-29 13:55:15 +08:00
zyxucp
a886e9dfb3 fix 修复兼容域名的情况 端口为0 2024-02-29 13:54:33 +08:00
zyxucp
5d6114c9ec update 升级SK 至1.5.0 和升级KM 2024-02-29 12:52:44 +08:00
zyxucp
e3b2e1f434 fix 修复没登陆时没有权限的问题 2024-02-29 12:41:50 +08:00
zyxucp
6145347d9b add 增加权限管理 2024-02-29 12:35:03 +08:00
zyxucp
49e694cbdc add 增加非管理员不允许操作系统设置 2024-02-29 12:00:22 +08:00
zyxucp
f860229993 fix 调整Util目录 2024-02-29 10:38:36 +08:00
20 changed files with 405 additions and 120 deletions

View File

@@ -13,14 +13,14 @@
<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="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" />

View File

@@ -57,6 +57,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开始
@@ -424,6 +429,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

View File

@@ -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; }
}

View File

@@ -37,6 +37,11 @@ namespace AntSK.Domain.Repositories
/// </summary>
[Required]
public string Describe { get; set; }
/// <summary>
/// 菜单权限
/// </summary>
[Required]
public string MenuRole { get; set; }
}
}

View File

@@ -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>
{

View File

@@ -35,10 +35,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 +52,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;
}

View File

@@ -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();
}
}
}

View File

@@ -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; }
}
}

View File

@@ -1,6 +1,6 @@
using System;
using System.Text.Json.Serialization;
using AntSK.Utils;
using AntSK.Domain.Utils;
namespace AntSK.Models
{

View File

@@ -23,28 +23,36 @@
</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>
<GridRow Gutter="(8, 8)" Style="margin:0">
<Virtualize Items="@(MessageList.OrderBy(o => o.CreateTime).ToList())" Context="item">
@if (item.IsSend)
{
<GridRow Style="width:100%">
<GridCol Span="23">
<div class="chat-bubble sent">
@(item.Context)
@* <span class="timestamp">@item.CreateTime</span> *@
</div>
</GridCol>
<GridCol Span="1">
<Image Width="100%" Style="margin-top:10px;" Src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" />
</GridCol>
</GridRow>
}
else
{
<GridRow Style="width:100%">
<GridCol Span="1">
<Image Width="100%" Style="margin-top:10px;" Src="https://gw.alipayobjects.com/zos/antfincdn/aPkFc8Sj7n/method-draw-image.svg" />
</GridCol>
<GridCol Span="23">
<div class="chat-bubble received">
@((MarkupString)(item.HtmlAnswers))
@* <span class="timestamp">@item.CreateTime</span> *@
</div>
</GridCol>
</GridRow>
}
</Virtualize>
</GridRow>
</div>
@@ -67,8 +75,8 @@
</Extra>
<Body>
<AntList Bordered DataSource="@RelevantSources">
<ChildContent Context="item">
<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))
@@ -80,7 +88,65 @@
</GridCol>
</GridRow>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 10px;
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-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;
}
.sent {
background-color: #daf8cb;
align-self: flex-end;
float: right;
}
.timestamp {
display: block;
font-size: 0.75em;
margin-top: 5px;
}
.received .timestamp {
text-align: right;
margin-right: 10px;
}
.sent .timestamp {
text-align: left;
margin-left: 10px;
}
</style>
@code {
}

View File

@@ -64,6 +64,15 @@ namespace AntSK.Pages.ChatPage
return;
}
MessageList.Add(new MessageInfo()
{
ID = Guid.NewGuid().ToString(),
Context = _messageInput,
CreateTime = DateTime.Now,
IsSend = true
});
Sendding = true;
await SendAsync(_messageInput);
_messageInput = "";
@@ -74,7 +83,7 @@ namespace AntSK.Pages.ChatPage
{
await Task.Run(() =>
{
_messageInput = item.Questions;
_messageInput = item.Context;
});
}
@@ -140,8 +149,7 @@ namespace AntSK.Pages.ChatPage
var info1 = new MessageInfo()
{
ID = Guid.NewGuid().ToString(),
Questions = questions,
Answers = answers,
Context = answers,
HtmlAnswers = htmlAnswers,
CreateTime = DateTime.Now,
};
@@ -193,9 +201,8 @@ namespace AntSK.Pages.ChatPage
{
info = new MessageInfo();
info.ID = Guid.NewGuid().ToString();
info.Questions = questions;
info.Answers = content.Content!;
info.HtmlAnswers = content.Content!;
info.Context = content?.Content?.ConvertToString();
info.HtmlAnswers = content?.Content?.ConvertToString();
info.CreateTime = DateTime.Now;
MessageList.Add(info);
@@ -208,7 +215,11 @@ namespace AntSK.Pages.ChatPage
await InvokeAsync(StateHasChanged);
}
//全部处理完后再处理一次Markdown
info!.HtmlAnswers = markdown.Transform(info.HtmlAnswers);
if (info.IsNotNull())
{
info!.HtmlAnswers = markdown.Transform(info.HtmlAnswers);
}
await InvokeAsync(StateHasChanged);
}
@@ -219,18 +230,31 @@ namespace AntSK.Pages.ChatPage
/// <returns></returns>
private async Task<string> HistorySummarize(string questions)
{
StringBuilder history = new StringBuilder();
foreach (var item in MessageList)
if (MessageList.Count > 1)
{
history.Append($"user:{item.Questions}{Environment.NewLine}");
history.Append($"assistant:{item.Answers}{Environment.NewLine}");
}
StringBuilder history = new StringBuilder();
foreach (var item in MessageList)
{
if (item.IsSend)
{
history.Append($"user:{item.Context}{Environment.NewLine}");
}
else
{
history.Append($"assistant:{item.Context}{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;
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;
}
else
{
return questions;
}
}
}

View File

@@ -8,27 +8,36 @@
<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 Items="@(MessageList.OrderBy(o => o.CreateTime).ToList())" Context="item">
@if (item.IsSend)
{
<GridRow>
<GridCol Span="23">
<div class="chat-bubble sent">
@(item.Context)
@* <span class="timestamp">@item.CreateTime</span> *@
</div>
</GridCol>
<GridCol Span="1">
<Image Width="100%" Style="margin-top:10px;" Src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" />
</GridCol>
</GridRow>
}
else
{
<GridRow>
<GridCol Span="1">
<Image Width="100%" Style="margin-top:10px;" Src="https://gw.alipayobjects.com/zos/antfincdn/aPkFc8Sj7n/method-draw-image.svg" />
</GridCol>
<GridCol Span="23">
<div class="chat-bubble received">
@((MarkupString)(item.HtmlAnswers))
@* <span class="timestamp">@item.CreateTime</span> *@
</div>
</GridCol>
</GridRow>
}
</Virtualize>
</div>
<div style="flex-shrink:0;margin:10px;">
@@ -40,6 +49,66 @@
</div>
</div>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 10px;
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-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;
}
.sent {
background-color: #daf8cb;
align-self: flex-end;
float: right;
}
.timestamp {
display: block;
font-size: 0.75em;
margin-top: 5px;
}
.received .timestamp {
text-align: right;
margin-right: 10px;
}
.sent .timestamp {
text-align: left;
margin-left: 10px;
}
</style>
@code {
}

View File

@@ -16,6 +16,7 @@ using Newtonsoft.Json;
using SqlSugar;
using System;
using System.Text;
using AntSK.Domain.Utils;
namespace AntSK.Pages.ChatPage
{
@@ -56,6 +57,14 @@ namespace AntSK.Pages.ChatPage
return;
}
MessageList.Add(new MessageInfo() {
ID=Guid.NewGuid().ToString(),
Context=_messageInput,
CreateTime=DateTime.Now,
IsSend=true
});
Sendding = true;
await SendAsync(_messageInput);
_messageInput = "";
@@ -66,7 +75,7 @@ namespace AntSK.Pages.ChatPage
{
await Task.Run(() =>
{
_messageInput = item.Questions;
_messageInput = item.Context;
});
}
@@ -132,8 +141,7 @@ namespace AntSK.Pages.ChatPage
var info1 = new MessageInfo()
{
ID = Guid.NewGuid().ToString(),
Questions = questions,
Answers = answers,
Context = answers,
HtmlAnswers = htmlAnswers,
CreateTime = DateTime.Now,
};
@@ -170,9 +178,8 @@ namespace AntSK.Pages.ChatPage
{
info = new MessageInfo();
info.ID = Guid.NewGuid().ToString();
info.Questions = questions;
info.Answers = content.Content!;
info.HtmlAnswers = content.Content!;
info.Context = content?.Content?.ConvertToString();
info.HtmlAnswers = content?.Content?.ConvertToString();
info.CreateTime = DateTime.Now;
MessageList.Add(info);
@@ -196,18 +203,31 @@ namespace AntSK.Pages.ChatPage
/// <returns></returns>
private async Task<string> HistorySummarize(string questions)
{
StringBuilder history = new StringBuilder();
foreach (var item in MessageList)
if (MessageList.Count > 1)
{
history.Append($"user:{item.Questions}{Environment.NewLine}");
history.Append($"assistant:{item.Answers}{Environment.NewLine}");
}
StringBuilder history = new StringBuilder();
foreach (var item in MessageList)
{
if (item.IsSend)
{
history.Append($"user:{item.Context}{Environment.NewLine}");
}
else
{
history.Append($"assistant:{item.Context}{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;
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;
}
else
{
return questions;
}
}
}
}

View File

@@ -3,7 +3,6 @@
@using AntSK.Models
@page "/setting/user/add"
@page "/setting/user/add/{UserId}"
@inject IMessageService _message
@using AntSK.Services.Auth
@inherits AuthComponentBase
@@ -26,14 +25,31 @@
<FormItem Label="用户备注" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
<Input Placeholder="请输入用户备注" @bind-Value="@context.Describe" />
</FormItem>
<FormItem Label="菜单权限" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
<Select Mode="multiple"
@bind-Values="_menuKeys"
Placeholder="选择菜单权限"
TItemValue="string"
TItem="string"
Size="@AntSizeLDSType.Default">
<SelectOptions>
@foreach (var menu in menuList)
{
<SelectOption TItem="string" TItemValue="string" Value="@menu.Key" Label="@menu.Name" />
}
</SelectOptions>
</Select>
</FormItem>
<FormItem Label=" " Style="margin-top:32px" WrapperCol="LayoutModel._submitFormLayout.WrapperCol">
<Button Type="primary" HtmlType="submit">
<Button Type="primary" OnClick="HandleSubmit">
保存
</Button>
<Button OnClick="Back">
返回
</Button>
</FormItem>
</FormItem>
</Form>
</Card>
</ChildContent>

View File

@@ -1,4 +1,5 @@
using AntDesign;
using AntDesign.ProLayout;
using AntSK.Domain.Options;
using AntSK.Domain.Repositories;
using AntSK.Domain.Utils;
@@ -12,14 +13,15 @@ namespace AntSK.Pages.Setting.User
{
[Parameter]
public string UserId { get; set; }
[Inject]
protected IUsers_Repositories _users_Repositories { get; set; }
[Inject]
protected MessageService? Message { get; set; }
[Inject] protected IUsers_Repositories _users_Repositories { get; set; }
[Inject] protected MessageService? Message { get; set; }
[Inject] public HttpClient HttpClient { get; set; }
private Users _userModel = new Users();
private string _password = "";
IEnumerable<string> _menuKeys;
private List<MenuDataItem> menuList = new List<MenuDataItem>();
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
@@ -28,10 +30,13 @@ namespace AntSK.Pages.Setting.User
_userModel= _users_Repositories.GetFirst(p => p.Id == UserId);
_password= _userModel.Password;
}
menuList = (await HttpClient.GetFromJsonAsync<MenuDataItem[]>("data/menu.json")).ToList().Where(p=>p.Key!= "setting").ToList();
_menuKeys= _userModel.MenuRole?.Split(",");
}
private void HandleSubmit()
{
_userModel.MenuRole = string.Join(",", _menuKeys);
if (string.IsNullOrEmpty(UserId))
{
//新增
@@ -47,7 +52,6 @@ namespace AntSK.Pages.Setting.User
_ = Message.Error("工号已存在!", 2);
return;
}
_userModel.Password=PasswordUtil.HashPassword(_userModel.Password);
_users_Repositories.Insert(_userModel);
}

View File

@@ -144,7 +144,7 @@ void InitSK(WebApplicationBuilder builder)
//Kernel Memory
var searchClientConfig = new SearchClientConfig
{
MaxAskPromptSize = 8000,
MaxAskPromptSize = 2048,
MaxMatchesCount = 3,
AnswerTokens = 1000,
EmptyAnswer = "知识库未搜索到相关内容"
@@ -158,12 +158,12 @@ void InitSK(WebApplicationBuilder builder)
.WithSimpleFileStorage(new SimpleFileStorageConfig { StorageType = FileSystemTypes.Volatile, Directory = "_files" })
.WithSearchClientConfig(searchClientConfig)
//如果用本地模型需要设置token小一点。
//.WithCustomTextPartitioningOptions(new Microsoft.KernelMemory.Configuration.TextPartitioningOptions
//{
// MaxTokensPerLine=99,
// MaxTokensPerParagraph=299,
// OverlappingTokens=47
//})
.WithCustomTextPartitioningOptions(new Microsoft.KernelMemory.Configuration.TextPartitioningOptions
{
MaxTokensPerLine = 99,
MaxTokensPerParagraph = 299,
OverlappingTokens = 47
})
.WithOpenAITextGeneration(new OpenAIConfig()
{
APIKey = OpenAIOption.Key,

View File

@@ -32,7 +32,7 @@ namespace AntSK.Services.LLamaSharp
{
var @params = new ModelParams(LLamaSharpOption.Chat)
{
ContextSize = 512,
ContextSize = 2048,
};
// todo: share weights from a central service

View File

@@ -36,7 +36,7 @@ namespace AntSK.Services.LLamaSharp
{
float[] embeddings =await _embedder.GetEmbeddings(text);
//PG只有1536维
return embeddings.ToList().Take(1536).ToList();
return embeddings.ToList();
}
}
}

View File

@@ -35,12 +35,17 @@ namespace AntSK.Services.LLamaSharp
public async Task ChatStream(OpenAIModel model, HttpContext HttpContext)
{
HttpContext.Response.ContentType = "text/event-stream";
HttpContext.Response.Headers.Add("Content-Type", "text/event-stream");
OpenAIStreamResult result = new OpenAIStreamResult();
result.created = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
result.choices = new List<StreamChoicesModel>() { new StreamChoicesModel() { delta = new OpenAIMessage() { role = "assistant" } } };
string questions = model.messages.LastOrDefault().content;
await foreach (var r in _lLamaChatService.ChatStreamAsync(questions))
{
Console.Write(r);
await HttpContext.Response.WriteAsync("data:" + r + "\n\n");
result.choices[0].delta.content = r.ConvertToString();
string message = $"data: {JsonConvert.SerializeObject(result)}\n\n";
await HttpContext.Response.WriteAsync(message, Encoding.UTF8);
await HttpContext.Response.Body.FlushAsync();
}
await HttpContext.Response.WriteAsync("data: [DONE]");

View File

@@ -39,9 +39,8 @@ namespace AntSK.Services.OpenApi
{
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())
@@ -53,26 +52,42 @@ namespace AntSK.Services.OpenApi
//普通会话
if (model.stream)
{
await SendChatStream( HttpContext, result, app, msg);
OpenAIStreamResult result1 = new OpenAIStreamResult();
result1.created = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
result1.choices = new List<StreamChoicesModel>() { new StreamChoicesModel() { delta = new OpenAIMessage() { role = "assistant" } } };
await SendChatStream( HttpContext, result1, app, msg);
HttpContext.Response.ContentType = "application/json";
await HttpContext.Response.WriteAsync(JsonConvert.SerializeObject(result1));
await HttpContext.Response.CompleteAsync();
return;
}
else
{
result.choices[0].message.content = await SendChat(msg, app);
OpenAIResult result2 = new OpenAIResult();
result2.created = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
result2.choices = new List<ChoicesModel>() { new ChoicesModel() { message = new OpenAIMessage() { role = "assistant" } } };
result2.choices[0].message.content = await SendChat(msg, app);
HttpContext.Response.ContentType = "application/json";
await HttpContext.Response.WriteAsync(JsonConvert.SerializeObject(result2));
await HttpContext.Response.CompleteAsync();
}
break;
case "kms":
//知识库问答
result.choices[0].message.content = await SendKms( msg, app);
OpenAIResult result3 = new OpenAIResult();
result3.created = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
result3.choices = new List<ChoicesModel>() { new ChoicesModel() { message = new OpenAIMessage() { role = "assistant" } } };
result3.choices[0].message.content = await SendKms( msg, app);
HttpContext.Response.ContentType = "application/json";
await HttpContext.Response.WriteAsync(JsonConvert.SerializeObject(result3));
await HttpContext.Response.CompleteAsync();
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)
private async Task SendChatStream( HttpContext HttpContext, OpenAIStreamResult result, Apps app, string msg)
{
HttpContext.Response.Headers.Add("Content-Type", "text/event-stream");
@@ -91,7 +106,7 @@ namespace AntSK.Services.OpenApi
await foreach (var content in chatResult)
{
result.choices[0].message.content = content.Content.ConvertToString();
result.choices[0].delta.content = content.Content.ConvertToString();
string message = $"data: {JsonConvert.SerializeObject(result)}\n\n";
await HttpContext.Response.WriteAsync(message, Encoding.UTF8);
await HttpContext.Response.Body.FlushAsync();