Merge pull request #348 from iceljc/features/add-botsharp-json-option
add botsharp options
This commit is contained in:
commit
a6e34b8dbb
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
|
|
|
|||
|
|
@ -47,4 +47,4 @@ public class RichContentJsonConverter : JsonConverter<IRichMessage>
|
|||
{
|
||||
JsonSerializer.Serialize(writer, value, value.GetType(), options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
using BotSharp.Abstraction.Messaging.JsonConverters;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace BotSharp.Abstraction.Options;
|
||||
|
||||
public class BotSharpOptions
|
||||
{
|
||||
private readonly static JsonSerializerOptions defaultJsonOptions = new JsonSerializerOptions()
|
||||
{
|
||||
PropertyNameCaseInsensitive = true,
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
AllowTrailingCommas = true,
|
||||
WriteIndented = true
|
||||
};
|
||||
|
||||
private JsonSerializerOptions _jsonSerializerOptions;
|
||||
|
||||
public JsonSerializerOptions JsonSerializerOptions
|
||||
{
|
||||
get
|
||||
{
|
||||
return _jsonSerializerOptions ?? defaultJsonOptions;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
_jsonSerializerOptions = defaultJsonOptions;
|
||||
}
|
||||
else
|
||||
{
|
||||
_jsonSerializerOptions = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public BotSharpOptions()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +1,25 @@
|
|||
using BotSharp.Abstraction.Functions;
|
||||
using BotSharp.Abstraction.Repositories;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using BotSharp.Abstraction.Routing;
|
||||
using BotSharp.Core.Plugins;
|
||||
using BotSharp.Abstraction.Settings;
|
||||
using BotSharp.Abstraction.Options;
|
||||
using BotSharp.Abstraction.Messaging;
|
||||
using System.Text.Json.Serialization;
|
||||
using Microsoft.Extensions.Options;
|
||||
using BotSharp.Abstraction.Messaging.JsonConverters;
|
||||
|
||||
namespace BotSharp.Core;
|
||||
|
||||
public static class BotSharpCoreExtensions
|
||||
{
|
||||
public static IServiceCollection AddBotSharpCore(this IServiceCollection services, IConfiguration config)
|
||||
public static IServiceCollection AddBotSharpCore(this IServiceCollection services, IConfiguration config, Action<BotSharpOptions>? configOptions = null)
|
||||
{
|
||||
services.AddScoped<ISettingService, SettingService>();
|
||||
services.AddScoped<IUserService, UserService>();
|
||||
|
||||
RegisterPlugins(services, config);
|
||||
ConfigureBotSharpOptions(services, configOptions);
|
||||
return services;
|
||||
}
|
||||
|
||||
|
|
@ -53,6 +57,24 @@ public static class BotSharpCoreExtensions
|
|||
return app;
|
||||
}
|
||||
|
||||
private static void ConfigureBotSharpOptions(IServiceCollection services, Action<BotSharpOptions>? configure)
|
||||
{
|
||||
var options = new BotSharpOptions();
|
||||
if (configure != null)
|
||||
{
|
||||
configure(options);
|
||||
}
|
||||
|
||||
AddDefaultJsonConverters(options);
|
||||
services.AddSingleton(options);
|
||||
}
|
||||
|
||||
private static void AddDefaultJsonConverters(BotSharpOptions options)
|
||||
{
|
||||
options.JsonSerializerOptions.Converters.Add(new RichContentJsonConverter());
|
||||
options.JsonSerializerOptions.Converters.Add(new TemplateMessageJsonConverter());
|
||||
}
|
||||
|
||||
public static void RegisterPlugins(IServiceCollection services, IConfiguration config)
|
||||
{
|
||||
var pluginSettings = new PluginSettings();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Messaging;
|
||||
using BotSharp.Abstraction.Messaging.Models.RichContent;
|
||||
using BotSharp.Abstraction.Routing.Settings;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using BotSharp.Abstraction.Messaging;
|
||||
using BotSharp.Abstraction.Messaging.JsonConverters;
|
||||
using BotSharp.Abstraction.Messaging.Models.RichContent;
|
||||
using BotSharp.Abstraction.Options;
|
||||
using BotSharp.Abstraction.Repositories;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
|
@ -15,6 +16,7 @@ public class ConversationStorage : IConversationStorage
|
|||
|
||||
public ConversationStorage(
|
||||
BotSharpDatabaseSettings dbSettings,
|
||||
BotSharpOptions options,
|
||||
IServiceProvider services)
|
||||
{
|
||||
_dbSettings = dbSettings;
|
||||
|
|
@ -64,6 +66,7 @@ public class ConversationStorage : IConversationStorage
|
|||
AgentId = agentId,
|
||||
MessageId = dialog.MessageId,
|
||||
SenderId = dialog.SenderId,
|
||||
FunctionName = dialog.FunctionName,
|
||||
CreateTime = dialog.CreatedAt
|
||||
};
|
||||
|
||||
|
|
@ -93,7 +96,7 @@ public class ConversationStorage : IConversationStorage
|
|||
var role = meta.Role;
|
||||
var currentAgentId = meta.AgentId;
|
||||
var messageId = meta.MessageId;
|
||||
var function = role == AgentRole.Function ? meta.FunctionName : null;
|
||||
var function = meta.FunctionName;
|
||||
var senderId = role == AgentRole.Function ? currentAgentId : meta.SenderId;
|
||||
var createdAt = meta.CreateTime;
|
||||
var richContent = !string.IsNullOrEmpty(dialog.RichContent) ?
|
||||
|
|
|
|||
|
|
@ -408,16 +408,12 @@ namespace BotSharp.Core.Repository
|
|||
Role = blocks[1],
|
||||
AgentId = blocks[2],
|
||||
MessageId = blocks[3],
|
||||
FunctionName = blocks[1] == AgentRole.Function ? blocks[4] : null,
|
||||
SenderId = blocks[1] == AgentRole.Function ? null : blocks[4],
|
||||
SenderId = !string.IsNullOrWhiteSpace(blocks[4]) ? blocks[4] : null,
|
||||
FunctionName = !string.IsNullOrWhiteSpace(blocks[5]) ? blocks[5] : null,
|
||||
CreateTime = DateTime.Parse(blocks[0])
|
||||
};
|
||||
|
||||
string? richContent = null;
|
||||
if (blocks.Count() > 5)
|
||||
{
|
||||
richContent = blocks[5];
|
||||
}
|
||||
var richContent = blocks.Count() > 6 ? blocks[6] : null;
|
||||
dialogs.Add(new DialogElement(meta, trimmed, richContent));
|
||||
}
|
||||
}
|
||||
|
|
@ -433,8 +429,7 @@ namespace BotSharp.Core.Repository
|
|||
{
|
||||
var meta = element.MetaData;
|
||||
var createTime = meta.CreateTime.ToString("MM/dd/yyyy hh:mm:ss.fff tt", CultureInfo.InvariantCulture);
|
||||
var source = meta.FunctionName ?? meta.SenderId;
|
||||
var metaStr = $"{createTime}|{meta.Role}|{meta.AgentId}|{meta.MessageId}|{source}|{element.RichContent}";
|
||||
var metaStr = $"{createTime}|{meta.Role}|{meta.AgentId}|{meta.MessageId}|{meta.SenderId}|{meta.FunctionName}|{element.RichContent}";
|
||||
dialogTexts.Add(metaStr);
|
||||
var content = $" - {element.Content}";
|
||||
dialogTexts.Add(content);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using BotSharp.Abstraction.Messaging.Enums;
|
||||
using BotSharp.Abstraction.Messaging.JsonConverters;
|
||||
using BotSharp.Abstraction.Options;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
|
||||
namespace BotSharp.Plugin.ChatHub.Hooks;
|
||||
|
|
@ -9,24 +9,16 @@ public class ChatHubConversationHook : ConversationHookBase
|
|||
private readonly IServiceProvider _services;
|
||||
private readonly IHubContext<SignalRHub> _chatHub;
|
||||
private readonly IUserIdentity _user;
|
||||
private readonly JsonSerializerOptions _serializerOptions;
|
||||
private readonly BotSharpOptions _options;
|
||||
public ChatHubConversationHook(IServiceProvider services,
|
||||
IHubContext<SignalRHub> chatHub,
|
||||
BotSharpOptions options,
|
||||
IUserIdentity user)
|
||||
{
|
||||
_services = services;
|
||||
_chatHub = chatHub;
|
||||
_user = user;
|
||||
|
||||
_serializerOptions = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
Converters =
|
||||
{
|
||||
new RichContentJsonConverter(),
|
||||
new TemplateMessageJsonConverter(),
|
||||
}
|
||||
};
|
||||
_options = options;
|
||||
}
|
||||
|
||||
public override async Task OnConversationInitialized(Conversation conversation)
|
||||
|
|
@ -67,6 +59,11 @@ public class ChatHubConversationHook : ConversationHookBase
|
|||
await base.OnMessageReceived(message);
|
||||
}
|
||||
|
||||
public override async Task OnPostbackMessageReceived(RoleDialogModel message, PostbackMessageModel replyMsg)
|
||||
{
|
||||
await this.OnMessageReceived(message);
|
||||
}
|
||||
|
||||
public override async Task OnResponseGenerated(RoleDialogModel message)
|
||||
{
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
|
|
@ -84,7 +81,7 @@ public class ChatHubConversationHook : ConversationHookBase
|
|||
LastName = "Assistant",
|
||||
Role = AgentRole.Assistant
|
||||
}
|
||||
}, _serializerOptions);
|
||||
}, _options.JsonSerializerOptions);
|
||||
|
||||
// Send typing-off to client
|
||||
await _chatHub.Clients.User(_user.Id).SendAsync("OnSenderActionGenerated", new ConversationSenderActionModel
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using BotSharp.Abstraction.Functions.Models;
|
|||
using BotSharp.Abstraction.Loggers;
|
||||
using BotSharp.Abstraction.Loggers.Enums;
|
||||
using BotSharp.Abstraction.Loggers.Models;
|
||||
using BotSharp.Abstraction.Options;
|
||||
using BotSharp.Abstraction.Repositories;
|
||||
using BotSharp.Abstraction.Routing;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
|
|
@ -12,7 +13,7 @@ namespace BotSharp.Plugin.ChatHub.Hooks;
|
|||
public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook, IRoutingHook
|
||||
{
|
||||
private readonly ConversationSetting _convSettings;
|
||||
private readonly JsonSerializerOptions _serializerOptions;
|
||||
private readonly BotSharpOptions _options;
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly IHubContext<SignalRHub> _chatHub;
|
||||
private readonly IConversationStateService _state;
|
||||
|
|
@ -22,6 +23,7 @@ public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook, IR
|
|||
|
||||
public StreamingLogHook(
|
||||
ConversationSetting convSettings,
|
||||
BotSharpOptions options,
|
||||
IServiceProvider serivces,
|
||||
IHubContext<SignalRHub> chatHub,
|
||||
IConversationStateService state,
|
||||
|
|
@ -30,19 +32,13 @@ public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook, IR
|
|||
IRoutingContext routingCtx)
|
||||
{
|
||||
_convSettings = convSettings;
|
||||
_options = options;
|
||||
_services = serivces;
|
||||
_chatHub = chatHub;
|
||||
_state = state;
|
||||
_user = user;
|
||||
_agentService = agentService;
|
||||
_routingCtx = routingCtx;
|
||||
_serializerOptions = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true,
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
AllowTrailingCommas = true,
|
||||
WriteIndented = true,
|
||||
};
|
||||
}
|
||||
|
||||
public override async Task OnMessageReceived(RoleDialogModel message)
|
||||
|
|
@ -63,7 +59,7 @@ public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook, IR
|
|||
{
|
||||
var conversationId = _state.GetConversationId();
|
||||
var log = $"{message.Content}";
|
||||
var replyContent = JsonSerializer.Serialize(replyMsg, _serializerOptions);
|
||||
var replyContent = JsonSerializer.Serialize(replyMsg, _options.JsonSerializerOptions);
|
||||
log += $"\r\n```json\r\n{replyContent}\r\n```";
|
||||
|
||||
var input = new ContentLogInputModel(conversationId, message)
|
||||
|
|
@ -90,7 +86,7 @@ public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook, IR
|
|||
var conversationId = _state.GetConversationId();
|
||||
var agent = await _agentService.LoadAgent(message.CurrentAgentId);
|
||||
message.FunctionArgs = message.FunctionArgs ?? "{}";
|
||||
var args = JsonSerializer.Serialize(JsonDocument.Parse(message.FunctionArgs), _serializerOptions);
|
||||
var args = JsonSerializer.Serialize(JsonDocument.Parse(message.FunctionArgs), _options.JsonSerializerOptions);
|
||||
var log = $"*{message.FunctionName}*\r\n```json\r\n{args}\r\n```\r\n=> {message.Content?.Trim()}";
|
||||
|
||||
var input = new ContentLogInputModel(conversationId, message)
|
||||
|
|
@ -145,7 +141,7 @@ public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook, IR
|
|||
var log = $"{message.Content}";
|
||||
if (message.RichContent != null && message.RichContent.Message.RichType != "text")
|
||||
{
|
||||
var richContent = JsonSerializer.Serialize(message.RichContent, _serializerOptions);
|
||||
var richContent = JsonSerializer.Serialize(message.RichContent, _options.JsonSerializerOptions);
|
||||
log += $"\r\n```json\r\n{richContent}\r\n```";
|
||||
}
|
||||
|
||||
|
|
@ -248,7 +244,7 @@ public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook, IR
|
|||
{
|
||||
var conversationId = _state.GetConversationId();
|
||||
var agent = await _agentService.LoadAgent(message.CurrentAgentId);
|
||||
var log = JsonSerializer.Serialize(instruct, _serializerOptions);
|
||||
var log = JsonSerializer.Serialize(instruct, _options.JsonSerializerOptions);
|
||||
log = $"```json\r\n{log}\r\n```";
|
||||
|
||||
var input = new ContentLogInputModel(conversationId, message)
|
||||
|
|
@ -293,7 +289,7 @@ public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook, IR
|
|||
CreateTime = DateTime.UtcNow
|
||||
};
|
||||
|
||||
var json = JsonSerializer.Serialize(output, _serializerOptions);
|
||||
var json = JsonSerializer.Serialize(output, _options.JsonSerializerOptions);
|
||||
|
||||
var convSettings = _services.GetRequiredService<ConversationSetting>();
|
||||
if (convSettings.EnableContentLog)
|
||||
|
|
@ -322,6 +318,6 @@ public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook, IR
|
|||
db.SaveConversationStateLog(log);
|
||||
}
|
||||
|
||||
return JsonSerializer.Serialize(log, _serializerOptions);
|
||||
return JsonSerializer.Serialize(log, _options.JsonSerializerOptions);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
using BotSharp.Abstraction.Messaging.Models.RichContent;
|
||||
using BotSharp.Abstraction.Messaging;
|
||||
using BotSharp.Abstraction.Templating;
|
||||
using BotSharp.Abstraction.Messaging.JsonConverters;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using BotSharp.Abstraction.Options;
|
||||
|
||||
namespace BotSharp.Plugin.ChatHub.Hooks;
|
||||
|
||||
|
|
@ -12,26 +12,19 @@ public class WelcomeHook : ConversationHookBase
|
|||
private readonly IHubContext<SignalRHub> _chatHub;
|
||||
private readonly IUserIdentity _user;
|
||||
private readonly IConversationStorage _storage;
|
||||
private readonly JsonSerializerOptions _serializerOptions;
|
||||
private readonly BotSharpOptions _options;
|
||||
|
||||
public WelcomeHook(IServiceProvider services,
|
||||
IHubContext<SignalRHub> chatHub,
|
||||
IUserIdentity user,
|
||||
IConversationStorage storage)
|
||||
IConversationStorage storage,
|
||||
BotSharpOptions options)
|
||||
{
|
||||
_services = services;
|
||||
_chatHub = chatHub;
|
||||
_user = user;
|
||||
_storage = storage;
|
||||
|
||||
_serializerOptions = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
Converters =
|
||||
{
|
||||
new RichContentJsonConverter(),
|
||||
new TemplateMessageJsonConverter(),
|
||||
}
|
||||
};
|
||||
_options = options;
|
||||
}
|
||||
|
||||
public override async Task OnUserAgentConnectedInitially(Conversation conversation)
|
||||
|
|
@ -66,7 +59,7 @@ public class WelcomeHook : ConversationHookBase
|
|||
LastName = "",
|
||||
Role = AgentRole.Assistant
|
||||
}
|
||||
}, _serializerOptions);
|
||||
}, _options.JsonSerializerOptions);
|
||||
|
||||
await Task.Delay(300);
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using BotSharp.OpenAPI;
|
|||
using BotSharp.Logger;
|
||||
using BotSharp.Plugin.ChatHub;
|
||||
using Serilog;
|
||||
using BotSharp.Abstraction.Messaging.JsonConverters;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
|
|
@ -28,9 +29,12 @@ string[] allowedOrigins = builder.Configuration.GetSection("AllowedOrigins").Get
|
|||
};
|
||||
|
||||
// Add BotSharp
|
||||
builder.Services.AddBotSharpCore(builder.Configuration)
|
||||
.AddBotSharpOpenAPI(builder.Configuration, allowedOrigins, builder.Environment, true)
|
||||
.AddBotSharpLogger(builder.Configuration);
|
||||
builder.Services.AddBotSharpCore(builder.Configuration, options =>
|
||||
{
|
||||
options.JsonSerializerOptions.Converters.Add(new RichContentJsonConverter());
|
||||
options.JsonSerializerOptions.Converters.Add(new TemplateMessageJsonConverter());
|
||||
}).AddBotSharpOpenAPI(builder.Configuration, allowedOrigins, builder.Environment, true)
|
||||
.AddBotSharpLogger(builder.Configuration);
|
||||
|
||||
// Add SignalR for WebSocket
|
||||
builder.Services.AddSignalR();
|
||||
|
|
|
|||
Loading…
Reference in a new issue