feat(worker): AskUser MCP tool so a running task can ask the user mid-run
A running task can call mcp__claudedo_run__AskUser(question) to block (up to 3 min) on a human answer. PendingQuestionRegistry holds the pending question + TaskCompletionSource; the tool broadcasts TaskQuestionAsked, awaits the answer (WorkerHub.AnswerTaskQuestion resolves it), and returns it as the tool result — or a 'proceed on your judgment' fallback on timeout. The run stays Running throughout (no status/schema change). ClaudeProcess raises MCP_TOOL_TIMEOUT so the 60s HTTP-MCP cap doesn't kill the wait; the run MCP is now wired for every task, not just standalone ones. System prompt updated to reconcile 'unattended'.
This commit is contained in:
@@ -90,21 +90,23 @@ public sealed class TaskRunner
|
||||
|
||||
var resolvedConfig = await ResolveConfigAsync(task, listConfig, null, ct);
|
||||
|
||||
// Improvement-eligible runs get a per-run MCP identity so the agent can file
|
||||
// out-of-scope follow-ups via SuggestImprovement. Children and planning runs do not.
|
||||
if (task.ParentTaskId is null && task.PlanningPhase == PlanningPhase.None)
|
||||
// Every run gets a per-run MCP identity so the agent can ask the user a
|
||||
// mid-run question via AskUser. Improvement-eligible (standalone top-level)
|
||||
// runs additionally get SuggestImprovement for filing out-of-scope follow-ups.
|
||||
mcpToken = TaskRunTokenRegistry.GenerateToken();
|
||||
_tokens.Register(mcpToken, task.Id);
|
||||
Directory.CreateDirectory(_cfg.LogRoot);
|
||||
mcpConfigPath = Path.Combine(_cfg.LogRoot, $"{task.Id}_mcp.json");
|
||||
await File.WriteAllTextAsync(mcpConfigPath, BuildRunMcpConfigJson(mcpToken), ct);
|
||||
|
||||
var improvementEligible = task.ParentTaskId is null && task.PlanningPhase == PlanningPhase.None;
|
||||
resolvedConfig = resolvedConfig with
|
||||
{
|
||||
mcpToken = TaskRunTokenRegistry.GenerateToken();
|
||||
_tokens.Register(mcpToken, task.Id);
|
||||
Directory.CreateDirectory(_cfg.LogRoot);
|
||||
mcpConfigPath = Path.Combine(_cfg.LogRoot, $"{task.Id}_mcp.json");
|
||||
await File.WriteAllTextAsync(mcpConfigPath, BuildRunMcpConfigJson(mcpToken), ct);
|
||||
resolvedConfig = resolvedConfig with
|
||||
{
|
||||
McpConfigPath = mcpConfigPath,
|
||||
AllowedTools = "mcp__claudedo_run__SuggestImprovement",
|
||||
};
|
||||
}
|
||||
McpConfigPath = mcpConfigPath,
|
||||
AllowedTools = improvementEligible
|
||||
? "mcp__claudedo_run__AskUser,mcp__claudedo_run__SuggestImprovement"
|
||||
: "mcp__claudedo_run__AskUser",
|
||||
};
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
// The queue picker claims Queued→Running atomically (incl. StartedAt) before
|
||||
|
||||
Reference in New Issue
Block a user