Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
2557c2b
init message queue
Jan 9, 2026
8f23c64
init mq connection and service
Jan 9, 2026
e7a169d
relocate
Jan 10, 2026
2c5ae64
minor change
Jan 10, 2026
4e46bc5
minor change
Jan 10, 2026
94355cc
Merge branch 'master' of https://github.com/SciSharp/BotSharp into fe…
Jan 12, 2026
d0249eb
refine mq
Jan 12, 2026
a7024e0
minor change
Jan 12, 2026
8621fff
Merge branch 'master' of https://github.com/SciSharp/BotSharp into fe…
Jan 16, 2026
56dae92
refine message queue
iceljc Jan 20, 2026
26c3b42
minor change
iceljc Jan 20, 2026
5a6761f
Merge branch 'master' of https://github.com/SciSharp/BotSharp into fe…
Jan 20, 2026
3380b89
add error handling
Jan 20, 2026
5c50205
minor change
Jan 20, 2026
caba30c
temp save
Jan 21, 2026
4a01a6f
refine queue message handling
Jan 21, 2026
292270c
refine rule criteria and actions
Jan 21, 2026
33c247f
rename to messaging
Jan 21, 2026
a8cdca7
remove delayed
Jan 21, 2026
7c6b477
add custom method action
iceljc Jan 22, 2026
ff57169
refine action and add mq channel pool
Jan 22, 2026
ee2e444
refine config
iceljc Jan 23, 2026
436990d
fix mq config
iceljc Jan 23, 2026
5281479
minor change
iceljc Jan 25, 2026
184035c
Merge branch 'master' of https://github.com/SciSharp/BotSharp into fe…
iceljc Jan 25, 2026
77c2adb
refien rule action
iceljc Jan 26, 2026
9341685
replace url
iceljc Jan 26, 2026
dc5e2e6
avoid negative delay qty
iceljc Jan 26, 2026
f73598b
add agent rule action
iceljc Jan 26, 2026
2ea5483
ignore action when null
iceljc Jan 26, 2026
3d1d0ea
return function calling response
iceljc Jan 26, 2026
4b7f5ac
refine http rule
Jan 27, 2026
0b97b67
add agent filter to rule trigger options
iceljc Jan 28, 2026
cd68f58
refine rule criteria
Jan 28, 2026
a318c7a
refine agent rule structure
Jan 28, 2026
953854a
add json options
Jan 28, 2026
208b775
validate nullable rule action name
Jan 29, 2026
2db1aa3
fix namespace and correct unit conversion
iceljc Jan 30, 2026
30c670a
refine type conversion and mq channel
iceljc Jan 30, 2026
17b93b1
add json options in mq publish options
iceljc Jan 30, 2026
3f57c48
Merge branch 'master' of https://github.com/SciSharp/BotSharp into fe…
Feb 9, 2026
beebe8f
Merge branch 'features/add-message-queue-2' of https://github.com/ice…
Feb 9, 2026
f645b0e
relocate
Feb 9, 2026
3020922
minor fix
Feb 11, 2026
dc950c0
rename to http_request_headers
Feb 11, 2026
4060011
minor change
Feb 11, 2026
030dee7
extend to actions
Feb 11, 2026
b0dfa76
pass rule criteria object
Feb 11, 2026
717ec7a
add action step result
Feb 11, 2026
00f84e2
Merge branch 'master' of https://github.com/SciSharp/BotSharp into fe…
Feb 17, 2026
e63e874
minor change criteria provider
Feb 17, 2026
b706f14
use string parameter
Feb 18, 2026
f7dd5af
rename
Feb 18, 2026
9b5a219
refine code hook
Feb 18, 2026
24d47b1
add chat action response
Feb 18, 2026
5fae936
add skipping expression
Feb 19, 2026
511c60f
minor change
Feb 19, 2026
7d64fa5
Merge branch 'master' of https://github.com/SciSharp/BotSharp into fe…
Feb 27, 2026
20ce335
use graph
Feb 27, 2026
7e10997
temp add deme rule trigger
Feb 27, 2026
fd73f2e
clean code
Feb 27, 2026
be64936
use step result
iceljc Feb 28, 2026
ad2940a
Merge branch 'master' of https://github.com/SciSharp/BotSharp into fe…
Mar 2, 2026
cf9cbf5
refine graph attributes
Mar 2, 2026
c054542
minor change
Mar 2, 2026
5e304b0
remove step results from params
Mar 2, 2026
adeb942
refine rule graph
Mar 2, 2026
90d86df
rename
Mar 3, 2026
871c617
refine to string
Mar 3, 2026
5a5d739
add rule condition and clean code
Mar 4, 2026
e6f1e9d
add rule graph service
Mar 4, 2026
23f2159
split item and payload
Mar 4, 2026
bdf124c
rename to GetGraphAsync
Mar 4, 2026
1b3f870
refine config
Mar 5, 2026
aa4a108
refine
iceljc Mar 5, 2026
b92308a
rename to IRuleFlow
iceljc Mar 5, 2026
97150ff
minor change
iceljc Mar 5, 2026
89f5204
rename
iceljc Mar 5, 2026
0e65f41
refine membase query
Mar 5, 2026
2b7eb3b
refine
Mar 5, 2026
4cccd62
refine
Mar 5, 2026
0650f11
add rule config
Mar 5, 2026
b7819b0
refine topology config
Mar 6, 2026
819c1df
refine config
Mar 6, 2026
ad46221
add graph clear
iceljc Mar 7, 2026
0f3172d
add bfs and refine rule graph
iceljc Mar 7, 2026
da9be1b
refine get config
Mar 9, 2026
ef61dcd
return all states
Mar 9, 2026
f1cb51d
temp save
Mar 9, 2026
7f8de52
minor change
iceljc Mar 10, 2026
36540a0
refine rule engine
Mar 10, 2026
30732a2
Merge branch 'master' of https://github.com/SciSharp/BotSharp into fe…
Mar 10, 2026
707167f
minor change
Mar 10, 2026
c491704
clean code
iceljc Mar 11, 2026
c99b8d9
fix
iceljc Mar 11, 2026
405ea82
remove rabbit mq reference
iceljc Mar 11, 2026
c831961
relocate
iceljc Mar 12, 2026
4aa0fc0
set node weight
iceljc Mar 12, 2026
3b81c16
refine topology
iceljc Mar 16, 2026
740fc85
minor change
Mar 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<PackageVersion Include="Google_GenerativeAI.Live" Version="3.6.3" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="Polly" Version="8.4.2" />
<PackageVersion Include="RabbitMQ.Client" Version="7.2.0" />
<PackageVersion Include="SharpFuzz" Version="2.2.0" />
<PackageVersion Include="SharpHook" Version="5.3.9" />
<PackageVersion Include="SixLabors.ImageSharp" Version="3.1.12" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ public class AgentRule
[JsonPropertyName("disabled")]
public bool Disabled { get; set; }

