Skip to content

Conversation

iceljc
Copy link
Collaborator

@iceljc iceljc commented Sep 19, 2025

PR Type

Enhancement


Description

  • Refactor conversation message handling and routing context

  • Remove unused imports and clean up dependencies

  • Move database persistence logic to conversation observer


Diagram Walkthrough

flowchart LR
  A["ChatHubObserver"] -- "removes DB persistence" --> B["ConversationObserver"]
  B -- "adds routing context" --> C["IRoutingContext"]
  B -- "handles intermediate messages" --> D["Database Storage"]
  E["Unused Imports"] -- "cleaned up" --> F["Cleaner Codebase"]
Loading

File Walkthrough

Relevant files
Formatting
BotSharpConversationSideCar.cs
Clean up unused imports                                                                   

src/Infrastructure/BotSharp.Core.SideCar/Services/BotSharpConversationSideCar.cs

  • Remove unused imports: NetTopologySuite.Index.KdTree,
    Newtonsoft.Json.Linq, and static
    System.Runtime.InteropServices.JavaScript.JSType
+0/-3     
ConversationStateService.cs
Remove unused imports                                                                       

src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs

  • Remove unused imports: BotSharp.Abstraction.Conversations.Enums and
    BotSharp.Abstraction.Hooks
+0/-2     
Enhancement
ConversationObserver.cs
Add intermediate message handling with routing context     

src/Infrastructure/BotSharp.Core/MessageHub/Observers/ConversationObserver.cs

  • Add routing context and storage service dependencies
  • Implement handling for OnIntermediateMessageReceivedFromAssistant
    event
  • Add dialog management through routing context
  • Add conditional database persistence for intermediate messages
+13/-0   
ChatHubObserver.cs
Remove database persistence from chat hub observer             

src/Plugins/BotSharp.Plugin.ChatHub/Observers/ChatHubObserver.cs

  • Remove database persistence logic from
    OnIntermediateMessageReceivedFromAssistant case
  • Remove storage service dependency and append operation
+0/-6     

Copy link

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Possible Null Handling

Ensure that routing context methods like GetDialogs() never return null and are thread-safe; otherwise adding to dialogs could throw or corrupt shared state under concurrency.

var dialogs = routeCtx.GetDialogs();
dialogs.Add(value.Data);
routeCtx.SetDialogs(dialogs);

if (value.SaveDataToDb)
{
    storage.Append(conv.ConversationId, value.Data);
}
Duplication Risk

Adding intermediate messages to routing context and later persisting them may result in duplicate entries or ordering issues; confirm lifecycle and whether messages are already present in context before adding.

var dialogs = routeCtx.GetDialogs();
dialogs.Add(value.Data);
routeCtx.SetDialogs(dialogs);

if (value.SaveDataToDb)
{
    storage.Append(conv.ConversationId, value.Data);
}

Copy link

qodo-merge-pro bot commented Sep 19, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Ensure thread-safe dialog list updates

To ensure thread safety when updating dialogs, create a new list with the added
item instead of modifying the existing list in-place.

src/Infrastructure/BotSharp.Core/MessageHub/Observers/ConversationObserver.cs [48-50]

 var dialogs = routeCtx.GetDialogs();
-dialogs.Add(value.Data);
-routeCtx.SetDialogs(dialogs);
+var newDialogs = new List<RoleDialogModel>(dialogs) { value.Data };
+routeCtx.SetDialogs(newDialogs);
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a critical thread-safety issue (race condition) in the newly added code, which could lead to data corruption in a concurrent message hub environment, and provides a correct fix.

Medium
High-level
Improve encapsulation of the routing context

Add a dedicated AddDialog(dialog) method to the IRoutingContext interface. This
will encapsulate the logic for updating the dialog history, improving the design
by hiding its internal state.

Examples:

src/Infrastructure/BotSharp.Core/MessageHub/Observers/ConversationObserver.cs [48-50]
            var dialogs = routeCtx.GetDialogs();
            dialogs.Add(value.Data);
            routeCtx.SetDialogs(dialogs);

Solution Walkthrough:

Before:

// In ConversationObserver.cs
public override void OnNext(...)
{
    // ...
    else if (value.EventName == ChatEvent.OnIntermediateMessageReceivedFromAssistant)
    {
        var routeCtx = _services.GetRequiredService<IRoutingContext>();
        var dialogs = routeCtx.GetDialogs();
        dialogs.Add(value.Data);
        routeCtx.SetDialogs(dialogs);
        // ...
    }
}

After:

// In IRoutingContext.cs (conceptual)
interface IRoutingContext
{
    // ...
    void AddDialog(RoleDialogModel dialog);
}

// In ConversationObserver.cs
public override void OnNext(...)
{
    // ...
    else if (value.EventName == ChatEvent.OnIntermediateMessageReceivedFromAssistant)
    {
        var routeCtx = _services.GetRequiredService<IRoutingContext>();
        routeCtx.AddDialog(value.Data);
        // ...
    }
}
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies a design weakness in the new code that breaks encapsulation and proposes a valid improvement to the IRoutingContext API, enhancing maintainability.

Medium
Learned
best practice
Remove blocking async call

Avoid blocking on async by removing .GetResult() and making the call
asynchronous, or use GetAwaiter().GetResult() only in non-async contexts with
clear justification.

src/Infrastructure/BotSharp.Core/MessageHub/Observers/ConversationObserver.cs [41-44]

 if (_listeners.TryGetValue(value.EventName, out var func) && func != null)
 {
-    func(value).ConfigureAwait(false).GetAwaiter().GetResult();
+    _ = func(value);
 }

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 5

__

Why:
Relevant best practice - Validate external/system state and avoid blocking async calls in async flows.

Low
  • Update

@iceljc iceljc merged commit bc35112 into SciSharp:master Sep 19, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant