diff --git a/README.md b/README.md
index ee3b629..0d7495e 100644
--- a/README.md
+++ b/README.md
@@ -191,6 +191,61 @@ app.UseNLWebNet(); // Add NLWebNet middleware (optional)
app.MapNLWebNet(); // Map NLWebNet minimal API endpoints
```
+### Configuration Format Support
+
+NLWebNet supports multiple configuration formats for enhanced flexibility:
+
+#### YAML Configuration
+
+```csharp
+// Enable YAML configuration support
+builder.Configuration.AddNLWebConfigurationFormats(builder.Environment);
+builder.Services.AddNLWebConfigurationFormats(builder.Configuration);
+```
+
+Example YAML configuration (`config_retrieval.yaml`):
+
+```yaml
+# Multi-backend configuration
+write_endpoint: primary_backend
+endpoints:
+ primary_backend:
+ enabled: true
+ db_type: azure_ai_search
+ priority: 1
+
+# NLWeb settings
+nlweb:
+ default_mode: List
+ enable_streaming: true
+ tool_selection_enabled: true
+```
+
+#### XML Tool Definitions
+
+Define tools for the tool selection framework:
+
+```xml
+
+
+
+ Advanced search with semantic understanding
+
+ 50
+ 30
+
+
+ search for*
+ find*
+
+
+
+```
+
+#### Backward Compatibility
+
+All existing JSON configuration continues to work unchanged. See the [Configuration Format Guide](doc/configuration-format-updates.md) for detailed documentation and migration examples.
+
### Prerequisites
- .NET 9.0 SDK
diff --git a/doc/configuration-format-updates.md b/doc/configuration-format-updates.md
new file mode 100644
index 0000000..f461851
--- /dev/null
+++ b/doc/configuration-format-updates.md
@@ -0,0 +1,223 @@
+# Configuration Format Updates
+
+This document describes the new configuration format support added to NLWebNet in response to the NLWeb June 2025 release requirements.
+
+## Overview
+
+NLWebNet now supports multiple configuration formats while maintaining full backward compatibility:
+
+- **YAML Configuration**: Enhanced multi-backend configuration with `enabled` flags
+- **XML Tool Definitions**: Structured tool definitions for the tool selection framework
+- **JSON Configuration**: Existing JSON configuration format continues to work unchanged
+
+## YAML Configuration Support
+
+### Basic Usage
+
+To enable YAML configuration support in your application:
+
+```csharp
+var builder = WebApplication.CreateBuilder(args);
+
+// Add YAML configuration format support
+builder.Configuration.AddNLWebConfigurationFormats(builder.Environment);
+
+// Register configuration format services
+builder.Services.AddNLWebConfigurationFormats(builder.Configuration);
+```
+
+### YAML Configuration Format
+
+The new YAML format supports the multi-backend configuration structure introduced in June 2025:
+
+```yaml
+# config_retrieval.yaml
+write_endpoint: primary_backend
+endpoints:
+ primary_backend:
+ enabled: true
+ db_type: azure_ai_search
+ priority: 1
+ properties:
+ service_name: "nlweb-search"
+ index_name: "nlweb-index"
+ api_version: "2023-11-01"
+
+ secondary_backend:
+ enabled: true
+ db_type: mock
+ priority: 0
+ properties:
+ data_source: "sample_data"
+ enable_fuzzy_matching: true
+
+ backup_backend:
+ enabled: false
+ db_type: azure_ai_search
+ priority: -1
+ properties:
+ service_name: "nlweb-backup"
+ index_name: "nlweb-backup-index"
+
+# Multi-backend settings
+enable_parallel_querying: true
+enable_result_deduplication: true
+max_concurrent_queries: 3
+backend_timeout_seconds: 30
+
+# General NLWeb settings
+nlweb:
+ default_mode: "List"
+ enable_streaming: true
+ default_timeout_seconds: 30
+ max_results_per_query: 50
+ enable_caching: true
+ cache_expiration_minutes: 60
+ tool_selection_enabled: true
+```
+
+### Auto-Detection
+
+The configuration system automatically looks for these YAML files:
+
+- `config_retrieval.yaml` / `config_retrieval.yml`
+- `nlweb.yaml` / `nlweb.yml`
+- Environment-specific versions (e.g., `config_retrieval.Development.yaml`)
+
+### Manual YAML Loading
+
+You can also manually load YAML configuration:
+
+```csharp
+builder.Configuration.AddYamlFile("my-config.yaml", optional: true, reloadOnChange: true);
+
+// Or from a stream
+using var stream = File.OpenRead("config.yaml");
+builder.Configuration.AddYamlStream(stream);
+```
+
+## XML Tool Definitions
+
+### Tool Definition Loader Service
+
+The `IToolDefinitionLoader` service provides XML-based tool definition support:
+
+```csharp
+// Register the service (included in AddNLWebConfigurationFormats)
+builder.Services.AddSingleton();
+
+// Use the service
+var toolLoader = serviceProvider.GetRequiredService();
+var toolDefinitions = await toolLoader.LoadFromFileAsync("tool_definitions.xml");
+```
+
+### XML Tool Definition Format
+
+```xml
+
+
+
+ Advanced search capability with semantic understanding
+
+ 50
+ 30
+ true
+
+
+
+
+
+
+ search for*
+ find*
+ what is*
+
+
+ azure_ai_search
+ mock
+
+
+
+```
+
+### Tool Types
+
+Supported tool types:
+- `search` - Enhanced search capabilities
+- `details` - Retrieve specific information about items
+- `compare` - Side-by-side comparison of items
+- `ensemble` - Create cohesive sets of related items
+
+## Backward Compatibility
+
+### Existing JSON Configuration
+
+All existing JSON configuration continues to work unchanged:
+
+```json
+{
+ "NLWebNet": {
+ "DefaultMode": "List",
+ "EnableStreaming": true,
+ "MultiBackend": {
+ "Enabled": true,
+ "WriteEndpoint": "primary",
+ "Endpoints": {
+ "primary": {
+ "Enabled": true,
+ "BackendType": "azure_ai_search"
+ }
+ }
+ }
+ }
+}
+```
+
+### Migration Path
+
+1. **Phase 1**: Add YAML support alongside existing JSON
+2. **Phase 2**: Gradually migrate configuration to YAML format
+3. **Phase 3**: Optionally remove JSON configuration files (JSON support remains)
+
+No code changes are required to existing applications - the new formats are additive.
+
+## Configuration Options
+
+### ConfigurationFormatOptions
+
+Control configuration format behavior:
+
+```csharp
+builder.Services.Configure(options =>
+{
+ options.ConfigurationFormat.EnableYamlSupport = true;
+ options.ConfigurationFormat.EnableXmlToolDefinitions = true;
+ options.ConfigurationFormat.AutoDetectConfigurationFiles = true;
+ options.ConfigurationFormat.YamlConfigPath = "custom-config.yaml";
+ options.ConfigurationFormat.XmlToolDefinitionsPath = "tools.xml";
+});
+```
+
+## Examples
+
+See the demo application for complete examples:
+- `/samples/Demo/config_retrieval.yaml` - Multi-backend YAML configuration
+- `/samples/Demo/tool_definitions.xml` - XML tool definitions
+- `/samples/Demo/Program.cs` - Integration example
+
+## Dependencies
+
+The new configuration format support adds these dependencies:
+- `YamlDotNet` (16.2.1) - YAML parsing
+- `Microsoft.Extensions.Configuration.Xml` (9.0.6) - XML configuration support
+
+## Testing
+
+Comprehensive tests cover:
+- YAML parsing and configuration binding
+- XML tool definition loading and validation
+- Service registration and dependency injection
+- Backward compatibility with existing JSON configuration
+- Error handling and validation
+
+Run tests with: `dotnet test --filter "ConfigurationFormatSupportTests"`
\ No newline at end of file
diff --git a/samples/Demo/Program.cs b/samples/Demo/Program.cs
index d455d2b..e11d096 100644
--- a/samples/Demo/Program.cs
+++ b/samples/Demo/Program.cs
@@ -6,6 +6,9 @@
var builder = WebApplication.CreateBuilder(args);
+// Configure configuration with NLWeb format support
+builder.Configuration.AddNLWebConfigurationFormats(builder.Environment);
+
// Detect if running in Aspire and configure accordingly
var isAspireEnabled = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("DOTNET_ASPIRE_URLS")) ||
!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT"));
@@ -82,6 +85,9 @@
});
}
+// Add NLWeb configuration format support (YAML, XML tool definitions)
+builder.Services.AddNLWebConfigurationFormats(builder.Configuration);
+
// IMPORTANT: Override the default MockDataBackend with our enhanced version AFTER AddNLWebNet
// Use enhanced data backend with RSS feed integration and better sample data
builder.Services.AddScoped();
diff --git a/samples/Demo/config_retrieval.yaml b/samples/Demo/config_retrieval.yaml
new file mode 100644
index 0000000..7a678ec
--- /dev/null
+++ b/samples/Demo/config_retrieval.yaml
@@ -0,0 +1,55 @@
+# NLWeb Multi-Backend Configuration Example
+# This file demonstrates the YAML-style configuration format introduced in June 2025
+
+# Primary backend for write operations
+write_endpoint: primary_backend
+
+# Backend endpoint configurations
+endpoints:
+ primary_backend:
+ enabled: true
+ db_type: azure_ai_search
+ priority: 1
+ properties:
+ service_name: "nlweb-search"
+ index_name: "nlweb-index"
+ api_version: "2023-11-01"
+ # connection_string: "..." # Set via environment variables
+
+ secondary_backend:
+ enabled: true
+ db_type: mock
+ priority: 0
+ properties:
+ data_source: "sample_data"
+ enable_fuzzy_matching: true
+
+ backup_backend:
+ enabled: false
+ db_type: azure_ai_search
+ priority: -1
+ properties:
+ service_name: "nlweb-backup"
+ index_name: "nlweb-backup-index"
+
+# Multi-backend settings
+enable_parallel_querying: true
+enable_result_deduplication: true
+max_concurrent_queries: 3
+backend_timeout_seconds: 30
+
+# General NLWeb settings that can also be configured via YAML
+nlweb:
+ default_mode: "List"
+ enable_streaming: true
+ default_timeout_seconds: 30
+ max_results_per_query: 50
+ enable_caching: true
+ cache_expiration_minutes: 60
+ tool_selection_enabled: true
+
+# Tool selection configuration
+tool_selection:
+ default_tool: "search"
+ enable_auto_detection: true
+ fallback_to_search: true
\ No newline at end of file
diff --git a/samples/Demo/tool_definitions.xml b/samples/Demo/tool_definitions.xml
new file mode 100644
index 0000000..51fc548
--- /dev/null
+++ b/samples/Demo/tool_definitions.xml
@@ -0,0 +1,137 @@
+
+
+
+
+
+
+ Advanced search capability with semantic understanding and keyword matching
+
+ 50
+ 30
+ true
+
+
+
+
+
+
+
+ search for*
+ find*
+ look for*
+ what is*
+ tell me about*
+
+
+ azure_ai_search
+ mock
+ custom
+
+
+
+
+
+ Retrieve specific detailed information about named items or entities
+
+ 10
+ 20
+ true
+
+
+
+
+
+
+
+ details about*
+ more information on*
+ tell me more about*
+ what are the details of*
+
+
+ azure_ai_search
+ custom
+
+
+
+
+
+ Side-by-side comparison of two or more items highlighting similarities and differences
+
+ 20
+ 45
+ true
+
+
+
+
+
+
+
+
+ compare*
+ difference between*
+ vs*
+ versus*
+ how does * compare to*
+
+
+ azure_ai_search
+ mock
+
+
+
+
+
+ Create cohesive sets of related items for comprehensive experiences
+
+ 30
+ 60
+ true
+
+
+
+
+
+
+
+
+ plan a*
+ create a set of*
+ give me a collection of*
+ ensemble of*
+ group of related*
+
+
+ azure_ai_search
+ mock
+ custom
+
+
+
+
+
+ Specialized tool for food-related queries including ingredient substitutions and meal planning
+
+ 15
+ 30
+ true
+
+
+
+
+
+
+
+
+ recipe for*
+ how to cook*
+ substitute for*
+ meal plan*
+ cooking*
+
+
+ custom
+
+
+
\ No newline at end of file
diff --git a/src/NLWebNet/Extensions/ConfigurationExtensions.cs b/src/NLWebNet/Extensions/ConfigurationExtensions.cs
new file mode 100644
index 0000000..b405524
--- /dev/null
+++ b/src/NLWebNet/Extensions/ConfigurationExtensions.cs
@@ -0,0 +1,351 @@
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.FileProviders;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Options;
+using NLWebNet.Models;
+using NLWebNet.Services;
+using YamlDotNet.Serialization;
+using YamlDotNet.Serialization.NamingConventions;
+
+namespace NLWebNet.Extensions;
+
+///
+/// Extension methods for adding YAML and XML configuration support to NLWebNet.
+///
+public static class ConfigurationExtensions
+{
+ ///
+ /// Adds a YAML configuration file to the configuration builder.
+ /// Supports the new YAML-style multi-backend configuration format.
+ ///
+ /// The configuration builder.
+ /// Path to the YAML configuration file.
+ /// Whether the file is optional.
+ /// Whether to reload when the file changes.
+ /// The configuration builder for chaining.
+ public static IConfigurationBuilder AddYamlFile(this IConfigurationBuilder builder,
+ string path,
+ bool optional = false,
+ bool reloadOnChange = false)
+ {
+ return builder.AddYamlFile(provider: null, path: path, optional: optional, reloadOnChange: reloadOnChange);
+ }
+
+ ///
+ /// Adds a YAML configuration file to the configuration builder.
+ ///
+ /// The configuration builder.
+ /// The file provider to use to access the file.
+ /// Path to the YAML configuration file.
+ /// Whether the file is optional.
+ /// Whether to reload when the file changes.
+ /// The configuration builder for chaining.
+ public static IConfigurationBuilder AddYamlFile(this IConfigurationBuilder builder,
+ IFileProvider? provider,
+ string path,
+ bool optional,
+ bool reloadOnChange)
+ {
+ if (builder == null)
+ throw new ArgumentNullException(nameof(builder));
+
+ if (string.IsNullOrEmpty(path))
+ throw new ArgumentException("Path cannot be null or empty.", nameof(path));
+
+ return builder.Add(s =>
+ {
+ s.FileProvider = provider;
+ s.Path = path;
+ s.Optional = optional;
+ s.ReloadOnChange = reloadOnChange;
+ s.ResolveFileProvider();
+ });
+ }
+
+ ///
+ /// Adds YAML configuration stream to the configuration builder.
+ ///
+ /// The configuration builder.
+ /// The stream containing YAML configuration.
+ /// The configuration builder for chaining.
+ public static IConfigurationBuilder AddYamlStream(this IConfigurationBuilder builder, Stream stream)
+ {
+ if (builder == null)
+ throw new ArgumentNullException(nameof(builder));
+
+ return builder.Add(s => s.Stream = stream);
+ }
+
+ ///
+ /// Adds NLWeb configuration format support including YAML and XML tool definitions.
+ /// This method should be called during application startup to enable advanced configuration formats.
+ ///
+ /// The service collection.
+ /// The configuration instance.
+ /// The service collection for chaining.
+ public static IServiceCollection AddNLWebConfigurationFormats(this IServiceCollection services,
+ IConfiguration configuration)
+ {
+ // Register the tool definition loader service
+ services.AddSingleton();
+
+ return services;
+ }
+
+ ///
+ /// Configures the configuration builder to automatically load YAML and XML configuration files.
+ /// This method scans for standard NLWeb configuration files and loads them if found.
+ ///
+ /// The configuration builder.
+ /// The hosting environment.
+ /// Optional base path to search for configuration files.
+ /// The configuration builder for chaining.
+ public static IConfigurationBuilder AddNLWebConfigurationFormats(this IConfigurationBuilder builder,
+ IHostEnvironment? environment = null,
+ string? basePath = null)
+ {
+ var searchPath = basePath ?? environment?.ContentRootPath ?? Directory.GetCurrentDirectory();
+
+ // Look for standard YAML configuration files
+ var yamlFiles = new[]
+ {
+ "config_retrieval.yaml",
+ "config_retrieval.yml",
+ "nlweb.yaml",
+ "nlweb.yml"
+ };
+
+ foreach (var yamlFile in yamlFiles)
+ {
+ var fullPath = Path.Combine(searchPath, yamlFile);
+ if (File.Exists(fullPath))
+ {
+ builder.AddYamlFile(yamlFile, optional: true, reloadOnChange: true);
+ break; // Use the first one found
+ }
+ }
+
+ // Add environment-specific YAML files
+ if (environment != null)
+ {
+ var envYamlFiles = new[]
+ {
+ $"config_retrieval.{environment.EnvironmentName}.yaml",
+ $"config_retrieval.{environment.EnvironmentName}.yml",
+ $"nlweb.{environment.EnvironmentName}.yaml",
+ $"nlweb.{environment.EnvironmentName}.yml"
+ };
+
+ foreach (var envYamlFile in envYamlFiles)
+ {
+ var fullPath = Path.Combine(searchPath, envYamlFile);
+ if (File.Exists(fullPath))
+ {
+ builder.AddYamlFile(envYamlFile, optional: true, reloadOnChange: true);
+ break; // Use the first one found
+ }
+ }
+ }
+
+ return builder;
+ }
+
+ ///
+ /// Creates a configuration builder with NLWeb configuration format support.
+ /// This is a convenience method that sets up YAML and other configuration providers.
+ ///
+ /// Command line arguments.
+ /// The hosting environment.
+ /// A configured configuration builder.
+ public static IConfigurationBuilder CreateNLWebConfiguration(string[]? args = null,
+ IHostEnvironment? environment = null)
+ {
+ var builder = new ConfigurationBuilder();
+
+ // Add standard configuration sources
+ builder.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
+
+ if (environment != null)
+ {
+ builder.AddJsonFile($"appsettings.{environment.EnvironmentName}.json", optional: true, reloadOnChange: true);
+ }
+
+ // Add NLWeb-specific configuration formats
+ builder.AddNLWebConfigurationFormats(environment);
+
+ // Add environment variables and command line
+ builder.AddEnvironmentVariables();
+
+ if (args != null && args.Length > 0)
+ {
+ builder.AddCommandLine(args);
+ }
+
+ return builder;
+ }
+}
+
+///
+/// Represents a YAML file as an IConfigurationSource.
+///
+public class YamlConfigurationSource : FileConfigurationSource
+{
+ ///
+ /// Builds the YamlConfigurationProvider for this source.
+ ///
+ /// The configuration builder.
+ /// A YamlConfigurationProvider.
+ public override IConfigurationProvider Build(IConfigurationBuilder builder)
+ {
+ EnsureDefaults(builder);
+ return new YamlConfigurationProvider(this);
+ }
+}
+
+///
+/// A YAML file based configuration provider.
+///
+public class YamlConfigurationProvider : FileConfigurationProvider
+{
+ ///
+ /// Initializes a new instance with the specified source.
+ ///
+ /// The source settings.
+ public YamlConfigurationProvider(YamlConfigurationSource source) : base(source) { }
+
+ ///
+ /// Loads the YAML data from a stream.
+ ///
+ /// The stream to read.
+ public override void Load(Stream stream)
+ {
+ try
+ {
+ Data = YamlConfigurationFileParser.Parse(stream);
+ }
+ catch (Exception ex)
+ {
+ throw new FormatException($"Could not parse the YAML file. Error on line {GetLineNumber(ex)}: {ex.Message}", ex);
+ }
+ }
+
+ private static int GetLineNumber(Exception ex)
+ {
+ // Try to extract line number from YamlDotNet exceptions
+ if (ex.Message.Contains("line"))
+ {
+ var parts = ex.Message.Split(' ');
+ foreach (var part in parts)
+ {
+ if (int.TryParse(part.Trim(':', ',', '.'), out int lineNumber))
+ {
+ return lineNumber;
+ }
+ }
+ }
+ return 0;
+ }
+}
+
+///
+/// Represents a YAML stream as an IConfigurationSource.
+///
+public class YamlStreamConfigurationSource : StreamConfigurationSource
+{
+ ///
+ /// Builds the YamlStreamConfigurationProvider for this source.
+ ///
+ /// The configuration builder.
+ /// A YamlStreamConfigurationProvider.
+ public override IConfigurationProvider Build(IConfigurationBuilder builder)
+ {
+ return new YamlStreamConfigurationProvider(this);
+ }
+}
+
+///
+/// A YAML stream based configuration provider.
+///
+public class YamlStreamConfigurationProvider : StreamConfigurationProvider
+{
+ ///
+ /// Initializes a new instance with the specified source.
+ ///
+ /// The source settings.
+ public YamlStreamConfigurationProvider(YamlStreamConfigurationSource source) : base(source) { }
+
+ ///
+ /// Loads the YAML data from a stream.
+ ///
+ /// The stream to read.
+ public override void Load(Stream stream)
+ {
+ Data = YamlConfigurationFileParser.Parse(stream);
+ }
+}
+
+///
+/// Helper class for parsing YAML configuration files.
+///
+internal static class YamlConfigurationFileParser
+{
+ ///
+ /// Parses a YAML stream into a configuration dictionary.
+ ///
+ /// The stream containing YAML data.
+ /// A dictionary of configuration key-value pairs.
+ public static IDictionary Parse(Stream stream)
+ {
+ var data = new Dictionary(StringComparer.OrdinalIgnoreCase);
+
+ using var reader = new StreamReader(stream);
+ var yamlContent = reader.ReadToEnd();
+
+ if (string.IsNullOrWhiteSpace(yamlContent))
+ {
+ return data;
+ }
+
+ var deserializer = new DeserializerBuilder()
+ .WithNamingConvention(UnderscoredNamingConvention.Instance)
+ .Build();
+
+ var yamlObject = deserializer.Deserialize(yamlContent);
+
+ if (yamlObject != null)
+ {
+ FlattenYamlObject(string.Empty, yamlObject, data);
+ }
+
+ return data;
+ }
+
+ private static void FlattenYamlObject(string prefix, object value, IDictionary data)
+ {
+ switch (value)
+ {
+ case Dictionary