fix(worker): prefix broadcast lines with [stdout] so UI parser routes them

This commit is contained in:
Mika Kuns
2026-04-21 15:35:40 +02:00
parent 374e811e78
commit 4283c67d81

View File

@@ -82,13 +82,7 @@ public sealed class TaskRunner
Directory.CreateDirectory(runDir);
}
// Resolve config: task overrides > list config > null.
var resolvedConfig = new ClaudeRunConfig(
Model: task.Model ?? listConfig?.Model ?? "claude-sonnet-4-6",
SystemPrompt: task.SystemPrompt ?? listConfig?.SystemPrompt,
AgentPath: task.AgentPath ?? listConfig?.AgentPath,
ResumeSessionId: null
);
var resolvedConfig = await ResolveConfigAsync(task, listConfig, null, ct);
var now = DateTime.UtcNow;
using (var context = _dbFactory.CreateDbContext())
@@ -186,12 +180,7 @@ public sealed class TaskRunner
worktree = await wtRepo.GetByTaskIdAsync(taskId, ct);
}
var resolvedConfig = new ClaudeRunConfig(
Model: task.Model ?? listConfig?.Model,
SystemPrompt: task.SystemPrompt ?? listConfig?.SystemPrompt,
AgentPath: task.AgentPath ?? listConfig?.AgentPath,
ResumeSessionId: lastRun.SessionId
);
var resolvedConfig = await ResolveConfigAsync(task, listConfig, lastRun.SessionId, ct);
// Determine run directory from existing worktree or sandbox.
string runDir;
@@ -268,7 +257,7 @@ public sealed class TaskRunner
async line =>
{
await logWriter.WriteLineAsync(line, ct);
await _broadcaster.TaskMessage(taskId, line);
await _broadcaster.TaskMessage(taskId, "[stdout] " + line);
},
ct);
@@ -372,4 +361,35 @@ public sealed class TaskRunner
_logger.LogError(ex, "Failed to mark task {TaskId} as failed", taskId);
}
}
private async Task<ClaudeRunConfig> ResolveConfigAsync(
TaskEntity task, ListConfigEntity? listConfig, string? resumeSessionId, CancellationToken ct)
{
AppSettingsEntity global;
using (var ctx = _dbFactory.CreateDbContext())
{
var settingsRepo = new AppSettingsRepository(ctx);
global = await settingsRepo.GetAsync(ct);
}
var instructions = MergeInstructions(
global.DefaultClaudeInstructions, listConfig?.SystemPrompt, task.SystemPrompt);
return new ClaudeRunConfig(
Model: task.Model ?? listConfig?.Model ?? global.DefaultModel,
SystemPrompt: string.IsNullOrWhiteSpace(instructions) ? null : instructions,
AgentPath: task.AgentPath ?? listConfig?.AgentPath,
ResumeSessionId: resumeSessionId,
MaxTurns: global.DefaultMaxTurns,
PermissionMode: global.DefaultPermissionMode);
}
public static string MergeInstructions(string? global, string? list, string? task)
{
var parts = new List<string>(3);
if (!string.IsNullOrWhiteSpace(global)) parts.Add(global.Trim());
if (!string.IsNullOrWhiteSpace(list)) parts.Add(list.Trim());
if (!string.IsNullOrWhiteSpace(task)) parts.Add(task.Trim());
return string.Join("\n\n", parts);
}
}