Skip to content

Conversation

@yileicn
Copy link
Member

@yileicn yileicn commented Dec 24, 2025

PR Type

Enhancement


Description

  • Convert synchronous MongoDB repository methods to async/await pattern

  • Add async file I/O operations in FileRepository implementations

  • Update service layer to properly await async repository calls

  • Add JWT Bearer token security configuration to Swagger/OpenAPI


Diagram Walkthrough

flowchart LR
  A["Repository Interface"] -->|"Add async signatures"| B["IBotSharpRepository"]
  B -->|"Implement async"| C["MongoRepository"]
  B -->|"Implement async"| D["FileRepository"]
  C -->|"Use async MongoDB"| E["Async Queries"]
  D -->|"Use async File I/O"| F["Async File Operations"]
  G["Service Layer"] -->|"Await calls"| C
  G -->|"Await calls"| D
  H["OpenAPI"] -->|"Add JWT config"| I["Swagger Security"]
Loading

File Walkthrough

Relevant files
Enhancement
19 files
IBotSharpRepository.cs
Add async method signatures to repository interface           
+6/-4     
AgentService.Coding.cs
Await async GetAgentCodeScript repository call                     
+2/-2     
AgentService.GetAgents.cs
Use new GetAgentAsync method with await                                   
+1/-1     
AgentService.UpdateAgent.cs
Replace sync GetAgent with async GetAgentAsync calls         
+2/-2     
ConversationService.cs
Await async GetConversation repository method                       
+3/-3     
FileRepository.AgentCodeScript.cs
Convert to async method with File.ReadAllTextAsync             
+2/-2     
FileRepository.Conversation.cs
Use async file read operations in conversation retrieval 
+3/-3     
FileRepository.KnowledgeBase.cs
Convert knowledge config methods to async pattern               
+4/-4     
BotSharpOpenApiExtensions.cs
Add JWT Bearer security definition to Swagger                       
+21/-0   
TranslationController.cs
Await async GetAgentAsync calls in translation endpoints 
+2/-2     
WelcomeHook.cs
Await async GetAgentAsync in welcome hook                               
+1/-1     
KnowledgeSettingHelper.cs
Convert helper method to async Task pattern                           
+2/-2     
KnowledgeService.Document.cs
Await async GetTextEmbedding method call                                 
+1/-1     
KnowledgeService.Vector.cs
Await async knowledge collection config methods                   
+9/-9     
KnowledgeService.cs
Convert GetTextEmbedding to async Task method                       
+2/-2     
MongoRepository.Agent.cs
Implement async GetAgentAsync with MongoDB LINQ                   
+12/-0   
MongoRepository.AgentCodeScript.cs
Convert GetAgentCodeScript to async MongoDB query               
+2/-2     
MongoRepository.Conversation.cs
Use async MongoDB queries for conversation retrieval         
+3/-3     
MongoRepository.KnowledgeBase.cs
Convert knowledge base methods to async pattern                   
+3/-3     

@qodo-code-review
Copy link

qodo-code-review bot commented Dec 24, 2025

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🔴
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status:
Async naming mismatch: New Task-returning repository methods (e.g., GetConversation, GetAgentCodeScript,
GetKnowledgeCollectionConfigs, GetKnowledgeCollectionConfig) are not consistently suffixed
with Async, reducing clarity and breaking common async naming conventions.

Referred Code
Task<AgentCodeScript?> GetAgentCodeScript(string agentId, string scriptName, string scriptType = AgentCodeScriptType.Src)
    => throw new NotImplementedException();
bool UpdateAgentCodeScripts(string agentId, List<AgentCodeScript> scripts, AgentCodeScriptDbUpdateOptions? options = null)
    => throw new NotImplementedException();
bool BulkInsertAgentCodeScripts(string agentId, List<AgentCodeScript> scripts)
    => throw new NotImplementedException();
bool DeleteAgentCodeScripts(string agentId, List<AgentCodeScript>? scripts = null)
    => throw new NotImplementedException();
#endregion

#region Conversation
void CreateNewConversation(Conversation conversation)
    => throw new NotImplementedException();
bool DeleteConversations(IEnumerable<string> conversationIds)
    => throw new NotImplementedException();
List<DialogElement> GetConversationDialogs(string conversationId)
    => throw new NotImplementedException();
void AppendConversationDialogs(string conversationId, List<DialogElement> dialogs)
    => throw new NotImplementedException();
ConversationState GetConversationStates(string conversationId)
    => throw new NotImplementedException();


 ... (clipped 100 lines)

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link

qodo-code-review bot commented Dec 24, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Adopt a consistent async migration strategy

The suggestion highlights an inconsistent async migration in
IBotSharpRepository. It recommends a uniform, non-breaking approach: add
Async-suffixed methods and mark the old synchronous ones as obsolete.

Examples:

src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs [73-76]
    Agent? GetAgent(string agentId, bool basicsOnly = false)
        => throw new NotImplementedException();
    Task<Agent?> GetAgentAsync(string agentId, bool basicsOnly = false)
        => throw new NotImplementedException();
src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs [143-145]
        => throw new NotImplementedException();
    Task<Conversation> GetConversation(string conversationId, bool isLoadStates = false)
        => throw new NotImplementedException();

Solution Walkthrough:

Before:

public interface IBotSharpRepository
{
    // Strategy 1: Add new async method, keep old sync one.
    Agent? GetAgent(string agentId, ...);
    Task<Agent?> GetAgentAsync(string agentId, ...);

    // Strategy 2: Replace sync method with async one (breaking change).
    // old: Conversation GetConversation(string conversationId, ...);
    Task<Conversation> GetConversation(string conversationId, ...);

    // Strategy 2: Replace sync method with async one (breaking change).
    // old: AgentCodeScript? GetAgentCodeScript(string agentId, ...);
    Task<AgentCodeScript?> GetAgentCodeScript(string agentId, ...);
}

After:

public interface IBotSharpRepository
{
    // Consistent Strategy: Add new async method, mark old as obsolete.
    [Obsolete("Use GetAgentAsync instead.")]
    Agent? GetAgent(string agentId, ...);
    Task<Agent?> GetAgentAsync(string agentId, ...);

    [Obsolete("Use GetConversationAsync instead.")]
    Conversation GetConversation(string conversationId, ...);
    Task<Conversation> GetConversationAsync(string conversationId, ...);

    [Obsolete("Use GetAgentCodeScriptAsync instead.")]
    AgentCodeScript? GetAgentCodeScript(string agentId, ...);
    Task<AgentCodeScript?> GetAgentCodeScriptAsync(string agentId, ...);
}
Suggestion importance[1-10]: 9

__

Why: This is a critical architectural suggestion that correctly identifies an inconsistent API design strategy, which can cause breaking changes and developer confusion.

High
Possible issue
Allow nullable conversation return

Update the GetConversation method's return type in the interface to Task<Conversation?> to
reflect that implementations can return null.

src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs [144-145]

-Task<Conversation> GetConversation(string conversationId, bool isLoadStates = false)
+Task<Conversation?> GetConversation(string conversationId, bool isLoadStates = false)
      => throw new NotImplementedException();
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: This is a critical correction. The implementations in FileRepository and MongoRepository can return null, so the interface IBotSharpRepository must declare the return type as Task<Conversation?> to ensure type safety and prevent runtime errors.

Medium
Make config return nullable

Update the GetKnowledgeCollectionConfig method's return type in the interface to
Task<VectorCollectionConfig?> to reflect that implementations can return null.

src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs [238-239]

-Task<VectorCollectionConfig> GetKnowledgeCollectionConfig(string collectionName, string vectorStroageProvider)
+Task<VectorCollectionConfig?> GetKnowledgeCollectionConfig(string collectionName, string vectorStroageProvider)
      => throw new NotImplementedException();
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: This is a critical correction. The implementations in FileRepository and MongoRepository can return null, so the interface IBotSharpRepository must declare the return type as Task<VectorCollectionConfig?> to ensure type safety and prevent runtime errors.

Medium
General
Check agent null before use

Add a null check for the agent variable and return an appropriate HTTP error
response if it is null to prevent potential exceptions.

src/Infrastructure/BotSharp.OpenAPI/Controllers/Conversation/TranslationController.cs [26]

 var agent = await db.GetAgentAsync(BuiltInAgentId.AIAssistant);
+if (agent is null)
+{
+    return NotFound(new { error = "Translation agent not found." });
+}
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: This suggestion correctly identifies a potential null reference exception if the agent is not found and proposes a robust error handling mechanism, improving the application's stability.

Medium
Learned
best practice
Add null checks for dependencies

Guard against embedding being null (e.g., provider not registered) before
calling methods on it, and fail fast with a clear error or fallback to a default
provider.

src/Plugins/BotSharp.Plugin.KnowledgeBase/Helpers/KnowledgeSettingHelper.cs [21-29]

 var embedding = services.GetServices<ITextEmbedding>().FirstOrDefault(x => x.Provider == provider);
+if (embedding == null)
+{
+    throw new InvalidOperationException($"No ITextEmbedding registered for provider '{provider}'.");
+}
+
 if (dimension <= 0)
 {
     dimension = GetLlmTextEmbeddingDimension(services, provider, model);
 }
 
 embedding.SetModelName(model);
 embedding.SetDimension(dimension);
 return embedding;

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 6

__

Why:
Relevant best practice - Improve defensive coding with precise null and state checks to prevent crashes and incorrect behavior.

Low
  • Update

@JackJiang1234
Copy link
Contributor

reviewed

@yileicn yileicn merged commit 1a92557 into SciSharp:master Dec 24, 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.

2 participants