Skip to content

Commit 68e4202

Browse files
fix(orchestrator): augment lazy final_answer with worker outputs
Root cause found via Railway logs: the brain LLM calls final_answer with a 95-char summary instead of the full synthesized content. The worker delegation results contain thousands of chars of detailed output, but the brain just says 'Task completed successfully.' Fix: when final_answer output is less than 20% of the combined worker outputs, automatically append all completed delegation results as structured markdown sections (## WorkerName). This ensures the full team output reaches Trello/Slack/Discord regardless of brain behavior. Also added DB fallback in webhookDispatcher: if no output is passed inline, fetch it from team_runs table as a safety net.
1 parent 1b6bb6b commit 68e4202

1 file changed

Lines changed: 38 additions & 2 deletions

File tree

task-runner/src/orchestratorExecutor.ts

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -542,8 +542,44 @@ async function executeToolCall(
542542
}
543543

544544
case 'final_answer': {
545-
const output = args.output as string;
546-
console.log(`[Orchestrator] final_answer received, output length: ${output?.length ?? 0} chars`);
545+
let output = (args.output as string) ?? '';
546+
console.log(`[Orchestrator] final_answer received, brain output length: ${output.length} chars`);
547+
548+
// ── Augment with worker outputs if the brain was lazy ────────
549+
// LLMs often call final_answer with a brief summary like
550+
// "Task completed successfully" instead of including the full
551+
// synthesized content. If the final answer is much shorter than
552+
// the accumulated worker outputs, append them.
553+
const completedDelegations = Array.from(delegations.values())
554+
.filter((d) => d.status === 'completed' && d.worker_output);
555+
556+
if (completedDelegations.length > 0) {
557+
const workerOutputsTotal = completedDelegations
558+
.reduce((sum, d) => sum + (d.worker_output?.length ?? 0), 0);
559+
560+
// If brain's final answer is less than 20% of workers' combined output,
561+
// the brain likely just wrote a summary — augment with full worker outputs
562+
if (output.length < workerOutputsTotal * 0.2) {
563+
console.log(`[Orchestrator] Brain output (${output.length} chars) << worker outputs (${workerOutputsTotal} chars) — augmenting`);
564+
565+
const workerSections = completedDelegations.map((d) => {
566+
const worker = workers.find((w) => w.id === d.worker_agent_id);
567+
const workerName = worker?.name ?? 'Worker';
568+
return `## ${workerName}\n\n${d.worker_output}`;
569+
});
570+
571+
output = [
572+
output,
573+
'',
574+
'---',
575+
'',
576+
...workerSections,
577+
].join('\n');
578+
579+
console.log(`[Orchestrator] Augmented final output: ${output.length} chars`);
580+
}
581+
}
582+
547583
await finalizeRun(run.id, output, 0, 0); // tokens/cost already tracked
548584
return { result: output, tokensUsed: 0, costUsed: 0, isDone: true };
549585
}

0 commit comments

Comments
 (0)