09eaf360a3
SharedKernel: IWorkerModule seam (RegisterWorker runs in the worker host only).
Bootstrap: AddTeamUpWorkerServices; the worker host now wires it.
Assembler module (schema "assembler", InitialAssembler migration):
- Job (Pending→Processing→Done/Failed) + AgentRun (Queued→Running→Completed/Failed) entities.
- JobQueue: enqueue + ClaimNextAsync using `FOR UPDATE SKIP LOCKED` in a transaction.
- AgentRunExecutor (Increment-1 placeholder — real assemble/model/parse lands in Increment 2).
- JobProcessor BackgroundService drains the queue on the worker host (web off the model path).
- POST /api/assembler/runs enqueues a run; GET /api/assembler/runs/{id} reads it.
Verified: build green; ArchitectureTests 8/8 (Assembler references only SharedKernel);
IntegrationTests 28/28 incl. enqueue→claim(SKIP LOCKED)→process→Completed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
73 lines
2.2 KiB
C#
73 lines
2.2 KiB
C#
using TeamUp.SharedKernel.Domain;
|
|
|
|
namespace TeamUp.Modules.Assembler.Domain;
|
|
|
|
internal enum AgentRunStatus
|
|
{
|
|
Queued,
|
|
Running,
|
|
Completed,
|
|
Failed,
|
|
}
|
|
|
|
/// <summary>
|
|
/// One execution of an AI seat against a task: the assembled prompt, the raw model output, the
|
|
/// parsed action + risk tag, and the reasoning/assembly trace. Nothing executes off this in M4 —
|
|
/// the action gate (M5) decides whether the parsed action runs or waits in review.
|
|
/// </summary>
|
|
internal sealed class AgentRun : Entity
|
|
{
|
|
public Guid SeatId { get; private set; }
|
|
public Guid WorkItemId { get; private set; }
|
|
public Guid? AgentId { get; private set; }
|
|
public AgentRunStatus Status { get; private set; }
|
|
public string? Prompt { get; private set; }
|
|
public string? Output { get; private set; }
|
|
public string? ActionType { get; private set; }
|
|
public string? ActionRisk { get; private set; }
|
|
public string? ResultJson { get; private set; }
|
|
public string? Trace { get; private set; }
|
|
public string? Error { get; private set; }
|
|
public long? LatencyMs { get; private set; }
|
|
public DateTimeOffset CreatedAtUtc { get; private set; }
|
|
public DateTimeOffset? CompletedAtUtc { get; private set; }
|
|
|
|
private AgentRun()
|
|
{
|
|
}
|
|
|
|
public AgentRun(Guid seatId, Guid workItemId, DateTimeOffset createdAtUtc)
|
|
{
|
|
SeatId = seatId;
|
|
WorkItemId = workItemId;
|
|
Status = AgentRunStatus.Queued;
|
|
CreatedAtUtc = createdAtUtc;
|
|
}
|
|
|
|
public void Start(Guid? agentId, string prompt, string? trace)
|
|
{
|
|
Status = AgentRunStatus.Running;
|
|
AgentId = agentId;
|
|
Prompt = prompt;
|
|
Trace = trace;
|
|
}
|
|
|
|
public void Complete(string output, string actionType, string actionRisk, string? resultJson, long latencyMs, DateTimeOffset nowUtc)
|
|
{
|
|
Status = AgentRunStatus.Completed;
|
|
Output = output;
|
|
ActionType = actionType;
|
|
ActionRisk = actionRisk;
|
|
ResultJson = resultJson;
|
|
LatencyMs = latencyMs;
|
|
CompletedAtUtc = nowUtc;
|
|
}
|
|
|
|
public void Fail(string error, DateTimeOffset nowUtc)
|
|
{
|
|
Status = AgentRunStatus.Failed;
|
|
Error = error;
|
|
CompletedAtUtc = nowUtc;
|
|
}
|
|
}
|