add session logging and crontab settings

This commit is contained in:
Jicheng Lu 2025-05-20 10:59:42 -05:00
parent 73c2e9c72e
commit aab468f410
24 changed files with 78 additions and 26 deletions

View file

@ -0,0 +1,12 @@
namespace BotSharp.Abstraction.Crontab.Settings;
public class CrontabSettings
{
public CrontabBaseSetting EventSubscriber { get; set; } = new();
public CrontabBaseSetting Watcher { get; set; } = new();
}
public class CrontabBaseSetting
{
public bool Enabled { get; set; } = true;
}

View file

@ -1,9 +1,12 @@
using Microsoft.Extensions.Logging;
using System.Text.Json;
namespace BotSharp.Abstraction.Realtime.Models.Session;
public class ChatSessionOptions
{
public string Provider { get; set; }
public int? BufferSize { get; set; }
public JsonSerializerOptions? JsonOptions { get; set; }
public ILogger? Logger { get; set; }
}

View file

@ -1,4 +1,4 @@
namespace BotSharp.Abstraction.Repositories;
namespace BotSharp.Abstraction.Repositories.Settings;
public class BotSharpDatabaseSettings : DatabaseBasicSettings
{

View file

@ -32,11 +32,22 @@ public class CrontabPlugin : IBotSharpPlugin
public void RegisterDI(IServiceCollection services, IConfiguration config)
{
var settings = new CrontabSettings();
config.Bind("Crontab", settings);
services.AddSingleton(settings);
services.AddScoped<IAgentUtilityHook, CrontabUtilityHook>();
services.AddScoped<ICrontabService, CrontabService>();
services.AddScoped<ITaskFeeder, CrontabService>();
services.AddHostedService<CrontabWatcher>();
services.AddHostedService<CrontabEventSubscription>();
if (settings.Watcher?.Enabled == true)
{
services.AddHostedService<CrontabWatcher>();
}
if (settings.EventSubscriber?.Enabled == true)
{
services.AddHostedService<CrontabEventSubscription>();
}
}
}

View file

@ -6,6 +6,7 @@ global using Microsoft.Extensions.DependencyInjection;
global using BotSharp.Abstraction.Agents.Enums;
global using BotSharp.Abstraction.Crontab;
global using BotSharp.Abstraction.Crontab.Models;
global using BotSharp.Abstraction.Crontab.Settings;
global using BotSharp.Abstraction.Agents;
global using BotSharp.Abstraction.Plugins;
global using BotSharp.Abstraction.Conversations.Models;

View file

@ -1,3 +1,4 @@
using BotSharp.Abstraction.Repositories.Settings;
using BotSharp.Abstraction.Tasks.Models;
using BotSharp.Abstraction.Users.Enums;
using System.IO;

View file

@ -1,4 +1,5 @@
using BotSharp.Abstraction.Repositories.Enums;
using BotSharp.Abstraction.Repositories.Settings;
using System.IO;
namespace BotSharp.Core.Agents.Services;

View file

@ -1,4 +1,5 @@
using BotSharp.Abstraction.Repositories.Enums;
using BotSharp.Abstraction.Repositories.Settings;
using BotSharp.Abstraction.Users.Enums;
using BotSharp.Abstraction.Users.Models;
using System.IO;

View file

@ -1,3 +1,4 @@
using BotSharp.Abstraction.Repositories.Settings;
using System.IO;
using System.Reflection;

View file

