Metadata-Version: 2.4
Name: agentenna
Version: 0.1.2
Summary: The agent awareness layer
Project-URL: Homepage, https://agentenna.com
Project-URL: Repository, https://github.com/agentenna/agentenna
Author-email: Håvard <contact@agentenna.com>
License-Expression: Apache-2.0
License-File: LICENSE
Requires-Python: >=3.12
Requires-Dist: httpx>=0.28
Requires-Dist: pydantic>=2
Provides-Extra: station
Requires-Dist: fastapi>=0.138.0; extra == 'station'
Requires-Dist: fastmcp>=2; extra == 'station'
Requires-Dist: uvicorn>=0.49.0; extra == 'station'
Description-Content-Type: text/markdown

# agentenna

The agent awareness layer.

The whole API on one page: [docs/cheatsheet.md](docs/cheatsheet.md).

## Quickstart

```bash
pip install agentenna
python examples/passive_quickstart.py
```

## Run A Station

```bash
pip install "agentenna[station]"
agentenna serve --db .agentenna/agentenna.db --port 1234 --token dev-token
```

## Passive Awareness

```python
from agentenna import Antenna, State

ant = Antenna.connect("http://localhost:1234", token="dev-token", entity="billing-service")
ch = ant.channel("prod.errors")

# Events are the ticker — what happened.
ch.emit("checkout latency elevated", severity="med", kind="metric", source="checkout_api")

# States are the gauges — what is true right now. `kind` is the cell, `message`
# is the current value; re-emitting overwrites it (latest-per-kind, no history noise).
ch.emit(State(kind="deploy.prod", message="rolled_back"))

# One read verb: listen() gathers the events delta and the latest states into one
# awareness surface, and render() composes the <agentenna-awareness> block.
awareness = ch.listen(window="30m", limit=5)
print(awareness.render())
```

## Producers

Anything can transmit:

```python
import logging
from agentenna import Antenna, AgentennaLogHandler

ant = Antenna.local(".agentenna/agentenna.db", entity="billing-service")
logging.getLogger().addHandler(AgentennaLogHandler(ant.channel("app.logs")))
```

```bash
tail -f app.log | agentenna pipe app.logs        # tee stdin onto the surface
agentenna run ci.builds -- pytest -q             # emit a command's outcome

# Any webhook → the surface, one URL (no per-source code):
curl -X POST "http://localhost:1234/v1/ingest/ci.builds?message_path=workflow_run.name&token=dev-token" \
  -H "Content-Type: application/json" -d '{"workflow_run": {"name": "deploy failed"}}'
```

## Hosts

Per-host guides with each host's delivery tier and guarantee:
[docs/hosts](docs/hosts/README.md) — raw message lists, Pydantic AI,
LangGraph, Cursor, Codex CLI.

## Triggers

See [`examples/trigger_receiver.py`](examples/trigger_receiver.py) for the active
awareness loop: emit an event with a `Trigger`, then run a receiver that wakes on it
and acks it.

## MCP

See [`examples/mcp_cursor.md`](examples/mcp_cursor.md) for connecting an MCP client
to a running Station. 
