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

# Sub-agent files

> The Markdown-with-frontmatter format for harness sub-agents across supported harnesses.

Sub-agents live in your harness's native format - a Markdown file per role,
with YAML frontmatter describing it and a body that is its system prompt. Karta
discovers those files; you do not redeclare them anywhere else.

| Harness     | Location                  |
| ----------- | ------------------------- |
| Claude Code | `.claude/agents/*.md`     |
| OpenCode    | `.opencode/agents/*.md`   |
| DeepAgents  | `.deepagents/agents/*.md` |
| Goose       | `.goose/agents/*.md`      |
| Codex CLI   | `.codex/agents/*.md`      |

## The format

```markdown .claude/agents/billing.md theme={null}
---
name: billing-specialist
description: Handles invoice and billing questions
model: claude-sonnet-4-6
temperature: 0.3
tools:
  read: true
  write: false
permissions:
  skill:
    billing-lookup: allow
type: primary
---

You are a billing specialist for Karta Coffee Co.

- Answer questions about invoices, charges, and refunds.
- Always cite the invoice number you are referring to.
- Never guess at an amount - look it up or say you cannot.
```

## Frontmatter fields

<ResponseField name="name" type="string" required>
  The sub-agent's identifier. This is the key you route to
  (`app.agents["billing-specialist"]`, `agent="billing-specialist"`).
</ResponseField>

<ResponseField name="description" type="string">
  A short summary of what the sub-agent does. Used for routing and display.
</ResponseField>

<ResponseField name="model" type="string">
  Optional model override for this sub-agent (e.g.
  `claude-sonnet-4-6`). Falls back to the harness/platform default if omitted.
</ResponseField>

<ResponseField name="temperature" type="number">
  Optional sampling temperature.
</ResponseField>

<ResponseField name="tools" type="object">
  Optional map of tool name -> enabled. Controls which tools this sub-agent may
  use.
</ResponseField>

<ResponseField name="permissions" type="object">
  Optional permission rules - for example, allowing or denying specific skills
  with `permissions.skill`.
</ResponseField>

<ResponseField name="type" type="string" default="primary">
  `primary` or `auxiliary`. Karta preserves this metadata for the harness and
  routing UI.
</ResponseField>

The body (everything after the frontmatter) is the sub-agent's prompt.

## Single vs. multiple sub-agents

* **One sub-agent** -> it is selected automatically; `app.default_agent`
  is it.
* **Multiple sub-agents** -> route explicitly by name, or set a default. For
  OpenCode, the default is declared in `.opencode/opencode.jsonc` as
  `"default_agent": "name"`. If Karta cannot resolve a default, startup fails
  with a configuration error instead of guessing.

```python theme={null}
app = Karta()
app.send_sync("Audit invoice #789", agent="billing-specialist")  # route by name
```

## Handing off between sub-agents

Routing chooses a sub-agent per message; **handoff** changes the current
sub-agent for the rest of a [session](/concepts/sessions-and-participants):

```python theme={null}
session = app.session(metadata={"customer_id": "abc123"})
session.send_sync("I have a billing question")
session.current_agent = app.agents["billing-specialist"]   # fires agent.handoff
session.send_sync("Was I charged twice for #789?")
```

<CardGroup cols={2}>
  <Card title="Skills" icon="wand-magic-sparkles" href="/build/skills">
    Reusable capabilities agents can invoke.
  </Card>

  <Card title="Sub-agents" icon="user-astronaut" href="/concepts/agents">
    Routing, handoff, and runtime authority.
  </Card>
</CardGroup>
