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

# Agent Types

> Understanding the four agent types on orchagent

orchagent has four canonical types: **prompt**, **tool**, **agent**, and **skill**.

<Tip>
  **Building with an AI coding assistant?** Install the agent-builder skill to give your AI the complete platform reference — sandbox contracts, boilerplate code, environment details, and debugging patterns:

  ```bash theme={null}
  orch skill install orchagent/agent-builder
  ```

  This works with Claude Code, Cursor, Amp, and other AI tools. Your AI will have everything it needs to build agents on orchagent without trial and error.
</Tip>

## The Four Types

| Type         | What it is                                  | Default execution engine |
| ------------ | ------------------------------------------- | ------------------------ |
| **`prompt`** | Prompt template + schema → single LLM call  | `direct_llm`             |
| **`tool`**   | Python or JavaScript code runs in a sandbox | `code_runtime`           |
| **`agent`**  | LLM tool-use loop with custom tools         | `managed_loop`           |
| **`skill`**  | Passive knowledge (markdown) — not runnable | N/A                      |

The first three are executable. Skills are passive knowledge that enhances other types.

<Info>
  **Quick distinction:** `prompt` types answer questions. `tool` types run your code. `agent` types reason and iterate with tools. `skill` types teach other agents.
</Info>

### Type determines execution engine

The `type` field sets sensible defaults for how your agent executes. You can still override with explicit declarations:

| Override                             | Effect                          |
| ------------------------------------ | ------------------------------- |
| Adding `runtime.command` to any type | Forces `code_runtime`           |
| Adding `loop` config to any type     | Forces `managed_loop`           |
| Neither declared on a `prompt` type  | Uses `direct_llm` (the default) |

You also control **when** the agent runs:

| `run_mode`            | Behavior                                                      |
| --------------------- | ------------------------------------------------------------- |
| `on_demand` (default) | Each call is independent — run via CLI, API, or schedule      |
| `always_on`           | Persistent service — Discord bots, webhook listeners, workers |

And whether the agent is **callable** by other agents:

| `callable`       | Behavior                                                  |
| ---------------- | --------------------------------------------------------- |
| `true` (default) | Other agents can call this agent as a dependency          |
| `false`          | Only users can call this agent (e.g., always-on services) |

<Tip>
  **Start with the type that matches your use case.** The type provides the right execution defaults automatically. You only need to override with `runtime` or `loop` declarations if you're doing something non-standard.
</Tip>

## Which Type Should I Use?

Ask yourself one question: **what does your agent need to do?**

```
What are you building?
│
├─ "LLM answers a question / generates content"
│   └─ type: "prompt"
│      e.g. sentiment analyzer, summarizer, translator, code explainer
│
├─ "My code does the work (maybe calls an LLM inside)"
│   └─ type: "tool"
│      e.g. security scanner, data pipeline, file converter, API integration
│
├─ "LLM figures things out using tools"
│   └─ type: "agent"
│      e.g. test fixer, code reviewer, research agent, deploy assistant
│
└─ "I want to share knowledge with agents or AI tools"
    └─ type: "skill"
       e.g. coding standards, security rules, brand guidelines
```

<Tip>
  **Start with the simplest type that works.** Most use cases need only a `prompt` (prompt + schema). If you need the LLM to iterate with tools, use `agent`. Only reach for `tool` when you need full programmatic control or don't need an LLM.
</Tip>

### Common Use Cases

Not sure which pattern fits? Find your use case below:

