Skip to main content

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.

Agents live in your harness’s native format — a Markdown file per agent, with YAML frontmatter describing it and a body that is its system prompt. Karta discovers them; you don’t redeclare them anywhere else.
HarnessLocation
Claude Code.claude/agents/*.md
OpenCode.opencode/agents/*.md

The format

.claude/agents/billing.md
---
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're referring to.
- Never guess at an amount — look it up or say you can't.

Frontmatter fields

name
string
required
The agent’s identifier. This is the key you route to (app.agents["…"], agent="…").
description
string
A short summary of what the agent does. Used for routing and display.
model
string
Optional model override for this agent (e.g. claude-sonnet-4-6). Falls back to the harness/platform default if omitted.
temperature
number
Optional sampling temperature.
tools
object
Optional map of tool name → enabled. Controls which tools this agent may use.
skills
object
Optional map binding skills to this agent.
permissions
object
Optional permission rules — for example, allowing or denying specific skills.
type
string
default:"primary"
primary or auxiliary. Primary agents can be routed to directly.
The body (everything after the frontmatter) is the agent’s prompt.

Single vs. multiple agents

  • One agent → it’s selected automatically; app.default_agent is it.
  • Multiple agents → route explicitly by name, or set a default. For OpenCode, the default is declared in .opencode/opencode.jsonc as "default_agent": "name". For Claude Code, supplying multiple agents without a clear default is an error — name one as the entry point.
app = Karta()
app.send_sync("Audit invoice #789", agent="billing-specialist")  # route by name

Handing off between agents

Routing chooses an agent per message; handoff changes the current agent for the rest of a session:
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?")

Skills

Reusable capabilities agents can invoke.

Agents (concept)

Routing, handoff, and agents as principals.