Metadata-Version: 2.4
Name: the-ment
Version: 0.2.0
Summary: Private, self-hosted multi-agent environment with secure identities
Author: The Environment Contributors
License-Expression: MIT
Project-URL: Homepage, https://github.com/dudu-lopes/the-environment
Project-URL: Repository, https://github.com/dudu-lopes/the-environment
Project-URL: Issues, https://github.com/dudu-lopes/the-environment/issues
Keywords: agent,identity,cryptography,ed25519,authentication,multi-agent,private,self-hosted
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: cryptography>=46.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Dynamic: license-file

# The Environment

```bash
pip install the-ment
```

Portable, pseudonymous agent identities with Ed25519 cryptographic signatures.

A minimal protocol for secure agent discovery, authentication, and communication. Create private, self-hosted environments for your organization's agents. Perfect for multi-agent systems, AI agents, and enterprise applications.

## Why The Environment?

- **Secure** - Ed25519 signatures, AES-GCM encryption, Scrypt KDF
- **Private** - Self-hosted environments with full control
- **Simple** - Small core with one cryptography dependency
- **Portable** - Export/import identities as bundles
- **Flexible** - Support any serializable Python data
- **Fast** - In-memory environment for real-time discovery

## Create an Identity

```python
from ment import create_identity

identity = create_identity("my-password")
print(f"Agent ID: {identity.id}")
unlocked = identity.unlock("my-password")
```

## Terminal UX

The package includes a small terminal interface for local identity setup and
connection. It does not create a human account or store passwords.

```bash
ment init
```

This creates an encrypted identity bundle at `~/.ment/identity.json` and
prints the Agent ID. Use `--identity PATH` for another agent or location.

### Start a Private Environment

First, start your own Environment server:

```bash
ment-server
```

This starts an HTTP server on `http://127.0.0.1:8765` by default. Use the
`PORT` environment variable to change the port.

### Connect to Your Environment

```bash
ment login --url http://127.0.0.1:8765 --check
```

This prompts for the password, unlocks the local identity, connects to your
Environment, verifies the connection, and exits. To keep the agent
present and receive messages in the terminal, run `ment login` without
`--check` and press `Ctrl+C` to disconnect.

```bash
ment status
ment logout
```

`status` verifies the local bundle and reports presence in your Environment.
`logout` removes the agent from the Environment. A password is never written to disk;
the private key is only unlocked in memory while the process is running.

### One-time agent pairing

To let another agent enter your Environment without sharing your password, create a short-lived
single-use token:

```bash
ment token --name chatgpt
# equivalent: ment token chatgpt
```

Give the printed token to the other agent once. The token contains no password
or private key. A compatible client redeems it with `EnvironmentClient.pair()`:

```python
from ment import connect

environment = connect("http://your-environment:8765")
presence = environment.pair("ment1.<token>", capabilities=["chat"])
print(presence["id"])
```

Non-Python agents can use the same one-time flow over plain JSON:

```bash
curl -X POST http://your-environment:8765/pair \
  -H "Content-Type: application/json" \
  -d '{"token":"ment1.<token>","capabilities":["chat"]}'
```

The token is signed by the issuing identity, expires quickly (five minutes by
default), and is consumed on first use. The recipient may provide its own
`agent_id` and `public_key`; if omitted, the Environment creates a temporary
session ID. The token is passwordless for the recipient, and is not a general
account password. Pairing replay protection is kept in the Environment's
in-memory state.

## Sign and Verify

```python
from ment import create_identity, verify_signature

identity = create_identity("my-password")
unlocked = identity.unlock("my-password")
signature = unlocked.sign({"action": "transfer"})

is_valid = verify_signature(identity.public_key, {"action": "transfer"}, signature)
print(f"Valid: {is_valid}")  # True
```

## Multi-Agent Communication

```python
from ment import create_identity, Environment

agent_a = create_identity("password-a")
agent_b = create_identity("password-b")

env = Environment()
env.join(agent_a.id, capabilities=["code"])
env.join(agent_b.id, capabilities=["search"])

env.send(agent_a.id, {"text": "Hello!"}, target_id=agent_b.id)
messages = env.receive(agent_b.id)
print(messages[0].content)  # {"text": "Hello!"}
```

For authenticated delivery, register the sender's public key and send a signed
`Message` through `env.send_message(...)`. The Environment verifies the
identity binding and signature before delivery. Unsigned messages remain
available for open discovery and communication.

## Message Architecture

Every message has the same small structure:

```json
{
  "source_id": "sender-agent-id",
  "target_id": "receiver-agent-id or null",
  "content": {},
  "t": 1790628318671,
  "signature": "optional-ed25519-signature"
}
```

- `source_id` identifies the sending agent.
- `target_id` is optional. When omitted, the message is broadcast to active
  agents.
- `content` is chosen by the agents and can contain any JSON-serializable
  structure.
- `t` is the creation or send timestamp in Unix milliseconds. It travels with
  the message and is included in the signed data when a signature is present.
- `signature` is optional. Signed messages are verified against the sender's
  registered public key before delivery.

The normal flow is:

```text
create message -> assign t -> sign (optional) -> send -> verify -> deliver
```

The Environment preserves `t` but does not use it as a database or permanent
history, and it does not reorder messages by timestamp. Messages are delivered
in the order they reach the Environment. Changing any signed field, including
`t`, invalidates the signature.

## Examples

```bash
python examples/basic_usage.py
python examples/multi_agent_chat.py
python examples/signed_messages.py
python examples/corporate_environment.py
python examples/admin_setup.py
```

## Minimal API

The Environment runs as a small in-memory HTTP service:

```python
from ment import serve

serve(host="127.0.0.1", port=8765)
```

Available endpoints:

```text
GET  /health
POST /join
POST /pair
GET  /discover
POST /send
GET  /receive
POST /heartbeat
POST /leave
```

The API has no database or graphical interface. It exposes the same temporary
Environment through JSON so agents in different processes can communicate.

To connect an agent to your Environment server, use the HTTP client:

```python
from ment import connect

environment = connect("http://127.0.0.1:8765")
environment.join(agent.id, public_key=agent.public_key)
```

### Run the HTTP service

For a local service:

```bash
ment-server
```

For hosting platforms, the service listens on `0.0.0.0` and uses the `PORT`
environment variable automatically. Use `pip install .` as the build command
and `ment-server` as the start command. The `/health` endpoint can be used for
health checks.

## Self-Hosting

The Environment is designed to be self-hosted. You can run it on:

- **Local development**: `ment-server`
- **Docker**: See `Dockerfile` and `docker-compose.yml` in the repository
- **Cloud platforms**: Any platform that supports Python (AWS, GCP, Azure, etc.)
- **Systemd**: Use the provided service file for persistent deployment

The Environment is stateless and ephemeral - it keeps only active presence and
undelivered messages in memory. For production use, consider running it behind
a reverse proxy (nginx, Caddy) with SSL/TLS for secure communication.

## Architecture

- **Identity**: Random Ed25519 key pair, password-protected via AES-GCM
- **Signatures**: Ed25519 for message authentication
- **Environment**: In-memory agent discovery and messaging with automatic verification of supplied signatures
- **Bundles**: Portable export/import of full identity
- **Self-Hosted**: Run your own private Environment for your organization

## Security

- Ed25519 signatures (fast, secure, small)
- AES-GCM encryption for private keys
- Scrypt KDF for password protection
- Constant-time comparison for ID verification
- Input length limits on identity and message source fields

## Testing

```bash
python -m pytest tests/ -v
```

26/26 tests passing

## License

MIT
