Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@iceljc
Copy link
Collaborator

@iceljc iceljc commented Oct 30, 2025

PR Type

Enhancement, Refactoring


Description

  • Code execution and rule engine improvements: Implemented code-based rule trigger execution with TriggerCodeScript method, refactored code execution context from CodeInstructContext to CodeExecutionContext, and updated hook signatures to use CodeExecutionResponseModel

  • Token management system: Added comprehensive token management service with JWT generation, validation, token renewal, and third-party authentication hook support

  • Knowledge base document handling: Refactored document upload to use FileKnowledgeWrapper and FileKnowledgeModel, extracted file processing logic into reusable HandleKnowledgeFiles method, and changed parameters from ChunkOption to KnowledgeDocOptions

  • Agent code script improvements: Changed GetAgentCodeScript return type from string? to AgentCodeScript? to return full domain objects with metadata, renamed CodeProcessOptions to CodeGenHandleOptions for clarity

  • Template rendering enhancements: Renamed GetAgentTemplate to RenderAgentTemplate with data parameter support, added RenderText method for dynamic content rendering across file instruction services

  • Property naming standardization: Updated ImageConvertProvider to ImageConverter consistently across controllers and view models, updated JSON property names accordingly

  • Python interpreter improvements: Added thread ID capture, cancellation token handling for graceful interruption, and updated provider constants to use BuiltInCodeProcessor.PyInterpreter

  • MongoDB indexing: Added CreateAgentCodeScriptIndex method with indexes on AgentId, Name, and ScriptType, extracted common index creation logic into helper method

  • Rule trigger interface enhancements: Added OutputArgs and Statement properties to IRuleTrigger, updated GetRuleTriggers endpoint to return AgentRuleViewModel with enhanced trigger information

  • Code execution logging: Added AfterCodeExecution hook implementation for logging code execution results with processor, script name, and arguments

  • User service refactoring: Converted UserService to partial class, added token renewal endpoint with improved authorization header parsing

  • Code execution concurrency: Improved semaphore handling with DEFAULT_MAX_CONCURRENCY constant and proper resource management

  • Instruction log filtering: Added regex-based SimilarTemplateName filter support with case-insensitive pattern matching

  • File handle options simplification: Changed FileHandleOptions to inherit from LlmConfigBase to reduce duplication


Diagram Walkthrough

flowchart LR
  A["Rule Engine"] -->|"Code Execution"| B["RuleEngine.TriggerCodeScript"]
  C["Token Management"] -->|"JWT Generation"| D["UserService.Token"]
  E["Knowledge Base"] -->|"Document Upload"| F["KnowledgeService.Document"]
  B -->|"Uses"| G["CodeExecutionContext"]
  D -->|"Supports"| H["IAuthenticationHook"]
  F -->|"Uses"| I["FileKnowledgeHandleOptions"]
  J["Agent Code Scripts"] -->|"Returns Full Object"| K["AgentCodeScript Model"]
  L["Template Rendering"] -->|"Enhanced with Data"| M["RenderAgentTemplate"]
  N["Python Interpreter"] -->|"Cancellation Support"| O["Thread Management"]
Loading

File Walkthrough

Relevant files
Enhancement
18 files
KnowledgeService.Document.cs
Refactor knowledge document upload with wrapper models     

src/Plugins/BotSharp.Plugin.KnowledgeBase/Services/KnowledgeService.Document.cs

  • Refactored document upload to use FileKnowledgeWrapper and
    FileKnowledgeModel for better knowledge handling
  • Extracted file processing logic into new HandleKnowledgeFiles method
    for code reuse
  • Changed parameter from ChunkOption to KnowledgeDocOptions for more
    flexible configuration
  • Replaced direct VectorPayloadValue.BuildStringValue() calls with
    implicit cast operators
  • Removed unused database and user ID retrieval from main upload flow
+153/-85
UserService.Token.cs
Add token management service implementation                           

src/Infrastructure/BotSharp.Core/Users/Services/UserService.Token.cs

  • New file containing token management methods including GetToken,
    RenewToken, ActiveUser, and GetAffiliateToken
  • Implements JWT token generation and validation with configurable
    expiration
  • Supports third-party authentication hooks for extensible
    authentication
  • Handles token refresh with JWT validation and user verification
+381/-0 
RuleEngine.cs
Implement code-based rule trigger execution                           

src/Infrastructure/BotSharp.Core.Rules/Engines/RuleEngine.cs

  • Added code script execution support for rule triggers with
    TriggerCodeScript method
  • Integrated CodingSettings and code processor services for dynamic rule
    evaluation
  • Changed method signature to accept RuleTriggerOptions for code-based
    trigger configuration
  • Added error handling and logging for code execution failures
  • Refactored to use ICodeProcessor for executing trigger validation
    scripts
+149/-29
FileInstructService.Image.cs
Enhance template rendering with data context                         

src/Infrastructure/BotSharp.Core/Files/Services/Instruct/FileInstructService.Image.cs

  • Renamed GetAgentTemplate to RenderAgentTemplate with data parameter
    support
  • Added RenderText method for template rendering of user input text
  • Updated property name from ImageConvertProvider to ImageConverter
    throughout
  • Enhanced template rendering with data context for dynamic content
+14/-9   
MongoDbContext.cs
Add MongoDB indexes for agent code scripts                             

src/Plugins/BotSharp.Plugin.MongoStorage/MongoDbContext.cs

  • Added CreateAgentCodeScriptIndex method to create indexes on AgentId,
    Name, and ScriptType
  • Extracted common index creation logic into CreateIndex helper method
  • Updated AgentCodeScripts property to use new index creation method
  • Improved code organization and reduced duplication in index management
+38/-14 
PyCodeInterpreter.cs
Improve Python interpreter with cancellation support         

