Maniac Docs
Background Tasks

Background Tasks

Run agents concurrently with BackgroundTaskDispatcher, background-eligible tools, and LM-facing bg_* control tools.

Background Tasks

The @maniac-ai/agents SDK schedules background agent runs in-process via BackgroundTaskDispatcher. Each enqueued task is a full runAgent call with its own tracer, cancellation signal, and optional persistence through BackgroundTaskStore.

Use background tasks when a supervisor agent should:

  • Spawn sub-agents without blocking the foreground turn
  • Fan out work and wait on one or many children (bg_wait)
  • Cap concurrency globally and per agent
  • Stream merged trace events from every in-flight child

Quick start

Enable the dispatcher on your Maniac app, register a background-eligible tool, and let the runner auto-inject control tools:

import { Maniac, OpenAICompatibleModel, tool } from "@maniac-ai/agents";

const research = tool({
  name: "research",
  description: "Run a research sub-agent in the background.",
  inputSchema: {
    type: "object",
    properties: { prompt: { type: "string" } },
    required: ["prompt"]
  },
  background: { enabled: true },
  handler: async ({ prompt }) => `ack for: ${prompt}`
});

const app = new Maniac({
  model: new OpenAICompatibleModel({ slug: "gpt-4o-mini" }),
  backgroundTasks: {
    enabled: true,
    global_concurrency: 10,
    per_agent_concurrency: 5
  }
});

app.agent({
  id: "supervisor",
  instructions: "Delegate research with the research tool; use bg_list and bg_wait to track children.",
  tools: [research]
});

When backgroundTasks.enabled is true, the app exposes app.dispatcher, app.enqueueBackground, app.runUntilIdle, and app.runStreamUntilIdle.

Topics

  • DispatcherBackgroundTaskDispatcher, concurrency caps, lifecycle hooks, and programmatic enqueue
  • Control toolsbg_list, bg_check, bg_cancel, and bg_wait

Python parity

BackgroundTaskDispatcher mirrors Python BackgroundAgentRunDispatcher / BackgroundTaskManager. Serialized task records use the same snake_case field names (task_id, thread_id, tool_call_id, enqueued_at, …). See the migration guide for the full matrix.

On this page