fix(worker): make list_tasks/batch_get_tasks lean by default
list_tasks on a list of ~100 verbosely-described tasks could return 390k+ characters in one call, blowing past the caller's token limit. Both tools now default to lean TaskRefDto references (no Description/Result) and take an includeDescription flag to opt back into the full TaskDto payload — same flag-alongside-nullable-payload idiom already used by BatchGetTaskResult/TaskConfigResult. get_task is unchanged.
This commit is contained in:
+30
-3
@@ -47,6 +47,15 @@ public sealed record TaskRefDto(
|
||||
int SortOrder,
|
||||
bool IsMyDay);
|
||||
|
||||
// tasks is populated when includeDescription=false (the default): lean references, no
|
||||
// Description/Result. tasksFull is populated when includeDescription=true: full tasks incl.
|
||||
// Description/Result. Exactly one of the two is non-null per the includeDescription flag —
|
||||
// same "flag alongside nullable payload" idiom as BatchGetTaskResult.
|
||||
public sealed record ListTasksResult(
|
||||
bool IncludeDescription,
|
||||
IReadOnlyList<TaskRefDto>? Tasks,
|
||||
IReadOnlyList<TaskDto>? TasksFull);
|
||||
|
||||
public sealed record WorktreeInfoDto(
|
||||
string Path, string Branch, string HeadCommit, string BaseCommit,
|
||||
int Ahead, int Behind, bool IsDirty, string? MergeCommit = null);
|
||||
@@ -139,11 +148,17 @@ public sealed class ExternalMcpService
|
||||
|
||||
[McpServerTool, Description(
|
||||
"List tasks in a given list. Optionally filter by creator (createdBy) and/or status. " +
|
||||
"Valid status values: Idle, Queued, Running, WaitingForReview, WaitingForChildren, Done, Failed, Cancelled.")]
|
||||
public async Task<IReadOnlyList<TaskDto>> ListTasks(
|
||||
"Valid status values: Idle, Queued, Running, WaitingForReview, WaitingForChildren, Done, Failed, Cancelled. " +
|
||||
"includeDescription=false (default): returns lean task references in `tasks` (no Description/Result) — " +
|
||||
"use this unless you actually need the description text, since a list of verbosely-described tasks can " +
|
||||
"otherwise blow past the response size limit. " +
|
||||
"includeDescription=true: returns full tasks (incl. Description/Result) in `tasksFull` instead; `tasks` is " +
|
||||
"null in that case.")]
|
||||
public async Task<ListTasksResult> ListTasks(
|
||||
string listId,
|
||||
string? createdBy = null,
|
||||
string? status = null,
|
||||
bool includeDescription = false,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
TaskStatus? statusFilter = null;
|
||||
@@ -162,7 +177,10 @@ public sealed class ExternalMcpService
|
||||
if (statusFilter is not null)
|
||||
query = query.Where(t => t.Status == statusFilter);
|
||||
|
||||
return query.Select(ToDto).ToList();
|
||||
var filtered = query.ToList();
|
||||
return includeDescription
|
||||
? new ListTasksResult(true, null, filtered.Select(ToDto).ToList())
|
||||
: new ListTasksResult(false, filtered.Select(ToRefDto).ToList(), null);
|
||||
}
|
||||
|
||||
[McpServerTool, Description(
|
||||
@@ -177,6 +195,15 @@ public sealed class ExternalMcpService
|
||||
return ToDto(task);
|
||||
}
|
||||
|
||||
// Lean counterpart to GetTask, used internally by BatchGetTasks' default (includeDescription=false)
|
||||
// path. Not an MCP tool itself — GetTask's own behavior stays untouched.
|
||||
internal async Task<TaskRefDto> GetTaskRefAsync(string taskId, CancellationToken cancellationToken)
|
||||
{
|
||||
var task = await _tasks.GetByIdAsync(taskId, cancellationToken)
|
||||
?? throw new InvalidOperationException($"Task {taskId} not found.");
|
||||
return ToRefDto(task);
|
||||
}
|
||||
|
||||
[McpServerTool, Description(
|
||||
"Create a new task in the given list. Set queueImmediately=true to enqueue it for agent execution. " +
|
||||
"Set model to the cheapest model that can do the task well — 'haiku' for trivial/mechanical work, " +
|
||||
|
||||
Reference in New Issue
Block a user