src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyCodeInterpreter.cs

  • Updated provider constant to use BuiltInCodeProcessor.PyInterpreter
  • Added Python thread ID capture and cancellation token handling for
    graceful interruption
  • Improved code generation with ProgrammingLanguage property support
  • Enhanced error handling during Python execution cancellation
+22/-8   
InstructionLogHook.cs
Add code execution logging hook                                                   

src/Infrastructure/BotSharp.Logger/Hooks/InstructionLogHook.cs

  • Added AfterCodeExecution hook implementation for logging code
    execution results
  • Extracted logging enablement check into IsLoggingEnabled helper method
  • Logs code processor, script name, execution result, and arguments
  • Improved code organization and reduced duplication
+41/-5   
FileRepository.AgentCodeScript.cs
Return full AgentCodeScript object with metadata                 

src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.AgentCodeScript.cs

  • Changed GetAgentCodeScript return type from string? to
    AgentCodeScript?
  • Now returns full AgentCodeScript object with metadata including
    CreatedTime and UpdatedTime
  • Improved null checking and error handling
+13/-4   
UserController.cs
Add token renewal endpoint                                                             

src/Infrastructure/BotSharp.OpenAPI/Controllers/User/UserController.cs

  • Added new /renew-token endpoint for token refresh functionality
  • Improved authorization header parsing with
    StringSplitOptions.RemoveEmptyEntries
  • Added support for RenewTokenModel with refresh and access tokens
+23/-1   
CodeScriptExecutor.cs
Improve code execution concurrency handling                           

src/Infrastructure/BotSharp.Core/Coding/CodeScriptExecutor.cs

  • Added DEFAULT_MAX_CONCURRENCY constant for clarity
  • Moved WaitAsync call inside try block for proper resource management
  • Improved semaphore initialization with configurable max concurrency
+5/-4     
AgentRuleViewModel.cs
Add agent rule view model                                                               

src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/View/AgentRuleViewModel.cs

  • New file defining view model for agent rule triggers with JSON
    serialization
  • Includes trigger name, channel, statement, and output arguments
  • Provides formatted JSON representation of arguments
+35/-0   
FileKnowledgeHandleOptions.cs
Add file knowledge handling options                                           

src/Infrastructure/BotSharp.Abstraction/Knowledges/Options/FileKnowledgeHandleOptions.cs

  • New file defining options for file knowledge handling
  • Extends LlmConfigBase with agent ID, instruction, user message, and
    template support
  • Includes data dictionary for template rendering
+34/-0   
MongoRepository.AgentCodeScript.cs
Return full AgentCodeScript from MongoDB                                 

src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.AgentCodeScript.cs

  • Changed GetAgentCodeScript return type from string? to
    AgentCodeScript?
  • Now returns full domain model object instead of just content string
+2/-2     
FileRepository.Log.cs
Add regex-based template name filtering                                   

src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Log.cs

  • Added SimilarTemplateName filter support with regex matching
  • Improved instruction log filtering with case-insensitive pattern
    matching
+7/-0     
IAuthenticationHook.cs
Add token renewal to authentication hook                                 

src/Infrastructure/BotSharp.Abstraction/Users/IAuthenticationHook.cs

  • Added RenewAuthentication method for token refresh support
  • Provides extensibility for third-party authentication providers
+9/-0     
AgentController.Rule.cs
Enhance rule trigger endpoint response                                     

src/Infrastructure/BotSharp.OpenAPI/Controllers/Agent/AgentController.Rule.cs

  • Updated GetRuleTriggers to return AgentRuleViewModel instead of
    AgentRule
  • Enhanced response with trigger channel, statement, and output
    arguments
  • Improved rule trigger information display
+7/-4     
IFileProcessor.cs
Add file knowledge extraction interface                                   

src/Infrastructure/BotSharp.Abstraction/Files/Proccessors/IFileProcessor.cs

  • Added GetFileKnowledgeAsync method for extracting knowledge from files
  • Supports file knowledge handling with options
+5/-0     
IRuleTrigger.cs
Enhance rule trigger interface                                                     

src/Infrastructure/BotSharp.Abstraction/Rules/IRuleTrigger.cs

  • Added OutputArgs property for displaying default trigger arguments
  • Added Statement property for explaining trigger purpose
+12/-0   
Refactoring
17 files
UserService.cs
Convert UserService to partial class                                         

src/Infrastructure/BotSharp.Core/Users/Services/UserService.cs

  • Changed class from sealed to partial to enable code splitting across
    multiple files
+1/-296 
InstructService.Execute.cs
Refactor code execution context and hook signatures           

src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.Execute.cs

  • Updated code execution context from CodeInstructContext to
    CodeExecutionContext
  • Changed hook signatures to pass CodeExecutionResponseModel instead of
    InstructResult
  • Improved error handling in code execution with try-catch blocks
  • Refactored code execution configuration extraction into helper method
  • Updated code processor provider constant to use
    BuiltInCodeProcessor.PyInterpreter
+28/-40 
InstructModeController.Image.cs
Update image converter property naming                                     

src/Infrastructure/BotSharp.OpenAPI/Controllers/Instruct/InstructModeController.Image.cs

  • Updated all references from ImageConvertProvider to ImageConverter
    property
  • Consistent naming across multiple image operation endpoints
+7/-7     
FileInstructService.cs
Refactor template rendering methods                                           

src/Infrastructure/BotSharp.Core/Files/Services/Instruct/FileInstructService.cs

  • Renamed GetAgentTemplate to RenderAgentTemplate with optional data
    parameter
  • Added RenderText method for rendering user input with template data
  • Updated GetImageConverter default provider from file-handler to
    image-handler
  • Improved template rendering with data context support
+17/-7   
AgentService.Coding.cs
Update code script retrieval and options naming                   

