anti_patterns
1. **Using tools that don't exist** — Always verify tools via `list_agent_tools()` before designing. Common hallucinations: `csv_read`, `csv_write`,…
Agents are declarative JSON configs in `exports/`: ``` exports/my_agent/ agent.json # The entire agent definition mcp_servers.json # MCP tool server config (optional, prefer registry refs) ```
$ npx -y skills add aden-hive/hive --agent claude-codeHow it fires
How this agent gets triggered: by you, by Claude, or both.
Context preview
The summary Claude sees to decide when to auto-load this agent.
Agents are declarative JSON configs in `exports/`: ``` exports/my_agent/ agent.json # The entire agent definition mcp_servers.json # MCP tool server config (optional, prefer registry refs) ```
Agents are declarative JSON configs in `exports/`:
exports/my_agent/ agent.json # The entire agent definition mcp_servers.json # MCP tool server config (optional, prefer registry refs)
No Python files. No `__init__.py`, `__main__.py`, `config.py`, or `nodes/`.
`AgentLoader.load()` reads `agent.json` and builds the execution graph. If `agent.py` exists (legacy), it's loaded as a Python module instead.
{
"name": "my-agent",
"version": "1.0.0",
"description": "What this agent does",
"goal": {
"description": "What to achieve",
"success_criteria": ["criterion 1", "criterion 2"],
"constraints": ["constraint 1"]
},
"identity_prompt": "You are a helpful agent.",
"conversation_mode": "continuous",
"loop_config": {
"max_iterations": 100,
"tool_call_budget": 30,
"max_context_tokens": 32000
},
"mcp_servers": [
{"name": "hive_tools"},
{"name": "gcu-tools"}
],
"variables": {
"spreadsheet_id": "1ZVx..."
},
"nodes": [...],
"edges": [...],
"entry_node": "process",
"terminal_nodes": []
}Use `{{variable_name}}` in `system_prompt` and `identity_prompt`. Variables are defined in the top-level `variables` object:
{
"variables": {"sheet_id": "1ZVx..."},
"nodes": [{
"id": "start",
"system_prompt": "Use sheet: {{sheet_id}}"
}]
}| Field | Type | Default | Description | |-------|------|---------|-------------| | id | str | required | kebab-case identifier | | name | str | id | Display name | | description | str | required | What the node does | | node_type | str | "event_loop" | `"event_loop"` | | input_keys | list | [] | Memory keys this node reads | | output_keys | list | [] | Memory keys this node writes via set_output | | system_prompt | str | "" | LLM instructions | | tools | object | {} | Tool access policy (see below) | | nullable_output_keys | list | [] | Keys that may remain unset | | max_node_visits | int | 1 | 0=unlimited (for forever-alive agents) | | success_criteria | str | "" | Natural language for judge evaluation | | client_facing | bool | false | Whether output is shown to user |
Each node declares its tools via a policy object:
{"tools": {"policy": "explicit", "allowed": ["web_search", "save_data"]}}
{"tools": {"policy": "all"}}
{"tools": {"policy": "none"}}| Field | Type | Description | |-------|------|-------------| | from_node | str | Source node ID | | to_node | str | Target node ID | | condition | str | `on_success`, `on_failure`, `always`, `conditional` | | condition_expr | str | Python expression for conditional routing | | priority | int | Higher = evaluated first |
condition_expr examples:
**Hard limit: 3-6 nodes for most agents.** Each node boundary serializes outputs and destroys in-context information. Merge unless: 1. Client-facing boundary (different interaction models) 2. Disjoint tool sets 3. Parallel execution (fan-out branches)
**Typical structure (2 nodes):**
process (autonomous) <-> review (queen-mediated)
The queen owns intake. Worker agents should NOT have a client-facing intake node. Mid-execution review should happen through queen escalation.
| Pattern | terminal_nodes | When | |---------|---------------|------| | Continuous loop | `["node-with-output-keys"]` | DEFAULT for all agents | | Linear | `["last-node"]` | One-shot/batch agents |
Every graph must have at least one terminal node.
`conversation_mode` has ONLY two valid states:
**INVALID values:** `"client_facing"`, `"interactive"`, `"shared"`.
Only three valid keys:
{
"max_iterations": 100,
"tool_call_budget": 20,
"max_context_tokens": 32000
}For large data that exceeds context:
`data_dir` is auto-injected by framework.
Multiple `on_success` edges from same source = parallel execution. Parallel nodes must have disjoint output_keys.
Always call `list_agent_tools()` first to see available tools. Do NOT rely on a static tool list.
list_agent_tools() # full summary list_agent_tools(group="gmail", output_schema="full") # drill into category
After building, run `validate_agent_package("{name}")` to check everything.
Repo: aden-hive/hive
1. **Using tools that don't exist** — Always verify tools via `list_agent_tools()` before designing. Common hallucinations: `csv_read`, `csv_write`,…
Agents are defined as a single `agent.yaml` file. No Python code needed. The runner loads this file directly -- no `agent.py`, `config.py`, or…
Use browser nodes (with `tools: {policy: "all"}`) when: - The task requires interacting with web pages (clicking, typing, navigating) - No API is available for…