Spaces:
Running
Running
File size: 9,264 Bytes
43aad2c |
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 |
import os
import textwrap
from datetime import date, datetime, timedelta
import gradio as gr
import pandas as pd
from apscheduler.schedulers.background import BackgroundScheduler
from datasets import Dataset
from dotenv import load_dotenv
from huggingface_hub import HfApi
from predibench.agent.agent import run_smolagent
from predibench.polymarket_api import (
MarketRequest,
filter_interesting_questions,
filter_out_resolved_markets,
get_open_markets,
)
load_dotenv()
# Configuration
WEEKLY_MARKETS_REPO = "m-ric/predibench-weekly-markets"
AGENT_CHOICES_REPO = "m-ric/predibench-agent-choices"
N_MARKETS = 10
def restart_space():
"""Restart the HuggingFace space"""
try:
HfApi(token=os.getenv("HF_TOKEN", None)).restart_space(
repo_id="m-ric/predibench-backend" # Update with your actual space repo
)
print(f"Space restarted on {datetime.now()}")
except Exception as e:
print(f"Failed to restart space: {e}")
def get_top_polymarket_questions(n_markets: int = 10) -> list:
"""Fetch top questions from Polymarket API"""
end_date = date.today() + timedelta(days=7)
request = MarketRequest(
limit=n_markets * 10,
active=True,
closed=False,
order="volumeNum",
ascending=False,
end_date_min=end_date,
end_date_max=end_date + timedelta(days=21),
)
markets = get_open_markets(request)
markets = filter_out_resolved_markets(markets)
# Filter for interesting questions
interesting_questions = filter_interesting_questions(
[market.question for market in markets]
)
markets = [market for market in markets if market.question in interesting_questions]
return markets[:n_markets]
def upload_weekly_markets(markets: list):
"""Upload weekly markets to HuggingFace dataset"""
markets_data = []
for market in markets:
markets_data.append(
{
"id": market.id,
"question": market.question,
"slug": market.slug,
"description": market.description,
"end_date": market.end_date,
"active": market.active,
"closed": market.closed,
"volume": market.volume,
"liquidity": market.liquidity,
"week_selected": date.today().strftime("%Y-%m-%d"),
"timestamp": datetime.now(),
}
)
df = pd.DataFrame(markets_data)
dataset = Dataset.from_pandas(df)
try:
# Try to load existing dataset and append
existing_dataset = Dataset.from_parquet(f"hf://datasets/{WEEKLY_MARKETS_REPO}")
combined_dataset = existing_dataset.concatenate(dataset)
combined_dataset.push_to_hub(WEEKLY_MARKETS_REPO, private=False)
except:
# If no existing dataset, create new one
dataset.push_to_hub(WEEKLY_MARKETS_REPO, private=False)
print(f"Uploaded {len(markets_data)} markets to {WEEKLY_MARKETS_REPO}")
def run_agent_decisions(markets: list, model_ids: list = None):
"""Run agent decision-making logic on the selected markets"""
if model_ids is None:
model_ids = [
"gpt-4o",
"gpt-4.1",
"anthropic/claude-sonnet-4-20250514",
"huggingface/Qwen/Qwen3-30B-A3B-Instruct-2507",
]
today = date.today()
decisions = []
for model_id in model_ids:
for market in markets:
# Create the investment decision prompt
full_question = textwrap.dedent(
f"""Let's say we are the {today.strftime("%B %d, %Y")}.
Please answer the below question by yes or no. But first, run a detailed analysis.
Here is the question:
{market.question}
More details:
{market.description}
Invest in yes only if you think the yes is underrated, and invest in no only if you think that the yes is overrated.
What would you decide: buy yes, buy no, or do nothing?
"""
)
try:
response = run_smolagent(model_id, full_question, cutoff_date=today)
choice = response.output.lower()
# Standardize choice format
if "yes" in choice:
choice_standardized = 1
choice_raw = "yes"
elif "no" in choice:
choice_standardized = -1
choice_raw = "no"
else:
choice_standardized = 0
choice_raw = "nothing"
decisions.append(
{
"agent_name": f"smolagent_{model_id}".replace("/", "--"),
"date": today,
"question": market.question,
"question_id": market.id,
"choice": choice_standardized,
"choice_raw": choice_raw,
"messages_count": len(response.messages),
"has_reasoning": len(response.messages) > 0,
"timestamp": datetime.now(),
}
)
print(f"Completed decision for {model_id} on {market.question[:50]}...")
except Exception as e:
print(f"Error processing {model_id} on {market.question[:50]}: {e}")
continue
return decisions
def upload_agent_choices(decisions: list):
"""Upload agent choices to HuggingFace dataset"""
df = pd.DataFrame(decisions)
dataset = Dataset.from_pandas(df)
try:
# Try to load existing dataset and append
existing_dataset = Dataset.from_parquet(f"hf://datasets/{AGENT_CHOICES_REPO}")
combined_dataset = existing_dataset.concatenate(dataset)
combined_dataset.push_to_hub(AGENT_CHOICES_REPO, private=False)
except:
# If no existing dataset, create new one
dataset.push_to_hub(AGENT_CHOICES_REPO, private=False)
print(f"Uploaded {len(decisions)} agent decisions to {AGENT_CHOICES_REPO}")
def weekly_pipeline():
"""Main weekly pipeline that runs every Sunday"""
print(f"Starting weekly pipeline at {datetime.now()}")
try:
# 1. Get top 10 questions from Polymarket
markets = get_top_polymarket_questions(N_MARKETS)
print(f"Retrieved {len(markets)} markets from Polymarket")
# 2. Upload to weekly markets dataset
upload_weekly_markets(markets)
# 3. Run agent decision-making
decisions = run_agent_decisions(markets)
print(f"Generated {len(decisions)} agent decisions")
# 4. Upload agent choices
upload_agent_choices(decisions)
print("Weekly pipeline completed successfully")
except Exception as e:
print(f"Weekly pipeline failed: {e}")
# Set up scheduler to run every Sunday at 8:30 AM
scheduler = BackgroundScheduler()
scheduler.add_job(restart_space, "cron", day_of_week="sun", hour=8, minute=0)
scheduler.add_job(weekly_pipeline, "cron", day_of_week="sun", hour=8, minute=30)
scheduler.start()
# Simple Gradio interface for monitoring
def get_status():
"""Get current status of the backend"""
try:
# Check if datasets exist and get their info
api = HfApi()
weekly_info = "Not available"
choices_info = "Not available"
try:
weekly_dataset = Dataset.from_parquet(
f"hf://datasets/{WEEKLY_MARKETS_REPO}"
)
weekly_info = f"{len(weekly_dataset)} markets"
except:
pass
try:
choices_dataset = Dataset.from_parquet(
f"hf://datasets/{AGENT_CHOICES_REPO}"
)
choices_info = f"{len(choices_dataset)} decisions"
except:
pass
return f"""
Backend Status (Last updated: {datetime.now()})
Weekly Markets Dataset: {weekly_info}
Agent Choices Dataset: {choices_info}
Next scheduled run: Next Sunday at 8:30 AM UTC
"""
except Exception as e:
return f"Error getting status: {e}"
def manual_run():
"""Manually trigger the weekly pipeline"""
weekly_pipeline()
return "Manual pipeline run completed. Check logs for details."
# Create Gradio interface
with gr.Blocks(title="PrediBench Backend") as demo:
gr.Markdown("# PrediBench Backend Monitor")
gr.Markdown(
"This backend automatically fetches new Polymarket questions every Sunday and runs agent predictions."
)
with gr.Row():
status_text = gr.Textbox(label="Status", value=get_status(), lines=10)
refresh_btn = gr.Button("Refresh Status")
refresh_btn.click(get_status, outputs=status_text)
with gr.Row():
manual_btn = gr.Button("Run Manual Pipeline", variant="primary")
manual_output = gr.Textbox(label="Manual Run Output", lines=5)
manual_btn.click(manual_run, outputs=manual_output)
if __name__ == "__main__":
print("Starting PrediBench backend...")
demo.launch(server_name="0.0.0.0", server_port=7860)
|