Some checks failed
Cross-Node Transaction Testing / transaction-test (push) Has been cancelled
Deploy to Testnet / deploy-testnet (push) Has been cancelled
Documentation Validation / validate-docs (push) Has been cancelled
Documentation Validation / validate-policies-strict (push) Has been cancelled
Multi-Node Stress Testing / stress-test (push) Has been cancelled
Node Failover Simulation / failover-test (push) Has been cancelled
Integration Tests / test-service-integration (push) Has been cancelled
Security Scanning / security-scan (push) Has been cancelled
Python Tests / test-python (push) Has been cancelled
CLI Tests / test-cli (push) Has been cancelled
Blockchain Synchronization Verification / sync-verification (push) Successful in 11s
Contract Performance Benchmarks / benchmark-gas-usage (push) Successful in 1m36s
Contract Performance Benchmarks / benchmark-execution-time (push) Successful in 1m24s
Contract Performance Benchmarks / benchmark-throughput (push) Successful in 1m25s
Cross-Chain Functionality Tests / test-cross-chain-sync (push) Successful in 2s
Cross-Chain Functionality Tests / test-cross-chain-transactions (push) Successful in 5s
Cross-Chain Functionality Tests / test-cross-chain-bridge (push) Has been skipped
Cross-Chain Functionality Tests / test-multi-chain-consensus (push) Successful in 3s
Cross-Chain Functionality Tests / aggregate-results (push) Has been skipped
Multi-Chain Island Architecture Tests / test-multi-chain-island (push) Successful in 2s
Multi-Node Blockchain Health Monitoring / health-check (push) Successful in 3s
P2P Network Verification / p2p-verification (push) Successful in 2s
Smart Contract Tests / test-solidity (map[name:aitbc-contracts path:contracts]) (push) Failing after 1m28s
Smart Contract Tests / test-solidity (map[name:aitbc-token path:packages/solidity/aitbc-token]) (push) Successful in 21s
Smart Contract Tests / test-foundry (push) Failing after 20s
Smart Contract Tests / lint-solidity (push) Successful in 30s
Smart Contract Tests / deploy-contracts (push) Successful in 1m40s
Systemd Sync / sync-systemd (push) Successful in 26s
Contract Performance Benchmarks / compare-benchmarks (push) Successful in 4s
- Update workflow paths from docs/openclaw to docs/hermes - Rename skill prefixes from openclaw-* to hermes-* - Update agent skill references in refactoring and analysis docs - Rename OPENCLAW_AITBC_MASTERY_PLAN.md to reflect hermes branding - Update CLI examples and command references throughout documentation
473 lines
15 KiB
Markdown
473 lines
15 KiB
Markdown
# AITBC CLI Architecture
|
|
|
|
This document describes the architecture of the AITBC CLI system, including component interactions, data flows, and extension points.
|
|
|
|
## System Overview
|
|
|
|
The AITBC CLI follows a modular, layered architecture:
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ User Interface Layer │
|
|
│ (Command Line Interface) │
|
|
└────────────────────┬────────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Parser Layer │
|
|
│ (Argument Parsing & Validation) │
|
|
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
|
│ │ wallet.py │ │ blockchain.py │ │ ai.py │ │
|
|
│ │ market.py │ │ network.py │ │ workflow.py │ │
|
|
│ │ ... │ │ ... │ │ ... │ │
|
|
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
|
└────────────────────┬────────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Unified CLI Layer │
|
|
│ (Handler Registration & Dispatch) │
|
|
│ ┌────────────────────────────────────────────────────┐ │
|
|
│ │ unified_cli.py │ │
|
|
│ │ - Parser registration │ │
|
|
│ │ - Handler wrappers │ │
|
|
│ │ - Handler dispatch table │ │
|
|
│ └────────────────────────────────────────────────────┘ │
|
|
└────────────────────┬────────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Handler Layer │
|
|
│ (Command Implementation) │
|
|
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
|
│ │ wallet.py │ │ ai.py │ │ system.py │ │
|
|
│ │ market.py │ │ blockchain.py │ │ ... │ │
|
|
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
|
└────────────────────┬────────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Backend Services Layer │
|
|
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
|
│ │ Blockchain │ │ Agent │ │ Marketplace │ │
|
|
│ │ RPC (8006) │ │ Coordinator │ │ Exchange │ │
|
|
│ │ │ │ (9001) │ │ (8001) │ │
|
|
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
|
└─────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## Component Interactions
|
|
|
|
### 1. Parser Registration Flow
|
|
|
|
```
|
|
parsers/__init__.py
|
|
│
|
|
├── import all parser modules
|
|
│ ├── from . import wallet
|
|
│ ├── from . import blockchain
|
|
│ ├── from . import ai
|
|
│ └── ...
|
|
│
|
|
└── register_all(subparsers, ctx)
|
|
│
|
|
├── wallet.register(subparsers, ctx)
|
|
│ └── add_parser("wallet")
|
|
│ └── add_subparser("create", "list", ...)
|
|
│
|
|
├── blockchain.register(subparsers, ctx)
|
|
│ └── add_parser("blockchain")
|
|
│ └── add_subparser("info", "block", ...)
|
|
│
|
|
└── ai.register(subparsers, ctx)
|
|
└── add_parser("ai")
|
|
└── add_subparser("submit", "jobs", ...)
|
|
```
|
|
|
|
### 2. Command Execution Flow
|
|
|
|
```
|
|
User Input: "aitbc-cli ai submit hermes-trainee inference test 10"
|
|
│
|
|
▼
|
|
unified_cli.py:run_cli()
|
|
│
|
|
├── Parse arguments with argparse
|
|
│ └── parser.parse_args()
|
|
│ └── parsed_args = Namespace(...)
|
|
│
|
|
├── Get handler from parsed_args
|
|
│ └── handler = parsed_args.handler
|
|
│ └── handle_ai_submit
|
|
│
|
|
└── Execute handler
|
|
└── handler(parsed_args)
|
|
│
|
|
└── unified_cli.py:handle_ai_submit()
|
|
│
|
|
└── ai_handlers.handle_ai_submit()
|
|
│
|
|
├── Get coordinator URL
|
|
├── Build job request
|
|
├── HTTP POST to Agent Coordinator
|
|
└── Render result
|
|
```
|
|
|
|
### 3. Handler Pattern
|
|
|
|
```
|
|
Handler Wrapper (unified_cli.py)
|
|
│
|
|
├── def handle_ai_submit(args):
|
|
│ └── ai_handlers.handle_ai_submit(args, default_rpc_url, default_coordinator_url, first, read_password, render_mapping)
|
|
│ └── Passes context parameters
|
|
│
|
|
└── Handler Implementation (handlers/ai.py)
|
|
│
|
|
├── def handle_ai_submit(args, default_rpc_url, default_coordinator_url, first, read_password, render_mapping):
|
|
│ ├── Extract arguments
|
|
│ ├── Use context (RPC URL, coordinator URL)
|
|
│ ├── Make backend call
|
|
│ └── Render result
|
|
│
|
|
└── Return success/failure
|
|
```
|
|
|
|
## Data Flow Diagrams
|
|
|
|
### AI Job Submission Flow
|
|
|
|
```
|
|
User Command
|
|
│
|
|
▼
|
|
Parser (ai.py)
|
|
│
|
|
├── Parse: wallet, job_type, prompt, payment
|
|
├── Set default coordinator URL (9001)
|
|
└── Map to handler: handle_ai_submit
|
|
│
|
|
▼
|
|
Handler Wrapper (unified_cli.py)
|
|
│
|
|
├── Get context: default_rpc_url, default_coordinator_url
|
|
└── Call: ai_handlers.handle_ai_submit()
|
|
│
|
|
▼
|
|
Handler Implementation (handlers/ai.py)
|
|
│
|
|
├── Extract parameters from args
|
|
├── Build request:
|
|
│ {
|
|
│ "task_data": {
|
|
│ "model": model,
|
|
│ "prompt": prompt,
|
|
│ "parameters": {}
|
|
│ }
|
|
│ }
|
|
│
|
|
├── HTTP POST to http://localhost:9001/tasks/submit
|
|
├── Parse response
|
|
└── Render result to user
|
|
│
|
|
▼
|
|
Agent Coordinator Service (9001)
|
|
│
|
|
├── Receive job request
|
|
├── Queue job for processing
|
|
└── Return job ID to CLI
|
|
```
|
|
|
|
### Blockchain Query Flow
|
|
|
|
```
|
|
User Command
|
|
│
|
|
▼
|
|
Parser (blockchain.py)
|
|
│
|
|
├── Parse: block height, RPC URL
|
|
├── Set default RPC URL (8006)
|
|
└── Map to handler: handle_blockchain_block
|
|
│
|
|
▼
|
|
Handler Wrapper (unified_cli.py)
|
|
│
|
|
├── Get context: default_rpc_url
|
|
└── Call: blockchain_handlers.handle_blockchain_block()
|
|
│
|
|
▼
|
|
Handler Implementation (handlers/blockchain.py)
|
|
│
|
|
├── Extract block height
|
|
├── Build request URL: http://localhost:8006/rpc/blocks/{height}
|
|
├── HTTP GET
|
|
├── Parse response
|
|
└── Render block data to user
|
|
│
|
|
▼
|
|
Blockchain RPC Service (8006)
|
|
│
|
|
├── Receive block request
|
|
├── Query blockchain state
|
|
└── Return block data
|
|
```
|
|
|
|
### Marketplace Operation Flow
|
|
|
|
```
|
|
User Command
|
|
│
|
|
▼
|
|
Parser (market.py)
|
|
│
|
|
├── Parse: action (list, buy, sell), parameters
|
|
├── Set default marketplace URL (8001)
|
|
└── Map to handler: handle_market_listings
|
|
│
|
|
▼
|
|
Handler Wrapper (unified_cli.py)
|
|
│
|
|
├── Get context: default_marketplace_url
|
|
└── Call: market_handlers.handle_market_listings()
|
|
│
|
|
▼
|
|
Handler Implementation (handlers/market.py)
|
|
│
|
|
├── Build request URL: http://localhost:8001/listings
|
|
├── HTTP GET
|
|
├── Parse response
|
|
└── Render listings to user
|
|
│
|
|
▼
|
|
Marketplace Exchange API (8001)
|
|
│
|
|
├── Receive listings request
|
|
├── Query marketplace database
|
|
└── Return listings
|
|
```
|
|
|
|
## Extension Points
|
|
|
|
### 1. Adding New Commands
|
|
|
|
**Location:** `/opt/aitbc/cli/parsers/`
|
|
|
|
Create new parser module following the pattern:
|
|
```python
|
|
def register(subparsers, ctx):
|
|
parser = subparsers.add_parser("command", help="description")
|
|
parser.set_defaults(handler=ctx.handle_command)
|
|
```
|
|
|
|
**Registration:** Add to `/opt/aitbc/cli/parsers/__init__.py`
|
|
```python
|
|
from . import mycommand
|
|
|
|
def register_all(subparsers, ctx):
|
|
mycommand.register(subparsers, ctx)
|
|
```
|
|
|
|
### 2. Adding New Handlers
|
|
|
|
**Location:** `/opt/aitbc/cli/handlers/`
|
|
|
|
Create handler module:
|
|
```python
|
|
def handle_command(args, render_mapping):
|
|
# Implementation
|
|
pass
|
|
```
|
|
|
|
**Registration:** Add to `/opt/aitbc/cli/unified_cli.py`
|
|
```python
|
|
from handlers import mycommand as mycommand_handlers
|
|
|
|
def handle_command(args):
|
|
mycommand_handlers.handle_command(args, render_mapping)
|
|
|
|
handlers = {
|
|
"handle_command": handle_command,
|
|
}
|
|
```
|
|
|
|
### 3. Adding Backend Service Integration
|
|
|
|
**Pattern:** Use HTTP requests to backend services
|
|
|
|
```python
|
|
import requests
|
|
|
|
def handle_command(args, service_url, render_mapping):
|
|
url = f"{service_url}/endpoint"
|
|
response = requests.get(url, timeout=30)
|
|
if response.status_code == 200:
|
|
result = response.json()
|
|
render_mapping("Result:", result)
|
|
```
|
|
|
|
### 4. Adding Context Parameters
|
|
|
|
**Location:** `/opt/aitbc/cli/unified_cli.py`
|
|
|
|
Add context to handler wrapper:
|
|
```python
|
|
def handle_command(args):
|
|
mycommand_handlers.handle_command(args, default_rpc_url, default_coordinator_url, render_mapping)
|
|
```
|
|
|
|
**Handler signature:**
|
|
```python
|
|
def handle_command(args, default_rpc_url, default_coordinator_url, render_mapping):
|
|
# Use provided context
|
|
rpc_url = args.rpc_url or default_rpc_url
|
|
coordinator_url = args.coordinator_url or default_coordinator_url
|
|
```
|
|
|
|
## Service Endpoints
|
|
|
|
### Active Services
|
|
|
|
| Service | Port | Endpoint | Usage |
|
|
|---------|------|----------|-------|
|
|
| Blockchain RPC | 8006 | `/rpc/blocks/{height}` | Blockchain queries |
|
|
| Agent Coordinator | 9001 | `/tasks/submit` | AI job submission |
|
|
| Marketplace Exchange | 8001 | `/listings` | Marketplace operations |
|
|
|
|
### Common Patterns
|
|
|
|
**Agent Coordinator Integration:**
|
|
```python
|
|
coordinator_url = "http://localhost:9001"
|
|
job_data = {
|
|
"task_data": {
|
|
"model": model,
|
|
"prompt": prompt,
|
|
"parameters": {}
|
|
}
|
|
}
|
|
requests.post(f"{coordinator_url}/tasks/submit", json=job_data)
|
|
```
|
|
|
|
**Blockchain RPC Integration:**
|
|
```python
|
|
rpc_url = "http://localhost:8006"
|
|
requests.get(f"{rpc_url}/rpc/blocks/latest")
|
|
```
|
|
|
|
**Marketplace API Integration:**
|
|
```python
|
|
marketplace_url = "http://localhost:8001"
|
|
requests.get(f"{marketplace_url}/listings")
|
|
```
|
|
|
|
## Error Handling Patterns
|
|
|
|
### Graceful Degradation
|
|
|
|
```python
|
|
def handle_command(args, render_mapping):
|
|
try:
|
|
# Try real backend call
|
|
result = backend_call()
|
|
render_mapping("Result:", result)
|
|
except Exception as e:
|
|
# Fall back to stub
|
|
print(f"Backend unavailable: {e}")
|
|
stub_result = {"status": "simulated"}
|
|
render_mapping("Result:", stub_result)
|
|
```
|
|
|
|
### Non-Exiting Errors
|
|
|
|
```python
|
|
def handle_command(args, render_mapping):
|
|
if not required_parameter:
|
|
print("Error: Missing required parameter")
|
|
return # Don't sys.exit(1)
|
|
```
|
|
|
|
## Performance Considerations
|
|
|
|
### HTTP Timeouts
|
|
|
|
```python
|
|
response = requests.get(url, timeout=30) # 30 second timeout
|
|
```
|
|
|
|
### Async Operations
|
|
|
|
For long-running operations, use stub handlers or background tasks:
|
|
```python
|
|
def handle_long_operation(args, render_mapping):
|
|
result = {
|
|
"status": "submitted",
|
|
"operation_id": generate_id(),
|
|
"estimated_time": "5 minutes"
|
|
}
|
|
render_mapping("Operation:", result)
|
|
```
|
|
|
|
## Security Considerations
|
|
|
|
### Password Handling
|
|
|
|
```python
|
|
def handle_command(args, read_password):
|
|
password = read_password(args.wallet, args.password_file)
|
|
# Use password for authentication
|
|
```
|
|
|
|
### API Keys
|
|
|
|
Store API keys in environment variables or config files, not in code.
|
|
|
|
### Input Validation
|
|
|
|
```python
|
|
if not validate_input(args.input):
|
|
print("Error: Invalid input")
|
|
return
|
|
```
|
|
|
|
## Testing Strategy
|
|
|
|
### Unit Testing
|
|
|
|
Test handler functions in isolation:
|
|
```python
|
|
def test_handle_command():
|
|
args = Namespace(option="value")
|
|
result = handle_command(args, mock_render_mapping)
|
|
assert result["status"] == "success"
|
|
```
|
|
|
|
### Integration Testing
|
|
|
|
Test complete command flow:
|
|
```bash
|
|
/opt/aitbc/venv/bin/python /opt/aitbc/cli/unified_cli.py mycommand --option value
|
|
```
|
|
|
|
## Monitoring & Debugging
|
|
|
|
### Logging
|
|
|
|
Add logging to handlers:
|
|
```python
|
|
import logging
|
|
logger = logging.getLogger(__name__)
|
|
|
|
def handle_command(args):
|
|
logger.info(f"Executing command with args: {args}")
|
|
```
|
|
|
|
### Error Messages
|
|
|
|
Provide clear, actionable error messages:
|
|
```python
|
|
print(f"Error: Failed to connect to service at {service_url}")
|
|
print(f" - Check if service is running")
|
|
print(f" - Verify URL is correct")
|
|
```
|