Files
aitbc/cli/commands/ai.py
aitbc 149fbb0abe
Some checks failed
CLI Tests / test-cli (push) Failing after 11s
Cross-Node Transaction Testing / transaction-test (push) Successful in 2s
Deploy to Testnet / deploy-testnet (push) Successful in 1m9s
Documentation Validation / validate-docs (push) Failing after 10s
Documentation Validation / validate-policies-strict (push) Successful in 4s
Integration Tests / test-service-integration (push) Successful in 2m38s
Multi-Node Stress Testing / stress-test (push) Successful in 2s
Node Failover Simulation / failover-test (push) Successful in 2s
Package Tests / Python package - aitbc-agent-sdk (push) Failing after 27s
Security Scanning / security-scan (push) Has been cancelled
Package Tests / Python package - aitbc-core (push) Successful in 13s
Package Tests / Python package - aitbc-crypto (push) Successful in 9s
Package Tests / Python package - aitbc-sdk (push) Successful in 11s
Package Tests / JavaScript package - aitbc-sdk-js (push) Successful in 8s
Package Tests / JavaScript package - aitbc-token (push) Successful in 27s
Python Tests / test-python (push) Failing after 1m25s
Delegate Click commands to click_cli and add agent subcommands
- Route Click commands (agent, ipfs, oracle, etc.) to click_cli module
- Add zk, knowledge, bounty, dispute subcommands to agent group
- Add AI test submission, power trading, and reputation commands
- Add cross-chain transfer and listing commands
- Add monitor start/stop/status/alerts commands
- Add swarm create/discover/add/distribute/status commands
- Update main() to check command type and delegate appropriately
- Fix genesis CLI
2026-05-08 10:43:53 +02:00

