Skip to content

[CRITICAL] Fix Agent Dispatch Pipeline β€” defaultDispatch Always Throws, All Tasks FailΒ #173

Description

@devJaja

🎯 Objective

CRITICAL / URGENT β€” Fix the complete agent dispatch pipeline failure. The coordinator's defaultDispatch always throws, meaning every task submitted fails immediately during execution. The entire multi-agent coordination system is non-functional.


πŸ“ Files to Modify

Action File Path Description
Modify backend/src/api/app.ts Replace defaultDispatch with HTTP dispatch
Modify backend/src/coordinator/coordinator.ts Accept dispatch function parameter

πŸ“ Files to Create

Action File Path Description
Create backend/src/coordinator/dispatch.ts HTTP dispatch with retries, timeouts, agent lookup

πŸ“ Files to Modify (Tests)

Action File Path Description
Modify backend/tests/e2e/pipeline.test.ts Add real HTTP dispatch test
Create backend/src/coordinator/dispatch.test.ts Unit tests for dispatch

πŸ” Root Cause Analysis

// backend/src/api/app.ts β€” line 397
const defaultDispatch = async (nodeId: string, task: any) => {
  throw new Error('No dispatch implementation configured'); // ← ALWAYS THROWS
};

The coordinator calls dispatch() for each DAG node. Since defaultDispatch always throws:

  1. Task is created in database βœ…
  2. DAG is decomposed βœ…
  3. Coordinator starts executing nodes βœ…
  4. dispatch() is called β†’ throws immediately ❌
  5. All nodes marked as failed ❌
  6. Task status becomes failed ❌

πŸ’₯ Impact (Severity: CRITICAL)

  • 100% of submitted tasks fail during execution
  • The entire agent coordination pipeline is dead
  • Research, Risk, Coding, Design, Report agents are never invoked
  • Payment layer never triggers (no nodes complete)
  • Frontend shows all tasks as "failed" immediately after submission
  • The core product value proposition is broken

βœ… Expected Implementation

Create backend/src/coordinator/dispatch.ts

import { SubTask } from '../types/task';
import { getAgentRegistry } from '../agents/registry';

interface DispatchOptions {
  timeoutMs: number;
  maxRetries: number;
  retryDelayMs: number;
}

const DEFAULT_OPTIONS: DispatchOptions = {
  timeoutMs: 60_000,
  maxRetries: 3,
  retryDelayMs: 1_000,
};

export async function httpDispatch(
  subtask: SubTask,
  options: DispatchOptions = DEFAULT_OPTIONS
): Promise<any> {
  const registry = getAgentRegistry();
  const agent = registry.lookupAgent(subtask.type);

  if (!agent) {
    throw new Error(`No agent available for type: ${subtask.type}`);
  }

  let lastError: Error | null = null;

  for (let attempt = 0; attempt <= options.maxRetries; attempt++) {
    try {
      const controller = new AbortController();
      const timeout = setTimeout(() => controller.abort(), options.timeoutMs);

      const response = await fetch(agent.endpoint, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(subtask),
        signal: controller.signal,
      });

      clearTimeout(timeout);

      if (!response.ok) {
        throw new Error(`Agent ${agent.id} returned ${response.status}`);
      }

      return await response.json();
    } catch (err) {
      lastError = err as Error;
      if (attempt < options.maxRetries) {
        await new Promise(r => setTimeout(r, options.retryDelayMs * Math.pow(2, attempt)));
      }
    }
  }

  throw lastError;
}

Update app.ts

import { httpDispatch } from '../coordinator/dispatch';

// Replace defaultDispatch
const dispatch = async (nodeId: string, task: SubTask) => {
  return httpDispatch(task);
};

πŸ“ Reference Files

File Path Lines Issue
backend/src/api/app.ts 397 defaultDispatch always throws
backend/src/coordinator/coordinator.ts ~50 Where dispatch is called
backend/src/agents/registry.ts β€” Agent endpoint lookup
backend/src/types/task.ts β€” SubTask type
backend/src/services/venice/client.ts β€” Retry pattern reference

βœ… Acceptance Criteria

  • Create backend/src/coordinator/dispatch.ts
  • Implement HTTP POST to agent endpoints
  • Implement configurable timeout (default 60s)
  • Implement exponential backoff retry (3 attempts)
  • Handle agent unavailable (503), timeout, network errors
  • Replace defaultDispatch in app.ts
  • Create backend/src/coordinator/dispatch.test.ts
  • Add test: successful dispatch returns response
  • Add test: timeout triggers retry
  • Add test: agent not found throws clear error
  • Update e2e pipeline test with mock HTTP server
  • Verify tasks complete successfully end-to-end

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions