feagi-agent 0.0.1-beta.2

Client library for building FEAGI agents in Rust
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
# FEAGI Agent SDK - Architecture

This document describes the architecture of the FEAGI Agent SDK system, including the Rust core SDK, Python bindings, and how they integrate with FEAGI.

---

## πŸ—οΈ **System Overview**

The FEAGI Agent SDK provides a production-ready, cross-platform client library for building agents that connect to FEAGI. The SDK is built in Rust for performance and reliability, with language bindings (starting with Python) that wrap the core functionality.

```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Agent Applications                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚ Pure Rust    β”‚  β”‚ Python       β”‚  β”‚ Future:  β”‚ β”‚
β”‚  β”‚ Agents       β”‚  β”‚ Agents       β”‚  β”‚ JS/C++   β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚                  β”‚                β”‚
          ↓                  ↓                ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ feagi-agent β”‚  β”‚ feagi-agent-     β”‚  β”‚ ...    β”‚
β”‚ (Rust)          β”‚  β”‚ sdk-py (PyO3)    β”‚  β”‚        β”‚
β”‚ - Core logic    β”‚  β”‚ - Python wrapper β”‚  β”‚        β”‚
β”‚ - Registration  │←── - Type conv      β”‚  β”‚        β”‚
β”‚ - Heartbeat     β”‚  β”‚ - Exceptions     β”‚  β”‚        β”‚
β”‚ - Reconnection  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚        β”‚
β”‚ - ZMQ I/O       β”‚                        β”‚        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜                        β”‚        β”‚
          β”‚                                β”‚        β”‚
          ↓                                ↓        ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚         feagi-io::agent_registry (Rust)            β”‚
β”‚         - Transport-agnostic core                   β”‚
β”‚         - Agent lifecycle management                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          ↑                    ↑
          β”‚                    β”‚
   β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”
   β”‚ Python FEAGI  β”‚    β”‚ Rust       β”‚
   β”‚ (via PyO3)    β”‚    β”‚ Engine     β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

---

## πŸ“¦ **Component Architecture**

### **1. feagi-io::agent_registry (Rust Module)**

**Purpose:** Server-side agent management (transport-agnostic)

**Responsibilities:**
- Agent registration/deregistration
- Agent lifecycle tracking
- Capability validation
- Activity monitoring
- Timeout-based pruning

**Key Types:**
- `AgentRegistry` - Core registry managing agent state
- `AgentInfo` - Agent metadata and capabilities
- `AgentType` - Enum: Sensory, Motor, Both
- `AgentTransport` - Trait for different communication protocols

**Usage:**
- Used by Python FEAGI (via PyO3 bindings)
- Used by Rust inference engine directly
- **Never run both simultaneously** (mutually exclusive deployment modes)

---

### **2. feagi-agent (Rust Crate)** ⭐ **CLIENT SDK**

**Purpose:** Production-ready client library for building agents

**Responsibilities:**
- Agent connection management
- Automatic registration with retry logic
- Background heartbeat service
- Reconnection with exponential backoff
- ZMQ communication (PUSH for sensory, SUB for motor)
- Graceful shutdown and deregistration

**Architecture:**

```
AgentClient
  β”œβ”€β”€ AgentConfig         (configuration builder)
  β”œβ”€β”€ RegistrationSocket  (ZMQ REQ for registration/heartbeat)
  β”œβ”€β”€ SensorySocket       (ZMQ PUSH for sensory data)
  β”œβ”€β”€ MotorSocket         (ZMQ SUB for motor commands)
  └── HeartbeatService    (background thread)
      └── ReconnectionStrategy (exponential backoff)
