Agentic AI Atlasby a5c.ai
OverviewWikiGraphFor AgentsEdgesSearchWorkspace
/
GitHubDocsDiscord
iiRecord
Agentic AI Atlas · Tasks-Adapter as Unified Task Routing Hub
page:docs-adapters-babysitter-integrations-tasks-adapter-routinga5c.ai
Search record views/
Record · tabs

Available views

II.Record viewspp. 1 - 1
overviewarticlejsongraph
III.Related pagespp. 1 - 1
II.
Page reference

page:docs-adapters-babysitter-integrations-tasks-adapter-routing

Reading · 6 min

Tasks-Adapter as Unified Task Routing Hub reference

Instead of the SDK talking to adapters directly, tasks-adapter becomes the single routing layer for all task dispatch — human responders, adapters adapters, and external issue trackers. The SDK only needs to know about tasks-adapter.

Pagewiki/docs/adapters-babysitter-integrations/tasks-adapter-routing.mdOutgoing · 0Incoming · 1

Tasks-Adapter as Unified Task Routing Hub

Motivation

Instead of the SDK talking to adapters directly, **tasks-adapter** becomes the single routing layer for all task dispatch — human responders, adapters adapters, and external issue trackers. The SDK only needs to know about tasks-adapter.

This is better because:

  • One routing system for all task types (human, agent, external)
  • Cross-cutting concerns (priorities, dependencies, tracking, SLA) apply uniformly
  • tasks-adapter already has backend abstraction, responder matching, lifecycle management
  • Adapters becomes a "responder type" in tasks-adapter, not a separate integration surface
  • External issue trackers are also responder types — same abstraction

Architecture

Code
SDK process: ctx.task(myTask)
  ↓ creates effect (journaled)
  ↓
tasks-adapter routes by responder type:
  ├─ type: "internal"  → agent-core session (direct API call)
  ├─ type: "human"     → breakpoint → human responder (existing)
  ├─ type: "agent"     → adapters adapter (claude-code, codex, etc.)
  ├─ type: "tracker"   → external issue tracker (Jira, Linear, GitHub Issues)
  └─ type: "auto"      → tasks-adapter picks best available responder

Design Changes

1. tasks-adapter: Responder Types

Current responders are human-only. Extend to support agent responders:

typescript
// packages/tasks-adapter/src/types.ts

type ResponderType = "human" | "agent" | "tracker" | "internal";

interface Responder {
  id: string;
  type: ResponderType;
  name: string;
  capabilities: string[];
  // Agent-specific:
  adapter?: string;        // adapters adapter name
  model?: string;          // default model
  provider?: string;       // default provider
  // Tracker-specific:
  trackerBackend?: string; // "github-issues" | "jira" | "linear"
  trackerConfig?: Record<string, unknown>;
}

2. tasks-adapter: Agent Responder Backend

New backend that wraps adapters:

typescript
// packages/tasks-adapter/src/backends/adapters.ts

class AgentMuxResponderBackend implements BreakpointBackend {
  async submitBreakpoint(params: SubmitBreakpointParams): Promise<Breakpoint> {
    // Route to adapters adapter
    const adapterClient = await getAmuxClient();
    const handle = await adapterClient.run({
      agent: params.routing.targetAdapter,
      prompt: params.question,
      model: params.routing.model,
      nonInteractive: true,
      timeout: params.routing.timeout ?? 300_000,
    });
    
    // Collect result
    const result = await handle.result;
    
    // Return as answered breakpoint
    return {
      ...breakpoint,
      status: "answered",
      answer: { text: result.output, responderId: params.routing.targetAdapter },
    };
  }
  
  // waitForAnswer is immediate — agent responds synchronously
  async waitForAnswer(id: string): Promise<BreakpointAnswer> {
    return this.answers.get(id)!;
  }
}

3. SDK: Task Definition Routes Through tasks-adapter

Replace direct adapters references with tasks-adapter routing:

javascript
// Process definition — routes through tasks-adapter
const reviewTask = defineTask("review", (args) => ({
  kind: "agent",
  title: "Code review",
  agent: {
    prompt: "Review the changes...",
    // Routing handled by tasks-adapter, not SDK:
    responderType: "agent",     // tasks-adapter routes to adapters
    adapter: "claude-code",     // hint for tasks-adapter routing
    fallbackType: "internal",   // if adapters unavailable, use internal
  },
}));

// Human review task — same routing system
const approvalTask = defineTask("approval", (args) => ({
  kind: "breakpoint",
  title: "Approve deployment",
  breakpoint: {
    question: "Approve deployment to production?",
    responderType: "human",     // tasks-adapter routes to human
    // Or sync to external tracker:
    responderType: "tracker",
    trackerBackend: "jira",
  },
}));

// Auto-routing — tasks-adapter picks best responder
const flexibleTask = defineTask("flexible", (args) => ({
  kind: "agent",
  title: "Implement feature",
  agent: {
    prompt: "Implement the feature...",
    responderType: "auto",      // tasks-adapter picks based on availability + capabilities
  },
}));

