Skip to content

Conversation

iceljc
Copy link
Collaborator

@iceljc iceljc commented Oct 22, 2025

PR Type

Enhancement


Description

  • Replace LlmConfigOptions with new LlmConfigFilter for flexible model filtering

  • Introduce LlmModelCapability enum replacing ImageGeneration boolean property

  • Add Capabilities list to LlmModelSetting for granular capability tracking

  • Extend LlmModelType enum with All and Web types

  • Update configuration files with model capabilities metadata

  • Refactor method signatures to use capabilities instead of boolean flags


Diagram Walkthrough

flowchart LR
  A["LlmConfigOptions<br/>deprecated"] -->|"replaced by"| B["LlmConfigFilter<br/>new filter class"]
  C["ImageGeneration<br/>boolean"] -->|"replaced by"| D["LlmModelCapability<br/>enum"]
  E["LlmModelSetting"] -->|"adds"| F["Capabilities list"]
  B -->|"filters by"| G["Providers, ModelIds,<br/>ModelNames, Types,<br/>Capabilities, MultiModal"]
  H["CompletionProvider"] -->|"uses"| B
  I["LlmProviderService"] -->|"implements"| B
Loading

File Walkthrough

Relevant files
Enhancement
7 files
LlmConfigFilter.cs
New filter class for LLM configuration queries                     
+13/-0   
ILlmProviderService.cs
Update interface with new filter and capabilities parameters
+3/-2     
LlmConfigOptions.cs
Remove deprecated LlmConfigOptions class                                 
+0/-8     
LlmModelSetting.cs
Add capabilities list and remove ImageGeneration property
+21/-6   
CompletionProvider.cs
Refactor method signatures and replace imageGenerate with capabilities
+20/-13 
LlmProviderService.cs
Implement new filter logic and capabilities-based filtering
+40/-17 
LlmProviderController.cs
Update API endpoints to use new filter and model type parameters
+6/-4     
Formatting
1 files
CrontabWatcher.cs
Simplify boolean comparison syntax                                             
+2/-1     
Configuration changes
1 files
appsettings.json
Add capabilities metadata to all model configurations       
+69/-10 

@iceljc iceljc marked this pull request as draft October 22, 2025 21:57
@qodo-merge-pro
Copy link

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 <!-- /create_ticket --create_ticket=true -->

</details></td></tr>
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
No custom compliance provided

Follow the guide to enable custom compliance check.

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

@qodo-merge-pro
Copy link

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Prevent crash when no models match

Prevent a potential ArgumentOutOfRangeException in GetProviderModel by checking
if the filtered models collection is empty. If it is, return null instead of
attempting to select an element, which would cause a crash.

src/Infrastructure/BotSharp.Core/Infrastructures/LlmProviderService.cs [61-69]

 if (capabilities != null)
 {
     models = models.Where(x => x.Capabilities != null && capabilities.Any(y => x.Capabilities.Contains(y)));
 }
 
+var availableModels = models.ToList();
+if (!availableModels.Any())
+{
+    return null;
+}
+
 var random = new Random();
-var index = random.Next(0, models.Count());
-var modelSetting = models.ElementAt(index);
+var index = random.Next(0, availableModels.Count);
+var modelSetting = availableModels.ElementAt(index);
 return modelSetting;
  • Apply / Chat
Suggestion importance[1-10]: 9

__

Why: This suggestion correctly identifies a bug that will cause an ArgumentOutOfRangeException if no models match the filter criteria, leading to a runtime crash. The proposed fix aligns with the expected nullable return type, as evidenced by the null-conditional access (?.Name) at its call site.

High
Correctly handle 'All' model type filter

In GetLlmProviderModels, handle the LlmModelType.All case for the modelType
query parameter. Add a condition to return the entire list of models without
filtering when modelType is LlmModelType.All.

src/Infrastructure/BotSharp.OpenAPI/Controllers/LlmProviderController.cs [26-31]

 [HttpGet("/llm-provider/{provider}/models")]
 public IEnumerable<LlmModelSetting> GetLlmProviderModels([FromRoute] string provider, [FromQuery] LlmModelType modelType = LlmModelType.Chat)
 {
     var list = _llmProvider.GetProviderModels(provider);
+    if (modelType == LlmModelType.All)
+    {
+        return list;
+    }
     return list.Where(x => x.Type == modelType);
 }
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: This suggestion correctly identifies a logic flaw where the newly added LlmModelType.All enum member would not work as intended. The fix correctly implements the "select all" behavior, which is crucial for the usability of the new query parameter.

Medium
High-level
Refine capability filtering logic

The suggestion proposes enhancing LlmConfigFilter to support both "any" (OR) and
"all" (AND) logic when filtering models by capabilities. This would make the
filtering more robust for different use cases.

Examples:

src/Infrastructure/BotSharp.Core/Infrastructures/LlmProviderService.cs [151]
                models = models.Where(x => x.Capabilities != null && filter.ModelCapabilities.Any(y => x.Capabilities.Contains(y)));
src/Infrastructure/BotSharp.Core/Infrastructures/LlmProviderService.cs [63]
            models = models.Where(x => x.Capabilities != null && capabilities.Any(y => x.Capabilities.Contains(y)));

Solution Walkthrough:

Before:

// In LlmProviderService.cs
public List<LlmProviderSetting> GetLlmConfigs(LlmConfigFilter? filter = null)
{
    // ...
    IEnumerable<LlmModelSetting> models = provider.Models ?? [];
    // ...
    if (filter.ModelCapabilities != null)
    {
        // Only checks if a model has ANY of the requested capabilities
        models = models.Where(x => x.Capabilities != null && 
                              filter.ModelCapabilities.Any(y => x.Capabilities.Contains(y)));
    }
    // ...
    return configs;
}

After:

// In LlmConfigFilter.cs
public class LlmConfigFilter
{
    // ...
    public List<LlmModelCapability>? ModelCapabilities { get; set; }
    public bool MatchAllCapabilities { get; set; } // New property
}

// In LlmProviderService.cs
public List<LlmProviderSetting> GetLlmConfigs(LlmConfigFilter? filter = null)
{
    // ...
    if (filter.ModelCapabilities != null)
    {
        if (filter.MatchAllCapabilities) { // AND logic
            models = models.Where(x => x.Capabilities != null && filter.ModelCapabilities.All(y => x.Capabilities.Contains(y)));
        } else { // OR logic (current behavior)
            models = models.Where(x => x.Capabilities != null && filter.ModelCapabilities.Any(y => x.Capabilities.Contains(y)));
        }
    }
    // ...
}
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies that the new capability filtering only supports "OR" logic (Any) and proposes adding "AND" logic, which is a significant design improvement that greatly enhances the flexibility of the new LlmConfigFilter.

Medium
General
Use case-insensitive model ID filtering

Update the model ID filtering logic in GetLlmConfigs to be case-insensitive. Use
StringComparer.OrdinalIgnoreCase when checking if filter.ModelIds contains a
model's ID to ensure consistent and robust filtering.

src/Infrastructure/BotSharp.Core/Infrastructures/LlmProviderService.cs [139-142]

 if (filter.ModelIds != null)
 {
-    models = models.Where(x => filter.ModelIds.Contains(x.Id));
+    models = models.Where(x => filter.ModelIds.Contains(x.Id, StringComparer.OrdinalIgnoreCase));
 }
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: The suggestion improves robustness by making the model ID filtering case-insensitive, which is consistent with how ModelNames are filtered in the same method. This enhances usability and prevents unexpected filtering failures due to casing differences.

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