[JsonPropertyName("criteria")]
public string Criteria { get; set; } = string.Empty;
[JsonPropertyName("config")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public RuleConfig? Config { get; set; }
}

public class RuleConfig
{
[JsonPropertyName("topology_name")]
public string? TopologyName { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ public class CodeExecutionContext
{
public AgentCodeScript CodeScript { get; set; }
public List<KeyValue> Arguments { get; set; } = [];
public string? InvokeFrom { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace BotSharp.Abstraction.Infrastructures.MessageQueues;

/// <summary>
/// Abstract interface for message queue consumers.
/// Implement this interface to create consumers that are independent of MQ products (e.g., RabbitMQ, Kafka, Azure Service Bus).
/// </summary>
public interface IMQConsumer : IDisposable
{
/// <summary>
/// Gets the consumer config
/// </summary>
object Config { get; }

/// <summary>
/// Handles the received message from the queue.
/// </summary>
/// <param name="channel">The consumer channel identifier</param>
/// <param name="data">The message data as string</param>
/// <returns>True if the message was handled successfully, false otherwise</returns>
Task<bool> HandleMessageAsync(string channel, string data);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using BotSharp.Abstraction.Infrastructures.MessageQueues.Models;

namespace BotSharp.Abstraction.Infrastructures.MessageQueues;

public interface IMQService : IDisposable
{
/// <summary>
/// Subscribe a consumer to the message queue.
/// The consumer will be initialized with the appropriate MQ-specific infrastructure.
/// </summary>
/// <param name="key">Unique identifier for the consumer</param>
/// <param name="consumer">The consumer implementing IMQConsumer interface</param>
/// <returns>Task<bool> representing the async subscription operation</returns>
Task<bool> SubscribeAsync(string key, IMQConsumer consumer);

/// <summary>
/// Unsubscribe a consumer from the message queue.
/// </summary>
/// <param name="key">Unique identifier for the consumer</param>
/// <returns>Task<bool> representing the async unsubscription operation</returns>
Task<bool> UnsubscribeAsync(string key);

/// <summary>
/// Publish payload to message queue
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="payload"></param>
/// <param name="options"></param>
/// <returns></returns>
Task<bool> PublishAsync<T>(T payload, MQPublishOptions options);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using Microsoft.Extensions.Logging;

namespace BotSharp.Abstraction.Infrastructures.MessageQueues;

/// <summary>
/// Abstract base class for RabbitMQ consumers.
/// Implements IMQConsumer to allow other projects to define consumers independently of RabbitMQ.
/// The RabbitMQ-specific infrastructure is handled by RabbitMQService.
/// </summary>
public abstract class MQConsumerBase : IMQConsumer
{
protected readonly IServiceProvider _services;
protected readonly ILogger _logger;
private bool _disposed = false;

/// <summary>
/// Gets the consumer config for this consumer.
/// Override this property to customize exchange, queue and routing configuration.
/// </summary>
public abstract object Config { get; }

protected MQConsumerBase(
IServiceProvider services,
ILogger logger)
{
_services = services;
_logger = logger;
}

/// <summary>
/// Handles the received message from the queue.
/// </summary>
/// <param name="channel">The consumer channel identifier</param>
/// <param name="data">The message data as string</param>
/// <returns>True if the message was handled successfully, false otherwise</returns>
public abstract Task<bool> HandleMessageAsync(string channel, string data);

public void Dispose()
{
if (_disposed)
{
return;
}

var consumerName = GetType().Name;
_logger.LogWarning($"Disposing consumer: {consumerName}");
_disposed = true;
GC.SuppressFinalize(this);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace BotSharp.Abstraction.Infrastructures.MessageQueues;

public class MessageQueueSettings
{
public bool Enabled { get; set; }
public string Provider { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace BotSharp.Abstraction.Infrastructures.MessageQueues.Models;

public class MQMessage<T>
{
public MQMessage(T payload, string messageId)
{
Payload = payload;
MessageId = messageId;
}

public T Payload { get; set; }
public string MessageId { get; set; }
public DateTime CreateDate { get; set; } = DateTime.UtcNow;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System.Text.Json;

namespace BotSharp.Abstraction.Infrastructures.MessageQueues.Models;

/// <summary>
/// Configuration options for publishing messages to a message queue.
/// These options are MQ-product agnostic and can be adapted by different implementations.
/// </summary>
public class MQPublishOptions
{
/// <summary>
/// The topic name (exchange in RabbitMQ, topic in Kafka/Azure Service Bus).
/// </summary>
public string TopicName { get; set; } = string.Empty;

/// <summary>
/// The routing key (partition key in some MQ systems, used for message routing).
/// </summary>
public string RoutingKey { get; set; } = string.Empty;

/// <summary>
/// Delay in milliseconds before the message is delivered.
/// </summary>
public long DelayMilliseconds { get; set; }

/// <summary>
/// Optional unique identifier for the message.
/// </summary>
public string? MessageId { get; set; }

/// <summary>
/// Additional arguments for the publish configuration (MQ-specific).
/// </summary>
public Dictionary<string, object?> Arguments { get; set; } = [];

/// <summary>
/// Json serializer options
/// </summary>
public JsonSerializerOptions? JsonOptions { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ public interface IInstructHook : IHookBase
Task OnResponseGenerated(InstructResponseModel response) => Task.CompletedTask;

Task BeforeCodeExecution(Agent agent, CodeExecutionContext context) => Task.CompletedTask;
Task AfterCodeExecution(Agent agent, CodeExecutionResponseModel response) => Task.CompletedTask;
Task AfterCodeExecution(Agent agent, CodeExecutionContext context, CodeExecutionResponseModel response) => Task.CompletedTask;
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public virtual async Task BeforeCodeExecution(Agent agent, CodeExecutionContext
await Task.CompletedTask;
}

public virtual async Task AfterCodeExecution(Agent agent, CodeExecutionResponseModel response)
public virtual async Task AfterCodeExecution(Agent agent, CodeExecutionContext context, CodeExecutionResponseModel response)
{
await Task.CompletedTask;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using BotSharp.Abstraction.Hooks;
using BotSharp.Abstraction.Rules.Models;

namespace BotSharp.Abstraction.Rules.Hooks;

public interface IRuleTriggerHook : IHookBase
{
Task BeforeRuleConditionExecuting(Agent agent, RuleNode conditionNode, IRuleTrigger trigger, RuleFlowContext context) => Task.CompletedTask;
Task AfterRuleConditionExecuted(Agent agent, RuleNode conditionNode, IRuleTrigger trigger, RuleFlowContext context, RuleNodeResult result) => Task.CompletedTask;

Task BeforeRuleActionExecuting(Agent agent, RuleNode actionNode, IRuleTrigger trigger, RuleFlowContext context) => Task.CompletedTask;
Task AfterRuleActionExecuted(Agent agent, RuleNode actionNode, IRuleTrigger trigger, RuleFlowContext context, RuleNodeResult result) => Task.CompletedTask;
}
20 changes: 18 additions & 2 deletions src/Infrastructure/BotSharp.Abstraction/Rules/IRuleAction.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
using BotSharp.Abstraction.Rules.Models;

namespace BotSharp.Abstraction.Rules;

public interface IRuleAction
/// <summary>
/// Base interface for rule actions that can be executed by the RuleEngine
/// </summary>
public interface IRuleAction : IRuleFlowUnit
{
}
/// <summary>
/// Execute the rule action
/// </summary>
/// <param name="agent">The agent that triggered the rule</param>
/// <param name="trigger">The rule trigger</param>
/// <param name="context">The flow context</param>
/// <returns>The action execution result</returns>
Task<RuleNodeResult> ExecuteAsync(
Agent agent,
IRuleTrigger trigger,
RuleFlowContext context);
}
22 changes: 22 additions & 0 deletions src/Infrastructure/BotSharp.Abstraction/Rules/IRuleCondition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using BotSharp.Abstraction.Rules.Models;

namespace BotSharp.Abstraction.Rules;

/// <summary>
/// Base interface for rule conditions that can be evaluated by the RuleEngine
/// </summary>
public interface IRuleCondition : IRuleFlowUnit
{
/// <summary>
/// Evaluate the rule condition
/// </summary>
/// <param name="agent">The agent that triggered the rule</param>
/// <param name="trigger">The rule trigger</param>
/// <param name="context">The flow context</param>
/// <returns>The condition evaluation result</returns>
Task<RuleNodeResult> EvaluateAsync(
Agent agent,
IRuleTrigger trigger,
RuleFlowContext context);
}

5 changes: 0 additions & 5 deletions src/Infrastructure/BotSharp.Abstraction/Rules/IRuleConfig.cs

This file was deleted.

This file was deleted.

13 changes: 13 additions & 0 deletions src/Infrastructure/BotSharp.Abstraction/Rules/IRuleEngine.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using BotSharp.Abstraction.Rules.Models;

namespace BotSharp.Abstraction.Rules;

public interface IRuleEngine
Expand All @@ -13,4 +15,15 @@ public interface IRuleEngine
/// <exception cref="NotImplementedException"></exception>
Task<IEnumerable<string>> Triggered(IRuleTrigger trigger, string text, IEnumerable<MessageState>? states = null, RuleTriggerOptions? options = null)
=> throw new NotImplementedException();

/// <summary>
/// Execute rule graph node
/// </summary>
/// <param name="node"></param>
/// <param name="graph"></param>
/// <param name="agentId"></param>
/// <param name="trigger"></param>
/// <param name="options"></param>
/// <returns></returns>
Task ExecuteGraphNode(RuleNode node, RuleGraph graph, string agentId, IRuleTrigger trigger, RuleNodeExecutionOptions options);
}
26 changes: 26 additions & 0 deletions src/Infrastructure/BotSharp.Abstraction/Rules/IRuleFlow.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using BotSharp.Abstraction.Rules.Models;

namespace BotSharp.Abstraction.Rules;

public interface IRuleFlow<T> where T : class
{
/// <summary>
/// Rule flow topology name
/// </summary>
string Name { get; }

/// <summary>
/// Get rule flow topology config
/// </summary>
/// <param name="options"></param>
/// <returns></returns>
Task<RuleConfigModel> GetTopologyConfigAsync(RuleFlowConfigOptions? options = null);

/// <summary>
/// Get rule flow topology
/// </summary>
/// <param name="id"></param>
/// <param name="options"></param>
/// <returns></returns>
Task<T?> GetTopologyAsync(string id, RuleFlowLoadOptions? options = null);
}
21 changes: 21 additions & 0 deletions src/Infrastructure/BotSharp.Abstraction/Rules/IRuleFlowUnit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using BotSharp.Abstraction.Rules.Models;

namespace BotSharp.Abstraction.Rules;

public interface IRuleFlowUnit
{
/// <summary>
/// The unique name of the rule flow unit, i.e., action, condition.
/// </summary>
string Name => string.Empty;

/// <summary>
/// The agent id
/// </summary>
string? AgentId => null;

/// <summary>
/// The trigger names
/// </summary>
IEnumerable<string>? Triggers => null;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Text.Json;

namespace BotSharp.Abstraction.Rules.Models;

public class RuleConfigModel
{
public string TopologyId { get; set; }
public string TopologyName { get; set; }
public JsonDocument CustomParameters { get; set; } = JsonDocument.Parse("{}");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Text.Json;

namespace BotSharp.Abstraction.Rules.Models;

/// <summary>
/// Context for rule flow execution (actions and conditions)
/// </summary>
public class RuleFlowContext
{
public string Text { get; set; } = string.Empty;
public Dictionary<string, string?> Parameters { get; set; } = [];
public IEnumerable<RuleFlowStepResult> PrevStepResults { get; set; } = [];
public JsonSerializerOptions? JsonOptions { get; set; }
public RuleNode Node { get; set; }
public RuleEdge Edge { get; set; }
public RuleGraph Graph { get; set; }
}

Loading
Loading