fix(mcp): report a Failed task's failureReason instead of a bare status

get_task/batch_get_tasks now return failureReason (max_turns|timeout|error|
cancelled|unknown) plus failureTurnsUsed/failureMaxTurns on a Failed task, so
max_turns (worktree usually fine, continue_task) is distinguishable from a
real error (reset_failed_task) without pulling get_task_log's raw NDJSON.
Classified and stamped onto TaskEntity by TaskRunner.MarkFailed via
TaskStateService.FailAsync; TaskRunEntity also keeps the CLI's raw
terminal_reason/result_subtype/errors for deeper diagnosis. reset_failed_task's
description now warns explicitly that it discards the worktree and points at
continue_task for max_turns. Surfaced on the task card's status-chip tooltip.
This commit is contained in:
mika kuns
2026-08-10 14:20:00 +02:00
parent 6a2a19cc9e
commit a067a7bfff
19 changed files with 1295 additions and 24 deletions
+6 -1
View File
@@ -20,7 +20,12 @@ public sealed class LifecycleMcpTools
_reset = reset;
}
[McpServerTool, Description("Reset a failed task back to Idle so it can be run again, discarding its now-stale worktree. Only tasks with Status=Failed are accepted; other statuses throw.")]
[McpServerTool, Description(
"Discards a failed task's worktree (and all uncommitted work in it) and resets it to Idle for a fresh " +
"run. Only tasks with Status=Failed are accepted; other statuses throw. Check failureReason from " +
"get_task/batch_get_tasks first: for failureReason=\"max_turns\" the worktree's work is usually still " +
"good and continue_task (resume the session, keep the worktree) is almost always the right call instead " +
"— reach for this tool only for a real error, not a task that just ran out of turns.")]
public async Task<ResetFailedTaskResult> ResetFailedTask(string taskId, CancellationToken cancellationToken)
{
var task = await _tasks.GetByIdAsync(taskId, cancellationToken)