Learn Claude Code
s08

Background Tasks

Concurrency

Background Threads + Notifications

230 LOC6 toolsBackgroundManager + notification queue
Run slow operations in the background; the agent keeps thinking ahead

s01 > s02 > s03 > s04 > s05 > s06 > s07 > [ s08 ] s09 > s10 > s11 > s12

"Don't block the main loop waiting for a slow task" -- background threads + notification bus let the agent work while waiting.

Harness layer: Concurrency -- non-blocking execution, background work doesn't stall the main loop.

Problem

Some tool calls are slow: npm install (30s), pytest (2min), docker build (5min). Synchronous waiting wastes time — the agent could do other work while waiting.

Solution

Background threads execute slow tasks, main loop continues. NotificationBus delivers completion results.

Key Code

class BackgroundExecutor:
    def submit(self, task_id, fn, *args):
        def wrapper():
            result = fn(*args)
            self.bus.notify(task_id, result)
        threading.Thread(target=wrapper, daemon=True).start()
        return task_id

TOOL_HANDLERS = {
    "bg_bash": lambda **kw: executor.submit(kw["id"], run_bash, kw["command"]),
    "check_bg": lambda **kw: bus.check(kw["id"]),
}

What's New (s07 → s08)

Components07s08
ExecutionSynchronousSync + async background
BlockingWait for every toolSlow tasks go background
ConcurrencySingle-threadedMain + N background threads

Deep Dive

Q1: Why threads not asyncio?

Simpler, and background tasks are I/O-bound (waiting for subprocesses). GIL irrelevant here.

Q2: How does the agent know background tasks are done?

Polling (check_bg(id)) in s08. Alternative: inject notifications into next tool_result.

Q3: What if background task fails?

Catch exception, store error in NotificationBus. Agent sees "ERROR: ..." on next check.

Q4: Max concurrent background tasks?

Empirically 3-5. More creates state tracking burden.

Q5: How does this differ from s20 Parallel Teams?

s08 = background threads in same process. s20 = multiple independent processes with separate contexts.

Try It

cd learn-claude-code
python agents/s08_background_tasks.py

References