Spaces:
Running on Zero
Running on Zero
Upload community_contributions/chrys/orchestrator.py with huggingface_hub
Browse files
community_contributions/chrys/orchestrator.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""ARIA orchestrator: run all agents in sequence and pass state."""
|
| 2 |
+
from typing import List, Tuple
|
| 3 |
+
|
| 4 |
+
from config import get_watchlist, ALERT_SCORE_THRESHOLD, PUSHOVER_USER, PUSHOVER_TOKEN
|
| 5 |
+
from models import AssetData, TechResult, SentimentResult, DecisionRecord
|
| 6 |
+
from agents import DataFetcherAgent, TechAnalystAgent, SentimentAgent, DecisionAgent, NotifierAgent
|
| 7 |
+
from db import log_decisions
|
| 8 |
+
|
| 9 |
+
from config import (
|
| 10 |
+
ALPHA_VANTAGE_API_KEY,
|
| 11 |
+
COMMODITY_PRICE_API_KEY,
|
| 12 |
+
NEWSAPI_KEY,
|
| 13 |
+
OPENROUTER_API_KEY,
|
| 14 |
+
SENTIMENT_MODEL,
|
| 15 |
+
)
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
def run_pipeline() -> Tuple[List[DecisionRecord], List[AssetData]]:
|
| 19 |
+
watchlist = get_watchlist()
|
| 20 |
+
# 1. Data Fetcher
|
| 21 |
+
fetcher = DataFetcherAgent(alpha_key=ALPHA_VANTAGE_API_KEY, metals_key=COMMODITY_PRICE_API_KEY)
|
| 22 |
+
asset_data = fetcher.run(watchlist)
|
| 23 |
+
if not asset_data:
|
| 24 |
+
return [], []
|
| 25 |
+
|
| 26 |
+
# 2. Tech Analyst
|
| 27 |
+
tech_agent = TechAnalystAgent()
|
| 28 |
+
tech_results = tech_agent.run(asset_data)
|
| 29 |
+
|
| 30 |
+
# 3. Sentiment (only for non-neutral)
|
| 31 |
+
assets_for_sentiment = [tr.asset for tr in tech_results if tr.bias != "NEUTRAL"]
|
| 32 |
+
sentiment_agent = SentimentAgent(
|
| 33 |
+
newsapi_key=NEWSAPI_KEY,
|
| 34 |
+
model=SENTIMENT_MODEL,
|
| 35 |
+
openrouter_key=OPENROUTER_API_KEY,
|
| 36 |
+
)
|
| 37 |
+
sentiment_results = sentiment_agent.run(tech_results, assets_for_sentiment)
|
| 38 |
+
sentiment_by_asset = {s.asset: s for s in sentiment_results}
|
| 39 |
+
asset_by_asset = {a.asset: a for a in asset_data}
|
| 40 |
+
|
| 41 |
+
# 4. Decision Agent
|
| 42 |
+
decision_agent = DecisionAgent()
|
| 43 |
+
records = decision_agent.run(tech_results, sentiment_results, asset_data)
|
| 44 |
+
|
| 45 |
+
# 5. Notifier: only ALERT, top 1-2 by score, up to MAX per hour (handled in decision)
|
| 46 |
+
alert_records = [r for r in records if r.decision == "ALERT"]
|
| 47 |
+
alert_records.sort(key=lambda x: x.final_score, reverse=True)
|
| 48 |
+
to_send = alert_records[:2] # Top 2
|
| 49 |
+
notifier = NotifierAgent(user=PUSHOVER_USER, token=PUSHOVER_TOKEN)
|
| 50 |
+
to_send_tuples: List[Tuple[DecisionRecord, TechResult, SentimentResult | None, AssetData | None]] = []
|
| 51 |
+
tech_by_asset = {t.asset: t for t in tech_results}
|
| 52 |
+
for rec in to_send:
|
| 53 |
+
tech = tech_by_asset[rec.asset]
|
| 54 |
+
sent = sentiment_by_asset.get(rec.asset)
|
| 55 |
+
ad = asset_by_asset.get(rec.asset)
|
| 56 |
+
to_send_tuples.append((rec, tech, sent, ad))
|
| 57 |
+
notifier.run(to_send_tuples)
|
| 58 |
+
|
| 59 |
+
# Audit log
|
| 60 |
+
log_decisions(records)
|
| 61 |
+
return records, asset_data
|