Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,43 @@ on:
push:
branches:
- main
workflow_dispatch:
inputs:
bump:
type: choice
options:
- patch
- minor
- major
default: patch
jobs:
bump:
name: bump-version
if: ${{ github.event_name == 'workflow_dispatch' }}
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
enable-cache: true
cache-dependency-glob: "uv.lock"
- name: Bump version
run: |
uvx hatch version ${{ inputs.bump }}
- name: Commit and tag
run: |
git config user.name "rhymiz"
git config user.email "lemuelboyce@gmail.com"
VERSION="$(python -c "from mas.__version__ import __version__; print(__version__)")"
git add src/mas/__version__.py
git commit -m "chore(release): v$VERSION"
git tag "v$VERSION"
git push --follow-tags
publish:
name: python
runs-on: ubuntu-latest
Expand Down
12 changes: 5 additions & 7 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1008,17 +1008,15 @@ Additional keys used by gateway:
| `message_nonces:{id}` | String | Nonce replay protection |
| `priority_queue:{target}:{priority}` | Sorted Set | Priority queues |

### When to Use the Gateway
### Gateway Use Cases

**Use Gateway**:
**Typical use cases**:
- Regulated industry (finance, healthcare, government)
- Handling sensitive data (PII, PHI, PCI)
- Compliance requirements (SOC2, HIPAA, GDPR)
- Multi-tenant with strict isolation
- Zero-trust security architecture required

P2P is not supported.

### Gateway Performance

**Throughput** (single gateway instance):
Expand Down Expand Up @@ -1098,10 +1096,10 @@ per_minute: int = 100 # Messages per minute per agent
per_hour: int = 1000 # Messages per hour per agent
```

**FeaturesSettings** (secure-by-default):
**FeaturesSettings** (secure-by-default, queues opt-in):
```python
dlp: bool = True # Data Loss Prevention scanning
priority_queue: bool = True # Message priority routing
priority_queue: bool = False # Message priority routing
rbac: bool = True # Role-Based Access Control
message_signing: bool = True # HMAC message signatures
circuit_breaker: bool = True # Circuit breaker for reliability
Expand Down Expand Up @@ -1175,7 +1173,7 @@ rate_limit:

features:
dlp: true
priority_queue: true
priority_queue: false
rbac: true
message_signing: true
circuit_breaker: true
Expand Down
73 changes: 53 additions & 20 deletions DOCUMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ A multi-agent system consists of multiple autonomous software agents that:
- **Distributed AI Systems**: Multiple AI agents collaborating on complex tasks
- **Microservices Coordination**: Services discovering and messaging each other
- **Workflow Orchestration**: Agents coordinating multi-step processes
- **Healthcare Systems**: HIPAA-compliant agent communication (gateway mode)
- **Financial Services**: SOC2/PCI-compliant agent interactions (gateway mode)
- **Healthcare Systems**: HIPAA-compliant agent communication through the gateway
- **Financial Services**: SOC2/PCI-compliant agent interactions through the gateway
- **Educational Platforms**: Tutoring systems with multiple specialized agents

---
Expand Down Expand Up @@ -649,11 +649,10 @@ async def main():
gateway = GatewayService() # Uses default redis://localhost:6379
await gateway.start()

# 2. Create agent with gateway mode enabled
# 2. Create agent (gateway routing is standard)
agent = Agent(
"my_agent",
capabilities=["worker"],
use_gateway=True # Enable gateway mode
)

# 3. Connect agent to gateway
Expand Down Expand Up @@ -723,7 +722,7 @@ Agents authenticate using tokens:

```python
# Tokens are automatically generated on registration
agent = Agent("my_agent", use_gateway=True)
agent = Agent("my_agent")
await agent.start() # Token stored in agent._token

# Agent token is automatically included in messages
Expand Down Expand Up @@ -1226,10 +1225,9 @@ def process_file(self, path: str):
Route sensitive operations through gateway:

```python
# Create agents with gateway mode for sensitive data
# Create agents for sensitive data
payment_agent = Agent(
"payment_processor",
use_gateway=True, # Enable security features
capabilities=["payment"]
)
```
Expand Down Expand Up @@ -1283,15 +1281,49 @@ brew services start redis
docker run -d -p 6379:6379 redis:latest
```

Start your agents:
Start MAS (recommended):

The definitive way to run MAS is the built-in runner. It starts the MAS service,
then brings up all configured agents automatically.

### Agent Runner (Config-Driven)

Define agent instances in `agents.yaml` (required) and start them with the
built-in runner. MAS routes all messages through the gateway.
by default.

`agents.yaml`:

```yaml
agents:
- agent_id: worker_agent
class_path: my_app.agents.worker:WorkerAgent
instances: 3
init_kwargs:
capabilities: ["worker"]
redis_url: redis://localhost:6379
batch_size: 10
start_service: true
service_redis_url: redis://localhost:6379
start_gateway: true
gateway_config_file: gateway.yaml
```

`start_gateway` must remain `true`.

Run MAS (auto-loads `agents.yaml` if present):

```bash
# Single agent
uv run python my_agent.py
uv run python -m mas
```

The runner searches upward from the current working directory to find the
nearest `agents.yaml` file.

# Multiple agents
uv run python agent_a.py &
uv run python agent_b.py &
Override the config file:

```bash
MAS_RUNNER_CONFIG_FILE=./agents.yaml uv run python -m mas
```

### Production Deployment
Expand Down Expand Up @@ -1391,7 +1423,6 @@ import os
agent = Agent(
agent_id=os.getenv("AGENT_ID", "default_agent"),
redis_url=os.getenv("REDIS_URL", "redis://localhost:6379"),
use_gateway=os.getenv("USE_GATEWAY", "false").lower() == "true"
)
```

Expand Down Expand Up @@ -1745,8 +1776,8 @@ class Agent:
capabilities: list[str] | None = None,
redis_url: str = "redis://localhost:6379",
state_model: type[BaseModel] | None = None,
use_gateway: bool = False,
gateway_url: str | None = None
reclaim_idle_ms: int = 30000,
reclaim_batch_size: int = 50
)
```

Expand All @@ -1755,14 +1786,16 @@ class Agent:
- `capabilities`: List of capability tags for discovery
- `redis_url`: Redis connection URL
- `state_model`: Optional Pydantic model for typed state
- `use_gateway`: Enable gateway mode (default: False)
- `gateway_url`: Gateway service URL (if different from redis_url)
- `reclaim_idle_ms`: Idle time in milliseconds before reclaiming pending messages
- `reclaim_batch_size`: Max pending messages reclaimed per reclaim cycle

Set `reclaim_idle_ms=0` to disable pending-message reclamation.

**Properties:**
- `id: str` - Agent identifier
- `capabilities: list[str]` - Agent capabilities
- `state: dict | BaseModel` - Current agent state
- `token: str | None` - Authentication token (gateway mode)
- `token: str | None` - Authentication token

**Methods:**

Expand Down Expand Up @@ -1870,7 +1903,7 @@ await agent.reset_state()
```

#### `set_gateway(gateway: GatewayService) -> None`
Set gateway instance for message routing (required for gateway mode).
Set gateway instance for message routing (optional, managed externally).

```python
gateway = GatewayService() # Uses default redis://localhost:6379
Expand Down
Loading