```

**Key Components:**

#### **AgentConfig (config.rs)**
- Builder pattern for configuration
- Type-safe capability definitions
- Validation before use
- Cloneable for multiple agents

#### **AgentClient (client.rs)**
- Main interface for agents
- Thread-safe (`Arc<Mutex<>>` internally)
- Auto-deregistration on drop
- Non-blocking motor data receive

#### **HeartbeatService (heartbeat.rs)**
- Runs in dedicated background thread (daemon)
- Configurable interval (default: 5 seconds)
- Automatic start/stop
- Prevents agent from being pruned

#### **ReconnectionStrategy (reconnect.rs)**
- Exponential backoff: `base * 2^attempt`
- Maximum backoff cap (60 seconds)
- Configurable max attempts
- Automatic reset on success

#### **Error Handling (error.rs)**
- `SdkError` with retryable classification
- Clear error messages
- Context preservation

---

### **3. feagi-agent-py (Python Extension)** 🐍

**Purpose:** Python bindings for the Rust SDK (via PyO3)

**Architecture:**

```python
Python Application
      ↓
PyAgentClient (Python wrapper)
      ↓ PyO3 FFI
AgentClient (Rust implementation)
      ↓
feagi-io::agent_registry (Rust)
```

**Key Features:**
- **Zero-Copy Data Transfer** - Efficient Python↔Rust
- **GIL Release** - Rust operations don't block Python threads
- **Type Conversion** - Automatic Python↔Rust type mapping
- **Exception Translation** - Rust errors β†’ Python exceptions
- **Pythonic API** - Natural Python interface

**Python API:**

```python
from feagi_agent_py import PyAgentClient, PyAgentConfig, AgentType

# Configuration
config = PyAgentConfig("agent_id", AgentType.Sensory)
config.with_feagi_host("localhost")
config.with_vision_capability("camera", 640, 480, 3, "i_vision")
config.with_heartbeat_interval(5.0)

# Client
client = PyAgentClient(config)
client.connect()

# Send data
client.send_sensory_data([(neuron_id, potential), ...])

# Receive motor commands (for motor agents)
motor_data = client.receive_motor_data()  # Non-blocking
```

---

## πŸ”„ **Data Flow**

### **Agent Registration Flow:**

```
Agent Application
    β”‚
    β”œβ”€1─→ Create AgentConfig
    β”‚     - Set agent_id, type, capabilities
    β”‚     - Configure endpoints, timeouts
    β”‚
    β”œβ”€2─→ Create AgentClient(config)
    β”‚     - Validates configuration
    β”‚     - Creates ZMQ context
    β”‚
    β”œβ”€3─→ client.connect()
    β”‚     β”œβ”€β†’ Create ZMQ sockets (REQ, PUSH, SUB)
    β”‚     β”œβ”€β†’ Register with FEAGI (with retry)
    β”‚     β”‚   β”œβ”€β†’ Send registration JSON via ZMQ REQ
    β”‚     β”‚   β”œβ”€β†’ Wait for response
    β”‚     β”‚   └─→ Handle "already registered" β†’ auto-deregister
    β”‚     └─→ Start HeartbeatService
    β”‚         └─→ Background thread sends heartbeat every N seconds
    β”‚
    └─4─→ client.send_sensory_data()
          └─→ ZMQ PUSH to FEAGI sensory endpoint