4. tasks-adapter: Routing Logic

typescript
// packages/tasks-adapter/src/router.ts

async function routeTask(task: TaskDef, context: RoutingContext): Promise<Responder> {
  const type = task.agent?.responderType ?? task.breakpoint?.responderType ?? "internal";
  
  switch (type) {
    case "internal":
      return { id: "agent-core", type: "internal", name: "Internal Agent", capabilities: ["text"] };
      
    case "human":
      return await matchHumanResponder(task, context);
      
    case "agent":
      return await matchAgentResponder(task, context);
      
    case "tracker":
      return await matchTrackerResponder(task, context);
      
    case "auto":
      // Try agent first (faster), fall back to human if no agent available
      const agent = await matchAgentResponder(task, context).catch(() => null);
      if (agent) return agent;
      return await matchHumanResponder(task, context);
      
    default:
      throw new Error(`Unknown responder type: ${type}`);
  }
}

async function matchAgentResponder(task: TaskDef, context: RoutingContext): Promise<Responder> {
  const discovery = await discoverExternalAgents();
  if (!discovery.available) {
    if (task.agent?.fallbackType === "internal") {
      return { id: "agent-core", type: "internal", name: "Internal (fallback)", capabilities: ["text"] };
    }
    throw new Error("No agent responders available (adapters not installed)");
  }
  
  const preferred = task.agent?.adapter;
  if (preferred) {
    const agent = discovery.agents.find(a => a.name === preferred && a.installed);
    if (agent) return { id: agent.name, type: "agent", name: agent.displayName, adapter: agent.name, capabilities: agent.capabilities };
    // Preferred not available — try any installed agent
  }
  
  const installed = discovery.agents.filter(a => a.installed && a.authenticated);
  if (installed.length === 0) throw new Error("No authenticated agent responders available");
  return { id: installed[0].name, type: "agent", name: installed[0].displayName, adapter: installed[0].name, capabilities: installed[0].capabilities };
}

5. Effect Resolution via tasks-adapter

Instead of the current direct dispatch, effects flow through tasks-adapter:

Code
Current:
  SDK effect → agent-platform resolveEffect → adapterBridge (direct)

New:
  SDK effect → tasks-adapter.submitTask(effect) → tasks-adapter.routeTask()
    → type=agent  → AgentMuxResponderBackend → adapterBridge
    → type=human  → BreakpointBackend (existing)
    → type=tracker → ExternalTrackerBackend (new)
    → type=internal → agent-core session (existing)

6. Plugin Mode Integration

In plugin mode (babysitter running inside claude-code), tasks-adapter routing is the same:

  • Internal tasks → delegated to host agent (via stop-hook)
  • Agent tasks → resolved internally by tasks-adapter → adapters → external agent
  • Human tasks → routed to tasks-adapter breakpoint system
  • Tracker tasks → synced to external tracker

The stop-hook handler queries tasks-adapter for task routing before deciding what to delegate to the host vs. resolve internally.

Benefits Over Direct Integration

ConcernDirect adaptersThrough tasks-adapter
Task prioritiesNot supportedBuilt-in (when added to tasks-adapter)
DependenciesNot supportedBuilt-in (when added)
SLA trackingNot supportedUnified metrics across all responder types
Retry/escalationManualtasks-adapter handles escalation chains
Audit trailPer-dispatchUnified breakpoint lifecycle
Cost trackingPer-dispatchAggregated across all tasks
Human fallbackCustom coderesponderType: "auto" handles it
External trackingSeparate integrationSame backend abstraction

Migration Path

1. **Phase 1:** Add agent responder type to tasks-adapter + AgentMuxResponderBackend 2. **Phase 2:** SDK routes through tasks-adapter instead of direct adapters 3. **Phase 3:** Add tracker responder type for external issue trackers 4. **Phase 4:** Add "auto" routing with capability-based responder matching 5. **Phase 5:** Add priorities, dependencies, SLA across all responder types

Files to Create

FileDescription
packages/tasks-adapter/src/backends/adapters.tsAdapters responder backend
packages/tasks-adapter/src/router.tsTask routing logic
packages/tasks-adapter/src/responders/types.tsExtended responder types
packages/tasks-adapter/src/backends/__tests__/adapters.test.tsTests

Files to Modify

FileChange
packages/tasks-adapter/src/types.tsAdd ResponderType, extend Responder
packages/tasks-adapter/src/backend.tsSupport multiple backend types
packages/babysitter-sdk/src/runtime/intrinsics/task.tsRoute through tasks-adapter
packages/genty/platform/src/harness/internal/createRun/orchestration/effects.tsUse tasks-adapter routing
packages/babysitter-sdk/src/harness/hooks/stopHookHandler.tsQuery tasks-adapter for routing decisions

Article source

The article body is owned directly by this record.

Related pages

No related wiki pages for this record.

Shortcuts

Open overview
Open JSON
Open graph