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:
mika kuns
2026-08-06 11:25:32 +02:00
parent 86f962ee7d
commit f8c48e2ed7
5 changed files with 151 additions and 22 deletions
@@ -947,10 +947,11 @@ public sealed class ExternalMcpServiceTests : IDisposable
await SeedTaskAsync(listId, "idle", TaskStatus.Idle);
var sut = NewService();
var result = await sut.ListTasks(listId, null, "WaitingForReview", CancellationToken.None);
var result = await sut.ListTasks(listId, null, "WaitingForReview", cancellationToken: CancellationToken.None);
Assert.Single(result);
Assert.Equal("WaitingForReview", result[0].Status);
Assert.NotNull(result.Tasks);
Assert.Single(result.Tasks!);
Assert.Equal("WaitingForReview", result.Tasks![0].Status);
}
[Fact]
@@ -961,10 +962,47 @@ public sealed class ExternalMcpServiceTests : IDisposable
await SeedTaskAsync(listId, "done", TaskStatus.Done);
var sut = NewService();
var result = await sut.ListTasks(listId, null, "WaitingForChildren", CancellationToken.None);
var result = await sut.ListTasks(listId, null, "WaitingForChildren", cancellationToken: CancellationToken.None);
Assert.Single(result);
Assert.Equal("WaitingForChildren", result[0].Status);
Assert.NotNull(result.Tasks);
Assert.Single(result.Tasks!);
Assert.Equal("WaitingForChildren", result.Tasks![0].Status);
}
[Fact]
public async Task ListTasks_Default_ReturnsLeanReferences_NoDescriptionOrTasksFull()
{
var listId = await SeedListAsync();
var task = await SeedTaskAsync(listId, "with desc");
task.Description = "a long description that should not come back by default";
await _tasks.UpdateAsync(task);
var sut = NewService();
var result = await sut.ListTasks(listId, cancellationToken: CancellationToken.None);
Assert.False(result.IncludeDescription);
Assert.NotNull(result.Tasks);
Assert.Null(result.TasksFull);
Assert.Single(result.Tasks!);
Assert.Equal(task.Id, result.Tasks![0].Id);
}
[Fact]
public async Task ListTasks_IncludeDescriptionTrue_ReturnsFullTasks()
{
var listId = await SeedListAsync();
var task = await SeedTaskAsync(listId, "with desc");
task.Description = "the full description";
await _tasks.UpdateAsync(task);
var sut = NewService();
var result = await sut.ListTasks(listId, includeDescription: true, cancellationToken: CancellationToken.None);
Assert.True(result.IncludeDescription);
Assert.Null(result.Tasks);
Assert.NotNull(result.TasksFull);
Assert.Single(result.TasksFull!);
Assert.Equal("the full description", result.TasksFull![0].Description);
}
// ── MergeTask allowWaitingForReview ───────────────────────────────────────