178 lines
6.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import subprocess
import sys
import uuid
import click
import httpx
from pydantic import BaseModel
@click.group(name='ai')
def ai_group():
"""AI marketplace commands."""
pass
@ai_group.command()
@click.option('--port', default=8015, show_default=True, help='AI provider port')
@click.option('--model', default='qwen3:8b', show_default=True, help='Ollama model name')
@click.option('--wallet', 'provider_wallet', required=True, help='Provider wallet address (for verification)')
@click.option('--marketplace-url', default='http://127.0.0.1:8002', help='Marketplace API base URL')
def status(port, model, provider_wallet, marketplace_url):
"""Check AI provider service status."""
try:
resp = httpx.get(f"http://127.0.0.1:{port}/health", timeout=5.0)
if resp.status_code == 200:
health = resp.json()
click.echo(f"✅ AI Provider Status: {health.get('status', 'unknown')}")
click.echo(f" Model: {health.get('model', 'unknown')}")
click.echo(f" Wallet: {health.get('wallet', 'unknown')}")
else:
click.echo(f"❌ AI Provider not responding (status: {resp.status_code})")
except httpx.ConnectError:
click.echo(f"❌ AI Provider not running on port {port}")
except Exception as e:
click.echo(f"❌ Error checking AI Provider: {e}")
@ai_group.command()
@click.option('--port', default=8015, show_default=True, help='AI provider port')
@click.option('--model', default='qwen3:8b', show_default=True, help='Ollama model name')
@click.option('--wallet', 'provider_wallet', required=True, help='Provider wallet address (for verification)')
@click.option('--marketplace-url', default='http://127.0.0.1:8002', help='Marketplace API base URL')
def start(port, model, provider_wallet, marketplace_url):
"""Start AI provider service - provides setup instructions"""
click.echo(f"AI Provider Service Setup:")
click.echo(f" Port: {port}")
click.echo(f" Model: {model}")
click.echo(f" Wallet: {provider_wallet}")
click.echo(f" Marketplace: {marketplace_url}")
click.echo("\n📋 To start the AI Provider service:")
click.echo(f" 1. Create systemd service: /etc/systemd/system/aitbc-ai-provider.service")
click.echo(f" 2. Run: sudo systemctl daemon-reload")
click.echo(f" 3. Run: sudo systemctl enable aitbc-ai-provider")
click.echo(f" 4. Run: sudo systemctl start aitbc-ai-provider")
click.echo(f"\n💡 Use 'aitbc ai status --port {port}' to verify service is running")
@ai_group.command()
def stop():
"""Stop AI provider service - provides shutdown instructions"""
click.echo("📋 To stop the AI Provider service:")
click.echo(" 1. Run: sudo systemctl stop aitbc-ai-provider")
click.echo(" 2. Run: sudo systemctl status aitbc-ai-provider (to verify)")
click.echo("\n💡 Use 'aitbc ai status' to check if service is stopped")
@ai_group.command()
@click.option('--to', required=True, help='Provider host (IP)')
@click.option('--port', default=8015, help='Provider port')
@click.option('--prompt', required=True, help='Prompt to send')
@click.option('--buyer-wallet', 'buyer_wallet', required=True, help='Buyer wallet name (in local wallet store)')
@click.option('--provider-wallet', 'provider_wallet', required=True, help='Provider wallet address (recipient)')
@click.option('--amount', default=1, help='Amount to pay in AITBC')
def request(to, port, prompt, buyer_wallet, provider_wallet, amount):
"""Send a prompt to an AI provider (buyer side) with onchain payment."""
# Helper to get provider balance
def get_balance():
res = subprocess.run([
sys.executable, "-m", "aitbc_cli.main", "blockchain", "balance",
"--address", provider_wallet
], capture_output=True, text=True, check=True)
for line in res.stdout.splitlines():
if "Balance:" in line:
parts = line.split(":")
return float(parts[1].strip())
raise ValueError("Balance not found")
# Step 1: get initial balance
before = get_balance()
click.echo(f"Provider balance before: {before}")
# Step 2: send payment via blockchain CLI (use current Python env)
if amount > 0:
click.echo(f"Sending {amount} AITBC from wallet '{buyer_wallet}' to {provider_wallet}...")
try:
subprocess.run([
sys.executable, "-m", "aitbc_cli.main", "blockchain", "send",
"--from", buyer_wallet,
"--to", provider_wallet,
"--amount", str(amount)
], check=True, capture_output=True, text=True)
click.echo("Payment sent.")
except subprocess.CalledProcessError as e:
raise click.ClickException(f"Blockchain send failed: {e.stderr}")
# Step 3: get new balance
after = get_balance()
click.echo(f"Provider balance after: {after}")
delta = after - before
click.echo(f"Balance delta: {delta}")
# Step 4: call provider
url = f"http://{to}:{port}/job"
payload = {
"prompt": prompt,
"buyer": provider_wallet,
"amount": amount
}
try:
resp = httpx.post(url, json=payload, timeout=30.0)
resp.raise_for_status()
data = resp.json()
click.echo("Result: " + data.get("result", ""))
except httpx.HTTPError as e:
raise click.ClickException(f"Request to provider failed: {e}")
@ai_group.command()
@click.option('--model', required=True, help='Model to test')
@click.option('--test-data', required=True, help='Test data file')
def submit(model: str, test_data: str):
"""Submit AI test job"""
import uuid
click.echo({
"job_id": f"job_{uuid.uuid4().hex[:16]}",
"model": model,
"test_data": test_data,
"status": "submitted"
})
@ai_group.command()
@click.option('--gpu-memory', help='Filter by GPU memory')
@click.option('--price-max', type=float, help='Maximum price')
def list_ai_power(gpu_memory: str, price_max: float):
"""List available AI compute power"""
click.echo({
"listings": [],
"gpu_memory": gpu_memory or "all",
"price_max": price_max or 0
})
@ai_group.command()
@click.option('--listing-id', required=True, help='Listing ID')
@click.option('--amount', type=float, required=True, help='Amount to trade')
def trade_ai_power(listing_id: str, amount: float):
"""Trade AI compute power"""
import uuid
click.echo({
"trade_id": f"trade_{uuid.uuid4().hex[:16]}",
"listing_id": listing_id,
"amount": amount,
"status": "executed"
})
@ai_group.command()
@click.option('--wallet', required=True, help='Wallet address')
def reputation(wallet: str):
"""Get AI provider reputation"""
click.echo({
"wallet": wallet,
"reputation_score": 0.0,
"total_jobs": 0,
"success_rate": 0.0
})
if __name__ == '__main__':
ai_group()