using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.ChatCompletion; using VideoStudy.Shared; using Microsoft.AspNetCore.RateLimiting; using System.Threading.RateLimiting; using VideoStudy.API.Services; #pragma warning disable SKEXP0010 // Ollama connector is experimental var builder = WebApplication.CreateBuilder(args); // Add Services builder.Services.AddScoped(); // Add CORS builder.Services.AddCors(options => { options.AddPolicy("AllowAll", policyBuilder => { policyBuilder .AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader(); }); }); // Add Swagger builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); // Configure AI Provider (Ollama or Groq) var aiProvider = builder.Configuration["LlmSettings:Provider"] ?? "Ollama"; builder.Services.AddKernel(); if (aiProvider.Equals("Ollama", StringComparison.OrdinalIgnoreCase)) { var ollamaUrl = builder.Configuration["LlmSettings:Ollama:BaseUrl"] ?? "http://localhost:11434"; var ollamaModel = builder.Configuration["LlmSettings:Ollama:Model"] ?? "llama3.1"; builder.Services.AddOpenAIChatCompletion( modelId: ollamaModel, apiKey: "ollama", endpoint: new Uri($"{ollamaUrl}/v1") ); } else if (aiProvider.Equals("Groq", StringComparison.OrdinalIgnoreCase)) { var groqApiKey = builder.Configuration["LlmSettings:Groq:ApiKey"] ?? builder.Configuration["LlmSettings:ApiKey"] ?? Environment.GetEnvironmentVariable("GROQ_API_KEY") ?? ""; var groqModel = builder.Configuration["LlmSettings:Groq:Model"] ?? builder.Configuration["LlmSettings:ModelId"] ?? "llama-3.3-70b-versatile"; var groqBaseUrl = builder.Configuration["LlmSettings:Groq:BaseUrl"] ?? builder.Configuration["LlmSettings:Endpoint"] ?? "https://api.groq.com/openai/v1"; builder.Services.AddOpenAIChatCompletion( modelId: groqModel, apiKey: groqApiKey, endpoint: new Uri(groqBaseUrl) ); } // Add Rate Limiting builder.Services.AddRateLimiter(options => { options.AddFixedWindowLimiter("api", opt => { opt.Window = TimeSpan.FromMinutes(1); opt.PermitLimit = 60; }); }); var app = builder.Build(); // Enable Rate Limiting app.UseRateLimiter(); // Enable Swagger if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseCors("AllowAll"); app.MapGet("/health", () => Results.Ok(new { status = "healthy", timestamp = DateTime.UtcNow })); // Video info endpoint (lightweight preview) app.MapGet("/api/video-info", async (string url, AnalysisService service) => { try { var info = await service.GetVideoInfoAsync(url, CancellationToken.None); return Results.Ok(info); } catch (Exception ex) { return Results.BadRequest(new { error = ex.Message }); } }) .WithName("GetVideoInfo"); // Main analysis endpoint app.MapPost("/api/analyze", (AnalysisRequest request, AnalysisService service, CancellationToken cancellationToken) => { return service.AnalyzeVideoAsync(request, cancellationToken); }) .WithName("AnalyzeVideo"); app.Run(); #pragma warning restore SKEXP0010