Files
Teamup/src/Modules/TeamUp.Modules.Assembler/Endpoints/AssemblerEndpoints.cs
T

48 lines
2.0 KiB
C#
Raw Normal View History

using System.Text.Json;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.EntityFrameworkCore;
using TeamUp.Modules.Assembler.Domain;
using TeamUp.Modules.Assembler.Persistence;
using TeamUp.Modules.Assembler.Queue;
using TeamUp.Modules.Assembler.Runtime;
using TeamUp.SharedKernel.Modularity;
namespace TeamUp.Modules.Assembler.Endpoints;
internal static class AssemblerEndpoints
{
public static void Map(IEndpointRouteBuilder endpoints)
{
var group = endpoints.MapGroup("/api/assembler").WithTags("Assembler");
group.MapGet("/ping", () => TypedResults.Ok(new ModulePing("assembler")));
group.MapPost("/runs", CreateRun).RequireAuthorization();
group.MapGet("/runs/{id:guid}", GetRun).RequireAuthorization();
}
// Dispatch a task to an AI seat: record a queued AgentRun and enqueue the job. The worker
// drains it off the request path. (Scope-checking the seat's team is added in Increment 2.)
private static async Task<IResult> CreateRun(
CreateRunRequest request, AssemblerDbContext db, JobQueue queue, TimeProvider clock, CancellationToken ct)
{
var run = new AgentRun(request.SeatId, request.WorkItemId, clock.GetUtcNow());
db.AgentRuns.Add(run);
await db.SaveChangesAsync(ct);
await queue.EnqueueAsync("agent.run", JsonSerializer.Serialize(new AgentRunPayload(run.Id)), ct);
return Results.Ok(ToResponse(run));
}
private static async Task<IResult> GetRun(Guid id, AssemblerDbContext db, CancellationToken ct)
{
var run = await db.AgentRuns.FirstOrDefaultAsync(r => r.Id == id, ct);
return run is null ? Results.NotFound() : Results.Ok(ToResponse(run));
}
private static RunResponse ToResponse(AgentRun run) => new(
run.Id, run.SeatId, run.WorkItemId, run.AgentId, run.Status.ToString(),
run.ActionType, run.ActionRisk, run.Prompt, run.Output, run.Error);
}