| I want to...                                         | Type     | Why                                       |
| ---------------------------------------------------- | -------- | ----------------------------------------- |
| Analyze sentiment or classify text                   | `prompt` | One LLM call, structured JSON output      |
| Summarize or translate documents                     | `prompt` | One LLM call, no tools needed             |
| Generate marketing copy or emails                    | `prompt` | Prompt engineering, structured output     |
| Extract data from text (names, dates, etc.)          | `prompt` | One LLM call with output schema           |
| Fix code until tests pass                            | `agent`  | LLM reads code, runs tests, iterates      |
| Review pull requests or audit code                   | `agent`  | LLM navigates files, checks patterns      |
| Research a topic and write a report                  | `agent`  | LLM searches, reads, synthesizes          |
| Scan repos for secrets or vulnerabilities            | `tool`   | Deterministic logic, fast, no LLM needed  |
| Process uploaded files (PDF, CSV, images)            | `tool`   | File I/O, custom parsing logic            |
| Call external APIs and transform data                | `tool`   | Full HTTP control, auth, error handling   |
| Run a multi-model pipeline (different LLMs per step) | `tool`   | You control which LLM handles each step   |
| Build a Discord bot or webhook listener              | `tool`   | Persistent service, event-driven          |
| Share coding standards with your team                | `skill`  | Passive knowledge, works with any AI tool |
| Package domain expertise (legal, medical, etc.)      | `skill`  | Reusable across multiple agents           |

<Info>
  **Still unsure?** Start with `type: "prompt"`. If you find yourself thinking "I wish it could run a command" or "it needs to iterate," switch to `type: "agent"`. If you need full control, use `type: "tool"`. You can always change later — just update the `type` field.
</Info>

***

## Prompt Type (`type: "prompt"`)

The simplest type. You provide a prompt template with variable placeholders, and orchagent handles the LLM call. Execution engine: `direct_llm`.

**When to use:**

* Single LLM call is sufficient
* No external API calls needed
* No complex logic or branching

**What you provide:**

```
my-agent/
+-- orchagent.json      # Manifest (type: "prompt")
+-- prompt.md           # Your prompt template
+-- schema.json         # Input/output schemas (optional)
\-- README.md           # Documentation (optional)
```

### Example

**`orchagent.json`:**

```json theme={null}
{
  "name": "sentiment-analyzer",
  "type": "prompt",
  "description": "Analyze sentiment of text",
  "supported_providers": ["openai", "anthropic"]
}
```

**`prompt.md`:**

```markdown theme={null}
Analyze the sentiment of the following text and return a JSON object
with 'sentiment' (positive, negative, or neutral) and 'confidence' (0-1).

Text: {{text}}
```

**`schema.json`:**

```json theme={null}
{
  "input": {
    "type": "object",
    "properties": {
      "text": { "type": "string", "description": "Text to analyze" }
    },
    "required": ["text"]
  },
  "output": {
    "type": "object",
    "properties": {
      "sentiment": { "type": "string", "enum": ["positive", "negative", "neutral"] },
      "confidence": { "type": "number", "minimum": 0, "maximum": 1 }
    }
  }
}
```

### Prompt Variables

Use `{{variable}}` syntax in your `prompt.md`:

```
Summarize the following {{document_type}} in {{language}}:

{{content}}

Focus on: {{focus_areas}}
```

Variables are replaced with input values at runtime. All template variables must be provided with non-empty values — the API returns a `400 MISSING_INPUT_FIELDS` error listing any that are missing.

***

## Agent Type (`type: "agent"`)

Agent types give the LLM a **tool-use loop inside a sandbox**. Think of it as "Claude Code in a container, configured by you." The platform provides built-in tools (bash, file read/write, list files) and you can define custom command-wrapper tools. The LLM iterates autonomously until it solves the task and submits a result. Execution engine: `managed_loop`.

**When to use:**

* The task requires running commands, reading/writing files, or iterating
* You want the LLM to figure out the steps, not hard-code them
* You'd otherwise write code just to orchestrate LLM + subprocess calls

**What you provide:**

```
my-agent/
+-- orchagent.json      # Manifest (type: "agent", loop + custom_tools)
+-- prompt.md           # Agent instructions (system prompt)
+-- schema.json         # Input/output schemas (optional)
+-- Dockerfile          # Custom environment (optional)
\-- requirements.txt    # Extra sandbox deps (optional)
```

**What you declare in the manifest:**

