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

# @hexr_agent

> The core decorator that gives your Python function or class a cryptographic SPIFFE identity, OpenTelemetry instrumentation, and optional A2A communication.

## Signature

```python theme={null}
@hexr_agent(
    name: str,
    tenant: str,
    resources: list[str] = None,
    subprocess_support: bool = False,
    regions: dict = None,
    a2a: bool = False,
    skills: list[dict] = None,
    description: str = None,
    version: str = None,
)
```

***

## Parameters

<ParamField path="name" type="string" required>
  The agent's name. Used in SPIFFE ID generation, Kubernetes resource naming, and observability.

  Must be kebab-case: `research-analyst`, `content-crew`, `data-pipeline`.
</ParamField>

<ParamField path="tenant" type="string" required>
  The tenant (organization) this agent belongs to. Maps to a Kubernetes namespace: `tenant-{tenant}`.
</ParamField>

<ParamField path="resources" type="list[str]" default="None">
  Cloud resources this agent needs access to. Used by OPA policies to scope credential exchange.

  Examples: `["aws_s3", "gcp_bigquery", "azure_storage"]`
</ParamField>

<ParamField path="subprocess_support" type="bool" default="False">
  Enable subprocess role management. When `True`, child processes can declare different roles and get distinct SPIFFE identities within the same pod.
</ParamField>

<ParamField path="regions" type="dict" default="None">
  Multi-region credential configuration.

  Example: `{"aws": "us-west-2", "gcp": "us-central1"}`
</ParamField>

<ParamField path="a2a" type="bool" default="False">
  Enable Agent-to-Agent communication. Starts the A2A bridge (HTTP server on `:8080`) that receives JSON-RPC messages from the A2A sidecar. Serves an Agent Card at `/.well-known/agent.json`.
</ParamField>

<ParamField path="skills" type="list[dict]" default="None">
  A2A skill declarations for the Agent Card. Each skill has `id`, `name`, and `description`.

  ```python theme={null}
  skills=[
      {"id": "research", "name": "Research", "description": "Deep web research on any topic"},
      {"id": "summarize", "name": "Summarize", "description": "Summarize long documents"}
  ]
  ```
</ParamField>

<ParamField path="description" type="string" default="None">
  Human-readable description for the Agent Card. Visible to other agents during A2A discovery.
</ParamField>

<ParamField path="version" type="string" default="None">
  Agent version string. Included in Agent Card and OTel spans.
</ParamField>

***

## Basic Usage

### Function Decorator

```python theme={null}
from hexr import hexr_agent, hexr_tool

@hexr_agent(name="research-analyst", tenant="acme-corp")
def analyze(topic: str) -> str:
    s3 = hexr_tool("aws_s3")
    # ... your agent logic
    return result
```

### Class Decorator

```python theme={null}
from hexr import hexr_agent

@hexr_agent(name="content-crew", tenant="acme-corp")
class ContentCrewAgent:
    def run(self, brief: str) -> str:
        # ... multi-step content creation
        return article
```

***

## What @hexr\_agent Does

When you decorate a function or class with `@hexr_agent`:

<Steps>
  <Step title="Sets Agent Context">
    Calls `HexrContext.set_agent_context()` which:

    * Sets ContextVars (`tenant`, `agent_name`, `framework`, `resources`)
    * Writes a process context marker file to `/tmp/hexr-context/`
    * Registers the process with the Auto-Registrar
  </Step>

  <Step title="Initializes OpenTelemetry">
    Creates a `TracerProvider` and `MeterProvider` pointing at the OTel Collector. All subsequent SDK calls emit spans and metrics automatically.
  </Step>

  <Step title="Starts A2A Bridge (if a2a=True)">
    Starts an HTTP server on `:8080` that:

    * Receives `/execute` calls from the A2A sidecar
    * Calls your function with the message content
    * Returns the result as a Task artifact
  </Step>

  <Step title="Wraps Execution">
    Every invocation of your function/class is wrapped with:

    * `hexr.agent.invoke` OTel span
    * `hexr.agent.invocations` metric counter
    * `hexr.agent.duration` histogram
    * Error capture and status propagation
  </Step>
</Steps>

***

## Framework Detection

`hexr build` uses AST analysis (\~2,900 lines) to auto-detect your agent framework:

| Framework          | Detection Pattern                                             |
| ------------------ | ------------------------------------------------------------- |
| **CrewAI**         | `from crewai import Agent, Crew`                              |
| **LangChain**      | `from langchain import ...`, `from langchain_core import ...` |
| **AutoGen**        | `from autogen import ...`, `AssistantAgent`, `UserProxyAgent` |
| **Strands Agents** | `from strands import Agent`, `@tool` decorator                |
| **OpenAI Swarm**   | `from swarm import Swarm`                                     |
| **Pure Python**    | No framework detected — uses `@hexr_agent` directly           |

The detected framework is stored in `HEXR_FRAMEWORK` env var and included in all OTel spans.

***

## A2A Agent Card

When `a2a=True`, your agent is discoverable by other agents via the A2A protocol:

```json theme={null}
// GET /.well-known/agent.json
{
  "name": "research-analyst",
  "description": "Deep research and analysis agent",
  "url": "http://research-analyst-a2a.tenant-acme-corp.svc:8090",
  "version": "1.0.0",
  "capabilities": {
    "streaming": true,
    "pushNotifications": false,
    "stateTransitionHistory": true
  },
  "skills": [
    {
      "id": "research",
      "name": "Research",
      "description": "Deep web research on any topic"
    }
  ],
  "securitySchemes": {
    "spiffe": {
      "type": "mtls",
      "trustDomain": "hexr.cloud"
    }
  }
}
```

***

## Examples

### Multi-Cloud Agent

```python theme={null}
@hexr_agent(
    name="multi-cloud-pipeline",
    tenant="acme-corp",
    resources=["aws_s3", "gcp_bigquery", "azure_storage"],
    regions={"aws": "us-west-2", "gcp": "us-central1"}
)
def pipeline():
    s3 = hexr_tool("aws_s3")
    bq = hexr_tool("gcp_bigquery")
    blob = hexr_tool("azure_storage")
```

### CrewAI with A2A

```python theme={null}
from crewai import Agent, Crew, Task
from hexr import hexr_agent

@hexr_agent(
    name="content-crew",
    tenant="acme-corp",
    a2a=True,
    skills=[{"id": "content", "name": "Content Creation", "description": "Blog posts and articles"}],
    description="Multi-agent content creation crew"
)
def create_content(brief: str) -> str:
    researcher = Agent(role="Research Analyst", ...)
    writer = Agent(role="Content Writer", ...)
    
    crew = Crew(agents=[researcher, writer], tasks=[...])
    return crew.kickoff()
```

### Subprocess Support

```python theme={null}
@hexr_agent(
    name="distributed-processor",
    tenant="acme-corp",
    subprocess_support=True
)
def process(data: list):
    # Child processes get distinct SPIFFE IDs
    # spiffe://hexr.cloud/agent/acme-corp/distributed-processor/worker-1
    # spiffe://hexr.cloud/agent/acme-corp/distributed-processor/worker-2
    with ProcessPoolExecutor() as pool:
        results = pool.map(process_chunk, data)
```
