rb512 commited on
Commit
459decf
Β·
verified Β·
1 Parent(s): 5a3d5ba

Upload agents/runner.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. agents/runner.py +191 -0
agents/runner.py ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Portfolio Runner β€” Orchestrates the CGAE Adaptive Portfolio Manager demo.
3
+
4
+ Flow:
5
+ 1. Create sub-agents (RegimeDetector, Rebalancer, YieldOptimizer)
6
+ 2. Run portfolio management cycles
7
+ 3. Adversarial agent attacks each cycle β€” all blocked by CGAE
8
+ 4. Display results
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import json
14
+ import logging
15
+ import time
16
+ import urllib.request
17
+ from typing import Optional
18
+
19
+ from dotenv import load_dotenv
20
+ load_dotenv()
21
+
22
+ from cgae_engine.gate import GateFunction, RobustnessVector, Tier
23
+ from cgae_engine.llm_agent import create_llm_agents
24
+ from cgae_engine.models_config import CONTESTANT_MODELS
25
+ from cgae_engine.audit import AuditOrchestrator
26
+ from agents.portfolio import (
27
+ PortfolioOrchestrator, RegimeDetector, Rebalancer,
28
+ YieldOptimizer, SubAgent, Allocation, Regime,
29
+ )
30
+ from agents.adversarial import AdversarialAgent
31
+
32
+ logger = logging.getLogger(__name__)
33
+
34
+
35
+ def fetch_market_data() -> dict:
36
+ """Fetch live market data for regime detection."""
37
+ try:
38
+ url = "https://api.coingecko.com/api/v3/simple/price?ids=ethereum,bitcoin&vs_currencies=usd&include_24hr_change=true"
39
+ req = urllib.request.Request(url, headers={"Accept": "application/json"})
40
+ with urllib.request.urlopen(req, timeout=10) as resp:
41
+ data = json.loads(resp.read())
42
+ return {
43
+ "eth_change_24h": data["ethereum"].get("usd_24h_change", 0),
44
+ "btc_change_24h": data["bitcoin"].get("usd_24h_change", 0),
45
+ "volatility": abs(data["ethereum"].get("usd_24h_change", 0)) * 0.5,
46
+ "funding_rate": 0.01,
47
+ "fear_greed": 55,
48
+ }
49
+ except Exception as e:
50
+ logger.warning(f"Market data fetch failed: {e}")
51
+ return {"eth_change_24h": 1.5, "btc_change_24h": 0.8, "volatility": 3.0, "funding_rate": 0.01, "fear_greed": 55}
52
+
53
+
54
+ def create_portfolio_system() -> tuple[PortfolioOrchestrator, AdversarialAgent]:
55
+ """Create the full portfolio system with all sub-agents."""
56
+ gate = GateFunction()
57
+ models = {m["model_name"]: m for m in CONTESTANT_MODELS}
58
+ llm_agents = create_llm_agents(list(models.values()))
59
+
60
+ # Fetch real robustness scores from framework APIs where available
61
+ orchestrator_audit = AuditOrchestrator()
62
+ agent_scores = {}
63
+ for name in ["nova-pro", "DeepSeek-V3.2", "Kimi-K2.5", "MiniMax-M2.5"]:
64
+ result = orchestrator_audit.audit_from_results(name, name)
65
+ agent_scores[name] = result.robustness
66
+ defaults = result.defaults_used
67
+ tier = gate.evaluate(result.robustness)
68
+ logger.info(f" {name}: CC={result.robustness.cc:.3f} ER={result.robustness.er:.3f} "
69
+ f"AS={result.robustness.as_:.3f} IH={result.robustness.ih:.3f} β†’ T{tier.value}"
70
+ f"{' (defaults: ' + ','.join(defaults) + ')' if defaults else ''}")
71
+
72
+ regime_r = agent_scores["nova-pro"]
73
+ rebal_r = agent_scores["Kimi-K2.5"]
74
+ yield_r = agent_scores["DeepSeek-V3.2"]
75
+
76
+ regime_detector = RegimeDetector(
77
+ name="nova-pro", role="regime_detector",
78
+ llm=llm_agents["nova-pro"],
79
+ tier=gate.evaluate(regime_r),
80
+ robustness=regime_r,
81
+ ) if "nova-pro" in llm_agents else None
82
+
83
+ rebalancer = Rebalancer(
84
+ name="Kimi-K2.5", role="rebalancer",
85
+ llm=llm_agents["Kimi-K2.5"],
86
+ tier=gate.evaluate(rebal_r),
87
+ robustness=rebal_r,
88
+ ) if "Kimi-K2.5" in llm_agents else None
89
+
90
+ yield_optimizer = YieldOptimizer(
91
+ name="DeepSeek-V3.2", role="yield_optimizer",
92
+ llm=llm_agents["DeepSeek-V3.2"],
93
+ tier=gate.evaluate(yield_r),
94
+ robustness=yield_r,
95
+ ) if "DeepSeek-V3.2" in llm_agents else None
96
+
97
+ if not all([regime_detector, rebalancer, yield_optimizer]):
98
+ raise RuntimeError("Could not create all sub-agents. Check AWS credentials.")
99
+
100
+ orchestrator = PortfolioOrchestrator(
101
+ regime_detector=regime_detector,
102
+ rebalancer=rebalancer,
103
+ yield_optimizer=yield_optimizer,
104
+ tier=Tier.T4, # Orchestrator has highest tier
105
+ )
106
+
107
+ # MiniMax-M2.5 as adversary β€” uses its real (low) robustness scores
108
+ minimax_r = agent_scores["MiniMax-M2.5"]
109
+ minimax_tier = gate.evaluate(minimax_r)
110
+ adversary = AdversarialAgent(tier=minimax_tier, robustness=minimax_r)
111
+
112
+ return orchestrator, adversary
113
+
114
+
115
+ def run_demo(rounds: int = 2, interval: int = 5):
116
+ """Run the full portfolio management demo with adversary attacks."""
117
+ logging.basicConfig(level=logging.INFO, format="%(message)s")
118
+
119
+ print("=" * 65)
120
+ print(" CGAE Adaptive Portfolio Manager β€” Arc Γ— Circle (RFB 04)")
121
+ print("=" * 65)
122
+
123
+ orchestrator, adversary = create_portfolio_system()
124
+
125
+ # Print agent roster
126
+ print(f"\n{'─' * 65}")
127
+ print(" AGENT ROSTER")
128
+ print(f"{'─' * 65}")
129
+ agents = [
130
+ ("Orchestrator", "coordinator", Tier.T4),
131
+ (orchestrator.regime_detector.name, "regime_detector", orchestrator.regime_detector.tier),
132
+ (orchestrator.rebalancer.name, "rebalancer", orchestrator.rebalancer.tier),
133
+ (orchestrator.yield_optimizer.name, "yield_optimizer", orchestrator.yield_optimizer.tier),
134
+ ("adversary", "adversarial", adversary.tier),
135
+ ]
136
+ print(f" {'Agent':<20} {'Role':<18} {'Tier':<5} {'Budget':<10}")
137
+ print(f" {'-'*53}")
138
+ for name, role, tier in agents:
139
+ budget = f"${GateFunction().budget_ceiling(tier)}"
140
+ print(f" {name:<20} {role:<18} T{tier.value:<4} {budget}")
141
+
142
+ # Run cycles
143
+ for i in range(rounds):
144
+ print(f"\n{'═' * 65}")
145
+ print(f" CYCLE {i+1}/{rounds}")
146
+ print(f"{'═' * 65}")
147
+
148
+ # Portfolio management
149
+ print(f"\n πŸ“ˆ Portfolio Management")
150
+ print(f" {'─' * 40}")
151
+ market = fetch_market_data()
152
+ result = orchestrator.run_cycle(market)
153
+
154
+ # Adversary attacks
155
+ print(f"\n πŸ”΄ Adversary Attacks")
156
+ print(f" {'─' * 40}")
157
+ attacks = adversary.run_all_attacks()
158
+ for attack in attacks:
159
+ status = "β›” BLOCKED" if attack.blocked else "⚠️ PASSED"
160
+ print(f" {status}: {attack.attack_type.value}")
161
+ print(f" └─ {attack.description}")
162
+
163
+ if i < rounds - 1:
164
+ time.sleep(interval)
165
+
166
+ # Final summary
167
+ print(f"\n{'═' * 65}")
168
+ print(" FINAL STATE")
169
+ print(f"{'═' * 65}")
170
+ ps = orchestrator.summary()
171
+ print(f"\n Portfolio: ${ps['aum']:.2f} AUM | Regime: {ps['regime']}")
172
+ print(f" Allocation: ETH={ps['allocation']['eth']:.0f}% BTC={ps['allocation']['btc']:.0f}% "
173
+ f"USDC={ps['allocation']['usdc']:.0f}% USYC={ps['allocation']['usyc']:.0f}%")
174
+ print(f" Delegations: {ps['total_delegations']} | Blocks: {ps['total_blocks']}")
175
+
176
+ pay = ps.get("payments", {})
177
+ if pay:
178
+ print(f"\n πŸ’Έ Nanopayments (x402 via Gateway):")
179
+ print(f" Spent: ${pay.get('spent', 0):.4f} / ${pay.get('budget_ceiling', 0)} ceiling")
180
+ print(f" Payments: {pay.get('payments_made', 0)} made, {pay.get('payments_blocked', 0)} blocked")
181
+
182
+ adv = adversary.summary()
183
+ print(f"\n Adversary: {adv['blocked']}/{adv['total_attacks']} attacks blocked "
184
+ f"({(1-adv['success_rate'])*100:.0f}% defense rate)")
185
+ print(f" Theorems enforced: {', '.join(set(a['theorem'][:20]+'...' for a in adv['attacks']))}")
186
+
187
+ return {"portfolio": ps, "adversary": adv}
188
+
189
+
190
+ if __name__ == "__main__":
191
+ run_demo()