```json theme={null}
{
  "name": "cairo-test-engineer",
  "type": "agent",
  "description": "Fixes Cairo code until tests pass",
  "supported_providers": ["anthropic"],
  "loop": {
    "max_turns": 30
  },
  "timeout_seconds": 300,
  "custom_tools": [
    {
      "name": "run_tests",
      "description": "Run the Cairo test suite with snforge",
      "command": "snforge test"
    },
    {
      "name": "build_project",
      "description": "Build the scarb project",
      "command": "scarb build"
    }
  ]
}
```

**What the platform provides:**

1. E2B sandbox with your custom environment (if Dockerfile provided)
2. Built-in tools: `bash`, `read_file`, `write_file`, `list_files`, `submit_result`
3. Your custom tools converted to named tool definitions
4. A managed loop that runs until the LLM calls `submit_result` or hits `max_turns`

### Custom Tools

Custom tools are command wrappers that give the LLM clean, named operations instead of having to guess shell commands.

**Simple tools** (no parameters):

```json theme={null}
{
  "name": "run_tests",
  "description": "Run the test suite",
  "command": "pytest"
}
```

**Tools with parameters** (use `{{param}}` placeholders):

```json theme={null}
{
  "name": "deploy",
  "description": "Deploy to the specified network",
  "command": "sncast deploy --network {{network}}",
  "input_schema": {
    "type": "object",
    "properties": {
      "network": { "type": "string", "description": "Target network (testnet/mainnet)" }
    },
    "required": ["network"]
  }
}
```

The LLM sees named tools like `run_tests` and `deploy` instead of guessing raw bash commands. Bash is always available as a fallback for ad-hoc commands.

### Built-in Tools

Every managed loop agent automatically gets these tools:

| Tool            | Description                                          |
| --------------- | ---------------------------------------------------- |
| `bash`          | Run shell commands (120s per-command timeout)        |
| `read_file`     | Read file contents                                   |
| `write_file`    | Write/create files (auto-creates parent directories) |
| `list_files`    | List directory contents (optional recursive)         |
| `submit_result` | Submit final structured output and end the loop      |

### Safety Limits

| Limit               | Default                   | Configurable                              |
| ------------------- | ------------------------- | ----------------------------------------- |
| `loop.max_turns`    | 25                        | Yes, in orchagent.json (platform max: 50) |
| Per-command timeout | 120 seconds               | No                                        |
| Overall timeout     | Agent's `timeout_seconds` | Yes                                       |

### Provider Support

Managed loop agents currently support **Anthropic (Claude) only**.

**Why?** The managed loop uses Claude's native tool-use protocol: the platform sends a system prompt with tool definitions, the LLM returns `tool_use` blocks, the platform executes them in the sandbox, and feeds `tool_result` messages back. This cycle repeats until the LLM calls `submit_result` or hits `max_turns`. The implementation relies on Anthropic-specific message formatting (system/user/assistant roles with structured tool-use content blocks) that doesn't map 1:1 to other providers' tool-calling APIs.

Multi-provider support for managed loop is on the roadmap. In the meantime, if you need to use OpenAI or Gemini models in a tool-use loop, use a **code runtime agent** instead — you have full control over the LLM calls and can use any provider's SDK directly.

***

## Tool Type (`type: "tool"`)

Tool types run your Python or JavaScript in **E2B sandboxes** — secure, isolated environments. Each call spins up a fresh sandbox, runs your script, and returns the result. You have full control over everything. Execution engine: `code_runtime`.

**When to use:**

* You need full programmatic control over the execution flow
* Your use case doesn't need an LLM at all (pure data processing, file conversion, etc.)
* You need multi-model orchestration (calling different LLMs for different steps)
* You have an existing codebase you want to wrap as an agent
* Agent types don't give you enough control

**What you declare in the manifest:**

