| 1 | using AgentForge.Abstractions; |
| 2 | using AgentForge.Services; |
| 3 | |
| 4 | namespace AgentForge.Endpoints; |
| 5 | |
| 6 | public static class ForgeCommandEndpoints |
| 7 | { |
| 8 | public static RouteGroupBuilder MapCommandEndpoints(this RouteGroupBuilder api) |
| 9 | { |
| 10 | api.MapPost("/commands/execute", ExecuteCommand); |
| 11 | return api; |
| 12 | } |
| 13 | |
| 14 | private static async Task<IResult> ExecuteCommand( |
| 15 | ForgeCommandExecuteRequest request, |
| 16 | HttpContext context, |
| 17 | ForgeCommandExecutor executor, |
| 18 | CancellationToken cancellationToken) |
| 19 | { |
| 20 | var result = await executor.ExecuteAsync(request, context, cancellationToken).ConfigureAwait(false); |
| 21 | |
| 22 | if (WantsJsonResponse(context)) |
| 23 | return ToJsonResult(result); |
| 24 | |
| 25 | return result.Kind switch |
| 26 | { |
| 27 | "redirect" when !string.IsNullOrWhiteSpace(result.RedirectUrl) => |
| 28 | Results.Redirect(result.RedirectUrl), |
| 29 | "json" => Results.Ok(result.Body), |
| 30 | _ => Results.BadRequest(new { error = result.Error ?? "Command failed." }), |
| 31 | }; |
| 32 | } |
| 33 | |
| 34 | private static bool WantsJsonResponse(HttpContext context) |
| 35 | { |
| 36 | if (context.Request.Headers.TryGetValue("X-Forge-Command-Client", out var client) |
| 37 | && client.ToString().Contains("slash", StringComparison.OrdinalIgnoreCase)) |
| 38 | return true; |
| 39 | |
| 40 | return context.Request.Headers.Accept.Any(value => |
| 41 | !string.IsNullOrEmpty(value) |
| 42 | && value.Contains("application/json", StringComparison.OrdinalIgnoreCase) |
| 43 | && !value.Contains("text/html", StringComparison.OrdinalIgnoreCase)); |
| 44 | } |
| 45 | |
| 46 | private static IResult ToJsonResult(ForgeCommandExecuteResponse result) => |
| 47 | result.Kind switch |
| 48 | { |
| 49 | "redirect" => Results.Ok(new { kind = result.Kind, redirectUrl = result.RedirectUrl }), |
| 50 | "json" => Results.Ok(new { kind = result.Kind, body = result.Body }), |
| 51 | _ => Results.BadRequest(new { kind = "error", error = result.Error ?? "Command failed." }), |
| 52 | }; |
| 53 | } |
| 54 | |