src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.Coding.cs

  • Changed GetAgentCodeScript return type from string? to
    AgentCodeScript?
  • Renamed CodeProcessOptions to CodeGenHandleOptions for clarity
  • Updated code processor provider constant to use
    BuiltInCodeProcessor.PyInterpreter
+4/-3     
PyProgrammerFn.cs
Update Python programmer function configuration                   

src/Plugins/BotSharp.Plugin.PythonInterpreter/Functions/PyProgrammerFn.cs

  • Updated code processor provider constant to use
    BuiltInCodeProcessor.PyInterpreter
  • Refactored code execution configuration extraction into helper method
  • Changed default timeout from 3 to 10 seconds
+7/-7     
InstructBaseRequest.cs
Standardize image converter property naming                           

src/Infrastructure/BotSharp.OpenAPI/ViewModels/Instructs/Request/InstructBaseRequest.cs

  • Renamed ImageConvertProvider property to ImageConverter across
    multiple request classes
  • Updated JSON property names from image_convert_provider to
    image_converter
+8/-8     
FileInstructService.Pdf.cs
Update PDF service with template rendering                             

src/Infrastructure/BotSharp.Core/Files/Services/Instruct/FileInstructService.Pdf.cs

  • Updated property name from ImageConvertProvider to ImageConverter
  • Added RenderText method call for text template rendering with data
    context
+3/-2     
InstructModeController.File.cs
Update file instruction controller property naming             

src/Infrastructure/BotSharp.OpenAPI/Controllers/Instruct/InstructModeController.File.cs

  • Updated property name from ImageConvertProvider to ImageConverter in
    PDF endpoints
+2/-2     
KnowledgeBaseController.cs
Update knowledge base upload parameters                                   

src/Infrastructure/BotSharp.OpenAPI/Controllers/KnowledgeBase/KnowledgeBaseController.cs

  • Changed parameter from ChunkOption to KnowledgeDocOptions for document
    upload
  • Updated endpoint route from /form-upload to /form
  • Improved parameter naming consistency across upload methods
+7/-5     
IAgentService.cs
Update agent service interface signatures                               

src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs

  • Changed GetAgentCodeScript return type from string? to
    AgentCodeScript?
  • Renamed CodeProcessOptions to CodeGenHandleOptions in interface
+3/-3     
IInstructHook.cs
Refactor instruction hook signatures                                         

src/Infrastructure/BotSharp.Abstraction/Instructs/IInstructHook.cs

  • Updated hook signatures to use CodeExecutionContext instead of
    CodeInstructContext
  • Changed AfterCodeExecution parameter from InstructResult to
    CodeExecutionResponseModel
  • Removed RoleDialogModel and message parameters from code execution
    hooks
+4/-3     
IUserService.cs
Update user service token renewal interface                           

src/Infrastructure/BotSharp.Abstraction/Users/IUserService.cs

  • Added RenewToken method with refresh and access token parameters
  • Removed old RenewToken method without parameters
+1/-1     
FileHandleOptions.cs
Simplify file handle options inheritance                                 

src/Infrastructure/BotSharp.Abstraction/Files/Options/FileHandleOptions.cs

  • Changed to inherit from LlmConfigBase instead of defining properties
    directly
  • Removed duplicate LLM configuration properties
+1/-21   
IBotSharpRepository.cs
Update repository interface for code scripts                         

src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs

  • Changed GetAgentCodeScript return type from string? to
    AgentCodeScript?
+1/-1     
AgentController.Coding.cs
Update code generation state management                                   

src/Infrastructure/BotSharp.OpenAPI/Controllers/Agent/AgentController.Coding.cs

  • Added state setting for code_processor configuration
  • Updated property name from Language to ProgrammingLanguage
+2/-1     
FileInstructService.Audio.cs
Update audio service template rendering                                   

src/Infrastructure/BotSharp.Core/Files/Services/Instruct/FileInstructService.Audio.cs

  • Updated method call from GetAgentTemplate to RenderAgentTemplate
  • Added RenderText method call for text template rendering
+6/-2     
Configuration changes
2 files
Using.cs
Add rules options to global usings                                             

src/Infrastructure/BotSharp.Abstraction/Using.cs

  • Added global using for BotSharp.Abstraction.Rules.Options
+1/-0     
BotSharp.Core.csproj
Reorganize and consolidate agent configuration file references

src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj

  • Reorganized and consolidated agent data file references by grouping
    them by agent ID with blank line separators
  • Removed duplicate entries (e.g., duplicate
    instruction.simulator.liquid for agent
    dfd9b46d-d00c-40af-8a75-3fbdc2b89869)
  • Added new function and template file references for agents
    01e2fc5c-2c89-4ec7-8470-7688608b496c,
    6745151e-6d46-4a02-8de4-1c4f21c7da95, and
    c2a2faf6-b8b5-47fe-807b-f4714cf25dd4
  • Reordered file entries to improve readability and maintainability of
    the project file structure
+80/-65 
Additional files
29 files
AgentCodeScript.cs +3/-0     
CodeExecutionContext.cs +7/-0     
BuiltInCodeProcessor.cs +6/-0     
CodeExecutionResponseModel.cs +10/-0   
CodeGenHandleOptions.cs +1/-1     
CodeGenerationOptions.cs +3/-4     
CodeInterpretResponse.cs +1/-1     
CodingSettings.cs +1/-1     
CodeInstructContext.cs +0/-8     
InstructHookBase.cs +12/-0   
InstructOptions.cs +1/-1     
IKnowledgeService.cs +2/-1     
FileKnowledgeModel.cs +18/-0   
KnowledgeFileModel.cs +1/-1     
KnowledgeDocOptions.cs +6/-0     
FileKnowledgeResponse.cs +6/-0     
InstructLogFilter.cs +1/-0     
IRuleEngine.cs +11/-1   
RuleTriggerOptions.cs +26/-0   
rule-trigger-code-generate_instruction.liquid +15/-0   
AgentCodeScriptGenerationRequest.cs +1/-1     
VectorKnowledgeUploadRequest.cs +2/-2     
RenewTokenModel.cs +12/-0   
StreamingLogHook.cs +0/-1     
KnowledgeSettingHelper.cs +0/-1     
AgentCodeScriptDocument.cs +3/-1     
MongoRepository.Log.cs +4/-0     
Using.cs +3/-0     
appsettings.json +43/-0   

