Skip to content

Commit 0dd20e3

Browse files
Copilotjongalloway
andcommitted
Implement core tool system infrastructure with model corrections
Co-authored-by: jongalloway <[email protected]>
1 parent 4bc7f05 commit 0dd20e3

11 files changed

+2353
-0
lines changed

src/NLWebNet/Extensions/ServiceCollectionExtensions.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using NLWebNet.Health;
1010
using NLWebNet.RateLimiting;
1111
using NLWebNet.Metrics;
12+
using NLWebNet.Extensions;
1213
using System.Diagnostics;
1314

1415
namespace NLWebNet;
@@ -38,6 +39,9 @@ public static IServiceCollection AddNLWebNet(this IServiceCollection services, A
3839
services.AddScoped<IResultGenerator, ResultGenerator>();
3940
services.AddScoped<IToolSelector, ToolSelector>();
4041

42+
// Register Advanced Tool System
43+
services.AddAdvancedToolSystem();
44+
4145
// Register MCP services
4246
services.AddScoped<IMcpService, McpService>(); // Register default data backend (can be overridden)
4347
services.AddScoped<IDataBackend, MockDataBackend>();
@@ -79,6 +83,9 @@ public static IServiceCollection AddNLWebNet<TDataBackend>(this IServiceCollecti
7983
services.AddScoped<IResultGenerator, ResultGenerator>();
8084
services.AddScoped<IToolSelector, ToolSelector>();
8185

86+
// Register Advanced Tool System
87+
services.AddAdvancedToolSystem();
88+
8289
// Register MCP services
8390
services.AddScoped<IMcpService, McpService>();
8491

@@ -155,6 +162,10 @@ public static IServiceCollection AddNLWebNetMultiBackend(this IServiceCollection
155162

156163
services.AddScoped<IQueryProcessor, QueryProcessor>();
157164
services.AddScoped<IToolSelector, ToolSelector>();
165+
166+
// Register Advanced Tool System
167+
services.AddAdvancedToolSystem();
168+
158169
services.AddScoped<IResultGenerator>(provider =>
159170
{
160171
var options = provider.GetRequiredService<IOptions<NLWebOptions>>();
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using Microsoft.Extensions.DependencyInjection;
2+
using NLWebNet.Services;
3+
4+
namespace NLWebNet.Extensions;
5+
6+
/// <summary>
7+
/// Extension methods for registering the Advanced Tool System services.
8+
/// </summary>
9+
public static class ToolSystemServiceCollectionExtensions
10+
{
11+
/// <summary>
12+
/// Adds the Advanced Tool System services to the dependency injection container.
13+
/// This includes all tool handlers and the tool executor.
14+
/// </summary>
15+
/// <param name="services">The service collection</param>
16+
/// <returns>The service collection for chaining</returns>
17+
public static IServiceCollection AddAdvancedToolSystem(this IServiceCollection services)
18+
{
19+
// Register the tool executor
20+
services.AddScoped<IToolExecutor, ToolExecutor>();
21+
22+
// Register all tool handlers
23+
services.AddScoped<IToolHandler, SearchToolHandler>();
24+
services.AddScoped<IToolHandler, DetailsToolHandler>();
25+
services.AddScoped<IToolHandler, CompareToolHandler>();
26+
services.AddScoped<IToolHandler, EnsembleToolHandler>();
27+
services.AddScoped<IToolHandler, RecipeToolHandler>();
28+
29+
// Register tool definition loader (already exists but ensure it's registered)
30+
services.AddScoped<IToolDefinitionLoader, ToolDefinitionLoader>();
31+
32+
return services;
33+
}
34+
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
using Microsoft.Extensions.Logging;
2+
using Microsoft.Extensions.Options;
3+
using NLWebNet.Models;
4+
5+
namespace NLWebNet.Services;
6+
7+
/// <summary>
8+
/// Base implementation for tool handlers providing common functionality.
9+
/// </summary>
10+
public abstract class BaseToolHandler : IToolHandler
11+
{
12+
protected readonly ILogger Logger;
13+
protected readonly NLWebOptions Options;
14+
protected readonly IQueryProcessor QueryProcessor;
15+
protected readonly IResultGenerator ResultGenerator;
16+
17+
protected BaseToolHandler(
18+
ILogger logger,
19+
IOptions<NLWebOptions> options,
20+
IQueryProcessor queryProcessor,
21+
IResultGenerator resultGenerator)
22+
{
23+
Logger = logger ?? throw new ArgumentNullException(nameof(logger));
24+
Options = options?.Value ?? throw new ArgumentNullException(nameof(options));
25+
QueryProcessor = queryProcessor ?? throw new ArgumentNullException(nameof(queryProcessor));
26+
ResultGenerator = resultGenerator ?? throw new ArgumentNullException(nameof(resultGenerator));
27+
}
28+
29+
/// <inheritdoc />
30+
public abstract string ToolType { get; }
31+
32+
/// <inheritdoc />
33+
public abstract Task<NLWebResponse> ExecuteAsync(NLWebRequest request, CancellationToken cancellationToken = default);
34+
35+
/// <inheritdoc />
36+
public virtual bool CanHandle(NLWebRequest request)
37+
{
38+
// Base implementation - can handle if not null and has a query
39+
return request?.Query != null && !string.IsNullOrWhiteSpace(request.Query);
40+
}
41+
42+
/// <inheritdoc />
43+
public virtual int GetPriority(NLWebRequest request)
44+
{
45+
// Default priority - can be overridden by specific handlers
46+
return 50;
47+
}
48+
49+
/// <summary>
50+
/// Creates a standard error response for tool execution failures.
51+
/// </summary>
52+
/// <param name="request">The original request</param>
53+
/// <param name="errorMessage">The error message</param>
54+
/// <param name="exception">Optional exception details</param>
55+
/// <returns>Error response</returns>
56+
protected NLWebResponse CreateErrorResponse(NLWebRequest request, string errorMessage, Exception? exception = null)
57+
{
58+
Logger.LogError(exception, "Tool '{ToolType}' error for request {QueryId}: {ErrorMessage}",
59+
ToolType, request.QueryId, errorMessage);
60+
61+
return new NLWebResponse
62+
{
63+
QueryId = request.QueryId ?? string.Empty,
64+
Query = request.Query,
65+
Mode = request.Mode,
66+
Results = new List<NLWebResult>
67+
{
68+
new NLWebResult
69+
{
70+
Name = "Tool Error",
71+
Description = errorMessage,
72+
Url = string.Empty,
73+
Site = "System",
74+
Score = 0.0
75+
}
76+
},
77+
Error = errorMessage,
78+
ProcessingTimeMs = 0,
79+
Timestamp = DateTimeOffset.UtcNow
80+
};
81+
}
82+
83+
/// <summary>
84+
/// Creates a standard success response template.
85+
/// </summary>
86+
/// <param name="request">The original request</param>
87+
/// <param name="results">The results to include</param>
88+
/// <param name="processingTimeMs">Processing time in milliseconds</param>
89+
/// <returns>Success response</returns>
90+
protected NLWebResponse CreateSuccessResponse(NLWebRequest request, IList<NLWebResult> results, long processingTimeMs)
91+
{
92+
return new NLWebResponse
93+
{
94+
QueryId = request.QueryId ?? string.Empty,
95+
Query = request.Query,
96+
Mode = request.Mode,
97+
Results = results,
98+
Error = null, // Success means no error
99+
ProcessingTimeMs = processingTimeMs,
100+
Timestamp = DateTimeOffset.UtcNow
101+
};
102+
}
103+
104+
/// <summary>
105+
/// Creates a tool result with proper property mapping.
106+
/// </summary>
107+
/// <param name="name">The name/title of the result</param>
108+
/// <param name="description">The description/summary of the result</param>
109+
/// <param name="url">The URL</param>
110+
/// <param name="site">The site identifier</param>
111+
/// <param name="score">The relevance score</param>
112+
/// <returns>A properly formatted NLWebResult</returns>
113+
protected NLWebResult CreateToolResult(string name, string description, string url = "", string site = "", double score = 1.0)
114+
{
115+
return new NLWebResult
116+
{
117+
Name = name,
118+
Description = description,
119+
Url = url,
120+
Site = string.IsNullOrEmpty(site) ? ToolType : site,
121+
Score = score
122+
};
123+
}
124+
}

0 commit comments

Comments
 (0)