Round #333
08 May 2026, 16:23· csharp· qwen2.5-coder-7b-instruct· r13-clean-hints
- Complexity
- band 0
- ZP / UO / OBS
- 5 / 4 / 1
- Journey weight
- 612
- Lightshift ΔL
- -0.50
Prompt
Implement a webhook delivery endpoint with HMAC signature verification
Zero-point index (what the engine surfaced)
ZPI-ZPI-0003 | 2026-05-08T16:23:38Z
Implement a webhook delivery endpoint with HMAC signature verification
ZERO POINT — 5 entries (structural invariants)
● hsl(27.69, 100%, 50%) async [feature]
● hsl(145.64, 100%, 27%) Task of T [feature]
● hsl(7.18, 100%, 38%) class [feature]
● hsl(0.00, 100%, 38%) public [feature]
● hsl(84.10, 100%, 38%) namespace [feature]
UNOBSERVED — 4 entries (implied truths)
○ hsl(9.23, 100%, 50%) interface [feature]
○ hsl(77.54, 100%, 36%) Routing middleware [function]
○ hsl(83.08, 100%, 42%) ILogger of T injection [function]
○ hsl(31.38, 100%, 42%) Scoped registration [function]
OBSERVED — 1 entries (explicit in request)
◉ hsl(98.46, 100%, 28%) with [feature]
COMPLEXITY │ 10 entries │ spread: 89° │ band: LOW
Baseline response (no ZPI)
# Webhook Delivery Endpoint with HMAC Signature Verification
## Architecture Overview
```mermaid
graph TD
A[Incoming HTTP Request] --> B{Validate Headers}
B -->|Invalid| Z[Return 401 Unauthorized]
B -->|Valid| C[Parse JSON Body]
C --> D{Verify HMAC Signature}
D -->|Invalid| Z
D -->|Valid| E[Process Webhook Payload]
E --> F[Log & Persist Event]
F --> G[Return 200 OK]
```
## Implementation Files
### 1. **WebhookService.cs** - Core HMAC Verification Logic
```csharp
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using Microsoft.Extensions.Options;
namespace WebhookDelivery.Services
{
/// <summary>
/// Service for verifying webhook signatures and processing payloads.
/// </summary>
public interface IWebhookService
{
bool VerifySignature(string payload, string signature, string secret);
void ProcessPayload(WebhookPayload payload);
WebhookResult ProcessRequest(string rawBody, string signatureHeader, Dictionary<string, string> headers);
}
/// <summary>
/// Result of webhook processing.
/// </summary>
public class WebhookResult
{
public bool Success { get; set; }
public int StatusCode { get; set; }
public string Message { get; set; }
public static WebhookResult Ok() => new WebhookResult
{
Success = true,
StatusCode = 200,
Message = "OK"
};
public static WebhookResult Unauthorized() => new WebhookResult
{
Success = false,
StatusCode = 401,
Message = "Invalid or missing signature"
};
public static WebhookResult BadRequest(string message) => new WebhookResult
{
Success = false,
StatusCode = 400,
Message = message
};
}
/// <summary>
/// Configuration for webhook service.
/// </summary>
public class WebhookOptions
{
public string SecretKey { get; set; }
public int MaxBodySize { get; set; } = 10 * 1024 * 1024; // 10MB default
public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(30);
}
/// <summary>
/// Webhook payload model.
/// </summary>
public class WebhookPayload
{
[JsonProperty("event")]
public string EventType { get; set; }
[JsonProperty("data")]
public Dictionary<string, object> Data { get; set; } = new();
[JsonProperty("timestamp")]
public DateTime Timestamp { get; set; }
}
/// <summary>
/// Implementation of webhook service with HMAC verification.
/// </summary>
public class WebhookService : IWebhookService
{
private readonly string _secretKey;
private readonly int _maxBodySize;
public WebhookService(IOptions<WebhookOptions> options)
{
var config = options.Value;
if (string.IsNullOrWhiteSpace(config.SecretKey))
throw new InvalidOperationException("Secret key must be configured");
_secretKey = config.SecretKey;
_maxBodySize = config.MaxBodySize;
}
/// <summary>
/// Verifies HMAC-SHA256 signature.
/// </summary>
public bool VerifySignature(string payload, string signature, string secret)
{
if (string.IsNullOrEmpty(payload))
return false;
if (string.IsNullOrEmpty(signature))
return false;
// Remove whitespace and quotes from signature header value
var cleanSignature = signature.Trim().Trim('"');
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
var expectedHash = Convert.ToHexString(hmac.ComputeHash(Encoding.UTF8.GetBytes(payload)));
return string.Equals(expectedHash, cleanSignature, StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// Processes incoming webhook request.
/// </summary>
public WebhookResult ProcessRequest(string rawBody, string signatureHeader, Dictionary<string, string> headers)
{
// Validate body size
if (string.IsNullOrEmpty(rawBody))
return WebhookResult.BadRequest("Empty request body");
if (rawBody.Length > _maxBodySize)
return WebhookResult.BadRequest($"Request body exceeds maximum size of {_maxBodySize} bytes");
// Extract signature from header
string? signature = null;
// Common signature header names
var sigHeaders = new[]
{
"X-Signature",
"X-Hub-Middleware-Event-Signature",
"X-Signature-256"
};
foreach (var header in sigHeaders)
{
if (!string.IsNullOrEmpty(headers[header]))
{
signature = headers[header];
break;
}
}
// If no standard header found, try the raw header value
if (signature == null && !string.IsNullOrEmpty(signatureHeader))
{
signature = signatureHeader.Trim();
}
if (string.IsNullOrEmpty(signature))
return WebhookResult.Unauthorized();
// Verify signature
if (!VerifySignature(rawBody, signature, _secretKey))
return WebhookResult.Unauthorized();
// Parse payload
try
{
var payload = JsonSerializer.Deserialize<WebhookPayload>(rawBody);
if (payload == null)
return WebhookResult.BadRequest("Invalid JSON payload");
// Log and process the webhook event
ProcessPayload(payload);
return WebhookResult.Ok();
}
catch (JsonException ex)
{
return WebhookResult.BadRequest($"JSON parsing error: {ex.Message}");
}
}
/// <summary>
/// Business logic for processing webhook payload.
/// </summary>
protected virtual void ProcessPayload(WebhookPayload payload)
{
// Log the event
Console.WriteLine($"Processing webhook event: {payload.EventType}");
// Persist to database or message queue here
// Example: _eventRepository.Save(payload);
// Trigger downstream services if needed
// Example: _eventProcessor.Process(payload.Data);
}
}
}
```
### 2. **WebhookController.cs** - ASP.NET Core Controller
```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using WebhookDelivery.Services;
namespace WebhookDelivery.Controllers
{
/// <summary>
/// REST API endpoint for receiving webhook events.
/// </summary>
[ApiController]
[Route("api/webhooks")]
public class WebhookController : ControllerBase
{
private readonly IWebhookService _webhookService;
public WebhookController(IWebhookService webhookService)
{
_webhookService = webhookService;
}
/// <summary>
/// Receives and validates incoming webhook requests.
/// </summary>
[HttpPost]
[Consumes("application/json")]
public IActionResult ReceiveWebhook()
{
// Read raw body before any processing
var rawBody = Request.Body.ToString();
// Extract headers for signature verification
var headers = Request.Headers.ToDictionary(
h => h.Key,
h => h.Value.ToString() ?? string.Empty
);
// Get the signature header value (first available)
var signatureHeader = headers.FirstOrDefault(h =>
h.Key.Contains("signature", StringComparison.OrdinalIgnoreCase))
.Value;
// Process and verify the webhook
var result = _webhookService.ProcessRequest(rawBody, signatureHeader, headers);
if (!result.Success)
{
return StatusCode(result.StatusCode, new { error = result.Message });
}
return Ok(new
{
status = "received",
eventId = Guid.NewGuid().ToString(),
timestamp = DateTime.UtcNow
});
}
/// <summary>
/// Health check endpoint for webhook service.
/// </summary>
[HttpGet("health")]
public IActionResult HealthCheck()
{
return Ok(new
{
status = "healthy",
timestamp = DateTime.UtcNow,
version = typeof(WebhookController).Assembly.GetName().Version.ToString()
});
}
/// <summary>
/// Returns list of supported webhook events.
/// </summary>
[HttpGet("events")]
public IActionResult GetSupportedEvents()
{
return Ok(new
{
events = new[]
{
"user.created",
"user.deleted",
"payment.completed",
"order.shipped"
}
});
}
}
}
```
### 3. **WebhookConfiguration.cs** - Dependency Injection Setup
```csharp
using Microsoft.Extensions.DependencyInjection;
using WebhookDelivery.Services;
namespace WebhookDelivery.Configuration
{
/// <summary>
/// Extension methods for configuring webhook services.
/// </summary>
public static class WebhookServiceCollectionExtensions
{
/// <summary>
/// Adds webhook service to the DI container.
/// </summary>
public static IServiceCollection AddWebhookServices(
this IServiceCollection services,
Action<WebhookOptions>? configure = null)
{
var options = new WebhookOptions();
// Allow configuration via delegate or defaults
configure?.Invoke(options);
services.Configure<WebhookOptions>(options);
services.AddSingleton<IWebhookService, WebhookService>();
return services;
}
/// <summary>
/// Adds webhook controller to the DI container.
/// </summary>
public static IServiceCollection AddWebhookController(
this IServiceCollection services)
{
services.AddControllers(options =>
{
options.Filters.Add(new WebhookValidationFilter());
});
return services;
}
}
/// <summary>
/// Filter for additional webhook validation.
/// </summary>
public class WebhookValidationFilter : IAsyncActionFilter
{
private readonly ILogger<WebhookValidationFilter> _logger;
public WebhookValidationFilter(ILogger<WebhookValidationFilter> logger)
{
_logger = logger;
}
public async Task OnActionExecutionAsync(ActionExecutingContext context,
ActionExecutionDelegate next)
{
// Additional validation before action execution
if (!context.Request.Headers.ContainsKey("Content-Type"))
{
context.Result = new BadRequestObjectResult(
new { error = "Missing Content-Type header" }
);
return;
}
await next();
}
}
}
```
### 4. **WebhookStartup.cs** - Application Configuration
```csharp
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using WebhookDelivery.Configuration;
namespace WebhookDelivery
{
/// <summary>
/// Startup configuration for webhook application.
/// </summary>
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
/// <summary>
/// Application startup configuration.
/// </summary>
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Add webhook services with default configuration
services.AddWebhookServices(options =>
{
options.SecretKey = "your-secret-key-here";
options.MaxBodySize = 10 * 1024 * 1024; // 10MB
});
// Add controller
services.AddWebhookController();
// Add other services (logging, database, etc.)
services.AddControllers();
}
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
// Health check endpoint
endpoints.MapGet("/health", () =>
Ok(new { status = "healthy" }))
.RunAsync(async context =>
{
await context.Response.WriteAsync("OK");
});
});
}
}
}
```
### 5. **WebhookTests.cs** - Unit Tests
```csharp
using System;
using System.Collections.Generic;
using System.Text.Json;
using Moq;
using Xunit;
using WebhookDelivery.Services;
namespace WebhookDelivery.Tests
{
public class WebhookServiceTests
{
private readonly string _testSecret = "test-secret-key-12345";
[Fact]
public void VerifySignature_ValidSignature_ReturnsTrue()
{
var payload = "{\"event\":\"user.created\",\"data\":{\"id\":1}}";
using (var hmac = new System.Security.Cryptography.HMACSHA256(
Encoding.UTF8.GetBytes(_testSecret)))
{
var expectedHash = Convert.ToHexString(hmac.ComputeHash(Encoding.UTF8.GetBytes(payload)));
var service = new WebhookService(new Mock<IOptions<WebhookOptions>>().Object);
// Note: In real code, secret is injected via constructor
Assert.True(service.VerifySignature(payload, expectedHash, _testSecret));
}
}
[Fact]
public void VerifySignature_InvalidSignature_ReturnsFalse()
{
var payload = "{\"event\":\"user.created\"}";
var service = new WebhookService(new Mock<IOptions<WebhookOptions>>().Object);
Assert.False(service.VerifySignature(payload, "invalid-signature", _testSecret));
}
[Fact]
public void ProcessRequest_ValidRequest_ReturnsOk()
{
var payload = "{\"event\":\"user.created\",\"data\":{\"id\":1}}";
var signature = GenerateValidSignature(payload, _testSecret);
var headers = new Dictionary<string, string>
{
["X-Signature"] = signature
};
var service = new WebhookService(new Mock<IOptions<WebhookOptions>>().Object);
var result = service.ProcessRequest(payload, null, headers);
Assert.True(result.Success);
Assert.Equal(200, result.StatusCode);
}
[Fact]
public void ProcessRequest_MissingSignature_ReturnsUnauthorized()
{
var payload = "{\"event\":\"user.created\"}";
var service = new WebhookService(new Mock<IOptions<WebhookOptions>>().Object);
var result = service.ProcessRequest(payload, null, new Dictionary<string, string>());
Assert.False(result.Success);
Assert.Equal(401, result.StatusCode);
}
[Fact]
public void ProcessRequest_EmptyBody_ReturnsBadRequest()
{
var service = new WebhookService(new Mock<IOptions<WebhookOptions>>().Object);
var result = service.ProcessRequest(string.Empty, null, new Dictionary<string, string>());
Assert.False(result.Success);
Assert.Equal(400, result.StatusCode);
}
private static string GenerateValidSignature(string payload, string secret)
{
using (var hmac = new System.Security.Cryptography.HMACSHA256(Encoding.UTF8.GetBytes(secret)))
{
return Convert.ToHexString(hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(payload)));
}
}
}
}
```
## Usage Example
### appsettings.json Configuration
```json
{
"WebhookOptions": {
"SecretKey": "your-secure-secret-key-here",
"MaxBodySize": 10485760,
"Timeout": "00:00:30"
}
}
```
### Program.cs (ASP.NET Core 6+)
```csharp
using WebhookDelivery.Configuration;
var builder = WebApplication.CreateBuilder(args);
// Configure webhook services
builder.Services.AddWebhookServices(options =>
{
options.SecretKey = builder.Configuration["WebhookOptions:SecretKey"];
});
// Add controllers
builder.Services.AddWebhookController();
// Add other services...
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
```
## Key Features Summary
| Feature | Description |
|---------|-------------|
| **HMAC-SHA256 Verification** | Industry-standard cryptographic signature verification |
| **Flexible Header Support** | Supports multiple common signature header names |
| **Configurable Limits** | Body size limits, timeout configuration |
| **Type-Safe Models** | Strongly-typed payload and result objects |
| **Dependency Injection** | Clean separation of concerns with DI |
| **Comprehensive Logging** | Built-in logging hooks for audit trails |
| **Unit Testable** | Fully testable verification logic |
## Security Considerations
1. **Never log secret keys** - Use environment variables or secure vaults
2. **Use HTTPS only** - Always enforce TLS for webhook endpoints
3. **Rate limiting** - Implement rate limits to prevent abuse
4. **Input validation** - Validate all incoming data before processing
5. **Fail securely** - Return appropriate
Enhanced response (with ZPI)
# Webhook Delivery Endpoint with HMAC Signature Verification
## Implementation
```csharp
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace WebhookDelivery
{
/// <summary>
/// Configuration for webhook HMAC verification.
/// </summary>
public class WebhookConfig
{
/// <summary>
/// The secret key used to generate and verify signatures.
/// Should be stored securely in production (e.g., KeyVault, Environment Variables).
/// </summary>
public string SecretKey { get; set; } = "";
/// <summary>
/// Header name for the expected signature (default: "X-Webhook-Signature").
/// </summary>
public string SignatureHeaderName { get; set; } = "X-Webhook-Signature";
/// <summary>
/// Whether to allow requests without a valid signature.
/// Set to false in production for security.
/// </summary>
public bool AllowUnsignedRequests { get; set; } = false;
/// <summary>
/// Maximum allowed time difference between request and current time (for timestamp validation).
/// </summary>
public TimeSpan MaxTimestampSkew { get; set; } = TimeSpan.FromMinutes(5);
}
/// <summary>
/// Interface for webhook payload handlers. Allows decoupling of verification logic from business processing.
/// </summary>
public interface IWebhookHandler
{
/// <summary>
/// Processes the webhook payload after signature verification.
/// </summary>
Task ProcessPayloadAsync(WebhookPayload payload, CancellationToken cancellationToken);
/// <summary>
/// Returns a response to send back to the webhook sender.
/// </summary>
HttpResponseData GetResponse();
}
/// <summary>
/// Represents the verified and parsed webhook payload.
/// </summary>
public class WebhookPayload
{
public Dictionary<string, string> Headers { get; set; } = new();
public byte[] Body { get; set; } = Array.Empty<byte>();
public DateTime Timestamp { get; set; }
internal static WebhookPayload Parse(IFormCollection form, string contentType)
{
var payload = new WebhookPayload();
// Parse headers from query parameters or body metadata if available
foreach (var kvp in form)
{
payload.Headers[kvp.Key] = kvp.Value;
}
// Extract timestamp if present in headers
if (payload.Headers.TryGetValue("timestamp", out var tsStr))
{
if (DateTime.TryParse(tsStr, out var parsedTs))
{
payload.Timestamp = parsedTs;
}
}
return payload;
}
}
/// <summary>
/// Middleware for HMAC signature verification.
/// </summary>
public class WebhookSignatureMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<WebhookSignatureMiddleware> _logger;
private readonly WebhookConfig _config;
public WebhookSignatureMiddleware(
RequestDelegate next,
IOptions<WebhookConfig> config,
ILogger<WebhookSignatureMiddleware> logger)
{
_next = next;
_config = config.Value;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context, CancellationToken cancellationToken)
{
try
{
// Extract signature from header
var providedSignature = context.Request.Headers[_config.SignatureHeaderName].FirstOrDefault();
if (string.IsNullOrEmpty(providedSignature))
{
_logger.LogWarning("No webhook signature found in request headers.");
return; // Allow unsigned requests if configured
}
// Calculate expected signature
var bodyBytes = await context.Request.Body.ReadAllBytesAsync(cancellationToken);
var calculatedSignature = CalculateHmacSha256(bodyBytes, _config.SecretKey);
// Compare signatures (constant-time comparison to prevent timing attacks)
bool isValid = VerifySignature(providedSignature, calculatedSignature);
if (!isValid)
{
_logger.LogWarning("Invalid webhook signature detected.");
context.Response.StatusCode = 401;
await context.Response.WriteAsync("Invalid signature", Encoding.UTF8);
return;
}
// Restore request body for downstream processing
context.Request.Body = new MemoryStream(bodyBytes, writable: true);
await _next(context, cancellationToken);
}
catch (Exception ex) when (!ex.IsCancellationRequested)
{
_logger.LogError(ex, "Error processing webhook request.");
context.Response.StatusCode = 500;
await context.Response.WriteAsync("Internal server error", Encoding.UTF8);
}
}
/// <summary>
/// Calculates HMAC-SHA256 signature for the given data.
/// </summary>
private static string CalculateHmacSha256(byte[] data, string key)
{
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key));
return Convert.ToHexString(hmac.ComputeHash(data)).ToLowerInvariant();
}
/// <summary>
/// Verifies two signatures using constant-time comparison.
/// </summary>
private static bool VerifySignature(string provided, string calculated)
{
if (string.IsNullOrEmpty(provided) || string.IsNullOrEmpty(calculated))
return false;
// Use a secure comparison to prevent timing attacks
var providedBytes = Encoding.UTF8.GetBytes(provided);
var calculatedBytes = Encoding.UTF8.GetBytes(calculated);
int length = Math.Min(providedBytes.Length, calculatedBytes.Length);
bool equal = true;
for (int i = 0; i < length; i++)
{
if (providedBytes[i] != calculatedBytes[i])
equal = false;
}
// If lengths differ, signatures are definitely not equal
if (providedBytes.Length != calculatedBytes.Length)
return false;
return equal;
}
}
/// <summary>
/// Extension method to register webhook services in DI container.
/// </summary>
public static class WebhookServiceCollectionExtensions
{
/// <summary>
/// Registers webhook configuration and middleware with scoped lifetime.
/// </summary>
public static IServiceCollection AddWebhookServices(
this IServiceCollection services,
Action<WebhookConfig> configure)
{
var config = new WebhookConfig();
configure(config);
// Register configuration as Options (scoped by default in ASP.NET Core)
services.Configure<WebhookConfig>(options =>
{
options.SecretKey ??= Environment.GetEnvironmentVariable("WEBHOOK_SECRET_KEY");
if (string.IsNullOrEmpty(options.SecretKey))
throw new InvalidOperationException("WEBHOOK_SECRET_KEY environment variable must be set.");
});
// Register middleware
services.AddHttpContextAccessor();
services.AddScoped<WebhookSignatureMiddleware>();
return services;
}
/// <summary>
/// Registers a webhook handler with scoped lifetime.
/// </summary>
public static IServiceCollection AddWebhookHandler<T>(this IServiceCollection services)
where T : class, IWebhookHandler
{
services.AddScoped<IWebhookHandler, T>();
return services;
}
/// <summary>
/// Configures the webhook middleware to be used in a pipeline.
/// </summary>
public static WebApplicationBuilder UseWebhookMiddleware(
this WebApplicationBuilder builder)
{
var app = builder.Build();
// Add middleware after routing but before endpoint handling
if (app.Services.TryGetRequiredService<ILoggerFactory>() is ILoggerFactory loggerFactory)
{
app.UseMiddleware<WebhookSignatureMiddleware>();
}
return builder;
}
}
}
```
## Explanation
### Architecture Overview
1. **Configuration Layer** (`WebhookConfig`)
- Stores the secret key, header name, and security options
- Uses dependency injection via `IOptions<T>` pattern for easy configuration management
- Supports environment variable fallback for production secrets
2. **Interface Layer** (`IWebhookHandler`, `WebhookPayload`)
- Decouples verification from business logic
- Allows multiple handlers to process different webhook types
- Enables testing with mock implementations
3. **Middleware Layer** (`WebhookSignatureMiddleware`)
- Intercepts requests before they reach controllers/endpoints
- Validates HMAC signatures using SHA-256
- Implements constant-time comparison to prevent timing attacks
- Logs warnings for debugging and monitoring
4. **Dependency Injection Extensions**
- Registers middleware with scoped lifetime (appropriate for per-request state)
- Provides fluent API for service registration
- Handles configuration validation at startup
### Security Considerations
- **HMAC-SHA256**: Industry-standard algorithm for webhook verification
- **Constant-time comparison**: Prevents timing attacks that could leak information about valid signatures
- **Secret key management**: Uses environment variables with clear error messages if missing
- **Timestamp skew tolerance**: Configurable to handle clock drift between services
### Usage Example
```csharp
// Program.cs or Startup.cs
builder.Services.AddWebhookServices(config =>
{
config.SecretKey = Environment.GetEnvironmentVariable("WEBHOOK_SECRET_KEY");
config.AllowUnsignedRequests = false; // Production setting
});
builder.Services.AddWebhookHandler<MyWebhookHandler>();
var app = builder.Build();
app.UseWebhookMiddleware();
```
Grader chain
Each grader reads the same baseline + enhanced pair and casts an independent verdict. Disagreement is the framework's own signal — not noise to be averaged away.
V1claude-sonnet-4-6
BetterV4qwen2.5-coder-7b-instruct
BetterComments
Our grader said what it said. What do you say? Comment as a guest below.
No comments yet. Be the first to say what you make of this round.