@iceljc iceljc marked this pull request as draft October 30, 2025 17:05
@qodo-code-review
Copy link

qodo-code-review bot commented Oct 30, 2025

PR Compliance Guide 🔍

(Compliance updated until commit dfbedf6)

Below is a summary of compliance checks for this PR:

Security Compliance
🔴
Weak password hashing

Description: Basic authentication decodes base64 credentials and compares MD5(password+salt), which is
a weak hashing scheme and susceptible to brute-force and collision attacks; consider using
a strong password hashing algorithm like bcrypt/Argon2/PBKDF2.
UserService.Token.cs [14-41]

Referred Code
public async Task<Token?> GetToken(string authorization)
{
    var base64 = Encoding.UTF8.GetString(Convert.FromBase64String(authorization));
    var (id, password, regionCode) = base64.SplitAsTuple(":");

    var db = _services.GetRequiredService<IBotSharpRepository>();
    var record = id.Contains("@") ? db.GetUserByEmail(id) : db.GetUserByUserName(id);
    if (record == null)
    {
        record = db.GetUserByPhone(id, regionCode: regionCode);
    }

    if (record != null && record.Type == UserType.Affiliate)
    {
        return default;
    }

    var hooks = _services.GetServices<IAuthenticationHook>();
    //verify password is correct or not.
    if (record != null && !hooks.Any())
    {


 ... (clipped 7 lines)
Refresh token validation

Description: Token renewal accepts a refresh token and validates with ValidateLifetime=false allowing
expired tokens to be accepted without additional checks, which risks replay; ensure
refresh tokens are stored/rotated server-side or lifetime validated with proper
revocation.
UserService.Token.cs [116-166]

Referred Code
try
{
    User? user = null;

    var hooks = _services.GetServices<IAuthenticationHook>();
    foreach (var hook in hooks)
    {
        user = await hook.RenewAuthentication(refreshToken, accessToken);
        if (user != null)
        {
            break;
        }
    }

    if (user == null)
    {
        // Validate the incoming JWT (signature, issuer, audience, lifetime)
        var config = _services.GetRequiredService<IConfiguration>();
        var validationParameters = new TokenValidationParameters
        {
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(config["Jwt:Key"])),


 ... (clipped 30 lines)
Arbitrary code execution

Description: Executes arbitrary Python code from scripts with process/in-GIL execution and only soft
interrupt on cancellation, which can allow harmful code execution if inputs are not
strictly controlled; sandboxing and strict allowlists are needed.
PyCodeInterpreter.cs [161-177]

Referred Code
try
{
    // Capture the Python thread ID for the current thread executing under the GIL
    var pythonThreadId = PythonEngine.GetPythonThreadID();
    using var reg = cancellationToken.Register(() =>
    {
        try
        {
            PythonEngine.Interrupt(pythonThreadId);
            _logger.LogWarning($"Cancellation requested: issued PythonEngine.Interrupt for thread {pythonThreadId} (request {requestId})");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to interrupt Python execution on cancellation.");
        }
    });
Token endpoint hardening

Description: Renew token endpoint accepts bearer-like refresh tokens from clients without CSRF
protection and may parse tokens from an arbitrary string; ensure HTTPS, CSRF mitigations
for browser contexts, and strict header parsing/validation.
UserController.cs [49-69]

Referred Code
[AllowAnonymous]
[HttpPost("/renew-token")]
public async Task<ActionResult<Token>> RenewToken([FromBody] RenewTokenModel request)
{
    request ??= new();
    if (request.RefreshToken?.Contains(" ") == true)
    {
        request.RefreshToken = request.RefreshToken?.Split(' ', StringSplitOptions.RemoveEmptyEntries)?.LastOrDefault() ?? string.Empty;
    }
    if (request.AccessToken?.Contains(" ") == true)
    {
        request.AccessToken = request.AccessToken?.Split(' ', StringSplitOptions.RemoveEmptyEntries)?.LastOrDefault();
    }

    var newToken = await _userService.RenewToken(request.RefreshToken, request.AccessToken);
    if (newToken == null)
    {
        return Unauthorized();
    }
    return Ok(newToken);
}
Prompt injection risk

Description: Template rendering merges user-supplied data into templates which could enable prompt
injection if later sent to LLMs; sanitize/escape or constrain data sources.
FileInstructService.cs [84-92]

Referred Code
{
    var agentService = _services.GetRequiredService<IAgentService>();
    var render = _services.GetRequiredService<ITemplateRender>();

    var renderData = data != null
                    ? new Dictionary<string, object>(data)
                    : agentService.CollectRenderData(new Agent());
    return render.Render(text, renderData);
}
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: Passed

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

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

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

🔴
Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Weak Hashing: Password verification uses MD5 hashing with salt which is considered insecure by modern
standards and risks credential compromise.

Referred Code
var hooks = _services.GetServices<IAuthenticationHook>();
//verify password is correct or not.
if (record != null && !hooks.Any())
{
    var hashPassword = Utilities.HashTextMd5($"{password}{record.Salt}");
    if (hashPassword != record.Password)
    {
        return default;
    }

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

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
Partial Coverage: New code execution and instruction rendering paths add significant critical actions, and
while a new AfterCodeExecution log was added, other critical events (e.g., token renewal,
rule trigger decisions) may not be consistently logged with user and outcome context.

Referred Code
public override async Task AfterCodeExecution(Agent agent, CodeExecutionResponseModel response)
{
    if (response == null || !IsLoggingEnabled(agent?.Id))
    {
        return;
    }

    var db = _services.GetRequiredService<IBotSharpRepository>();
    var codeScriptVersion = response.CodeScript?.UpdatedTime ?? DateTime.UtcNow;
    var user = db.GetUserById(_user.Id);

    db.SaveInstructionLogs(new List<InstructionLogModel>
    {
        new InstructionLogModel
        {
            AgentId = agent?.Id,
            Provider = response.CodeProcessor,
            Model = string.Empty,
            TemplateName = response.CodeScript?.Name,
            UserMessage = response.Text,
            SystemInstruction = $"Code script name: {response.CodeScript}, Version: {codeScriptVersion.ToString("o")}",


 ... (clipped 17 lines)

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

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Token Errors: Token renewal and authentication paths catch and log exceptions but often return
null/default without conveying actionable context or handling edge cases like malformed
Base64 input, which may lead to silent failures.

Referred Code
try
{
    User? user = null;

    var hooks = _services.GetServices<IAuthenticationHook>();
    foreach (var hook in hooks)
    {
        user = await hook.RenewAuthentication(refreshToken, accessToken);
        if (user != null)
        {
            break;
        }
    }

    if (user == null)
    {
        // Validate the incoming JWT (signature, issuer, audience, lifetime)
        var config = _services.GetRequiredService<IConfiguration>();
        var validationParameters = new TokenValidationParameters
        {
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(config["Jwt:Key"])),


 ... (clipped 51 lines)

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

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status:
Argument Logging: RuleEngine logs code script execution with raw argument JSON text which may contain
sensitive data, risking exposure in logs depending on input content.

Referred Code
var msg = $"rule trigger ({triggerName}) code script ({scriptName}) in agent ({agent.Name}) => args: {options.ArgumentContent?.RootElement.GetRawText()}.";

if (codeScript == null || string.IsNullOrWhiteSpace(codeScript.Content))
{
    _logger.LogWarning($"Unable to find {msg}.");
    return false;
}

try
{
    var hooks = _services.GetHooks<IInstructHook>(agent.Id);

    var arguments = BuildArguments(options.ArgumentName, options.ArgumentContent);
    var context = new CodeExecutionContext
    {
        CodeScript = codeScript,
        Arguments = arguments
    };

    foreach (var hook in hooks)
    {


 ... (clipped 20 lines)

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

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

Previous compliance checks

Compliance check up to commit 8fce79d
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: Passed

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
Limited auditing: New critical actions like code script execution and rule triggering are only partially
logged (warnings/info) without consistent audit entries including user/context, making it
unclear if full audit trail requirements are met.

Referred Code
#region Private methods
private async Task<bool> TriggerCodeScript(string agentId, string triggerName, RuleTriggerOptions options)
{
    if (string.IsNullOrWhiteSpace(agentId))
    {
        return false;
    }

    var provider = options.CodeProcessor ?? BuiltInCodeProcessor.PyInterpreter;
    var processor = _services.GetServices<ICodeProcessor>().FirstOrDefault(x => x.Provider.IsEqualTo(provider));
    if (processor == null)
    {
        _logger.LogWarning($"Unable to find code processor: {provider}.");
        return false;
    }

    var agentService = _services.GetRequiredService<IAgentService>();
    var scriptName = options.CodeScriptName ?? $"{triggerName}_rule.py";
    var codeScript = await agentService.GetAgentCodeScript(agentId, scriptName, scriptType: AgentCodeScriptType.Src);

    var msg = $"rule trigger ({triggerName}) code script ({scriptName}) in agent ({agentId}) => args: {options.Arguments?.RootElement.GetRawText()}.";


 ... (clipped 54 lines)
Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Sparse error context: Exceptions from code script execution are caught and logged but without including
operation context like script name/provider/args in structured form, and earlier null
cases return false without clear upstream handling.

Referred Code
try
{
    var response = await processor.RunAsync(codeScript, options: new()
    {
        ScriptName = scriptName,
        Arguments = BuildArguments(options.ArgsName, options.Arguments)
    });

    if (response == null || !response.Success)
    {
        _logger.LogWarning($"Failed to handle {msg}");
        return false;
    }

    bool result;
    LogLevel logLevel;
    if (response.Result.IsEqualTo("true") || response.Result.IsEqualTo("1"))
    {
        logLevel = LogLevel.Information;
        result = true;
    }


 ... (clipped 16 lines)
Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status:
Args logged raw: The code logs raw arguments from JsonDocument via GetRawText which may include sensitive
data, without redaction or classification, potentially exposing secrets in logs.

Referred Code
var msg = $"rule trigger ({triggerName}) code script ({scriptName}) in agent ({agentId}) => args: {options.Arguments?.RootElement.GetRawText()}.";

if (string.IsNullOrWhiteSpace(codeScript))
{
    _logger.LogWarning($"Unable to find {msg}.");
    return false;
}

try
{
    var response = await processor.RunAsync(codeScript, options: new()
    {
        ScriptName = scriptName,
        Arguments = BuildArguments(options.ArgsName, options.Arguments)
    });

    if (response == null || !response.Success)
    {
        _logger.LogWarning($"Failed to handle {msg}");
        return false;
    }


 ... (clipped 16 lines)
Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Unvalidated input: Code script execution consumes Arguments and ArgsName without validation or sanitization,
and scriptName defaults from triggerName without normalization, which may pose
injection/path risks depending on downstream implementations.

Referred Code
#region Private methods
private async Task<bool> TriggerCodeScript(string agentId, string triggerName, RuleTriggerOptions options)
{
    if (string.IsNullOrWhiteSpace(agentId))
    {
        return false;
    }

    var provider = options.CodeProcessor ?? BuiltInCodeProcessor.PyInterpreter;
    var processor = _services.GetServices<ICodeProcessor>().FirstOrDefault(x => x.Provider.IsEqualTo(provider));
    if (processor == null)
    {
        _logger.LogWarning($"Unable to find code processor: {provider}.");
        return false;
    }

    var agentService = _services.GetRequiredService<IAgentService>();
    var scriptName = options.CodeScriptName ?? $"{triggerName}_rule.py";
    var codeScript = await agentService.GetAgentCodeScript(agentId, scriptName, scriptType: AgentCodeScriptType.Src);

    var msg = $"rule trigger ({triggerName}) code script ({scriptName}) in agent ({agentId}) => args: {options.Arguments?.RootElement.GetRawText()}.";


 ... (clipped 22 lines)

@qodo-code-review
Copy link

qodo-code-review bot commented Oct 30, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Consider a more flexible rule evaluation

The current rule engine only triggers based on code script execution. It should
be enhanced to also support the previous method of using an LLM to evaluate
natural language criteria, making the engine more versatile.

Examples:

src/Infrastructure/BotSharp.Core.Rules/Engines/RuleEngine.cs [43-56]
        foreach (var agent in filteredAgents)
        {
            var isTriggered = true;

            // Code trigger
            if (options != null)
            {
                isTriggered = await TriggerCodeScript(agent.Id, trigger.Name, options);
            }


 ... (clipped 4 lines)

Solution Walkthrough:

Before:

// In RuleEngine.cs
public async Task<IEnumerable<string>> Trigger(IRuleTrigger trigger, string text, RuleTriggerOptions? options = null)
{
    // ... get agents ...
    foreach (var agent in filteredAgents)
    {
        var isTriggered = true;

        // Trigger is determined ONLY by code script execution.
        if (options != null)
        {
            isTriggered = await TriggerCodeScript(agent.Id, trigger.Name, options);
        }

        if (isTriggered)
        {
            // Create new conversation...
        }
    }
    return newConversationIds;
}

After:

// In RuleEngine.cs
public async Task<IEnumerable<string>> Trigger(IRuleTrigger trigger, string text, RuleTriggerOptions? options = null)
{
    // ... get agents ...
    foreach (var agent in filteredAgents)
    {
        bool isTriggered = false;

        // Support both code-based and natural language-based rule evaluation.
        if (options != null && !string.IsNullOrEmpty(options.CodeScriptName))
        {
            isTriggered = await TriggerCodeScript(agent.Id, trigger.Name, options);
        }
        else // Fallback to natural language evaluation
        {
            isTriggered = await EvaluateNaturalLanguageCriteria(agent, text);
        }

        if (isTriggered)
        {
            // Create new conversation...
        }
    }
    return newConversationIds;
}
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies that the PR replaces a flexible, LLM-based rule evaluation with a code-only approach, and proposes a more versatile design supporting both, which would significantly enhance the rule engine's power and usability.

Medium
Possible issue
Dispose JsonDocument to prevent memory leaks

In the BuildArguments method, wrap the JsonDocument parameter args in a using
statement to ensure it is properly disposed and prevent potential memory leaks.

src/Infrastructure/BotSharp.Core.Rules/Engines/RuleEngine.cs [157-165]

 private IEnumerable<KeyValue> BuildArguments(string? argName, JsonDocument? args)
 {
     var keyValues = new List<KeyValue>();
     if (args != null)
     {
-        keyValues.Add(new KeyValue(argName ?? "rule_args", args.RootElement.GetRawText()));
+        using (args)
+        {
+            keyValues.Add(new KeyValue(argName ?? "rule_args", args.RootElement.GetRawText()));
+        }
     }
     return keyValues;
 }
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies a potential memory leak by not disposing the JsonDocument instance and provides a valid fix, improving resource management.

Medium
General
Improve fallback logic for LLM configuration

Improve the GetLlmProviderModel method's fallback logic. Before resorting to
hardcoded values, attempt to use the agent's default LLM configuration from
_agentSettings.LlmConfig.

src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyCodeInterpreter.cs [186-200]

 private (string, string) GetLlmProviderModel()
 {
     var provider = _agentSettings.Coding?.Provider;
     var model = _agentSettings.Coding?.Model;
 
     if (!string.IsNullOrEmpty(provider) && !string.IsNullOrEmpty(model))
     {
         return (provider, model);
     }
 
-    provider = "openai";
-    model = "gpt-5-mini";
+    // Fallback to agent's default LLM config
+    if (!string.IsNullOrEmpty(_agentSettings.LlmConfig?.Provider) && !string.IsNullOrEmpty(_agentSettings.LlmConfig?.Model))
+    {
+        return (_agentSettings.LlmConfig.Provider, _agentSettings.LlmConfig.Model);
+    }
 
-    return (provider, model);
+    // Fallback to hardcoded values if no config is available
+    return ("openai", "gpt-5-mini");
 }
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: The suggestion proposes a more robust fallback mechanism by using the agent's general LLM configuration before resorting to hardcoded values, which improves the configuration logic's flexibility and consistency.

Low
Learned
best practice
Cache default JsonDocument

Avoid parsing a new JsonDocument on every property access and return a cached,
safely created instance. Guard against exceptions and unnecessary allocations.

src/Infrastructure/BotSharp.Abstraction/Rules/IRuleTrigger.cs [18]

-JsonDocument OutputArgs => JsonDocument.Parse("{}");
+private static readonly JsonDocument EmptyArgs = JsonDocument.Parse("{}");
+JsonDocument OutputArgs => EmptyArgs;
  • Apply / Chat
Suggestion importance[1-10]: 5

__

Why:
Relevant best practice - Ensure nullability guards before property access and default to safe fallbacks when inputs can be missing.

Low
  • More

@iceljc iceljc marked this pull request as ready for review November 12, 2025 22:39
@iceljc iceljc merged commit ff08a39 into SciSharp:master Nov 12, 2025
4 checks passed
@qodo-code-review
Copy link

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
Weak JWT validation

Description: Refresh token validation disables issuer, audience, and lifetime checks and accepts any
token signed with the configured key, which can allow reuse of expired or cross-audience
tokens if the signing key is leaked or misused.
UserService.Token.cs [134-167]

Referred Code
var validationParameters = new TokenValidationParameters
{
    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(config["Jwt:Key"])),
    ValidateIssuerSigningKey = true,
    ValidateIssuer = false,
    ValidateAudience = false,
    ValidateLifetime = false,
    ClockSkew = TimeSpan.Zero
};

var tokenHandler = new JwtSecurityTokenHandler();
var principal = tokenHandler.ValidateToken(refreshToken, validationParameters, out var validatedToken);
var userId = principal?.Claims?
    .FirstOrDefault(x => x.Type.IsEqualTo(JwtRegisteredClaimNames.NameId)
                       || x.Type.IsEqualTo(ClaimTypes.NameIdentifier)
                       || x.Type.IsEqualTo("uid")
                       || x.Type.IsEqualTo("user_id")
                       || x.Type.IsEqualTo("userId"))?.Value;

if (string.IsNullOrEmpty(userId))
{


 ... (clipped 13 lines)
Arbitrary code execution

Description: Arbitrary Python code execution with optional process-less execution may allow server
compromise if untrusted scripts are run; while interruption on cancellation is added,
sandboxing and resource limits are not apparent.
PyCodeInterpreter.cs [160-177]

Token replay risk

Description: The renew-token endpoint accepts refresh tokens without binding to client context and
strips prefixes by splitting on spaces, which could increase token replay risk without
additional checks like rotation or revocation.
UserController.cs [50-69]

Referred Code
[HttpPost("/renew-token")]
public async Task<ActionResult<Token>> RenewToken([FromBody] RenewTokenModel request)
{
    request ??= new();
    if (request.RefreshToken?.Contains(" ") == true)
    {
        request.RefreshToken = request.RefreshToken?.Split(' ', StringSplitOptions.RemoveEmptyEntries)?.LastOrDefault() ?? string.Empty;
    }
    if (request.AccessToken?.Contains(" ") == true)
    {
        request.AccessToken = request.AccessToken?.Split(' ', StringSplitOptions.RemoveEmptyEntries)?.LastOrDefault();
    }

    var newToken = await _userService.RenewToken(request.RefreshToken, request.AccessToken);
    if (newToken == null)
    {
        return Unauthorized();
    }
    return Ok(newToken);
}
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: Passed

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

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

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

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
Partial logging: New code adds logging for code execution and instruction responses, but other critical
actions like token issuance/renewal and knowledge uploads are not clearly logged with
user/context in the added code diff.

Referred Code
public override async Task AfterCodeExecution(Agent agent, CodeExecutionResponseModel response)
{
    if (response == null || !IsLoggingEnabled(agent?.Id))
    {
        return;
    }

    var db = _services.GetRequiredService<IBotSharpRepository>();
    var codeScriptVersion = response.CodeScript?.UpdatedTime ?? DateTime.UtcNow;
    var user = db.GetUserById(_user.Id);

    db.SaveInstructionLogs(new List<InstructionLogModel>
    {
        new InstructionLogModel
        {
            AgentId = agent?.Id,
            Provider = response.CodeProcessor,
            Model = string.Empty,
            TemplateName = response.CodeScript?.Name,
            UserMessage = response.Text,
            SystemInstruction = $"Code script name: {response.CodeScript}, Version: {codeScriptVersion.ToString("o")}",


 ... (clipped 18 lines)

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

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Weak error details: Token renewal and authentication paths catch exceptions and return null but do not
consistently include actionable context or validate all edge cases (e.g., malformed
base64) in the new code.

Referred Code
try
{
    User? user = null;

    var hooks = _services.GetServices<IAuthenticationHook>();
    foreach (var hook in hooks)
    {
        user = await hook.RenewAuthentication(refreshToken, accessToken);
        if (user != null)
        {
            break;
        }
    }

    if (user == null)
    {
        // Validate the incoming JWT (signature, issuer, audience, lifetime)
        var config = _services.GetRequiredService<IConfiguration>();
        var validationParameters = new TokenValidationParameters
        {
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(config["Jwt:Key"])),


 ... (clipped 51 lines)

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

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status:
Potential PII in logs: Logs include dynamic script names, trigger args raw JSON, and execution results which may
contain sensitive data without redaction in the added code.

Referred Code
var msg = $"rule trigger ({triggerName}) code script ({scriptName}) in agent ({agent.Name}) => args: {options.ArgumentContent?.RootElement.GetRawText()}.";

if (codeScript == null || string.IsNullOrWhiteSpace(codeScript.Content))
{
    _logger.LogWarning($"Unable to find {msg}.");
    return false;
}

try
{
    var hooks = _services.GetHooks<IInstructHook>(agent.Id);

    var arguments = BuildArguments(options.ArgumentName, options.ArgumentContent);
    var context = new CodeExecutionContext
    {
        CodeScript = codeScript,
        Arguments = arguments
    };

    foreach (var hook in hooks)
    {


 ... (clipped 47 lines)

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

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Token parsing trust: The new renew-token endpoint accepts refresh/access tokens from the request body and
strips prefixes, but the added code does not validate formats or rate-limit, relying on
downstream validation.

Referred Code
[AllowAnonymous]
[HttpPost("/renew-token")]
public async Task<ActionResult<Token>> RenewToken([FromBody] RenewTokenModel request)
{
    request ??= new();
    if (request.RefreshToken?.Contains(" ") == true)
    {
        request.RefreshToken = request.RefreshToken?.Split(' ', StringSplitOptions.RemoveEmptyEntries)?.LastOrDefault() ?? string.Empty;
    }
    if (request.AccessToken?.Contains(" ") == true)
    {
        request.AccessToken = request.AccessToken?.Split(' ', StringSplitOptions.RemoveEmptyEntries)?.LastOrDefault();
    }

    var newToken = await _userService.RenewToken(request.RefreshToken, request.AccessToken);
    if (newToken == null)
    {
        return Unauthorized();
    }
    return Ok(newToken);
}

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

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

@qodo-code-review
Copy link

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Security
Fix critical token validation vulnerability

Enable lifetime validation for refresh tokens by setting ValidateLifetime to
true to prevent the use of expired tokens.

src/Infrastructure/BotSharp.Core/Users/Services/UserService.Token.cs [134-142]

 var validationParameters = new TokenValidationParameters
 {
     IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(config["Jwt:Key"])),
     ValidateIssuerSigningKey = true,
     ValidateIssuer = false,
     ValidateAudience = false,
-    ValidateLifetime = false,
+    ValidateLifetime = true,
     ClockSkew = TimeSpan.Zero
 };
  • Apply / Chat
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a critical security vulnerability introduced in the PR, where expired refresh tokens could be used, and proposes the correct fix.

High
Possible issue
Ensure unique IDs for configurations

Update the duplicate Id fields in the two new provider configurations to be
unique, as they currently share the same value "gpt-4o-web".

src/WebStarter/appsettings.json [388-429]

 {
-  "Id": "gpt-4o-web",
+  "Id": "gpt-4o-search-preview",
   "Name": "gpt-4o-search-preview",
   "Version": "gpt-4o-search-preview",
   "ApiKey": "",
   "Type": "chat",
   "Capabilities": [
     "WebSearch"
   ],
   "WebSearch": {
     "SearchContextSize": "low"
   },
   ...
 },
 {
-  "Id": "gpt-4o-web",
+  "Id": "gpt-4o-mini-search-preview",
   "Name": "gpt-4o-mini-search-preview",
   "Version": "gpt-4o-mini-search-preview",
   "ApiKey": "",
   "Type": "chat",
   "Capabilities": [
     "WebSearch"
   ],
   "WebSearch": {
     "IsDefault": true,
     "SearchContextSize": "low"
   },
   ...
 }

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a critical issue where two new provider configurations share the same Id, which would likely cause configuration conflicts or runtime errors.

High
Fix incorrect Python thread interruption

Execute PythonEngine.Interrupt on a separate thread within the cancellation
token callback to ensure correct interruption of Python code execution.

src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyCodeInterpreter.cs [165-181]

 // Capture the Python thread ID for the current thread executing under the GIL
 var pythonThreadId = PythonEngine.GetPythonThreadID();
 using var reg = cancellationToken.Register(() =>
 {
-    try
+    // PythonEngine.Interrupt must be called from a different thread.
+    Task.Run(() =>
     {
-        PythonEngine.Interrupt(pythonThreadId);
-        _logger.LogWarning($"Cancellation requested: issued PythonEngine.Interrupt for thread {pythonThreadId} (request {requestId})");
-    }
-    catch (Exception ex)
-    {
-        _logger.LogError(ex, "Failed to interrupt Python execution on cancellation.");
-    }
+        try
+        {
+            PythonEngine.Interrupt(pythonThreadId);
+            _logger.LogWarning($"Cancellation requested: issued PythonEngine.Interrupt for thread {pythonThreadId} (request {requestId})");
+        }
+        catch (Exception ex)
+        {
+            _logger.LogError(ex, "Failed to interrupt Python execution on cancellation.");
+        }
+    });
 });
 
 // Redirect standard output/error to capture it
 dynamic outIO = io.StringIO();

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a subtle but important issue with thread handling when interrupting the Python engine, which could lead to deadlocks, and provides a correct fix.

Medium
Learned
best practice
Add config null checks

Guard against missing JWT key in configuration and return a safe failure instead
of throwing. Validate the key string before using it.

src/Infrastructure/BotSharp.Core/Users/Services/UserService.Token.cs [133-142]

 var config = _services.GetRequiredService<IConfiguration>();
+var jwtKey = config["Jwt:Key"];
+if (string.IsNullOrWhiteSpace(jwtKey))
+{
+    _logger.LogWarning("JWT key missing in configuration.");
+    return null;
+}
 var validationParameters = new TokenValidationParameters
 {
-    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(config["Jwt:Key"])),
+    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtKey)),
     ValidateIssuerSigningKey = true,
     ValidateIssuer = false,
     ValidateAudience = false,
     ValidateLifetime = false,
     ClockSkew = TimeSpan.Zero
 };
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why:
Relevant best practice - Ensure nullability guards before property access and default to safe fallbacks when inputs can be missing.

Low
Safeguard semaphore release

Guard against releasing a semaphore that wasn't acquired by tracking acquisition
success, preventing release mismatch on pre-wait exceptions or cancellations.

src/Infrastructure/BotSharp.Core/Coding/CodeScriptExecutor.cs [22-35]

 public async Task<T> ExecuteAsync<T>(Func<Task<T>> func, CancellationToken cancellationToken = default)
 {
+    var acquired = false;
     try
     {
         await _semLock.WaitAsync(cancellationToken);
+        acquired = true;
         return await func();
     }
     catch (Exception ex)
     {
         _logger.LogError(ex, "Failed to execute code script");
         throw;
     }
     finally
     {
-        _semLock.Release();
+        if (acquired)
+        {
+            _semLock.Release();
+        }
     }
 }

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 5

__

Why:
Relevant best practice - Validate async/locking semantics to avoid subtle concurrency bugs (ensure semaphore always released even on early failures).

Low
  • More

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