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

# Orchestrator Pattern

> Route requests across specialized agents using a classifier front-end

## What is the orchestrator?

The orchestrator is an agent config with **no direct tools**. Its job is to classify an incoming request and route it to the right specialist agent. This lets you expose a single endpoint to users while keeping specialists tightly scoped.

```
User message
    ↓
Orchestrator (classifier_model classifies intent)
    ↓ routes to
┌─────────────────────────────────────────────┐
│ gtm_analyst  │ outreach_writer │ crm_enricher │
└─────────────────────────────────────────────┘
    ↓ specialist runs, returns result
Orchestrator (synthesis_model merges if multi-domain)
    ↓
Final response to user
```

## Setting up an orchestrator

Create an agent config with `tools: []` and a `classifier_model`:

```bash theme={null}
curl -X PUT https://ascend-gateway-v5.ascendgtm.workers.dev/admin/agent-configs/kahuna/orchestrator \
  -H "Authorization: Bearer <admin-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-5",
    "max_tokens": 1024,
    "max_iterations": 3,
    "system_prompt": "You classify GTM questions and route to specialists. Respond only with {\"route\": \"<agent_type>\", \"refined_message\": \"<message>\"}. Agent types: gtm_analyst, outreach_writer, crm_enricher, report_builder.",
    "tools": [],
    "classifier_model": "claude-haiku-4-5",
    "synthesis_model": "claude-sonnet-4-5"
  }'
```

The `classifier_model` is used for the intent classification step (cheaper, faster). The `synthesis_model` merges results from multiple specialists when a request spans domains.

## Routing logic

When a request hits the orchestrator:

1. **Classify** — `classifier_model` reads the message and returns `{route, refined_message}`
2. **Delegate** — Hermes starts the target specialist agent with `refined_message` as the input
3. **Synthesise** (multi-domain only) — if the message required more than one specialist, `synthesis_model` merges the responses
4. **Return** — the unified response goes back to the caller

## Multi-domain example

User: *"Pull last month's Google Ads performance and draft a Slack update summarizing it for the team."*

1. Orchestrator classifies: `["gtm_analyst", "outreach_writer"]` (two domains)
2. `gtm_analyst` runs → performance summary
3. `outreach_writer` runs → Slack message draft using the analyst output
4. `synthesis_model` merges into one response

## When NOT to use the orchestrator

* **Known single-domain requests** — route directly to the specialist; skip classification overhead
* **Scheduled jobs** — use explicit `agent_type` in the job config, no orchestrator needed
* **High-frequency calls** — orchestrator adds 1–2 LLM calls per request; direct routing is cheaper

## Admin API reference

| Endpoint                                    | Description                     |
| ------------------------------------------- | ------------------------------- |
| `GET /admin/agent-configs/:tenant`          | List all configured agent types |
| `GET /admin/agent-configs/:tenant/:type`    | Get one agent config            |
| `PUT /admin/agent-configs/:tenant/:type`    | Create or update config         |
| `DELETE /admin/agent-configs/:tenant/:type` | Remove config                   |

Tool validation is enforced on PUT — unknown tool names in the `tools` array are rejected with `VALIDATION_ERROR`.