<Tabs>
  <Tab title="Python">
    ```json theme={null}
    {
      "name": "leak-finder",
      "type": "tool",
      "description": "Finds leaked secrets in codebases",
      "supported_providers": ["gemini"],
      "runtime": {
        "command": "python main.py"
      }
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```json theme={null}
    {
      "name": "leak-finder",
      "type": "tool",
      "description": "Finds leaked secrets in codebases",
      "supported_providers": ["gemini"],
      "runtime": {
        "command": "node main.js"
      }
    }
    ```
  </Tab>
</Tabs>

### Example

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    # main.py
    import json
    import sys

    def main():
        # Read input from stdin
        input_data = json.load(sys.stdin)
        repo_url = input_data.get("repo_url")

        # Your logic here: clone repo, scan files, call LLM, etc.
        result = {
            "issues": ["Found hardcoded API key in config.py"],
            "risk_score": 0.7
        }

        # Write output to stdout
        print(json.dumps(result))

    if __name__ == "__main__":
        main()
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    // main.js
    const fs = require('fs');

    function main() {
      const inputData = JSON.parse(fs.readFileSync('/dev/stdin', 'utf-8'));
      const repoUrl = inputData.repo_url;

      // Your logic here: clone repo, scan files, call LLM, etc.
      const result = {
        issues: ['Found hardcoded API key in config.py'],
        risk_score: 0.7,
      };

      // Write output to stdout
      console.log(JSON.stringify(result));
    }

    main();
    ```
  </Tab>
</Tabs>

### Input/Output Contract

Code runtime agents communicate via stdin/stdout as JSON.

**Standard input:**

```json theme={null}
{"repo_url": "https://github.com/user/repo"}
```

**File uploads:** When files are uploaded, you receive a manifest:

```json theme={null}
{
  "files": [
    {
      "path": "/tmp/uploads/invoice.pdf",
      "original_name": "invoice.pdf",
      "content_type": "application/pdf",
      "size_bytes": 1234567
    }
  ]
}
```

**Standard output:**

```json theme={null}
{"issues": ["..."], "risk_score": 0.7}
```

### Directory Structure

<Tabs>
  <Tab title="Python">
    ```
    my-agent/
    +-- orchagent.json      # Agent manifest
    +-- main.py             # Entry point
    +-- requirements.txt    # Dependencies
    \-- README.md           # Documentation (optional)
    ```
  </Tab>

  <Tab title="JavaScript">
    ```
    my-agent/
    +-- orchagent.json      # Agent manifest
    +-- main.js             # Entry point
    +-- package.json        # Dependencies
    \-- README.md           # Documentation (optional)
    ```
  </Tab>
</Tabs>

The CLI auto-detects entrypoints: `main.py`, `app.py`, `index.py`, `main.js`, `index.js`. Override with:

```json theme={null}
{"entrypoint": "run.py"}
```

### Skills in Tool Types

Tool types can access skills at runtime. When skills are passed via the `--skills` flag or `X-Orchagent-Skills` header, they are mounted as files in your sandbox:

```python theme={null}
import os
from pathlib import Path

skills_dir = os.environ.get("ORCHAGENT_SKILLS_DIR")
if skills_dir:
    skills_path = Path(skills_dir)

    # Read all skill files
    for skill_file in skills_path.glob("*.md"):
        content = skill_file.read_text()
        # Use skill content in your prompts or logic

    # Or read the manifest for metadata
    import json
    manifest = json.loads((skills_path / "manifest.json").read_text())
    for skill in manifest:
        print(f"Skill: {skill['org']}/{skill['name']}@{skill['version']}")
```

Skills are written to `/home/user/orchagent/skills/` with filenames like `org_name_version.md`. A `manifest.json` file provides metadata for programmatic access.

***

## Skill Type (`type: "skill"`)

Skills are passive knowledge — markdown files containing instructions, rules, or expertise that enhance agents. They are not runnable.

**Use cases:**

* Coding standards (React patterns, security rules)
* Domain knowledge (legal requirements, company policies)
* Writing guidelines (tone, formatting, brand voice)

### SKILL.md Format

