refactor: Datei-Scope-Serialisierung entfernen
ScopeGlobs auf Tasks und SerializeOnFileOverlap auf der Listen-Config waren ungenutzt: der Scope wurde nie befuellt, also hat der Queue-Picker nie serialisiert. ScopeOverlap, das Picker-Gate, die DTO-Felder, die UI-Option und die Spalten fallen weg (Migration DropFileScopeSerialization).
This commit is contained in:
+4
-6
@@ -105,12 +105,11 @@ public sealed class ConfigMcpTools
|
||||
|
||||
// Fields this tool doesn't expose but that live on the same row. They must survive every
|
||||
// write here — ListRepository.SetConfigAsync copies the entity verbatim, so anything left
|
||||
// at its default would silently reset (a SerializeOnFileOverlap reset only shows up as
|
||||
// tasks no longer serializing, long after this write; a TicketProjectId reset silently
|
||||
// kills the list<->ticket-project link — the tool has no ticket parameter on purpose,
|
||||
// that link is UI-only).
|
||||
// at its default would silently reset (a TicketProjectId reset silently kills the
|
||||
// list<->ticket-project link — the tool has no ticket parameter on purpose, that link is
|
||||
// UI-only).
|
||||
var hasUnrelatedSettings = existing is not null
|
||||
&& (existing.SessionSkills is not null || existing.SerializeOnFileOverlap
|
||||
&& (existing.SessionSkills is not null
|
||||
|| existing.PermissionMode is not null || existing.TicketProjectId is not null);
|
||||
|
||||
ListConfigDto? config;
|
||||
@@ -130,7 +129,6 @@ public sealed class ConfigMcpTools
|
||||
{
|
||||
ListId = listId, Model = m, SystemPrompt = sp, AgentPath = ap, MaxTurns = mt,
|
||||
VerifyCommand = vc, SessionSkills = existing?.SessionSkills,
|
||||
SerializeOnFileOverlap = existing?.SerializeOnFileOverlap ?? false,
|
||||
PermissionMode = existing?.PermissionMode,
|
||||
TicketProjectId = existing?.TicketProjectId,
|
||||
}, cancellationToken);
|
||||
|
||||
+2
-33
@@ -9,14 +9,11 @@ namespace ClaudeDo.Worker.External;
|
||||
|
||||
public sealed record QueueSlotDto(string Slot, string TaskId, int? Number, DateTime StartedAt);
|
||||
|
||||
public sealed record QueueWaitReasonDto(string TaskId, int Number, string Reason, string BlockedByTaskId, int? BlockedByNumber);
|
||||
|
||||
public sealed record GetQueueStateResult(
|
||||
int ConfiguredSlots,
|
||||
int EffectiveSlots,
|
||||
IReadOnlyList<QueueSlotDto> ActiveSlots,
|
||||
IReadOnlyList<string> WaitingTaskIds,
|
||||
IReadOnlyList<QueueWaitReasonDto> ScopeBlockedTasks,
|
||||
IReadOnlyList<int> WaitingTaskNumbers);
|
||||
|
||||
[McpServerToolType]
|
||||
@@ -37,11 +34,7 @@ public sealed class QueueStateMcpTools
|
||||
"by the usage throttle (lower when the 5h/7d usage window fills up), so comparing the two " +
|
||||
"shows whether throttling is currently active. Each active slot is \"queue\" (a normal " +
|
||||
"queue slot) or \"override\" (the single run_task_now/continue_task slot). waitingTaskIds " +
|
||||
"lists queued, unblocked, non-manual, due tasks in the order the queue would pick them next -- " +
|
||||
"including any held back purely by file-scope overlap, which is why a waiting task can " +
|
||||
"outlast a free slot. scopeBlockedTasks explains those: the list opted into " +
|
||||
"serializeOnFileOverlap and this task's declared scope overlaps blockedByTaskId, a running " +
|
||||
"or awaiting-merge sibling in the same list.")]
|
||||
"lists queued, unblocked, non-manual, due tasks in the order the queue would pick them next.")]
|
||||
public async Task<GetQueueStateResult> GetQueueState(CancellationToken cancellationToken = default)
|
||||
{
|
||||
var (configured, effective) = await _queue.GetSlotCountsAsync(cancellationToken);
|
||||
@@ -68,32 +61,8 @@ public sealed class QueueStateMcpTools
|
||||
.OrderBy(t => t.SortOrder).ThenBy(t => t.CreatedAt)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
var serializingListIds = (await ctx.ListConfigs
|
||||
.Where(c => c.SerializeOnFileOverlap)
|
||||
.Select(c => c.ListId)
|
||||
.ToListAsync(cancellationToken))
|
||||
.ToHashSet(StringComparer.Ordinal);
|
||||
|
||||
var scopeBlocked = new List<QueueWaitReasonDto>();
|
||||
if (serializingListIds.Count > 0)
|
||||
{
|
||||
foreach (var t in waiting)
|
||||
{
|
||||
if (!serializingListIds.Contains(t.ListId)) continue;
|
||||
var blockerId = await ScopeOverlap.FindBlockingSiblingAsync(ctx, t, cancellationToken);
|
||||
if (blockerId is not null)
|
||||
{
|
||||
var blockerNumber = await ctx.Tasks
|
||||
.Where(b => b.Id == blockerId)
|
||||
.Select(b => (int?)b.Number)
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
scopeBlocked.Add(new QueueWaitReasonDto(t.Id, t.Number, "scope_overlap", blockerId, blockerNumber));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new GetQueueStateResult(
|
||||
configured, effective, activeSlots, waiting.Select(t => t.Id).ToList(), scopeBlocked,
|
||||
configured, effective, activeSlots, waiting.Select(t => t.Id).ToList(),
|
||||
waiting.Select(t => t.Number).ToList());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user