```

### **Heartbeat Flow:**

```
HeartbeatService (Background Thread)
    β”‚
    β”œβ”€β†’ Sleep(interval) [5 seconds]
    β”‚
    β”œβ”€β†’ Send heartbeat JSON
    β”‚   {"type": "heartbeat", "agent_id": "...", "timestamp": ...}
    β”‚
    β”œβ”€β†’ Wait for response (1 second timeout)
    β”‚   β”œβ”€β†’ Success β†’ log βœ“
    β”‚   └─→ Timeout β†’ log warning (don't fail)
    β”‚
    └─→ Repeat until stopped
```

### **Sensory Data Flow:**

```
Agent Application
    β”‚
    β”œβ”€β†’ Process sensor input (camera, lidar, etc.)
    β”‚
    β”œβ”€β†’ Convert to neuron activations
    β”‚   [(neuron_id: int, potential: float), ...]
    β”‚
    β”œβ”€β†’ client.send_sensory_data(neuron_pairs)
    β”‚   β”‚
    β”‚   └─→ Build JSON: {
    β”‚         "neuron_id_potential_pairs": [[id, pot], ...],
    β”‚         "agent_id": "...",
    β”‚         "frame_number": N
    β”‚       }
    β”‚
    └─→ ZMQ PUSH to FEAGI
        └─→ FEAGI receives β†’ injects into NPU
```

### **Motor Data Flow (for motor agents):**

```
FEAGI NPU
    β”‚
    β”œβ”€β†’ Neural processing produces motor outputs
    β”‚
    β”œβ”€β†’ FEAGI publishes via ZMQ PUB
    β”‚   {agent_id, motor_commands: [...]}
    β”‚
    └─→ Agent receives via ZMQ SUB
        β”‚
        └─→ client.receive_motor_data() [non-blocking]
            β”œβ”€β†’ Returns Some(data) if available
            └─→ Returns None if no data
```

---

## 🌐 **Network Protocol (ZMQ)**

### **Endpoints:**

| Socket Type | Direction | Default Port | Purpose |
|-------------|-----------|--------------|---------|
| REQ/REP | Agent ↔ FEAGI | 30001 | Registration & Heartbeat |
| PUSH/PULL | Agent β†’ FEAGI | 5555 | Sensory Data |
| SUB/PUB | FEAGI β†’ Agent | 5564 | Motor Commands |

### **Registration Protocol (REQ/REP):**

**Request (Agent β†’ FEAGI):**
```json
{
  "type": "register",
  "agent_id": "video_camera_01",
  "agent_type": "sensory",
  "capabilities": {
    "vision": {
      "modality": "camera",
      "dimensions": [640, 480],
      "channels": 3,
      "target_cortical_area": "i_vision"
    }
  }
}
```

**Response (FEAGI β†’ Agent):**
```json
{
  "status": "success",
  "agent_id": "video_camera_01",
  "message": "Agent registered successfully",
  "endpoints": {
    "sensory_endpoint": "tcp://0.0.0.0:5555",
    "motor_endpoint": "tcp://0.0.0.0:5564"
  }
}
```

### **Heartbeat Protocol (REQ/REP):**

**Request:**
```json
{
  "type": "heartbeat",
  "agent_id": "video_camera_01",
  "timestamp": 1234567890
}
```

**Response:**
```json
{
  "status": "success",
  "agent_id": "video_camera_01"
}
```

### **Sensory Data Protocol (PUSH):**

**Message:**
```json
{
  "neuron_id_potential_pairs": [
    [0, 50.0],
    [1, 75.0],
    [2, 30.0]
  ],
  "agent_id": "video_camera_01",
  "frame_number": 42
}
```

---

## βš™οΈ **Configuration System**

### **Agent Configuration:**

```rust
AgentConfig {
    // Identity
    agent_id: String,
    agent_type: AgentType,
    
    // Network
    registration_endpoint: String,  // tcp://host:30001
    sensory_endpoint: String,       // tcp://host:5555
    motor_endpoint: String,         // tcp://host:5564
    
    // Reliability
    heartbeat_interval: f64,        // seconds (0 = disabled)
    connection_timeout_ms: u64,     // milliseconds
    registration_retries: u32,      // max attempts
    retry_backoff_ms: u64,          // initial backoff
    
    // Capabilities
    capabilities: AgentCapabilities {
        vision: Option<VisionCapability>,
        motor: Option<MotorCapability>,
        custom: Map<String, Value>,
    }
}
```

### **Recommended Settings:**

**Development:**
```rust
AgentConfig::new("agent", AgentType::Sensory)
    .with_heartbeat_interval(5.0)    // 5 second heartbeat
    .with_connection_timeout_ms(5000) // 5 second timeout
    .with_registration_retries(3)     // Try 3 times
```

**Production:**
```rust
AgentConfig::new("agent", AgentType::Sensory)
    .with_heartbeat_interval(10.0)    // 10 second heartbeat
    .with_connection_timeout_ms(10000) // 10 second timeout
    .with_registration_retries(5)      // Try 5 times
```

**Embedded/Constrained:**
```rust
AgentConfig::new("agent", AgentType::Sensory)
    .with_heartbeat_interval(30.0)    // 30 second heartbeat
    .with_connection_timeout_ms(30000) // 30 second timeout
    .with_registration_retries(10)     // Try 10 times
```

---

## πŸ”’ **Thread Safety**

### **Rust SDK:**
- `AgentClient` uses `Arc<Mutex<>>` for internal state
- Safe to clone and share across threads
- ZMQ sockets are NOT thread-safe, but protected by mutexes
- Heartbeat runs in dedicated background thread

### **Python Bindings:**
- `PyAgentClient` wraps Rust `AgentClient` with `Arc<Mutex<>>`
- Safe to use from multiple Python threads
- GIL released during Rust operations (no Python thread blocking)

---

## 🚨 **Error Handling Strategy**

### **Classification:**

**Retryable Errors:**
- Network timeouts
- Connection failures
- ZMQ socket errors
- Registration "already registered" (auto-deregister + retry)

**Non-Retryable Errors:**
- Invalid configuration
- Validation failures
- Agent not registered (when trying to send data)
- Malformed JSON

### **Retry Logic:**

```
Attempt 1: Immediate
Attempt 2: Wait 1s  (base_backoff)
Attempt 3: Wait 2s  (base_backoff * 2)
Attempt 4: Wait 4s  (base_backoff * 4)
Attempt 5: Wait 8s  (base_backoff * 8)
...
Max Wait: 60s (capped)
```

---

## πŸ“Š **Performance Characteristics**

### **Rust SDK:**
- **Registration**: ~5-50ms (network dependent)
- **Heartbeat**: ~1-10ms per heartbeat
- **Send Data**: ~0.1-1ms per message (ZMQ PUSH)
- **Receive Data**: ~0.1-1ms per poll (ZMQ SUB)
- **Memory**: ~1-2MB per agent (including ZMQ buffers)

### **Python Bindings:**
- **Overhead**: <100μs per Python→Rust call (PyO3)
- **Data Transfer**: Zero-copy for most operations
- **GIL**: Released during Rust operations

### **Scalability:**
- **Agents per FEAGI**: 1000+ (tested)
- **Messages per Second**: 10,000+ per agent (hardware dependent)
- **Heartbeat Overhead**: Negligible (<0.1% CPU)

---

## πŸ”§ **Deployment Modes**

### **Mode 1: Python FEAGI (Most Common)**

```
Python FEAGI Process
    β”œβ”€β”€ PyO3 bindings to feagi_rust
    β”œβ”€β”€ Uses PyAgentRegistry (Rust-backed)
    └── ZmqRegistrationListener handles agents

Agents (separate processes)
    β”œβ”€β”€ Rust agents use feagi-agent directly
    └── Python agents use feagi-agent-py (wraps Rust SDK)
```

### **Mode 2: Standalone Rust Inference Engine**

```
Rust Inference Engine Process
    β”œβ”€β”€ Uses AgentRegistry directly
    └── Built-in ZMQ registration listener

Agents (separate processes)
    └── Same as Mode 1
```

**Note:** Mode 1 and Mode 2 are **mutually exclusive** - never run both simultaneously.

---

## πŸ› οΈ **Development Workflow**

### **Building Rust SDK:**
```bash
cd feagi_core/feagi-rust/crates/feagi-agent
cargo build --release
cargo test
cargo run --example simple_sensory_agent
```

### **Building Python Bindings:**
```bash
cd feagi_core/feagi-rust/crates/feagi-agent-py
maturin develop --release
python test_bindings.py
```

### **Using in Python Projects:**
```python
# Add to requirements.txt or install directly
pip install feagi-agent-py  # (when published)

# Or install from local source:
cd feagi_core/feagi-rust/crates/feagi-agent-py
maturin develop --release
```

---

## πŸ“š **Further Reading**

- [Rust SDK README]./README.md - Rust-specific documentation
- [Python Bindings README]../feagi-agent-py/README.md - Python-specific documentation
- [Agent Registry Documentation]../feagi-io/src/agent_registry.rs - Server-side registry
- [ZMQ Guide]https://zguide.zeromq.org/ - ZeroMQ documentation

---

## 🀝 **Contributing**

See [CONTRIBUTING.md](../../../../CONTRIBUTING.md) for development guidelines.

---

## πŸ“„ **License**

Apache-2.0