@ -16,6 +16,7 @@ using BotSharp.Abstraction.Templating;
using BotSharp.Core.Templating;
using BotSharp.Abstraction.Infrastructures.Enums;
using BotSharp.Abstraction.Realtime;
using BotSharp.Abstraction.Repositories.Settings;
namespace BotSharp.Core;
@ -71,17 +72,6 @@ public static class BotSharpCoreExtensions
return services;
}
//public static IServiceCollection UsingFileRepository(this IServiceCollection services, IConfiguration config)
//{
// services.AddScoped<IBotSharpRepository>(sp =>
// {
// var myDatabaseSettings = sp.GetRequiredService<BotSharpDatabaseSettings>();
// return new FileRepository(myDatabaseSettings, sp);
// });
// return services;
//}
public static IApplicationBuilder UseBotSharp(this IApplicationBuilder app)
{
if (app == null)

View file

@ -1,3 +1,4 @@
using BotSharp.Abstraction.Repositories.Settings;
using System.IO;
namespace BotSharp.Core.Files.Services;

View file

@ -24,7 +24,9 @@ public class DistributedLocker : IDistributedLocker
var redis = _services.GetService<IConnectionMultiplexer>();
if (redis == null)
{
#if !DEBUG
_logger.LogInformation($"The Redis server is experiencing issues and is not functioning as expected.");
#endif
await action();
return true;
}
@ -50,7 +52,9 @@ public class DistributedLocker : IDistributedLocker
var redis = _services.GetRequiredService<IConnectionMultiplexer>();
if (redis == null)
{
#if !DEBUG
_logger.LogWarning($"The Redis server is experiencing issues and is not functioning as expected.");
#endif
action();
return false;
}

View file

@ -1,4 +1,3 @@
using BotSharp.Abstraction.Realtime.Models.Session;
using System.ClientModel;
using System.Net.WebSockets;
@ -7,16 +6,16 @@ namespace BotSharp.Core.Infrastructures.Websocket;
internal class AsyncWebsocketDataCollectionResult : AsyncCollectionResult<ClientResult>
{
private readonly WebSocket _webSocket;
private readonly ChatSessionOptions? _sessionOptions;
private readonly ChatSessionOptions? _options;
private readonly CancellationToken _cancellationToken;
public AsyncWebsocketDataCollectionResult(
WebSocket webSocket,
ChatSessionOptions? sessionOptions,
ChatSessionOptions? options,
CancellationToken cancellationToken)
{
_webSocket = webSocket;
_sessionOptions = sessionOptions;
_options = options;
_cancellationToken = cancellationToken;
}
@ -27,7 +26,7 @@ internal class AsyncWebsocketDataCollectionResult : AsyncCollectionResult<Client
public override async IAsyncEnumerable<ClientResult> GetRawPagesAsync()
{
await using var enumerator = new AsyncWebsocketDataResultEnumerator(_webSocket, _sessionOptions, _cancellationToken);
await using var enumerator = new AsyncWebsocketDataResultEnumerator(_webSocket, _options, _cancellationToken);
while (await enumerator.MoveNextAsync().ConfigureAwait(false))
{
yield return enumerator.Current;

View file

@ -1,3 +1,4 @@
using Microsoft.AspNetCore.Builder;
using System.Buffers;
using System.ClientModel;
using System.Net.WebSockets;
@ -7,7 +8,7 @@ namespace BotSharp.Core.Infrastructures.Websocket;
internal class AsyncWebsocketDataResultEnumerator : IAsyncEnumerator<ClientResult>
{
private readonly WebSocket _webSocket;
private readonly ChatSessionOptions? _sessionOptions;
private readonly ChatSessionOptions? _options;
private readonly CancellationToken _cancellationToken;
private readonly byte[] _buffer;
@ -15,13 +16,13 @@ internal class AsyncWebsocketDataResultEnumerator : IAsyncEnumerator<ClientResul
public AsyncWebsocketDataResultEnumerator(
WebSocket webSocket,
ChatSessionOptions? sessionOptions,
ChatSessionOptions? options,
CancellationToken cancellationToken)
{
_webSocket = webSocket;
_sessionOptions = sessionOptions;
_options = options;
_cancellationToken = cancellationToken;
var bufferSize = sessionOptions?.BufferSize > 0 ? sessionOptions.BufferSize.Value : DEFAULT_BUFFER_SIZE;
var bufferSize = options?.BufferSize > 0 ? options.BufferSize.Value : DEFAULT_BUFFER_SIZE;
_buffer = ArrayPool<byte>.Shared.Rent(bufferSize);
}
@ -44,7 +45,10 @@ internal class AsyncWebsocketDataResultEnumerator : IAsyncEnumerator<ClientResul
if (receivedResult.CloseStatus.HasValue)
{
#if DEBUG
Console.WriteLine($"Websocket close: {receivedResult.CloseStatus} {receivedResult.CloseStatusDescription}");
if (_options?.Logger != null)
{
_options.Logger.LogWarning($"{_options?.Provider} Websocket close: ({receivedResult.CloseStatus}) {receivedResult.CloseStatusDescription}");
}
#endif
Current = null;
return false;

View file

@ -1,3 +1,4 @@
using BotSharp.Abstraction.Repositories.Settings;
using Microsoft.Data.SqlClient;
using System.Data.Common;

View file

@ -5,6 +5,7 @@ using FunctionDef = BotSharp.Abstraction.Functions.Models.FunctionDef;
using BotSharp.Abstraction.Users.Models;
using BotSharp.Abstraction.Plugins.Models;
using BotSharp.Abstraction.Tasks.Models;
using BotSharp.Abstraction.Repositories.Settings;
namespace BotSharp.Core.Repository;

View file

@ -1,4 +1,5 @@
using BotSharp.Abstraction.Repositories.Enums;
using BotSharp.Abstraction.Repositories.Settings;
using BotSharp.Abstraction.Settings;
using Microsoft.Extensions.Configuration;

View file

@ -1,3 +1,4 @@
using BotSharp.Abstraction.Repositories.Settings;
using Whisper.net;
using Whisper.net.Ggml;

View file

@ -54,6 +54,7 @@ public class ChatStreamMiddleware
_session?.Dispose();
_session = new BotSharpRealtimeSession(services, webSocket, new ChatSessionOptions
{
Provider = "BotSharp Chat Stream",
BufferSize = 1024 * 16,
JsonOptions = BotSharpOptions.defaultJsonOptions
});

View file

@ -97,7 +97,9 @@ public class GoogleRealTimeProvider : IRealTimeCompletion
_outputStream = new();
_session = new LlmRealtimeSession(_services, new ChatSessionOptions
{
JsonOptions = _jsonOptions
Provider = Provider,
JsonOptions = _jsonOptions,
Logger = _logger
});
var uri = BuildWebsocketUri(modelSettings.ApiKey, "v1beta");

View file

@ -1,3 +1,5 @@
using BotSharp.Abstraction.Repositories.Settings;
namespace BotSharp.Plugin.MongoStorage;
public class MongoDbContext

View file

@ -1,4 +1,5 @@
using BotSharp.Abstraction.Repositories.Enums;
using BotSharp.Abstraction.Repositories.Settings;
using BotSharp.Plugin.MongoStorage.Repository;
namespace BotSharp.Plugin.MongoStorage;

View file

@ -72,7 +72,9 @@ public class RealTimeCompletionProvider : IRealTimeCompletion
_session?.Dispose();
_session = new LlmRealtimeSession(_services, new ChatSessionOptions
{
JsonOptions = _botsharpOptions.JsonSerializerOptions
Provider = Provider,
JsonOptions = _botsharpOptions.JsonSerializerOptions,
Logger = _logger
});
await _session.ConnectAsync(

View file

@ -325,6 +325,15 @@
"Enabled": false
},
"Crontab": {
"Watcher": {
"Enabled": false
},
"EventSubscriber": {
"Enabled": false
}
},
"Instruction": {
"Logging": {
"Enabled": true,
@ -427,6 +436,7 @@
"BucketName": "",
"Region": ""
},
"Qdrant": {
"Url": "",
"ApiKey": ""
@ -468,6 +478,7 @@
"ApiSecret": "",
"ModelVersion": "V3_5"
},
"MetaGLM": {
"ApiKey": "6b6c8b3fca3e5da21d633e350980744d.938gruOqrK4BDqW8",
"BaseAddress": "http://localhost:8100/v1/",