Add gRPC-based plugin protocol implementation to the AI sidecar, enabling the GitCaddy server to manage it as an external plugin with lifecycle control and health monitoring. Plugin Protocol Implementation: - Add plugin.proto with PluginService definition (Initialize, Shutdown, HealthCheck, GetManifest, OnEvent, HandleHTTP) - Implement PluginServiceImpl gRPC service in C# - Return manifest declaring AI service capabilities, routes, and required permissions - Integrate license validation into health checks - Register plugin service alongside existing AI service Server Integration: - Configure Kestrel for HTTP/1.1 + HTTP/2 on port 5000 (enables gRPC + REST) - Map PluginService gRPC endpoint at /plugin.v1.PluginService - Enable server to call Initialize on startup, HealthCheck periodically, and Shutdown on graceful stop This completes Phase 5 of the AI integration, allowing the server's external plugin manager to monitor and control the sidecar's lifecycle instead of relying on manual process management.
89 lines
3.0 KiB
C#
89 lines
3.0 KiB
C#
// Copyright 2026 MarketAlly. All rights reserved.
|
|
// SPDX-License-Identifier: BSL-1.1
|
|
|
|
using GitCaddy.AI.Service.Services;
|
|
using GitCaddy.AI.Service.Configuration;
|
|
using GitCaddy.AI.Service.Licensing;
|
|
using Serilog;
|
|
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
|
|
// Configure Serilog
|
|
Log.Logger = new LoggerConfiguration()
|
|
.ReadFrom.Configuration(builder.Configuration)
|
|
.Enrich.FromLogContext()
|
|
.WriteTo.Console()
|
|
.WriteTo.File("logs/gitcaddy-ai-.log", rollingInterval: RollingInterval.Day)
|
|
.CreateLogger();
|
|
|
|
builder.Host.UseSerilog();
|
|
|
|
// Add configuration
|
|
builder.Services.Configure<AIServiceOptions>(builder.Configuration.GetSection("AIService"));
|
|
builder.Services.Configure<LicenseOptions>(builder.Configuration.GetSection("License"));
|
|
builder.Services.Configure<ProviderOptions>(builder.Configuration.GetSection("Providers"));
|
|
|
|
// Add services
|
|
builder.Services.AddSingleton<ILicenseValidator, LicenseValidator>();
|
|
builder.Services.AddSingleton<IAIProviderFactory, AIProviderFactory>();
|
|
builder.Services.AddSingleton<ICodeReviewService, CodeReviewService>();
|
|
builder.Services.AddSingleton<ICodeIntelligenceService, CodeIntelligenceService>();
|
|
builder.Services.AddSingleton<IIssueService, IssueService>();
|
|
builder.Services.AddSingleton<IDocumentationService, DocumentationService>();
|
|
builder.Services.AddSingleton<IWorkflowService, WorkflowService>();
|
|
builder.Services.AddSingleton<IChatService, ChatService>();
|
|
builder.Services.AddSingleton<PluginServiceImpl>();
|
|
|
|
// Add gRPC
|
|
builder.Services.AddGrpc(options =>
|
|
{
|
|
options.EnableDetailedErrors = builder.Environment.IsDevelopment();
|
|
options.MaxReceiveMessageSize = 50 * 1024 * 1024; // 50MB for large diffs
|
|
options.MaxSendMessageSize = 50 * 1024 * 1024;
|
|
});
|
|
|
|
// Add REST API controllers
|
|
builder.Services.AddControllers();
|
|
builder.Services.AddEndpointsApiExplorer();
|
|
|
|
// Add health checks
|
|
builder.Services.AddHealthChecks();
|
|
|
|
builder.WebHost.ConfigureKestrel(options =>
|
|
{
|
|
options.ListenAnyIP(5000, listenOptions =>
|
|
{
|
|
listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http1AndHttp2;
|
|
});
|
|
});
|
|
|
|
var app = builder.Build();
|
|
|
|
// Validate license on startup
|
|
var licenseValidator = app.Services.GetRequiredService<ILicenseValidator>();
|
|
var licenseResult = await licenseValidator.ValidateAsync();
|
|
if (!licenseResult.IsValid)
|
|
{
|
|
Log.Warning("License validation failed: {Error}. Running in limited mode.", licenseResult.Error);
|
|
}
|
|
else
|
|
{
|
|
Log.Information("License validated: {Tier} tier for {Customer}, expires {Expires}",
|
|
licenseResult.License?.Tier, licenseResult.License?.Customer, licenseResult.License?.ExpiresAt);
|
|
}
|
|
|
|
// Map gRPC services
|
|
app.MapGrpcService<GitCaddyAIServiceImpl>();
|
|
app.MapGrpcService<PluginServiceImpl>();
|
|
app.MapHealthChecks("/healthz");
|
|
|
|
// Map REST API controllers
|
|
app.MapControllers();
|
|
|
|
// HTTP endpoint for basic health check
|
|
app.MapGet("/", () => "GitCaddy AI Service is running. Use gRPC or REST API to connect.");
|
|
|
|
Log.Information("GitCaddy AI Service starting on {Urls}", string.Join(", ", app.Urls));
|
|
|
|
app.Run();
|