Skills use the [Agent Skills](https://agentskills.io) standard:

```markdown theme={null}
---
name: react-best-practices
description: React optimization patterns for performance-critical apps
license: MIT
metadata:
  author: yourname
  version: "1.0"
---

## Rules

- Use functional components over class components
- Memoize expensive computations with useMemo
- Avoid inline function definitions in JSX
```

### Frontmatter Fields

| Field         | Required | Description                             |
| ------------- | -------- | --------------------------------------- |
| `name`        | Yes      | Lowercase, hyphens only, max 64 chars   |
| `description` | Yes      | When to use this skill (max 1024 chars) |
| `license`     | No       | e.g., MIT                               |
| `metadata`    | No       | Author, version, etc.                   |

### Using Skills

**Install locally** for any AI coding tool:

```bash theme={null}
# Install to current project
orch skill install yourorg/react-best-practices

# Install globally (available in all projects)
orch skill install yourorg/react-best-practices --global

# Install to specific formats only
orch skill install yourorg/react-best-practices --format claude-code,cursor
```

Writes to `.claude/skills/`, `.cursor/skills/`, `.codex/skills/`, `.agent/skills/`.

**Compose with agents** at run time:

```bash theme={null}
orch run yourorg/code-reviewer --skills yourorg/react-best-practices
```

### Using Agents as Sub-Agents

Export agents as sub-agent configuration files for AI tools:

```bash theme={null}
# Install agent as Claude Code sub-agent
orch install yourorg/code-reviewer

# Install to Cursor
orch install yourorg/code-reviewer --format cursor

# Install to project only
orch install yourorg/code-reviewer --scope project

# Update installed agents
orch update
```

See [CLI Commands](/using-agents/cli-commands#install) for full details.

***

## LLM Provider Configuration

Specify supported providers in your manifest:

```json theme={null}
{"supported_providers": ["openai", "anthropic", "gemini"]}
```

Use `"any"` if your agent works with any provider:

```json theme={null}
{"supported_providers": ["any"]}
```

<Note>
  `agent` types (managed loop) currently only support `"anthropic"`. This will be expanded in the future.
</Note>

***

## Choosing the Right Type

|                     | **`prompt`**                    | **`agent`**                              | **`tool`**                   | **`skill`**          |
| ------------------- | ------------------------------- | ---------------------------------------- | ---------------------------- | -------------------- |
| **Best for**        | Single-step LLM tasks           | Multi-step LLM reasoning                 | Your own code logic          | Sharing knowledge    |
| **LLM involved?**   | Yes (one call)                  | Yes (iterative loop)                     | Optional (you decide)        | No                   |
| **Sandbox?**        | No                              | Yes (E2B)                                | Yes (E2B)                    | No                   |
| **Providers**       | Any (OpenAI, Anthropic, Gemini) | Any (OpenAI, Anthropic, Gemini)          | Any (you call the API)       | N/A                  |
| **Typical latency** | 2-5 seconds                     | 10-120 seconds                           | 1-60 seconds                 | Instant (install)    |
| **Example**         | Sentiment analyzer, translator  | Test fixer, code reviewer                | Security scanner, PDF parser | React best practices |
| **You write**       | prompt.md + schema.json         | prompt.md + orchagent.json (loop config) | main.py or main.js           | SKILL.md             |

***

## Migration Note

<Info>
  **February 2026:** orchagent uses four canonical types: `prompt`, `tool`, `agent`, `skill`. Legacy type values `code` and `agentic` are still accepted by the API and CLI for backward compatibility:

  * `code` → `tool` (execution engine: `code_runtime`)
  * `agentic` → `agent` (execution engine: `managed_loop`)

  The `execution_engine` field (`direct_llm`, `managed_loop`, `code_runtime`) is inferred from your `type` at publish time. You do not need to set it manually — the type provides the right default.
</Info>

## Next Steps

<CardGroup cols={2}>
  <Card title="Manifest Format" icon="file-code" href="/building-agents/manifest-format">
    Full orchagent.json schema
  </Card>

  <Card title="Publishing" icon="upload" href="/building-agents/publishing">
    Publish your agent or skill
  </Card>

  <Card title="Orchestration" icon="diagram-project" href="/building-agents/orchestration">
    Compose agents and skills
  </Card>

  <Card title="Agent Builder Skill" icon="wand-magic-sparkles">
    Run `orch skill install orchagent/agent-builder` to give your AI coding tool the complete platform reference for building agents.
  </Card>
</CardGroup>
