Subagents
The Bub app includes a built-in subagent tool that lets the current agent delegate a specific subtask to a child run of the same agent.
Subagents are a good fit for tasks that generate a huge amount of intermediate context — large-scale retrieval, long document reading, independent code review — so that only the final conclusions return to the main session and intermediate details don’t consume its context window.
Delegate a task
Section titled “Delegate a task”In bub chat, you can ask the model to call a subagent directly:
Use the subagent tool to review the authentication flow:1. Use a temporary session and allow only fs.read and bash;2. Do not modify files;3. Return the review findings with the relevant file paths.The parent agent then calls the subagent tool, which starts the child in the background and returns a task ID at once. The child calls tools inside its own loop, finishes the analysis, and its final answer reaches the parent as a message. Only that answer, the text of the child’s last step, comes back; the child’s intermediate narration and tool calls stay out of the parent’s context.
The child sees only its prompt (and, with session="fork", the conversation so far), so the prompt should be self-contained: say what to do, what to return, and any limits.
Beyond asking by hand, you can also set a rule in the workspace AGENTS.md or in a skill (for example, “complex retrieval or code review should be delegated to a read-only subagent first, and the main agent only applies changes based on the review”) to get automatic delegation.
Choose a session strategy
Section titled “Choose a session strategy”The session parameter decides what the child starts from and what is kept:
| Session mode | Behavior | Use it for |
|---|---|---|
temp (default) |
A new, empty temp/<task_id> session, discarded afterwards |
Most common. One-off analysis or research that returns conclusions only |
fork |
Starts from a copy of the current conversation, including the current turn so far; discarded afterwards | Subtasks that need what the user and the parent already said, without the parent re-explaining it |
| A custom string | Uses that fixed session ID, which is kept | Longer work you want to continue later with subagent.send, or inspect afterwards |
inherit is accepted as an alias of fork. A fork copies the conversation at the moment of the call, so the child does not see what the parent does next, and nothing the child does is written back to the parent’s history.
Receive results
Section titled “Receive results”Subagents always run in the background: the parent keeps working while they run, so several subagents can work in parallel while the parent does something else:
Start three subagents, one per service, to check the logs for errors.Keep working on the migration; summarize their findings when they are done.When a task ends, its result reaches the parent as a message:
<subagent-notification task_id="sub-1a2b3c4d" status="completed">No errors in the payments service logs since the last deploy.</subagent-notification>The parent reads it before its next step. A turn does not end while subagents it started are still running: when the parent has nothing else to do, it waits for the next result and continues with it, so it can summarize every finding before replying. A task that outlives its turn, because the turn failed, was cancelled or reached its step limit, reports with the session’s next turn. The parent can also manage tasks directly:
| Tool | What it does |
|---|---|
subagent.wait |
Return results, waiting up to timeout_seconds (default 60; 0 only checks). Without task_ids, covers the session’s unread tasks. A result read here sends no notification. |
subagent.send |
Message a running task, which reads it before its next step; or continue a finished task that used a named session. |
subagent.cancel |
Stop a running task. |
At most BUB_SUBAGENT_MAX_CONCURRENCY subagents (default 4) run at once; later ones wait in a queue. timeout_seconds on the call, or BUB_SUBAGENT_TIMEOUT_SECONDS globally, stops a child that runs too long. Ending Bub, or the ,quit command for a session, cancels its running subagents.
Define subagent profiles
Section titled “Define subagent profiles”A profile is a reusable subagent: a markdown file in .agents/agents/ in the workspace, or in ~/.agents/agents/ for every workspace. The front matter sets its configuration, and the body is added to the child’s system prompt:
---description: Reviews a change for bugs and reports findings without editing filesmodel: openai:gpt-5-minitools: [fs.read, bash, tape.search]skills: []timeout_seconds: 600---
You review code. Read the relevant files, report concrete findings with filepaths and line numbers, and never modify files.| Field | Meaning |
|---|---|
description |
Required. Tells the parent when to use the profile |
name |
Optional; defaults to the file name without .md |
model, reasoning_effort |
The child’s model and reasoning effort |
tools, skills |
The child’s allowed tools and skills (a list, or a comma-separated string) |
timeout_seconds |
The child’s time limit |
When the subagent tool is available, the parent’s system prompt lists the profiles, and the model uses one by passing its name as agent. Arguments given in the call take precedence over the profile. A workspace profile overrides a home profile with the same name.
State sharing and capability boundaries
Section titled “State sharing and capability boundaries”A subagent is a child run of the same agent instance as its parent. What it inherits and what stays isolated:
| Resource | Boundary | Notes and controls |
|---|---|---|
| Base instance | Fully shared | Shares plugin hooks, model credentials, and BubAgent configuration |
| Execution environment | Fully shared | Shares the workspace directory, local filesystem, Shell processes, and network access |
| Model selection | Set separately | Defaults to the profile’s model or the parent’s; use model to pick a lighter one |
| Tools and skills | At most the parent’s | Defaults to the parent run’s tools and skills; allowed_tools and allowed_skills narrow them further. Children cannot start subagents |
| Turn state | Copied | The child gets a copy of the parent’s turn state with its own steering key, so messages sent to the parent stay with the parent |
| Conversation records | Per session strategy | temp and fork are discarded; a named session is kept |
Parameter types and defaults are listed in the subagent reference. Channels can observe subagents through events.
Security limits
Section titled “Security limits”Like the parent, a subagent also runs in the local environment under the current user’s privileges, and can affect the current system:
- A session strategy isolates only conversation records and model context, not files, network requests, or system processes. File changes and network requests made by the child have real system side effects and are not rolled back on exit.
- In chat, the model writes the
subagentarguments, soallowed_toolsrestricts model behavior but is not an enforced security boundary. To hard-block dangerous commands or out-of-scope tools, use tool interception hooks; for physical isolation, configure a separate execution environment.