Fuellarbeit: zeitlich flexible Arbeit fuellt ungenutztes Budget (#717, Stufe 1)
Eine einmalige Aufgabe mit fill_by (spaetestens bis) statt Termin laeuft, wenn der Tag Budget uebrig laesst: nach regulaerer und nachgeholter Arbeit, nur wenn nichts vom Agenten wartet, bevorzugt ab 18 Uhr, und nur wenn ihre eigene Schaetzung in den Spielraum aus #716 passt. Kurz vor der Frist wird einmal ein Mensch gefragt; nach der Frist laeuft sie als regulaere Arbeit. Ehrliche Schaetzung (TaskCostEstimator): eigene Laeufe, dann Geschwister unter derselben Elternaufgabe, dann die Angabe des Autors (als Schaetzung gekennzeichnet), zuletzt das Mittel des Agenten. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
25f74d9ad6
commit
183e922278
@@ -0,0 +1,53 @@
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using ClawdDotNet.Core.Tasks;
|
||||
|
||||
namespace ClawdDotNet.Core.Budget;
|
||||
|
||||
/// <summary>
|
||||
/// #717: The question to a human about fill work that has found no room before its deadline.
|
||||
/// Only a human can answer it — raise the budget or move the deadline — so it goes on the
|
||||
/// board as a human's task, below the fill work it is about.
|
||||
/// </summary>
|
||||
public static class FillWorkNotice
|
||||
{
|
||||
public static TaskItem QuestionFor(TaskItem fill, TaskEstimate estimate)
|
||||
{
|
||||
var body = new StringBuilder();
|
||||
body.AppendLine($"Fill work {fill.Id} (\"{fill.Title}\") is due by {fill.FillBy:yyyy-MM-dd HH:mm} UTC " +
|
||||
"and has not found room in the budget so far.");
|
||||
body.AppendLine();
|
||||
body.AppendLine($"Assigned to: {fill.Assignee}");
|
||||
body.AppendLine($"Expected cost per run: {Describe(estimate)}");
|
||||
body.AppendLine();
|
||||
body.AppendLine("Fill work only runs on budget the rest of the day leaves unused. Please decide:");
|
||||
body.AppendLine("- raise the agent's daily budget, or");
|
||||
body.AppendLine($"- move the deadline (fill_by in {fill.Id}), or");
|
||||
body.AppendLine("- leave it: at the deadline it runs as regular work, ahead of other late work.");
|
||||
|
||||
return new TaskItem
|
||||
{
|
||||
Title = $"Fill work {fill.Id} finds no room before its deadline",
|
||||
Body = body.ToString().TrimEnd(),
|
||||
Assignee = TaskAssignee.Human,
|
||||
Type = TaskItemType.HumanInput,
|
||||
Priority = Math.Clamp(fill.Priority + 1, 1, 5),
|
||||
Status = TaskItemStatus.Todo,
|
||||
ParentId = fill.Id
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>"0.80 USD (measured over 3 runs)" — and a guess says it is one.</summary>
|
||||
public static string Describe(TaskEstimate estimate)
|
||||
{
|
||||
var usd = estimate.Run.CostUsd.ToString("0.00##", CultureInfo.InvariantCulture) + " USD";
|
||||
return estimate.Source switch
|
||||
{
|
||||
EstimateSource.Measured => $"{usd} (measured over {estimate.Samples} run(s))",
|
||||
EstimateSource.Siblings => $"{usd} (measured on {estimate.Samples} run(s) of its sibling tasks)",
|
||||
EstimateSource.Stated => $"{usd} (estimated by its author, not measured)",
|
||||
EstimateSource.AgentAverage => $"{usd} (the agent's average run, not measured on this task)",
|
||||
_ => "unknown - nothing measured and no estimate given"
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user