> ## Documentation Index
> Fetch the complete documentation index at: https://cadenya.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Delegate to sub-agents

> Attach a published specialist to one parent variation, run the specialist in a child objective, and inspect the handoff.

A sub-agent is a normal published agent assigned to another agent variation. The parent sees it as a callable tool. When the parent calls it, Cadenya creates a child objective with the specialist's own variation, model, context, tools, and memory.

```mermaid theme={null}
---
config:
  themeCSS: |
    .actor {
      fill: #347763 !important;
      stroke: #165B41 !important;
    }
    text.actor, text.actor-box,
    text.actor tspan, text.actor-box tspan {
      fill: #FFFFFF !important;
    }
    .actor-line {
      stroke: #739486 !important;
    }
---
sequenceDiagram
    participant P as Parent agent
    participant C as Cadenya
    participant S as Specialist
    P->>C: Call specialist with a message
    C->>S: Create child objective
    S-->>C: Return specialist result
    C-->>P: Return tool result
    P->>P: Continue in the parent context
```

## What you need

* A published parent agent with a variation.
* A second published agent to use as the specialist.
* Both agents in the same workspace.

## Build a focused specialist

Use [Create and publish an agent](/docs/guides/configure-a-simple-agent) to create `Refund Specialist`.

Configure the agent:

| Field           | Value                                                                                 |
| --------------- | ------------------------------------------------------------------------------------- |
| **Name**        | `Refund Specialist`                                                                   |
| **External ID** | `refund-specialist`                                                                   |
| **Description** | `Evaluates whether a damaged order qualifies for a refund and explains the decision.` |

Configure one variation:

```text theme={null}
You are a refund policy specialist. Evaluate the facts in the delegated message. Return a concise eligibility decision and the reason. Do not answer unrelated questions.
```

Do not assign other agents to this specialist, then publish it.

<Note>
  The specialist's agent description helps the parent model decide when to call it. Keep the description specific to the task boundary.
</Note>

## Attach the specialist

Open the parent agent, stay on **Variations**, and select the target variation. Under **Assignments**, click **Add**, choose **Sub-Agent**, search for `Refund Specialist`, and select it.

<Frame caption="The assignment picker offers Tool, Tool Set, and Sub-Agent">
  <img src="https://mintcdn.com/cadenya/uaQ7Uw3TsXMwadaa/images/docs/agents/sub-agent-picker.webp?fit=max&auto=format&n=uaQ7Uw3TsXMwadaa&q=85&s=bab3725dd6c9fdf7366c18c76b218ea7" alt="Inline assignment picker set to Sub-Agent with a search field and an existing Faker MCP assignment" width="1910" height="358" data-path="images/docs/agents/sub-agent-picker.webp" />
</Frame>

The assignment belongs only to this parent variation. Other variations on the same agent do not receive the specialist automatically.

From the SDK:

```typescript theme={null}
await client.agents.variations.addAssignment(
  parentAgentId,
  parentVariationId,
  {
    workspaceId,
    type: 'subAgentId',
    subAgentId: 'external_id:refund-specialist',
  },
);
```

## Bound the parent's delegation

Edit the parent variation and set **Max sub-objectives** to a deliberate positive limit, such as `2`.

`constraints.maxSubObjectives` caps the number of child objectives one parent objective can create. A value of `0` means no limit.

```typescript theme={null}
await client.agents.variations.update(
  parentAgentId,
  parentVariationId,
  {
    workspaceId,
    updateMask: 'spec.constraints',
    spec: {
      constraints: {
        maxSubObjectives: 2,
      },
    },
  },
);
```

Also tell the parent prompt when to delegate and when to answer directly:

```text theme={null}
Call Refund Specialist only when the user asks for a refund eligibility decision. Pass the order facts in the delegated message. For all other support questions, answer directly.
```

## Run the parent

Dispatch an objective that crosses the specialist boundary:

```typescript theme={null}
const objective = await client.objectives.create({
  workspaceId,
  agentId: parentAgentId,
  variationId: parentVariationId,
  systemPromptData: {},
  firstUserMessage:
    'Order A-1007 arrived with a cracked screen. Is it eligible for a refund?',
});
```

Open the parent objective. The **Timeline** records **Sub-Agent Spawned**. Expand the event to open the child objective directly.

<Frame caption="The parent timeline links the spawned specialist objective">
  <img src="https://mintcdn.com/cadenya/uaQ7Uw3TsXMwadaa/images/docs/agents/sub-agent-spawned.webp?fit=max&auto=format&n=uaQ7Uw3TsXMwadaa&q=85&s=6d037ea101c3e9ed19e8acb470950ef1" alt="Expanded Sub-Agent Spawned event linking to the Refund Specialist child objective" width="2664" height="256" data-path="images/docs/agents/sub-agent-spawned.webp" />
</Frame>

Select **Sub-Agents** to compare each child's status, delegated message, agent, token usage, and creation time.

<Frame caption="Every delegated objective remains inspectable">
  <img src="https://mintcdn.com/cadenya/uaQ7Uw3TsXMwadaa/images/docs/agents/sub-agents-tab.webp?fit=max&auto=format&n=uaQ7Uw3TsXMwadaa&q=85&s=37b8f05818ea835034f1fb52e75bc481" alt="Sub-Agents tab showing a finalized Refund Specialist objective for order A-1007" width="2664" height="380" data-path="images/docs/agents/sub-agents-tab.webp" />
</Frame>

The typed `subAgentSpawned` event includes the specialist and child objective metadata:

```typescript theme={null}
let childObjectiveId: string | undefined;

for await (const event of client.objectives.listEvents(
  objective.metadata.id,
  { workspaceId },
)) {
  const data = event.data;

  switch (data.type) {
    case 'subAgentSpawned':
      console.log({
        agent: data.subAgentSpawned.agent?.name,
        objectiveId: data.subAgentSpawned.objective?.id,
        task: data.subAgentSpawned.task,
      });
      childObjectiveId = data.subAgentSpawned.objective?.id;
      break;
    default:
      break;
  }
}

if (!childObjectiveId) {
  throw new Error('The parent did not spawn a specialist');
}

const child = await client.objectives.retrieve(childObjectiveId, {
  workspaceId,
});

console.log(child.state);
```

## Foreground and background calls

The generated sub-agent tool accepts:

* `message`, the required task sent to the specialist.
* `background`, an optional boolean.

The default foreground call waits for the child and returns its result to the parent. With `background: true`, the call returns the child objective ID immediately. The parent can do other work, then call Cadenya's built-in `get_sub_agent_results` with one or more child objective IDs.

Use background delegation only when the parent prompt explains when to collect the results. Otherwise a child can finish without its answer being incorporated.

## Choose a sub-agent boundary

Create a specialist when the work benefits from at least one separate concern:

* A different system prompt or model.
* A different tool or memory boundary.
* An isolated context window.
* Parallel work through background calls.
* An independently measurable objective and timeline.

Keep a step in the parent when it is small, uses the same context, and does not need separate controls.

<CardGroup cols={2}>
  <Card title="Assign capabilities" icon="screwdriver-wrench" href="/docs/guides/agents/assignments">
    Compare sub-agents with individual tools and complete tool sets.
  </Card>

  <Card title="How objectives work" icon="diagram-project" href="/docs/guides/objectives">
    Understand parent and child objectives, snapshots, and event timelines.
  </Card>
</CardGroup>
