This repository was archived by the owner on Apr 20, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Expand file tree
/
Copy pathmain.py
More file actions
170 lines (134 loc) · 6.69 KB
/
main.py
File metadata and controls
170 lines (134 loc) · 6.69 KB
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
"""
World-Aware CrewAI Crew — Multi-agent system with shared real-time world context.
Problem: In a multi-agent crew, each agent hallucinates different numbers.
The researcher says "recession probability is low," the risk officer says
"recession probability is elevated." They're not disagreeing — they just
have different training data cutoffs.
Solution: Fetch real-time world state from prediction markets once, share
it across all agents. Everyone cites the same calibrated probabilities.
Data source: SimpleFunctions (https://simplefunctions.dev/world)
- 9,706 prediction markets from Kalshi + Polymarket
- No API key needed — free and public
- ~800 tokens, updated every 15 minutes
"""
import requests
from crewai import Agent, Task, Crew
from crewai.tools import tool
# ── Shared world context ───────────────────────────────────────────────────────
world = requests.get("https://simplefunctions.dev/api/agent/world").text
SHARED_CONTEXT = f"""You have access to real-time world data from prediction markets.
Use the numbers below as ground truth. Do NOT hallucinate probabilities.
Cite specific contract prices and probabilities directly.
When citing data, mention the source: SimpleFunctions World Model.
{world}"""
# ── Tools ──────────────────────────────────────────────────────────────────────
@tool("get_focused_world_state")
def get_focused_world_state(topics: str) -> str:
"""Get world state focused on specific topics for deeper coverage.
Same token budget, concentrated on fewer topics — more contracts per topic.
Args:
topics: Comma-separated topics, e.g. 'geopolitics,energy'.
Options: geopolitics, economy, energy, elections, crypto, tech.
"""
return requests.get(
f"https://simplefunctions.dev/api/agent/world?focus={topics}"
).text
@tool("search_prediction_markets")
def search_prediction_markets(query: str) -> str:
"""Search for specific prediction market contracts across Kalshi and Polymarket.
Args:
query: Natural language query, e.g. 'iran oil', 'fed rate cut', 'bitcoin'.
"""
import json
resp = requests.get(
f"https://simplefunctions.dev/api/public/scan?q={query}&limit=10"
)
return json.dumps(resp.json().get("markets", [])[:10], indent=2)
@tool("get_market_detail")
def get_market_detail(ticker: str) -> str:
"""Get detailed data for a specific prediction market contract.
Includes price, spread, volume, orderbook depth, and related thesis edges.
Args:
ticker: Kalshi ticker (e.g. KXIRANINVASION) or Polymarket condition ID.
"""
import json
resp = requests.get(
f"https://simplefunctions.dev/api/public/market/{ticker}?depth=true"
)
return json.dumps(resp.json(), indent=2)
# ── Agents ─────────────────────────────────────────────────────────────────────
researcher = Agent(
role="Macro Research Analyst",
goal="Analyze geopolitical and economic developments using real-time probability data",
backstory=SHARED_CONTEXT
+ "\nYou are a senior macro analyst at a global macro fund. You cite specific "
"probabilities and prices from prediction markets. You never say 'approximately' "
"when you have exact numbers. You identify the most important risks and opportunities.",
verbose=True,
)
risk_officer = Agent(
role="Risk Officer",
goal="Identify portfolio risks based on current world conditions",
backstory=SHARED_CONTEXT
+ "\nYou are a risk officer. You flag when probabilities cross thresholds that "
"matter for portfolio exposure. You reference specific contract prices. You never "
"say 'could' when you have a specific probability.",
verbose=True,
)
writer = Agent(
role="Morning Briefing Writer",
goal="Produce a concise morning briefing for the investment committee",
backstory=SHARED_CONTEXT
+ "\nYou write crisp, data-driven briefings for busy portfolio managers. Every "
"claim has a number attached. No hedging language. No filler. 200 words max.",
verbose=True,
)
# ── Tasks ──────────────────────────────────────────────────────────────────────
research_task = Task(
description=(
"Analyze the current geopolitical and economic situation. Focus on: "
"1) The top geopolitical risk and its probability, "
"2) Recession and Fed rate expectations, "
"3) Energy market conditions. "
"Use the world state data and search for specific contracts if needed. "
"Cite every number with its source contract."
),
expected_output="Structured analysis with specific probability citations from prediction markets",
agent=researcher,
tools=[get_focused_world_state, search_prediction_markets],
)
risk_task = Task(
description=(
"Based on the research analysis, identify the top 3 portfolio risks right now. "
"For each risk: state the specific prediction market probability, explain why "
"it matters for portfolio exposure, and recommend one action."
),
expected_output="3 risks with probability levels, portfolio implications, and actions",
agent=risk_officer,
tools=[get_focused_world_state, get_market_detail],
context=[research_task],
)
briefing_task = Task(
description=(
"Write a 200-word morning briefing combining the research and risk analysis. "
"Rules: every sentence must contain a number. No hedging. No filler. "
"End with the single most important thing the PM should do today."
),
expected_output="200-word morning briefing with data citations",
agent=writer,
context=[research_task, risk_task],
)
# ── Crew ───────────────────────────────────────────────────────────────────────
crew = Crew(
agents=[researcher, risk_officer, writer],
tasks=[research_task, risk_task, briefing_task],
verbose=True,
)
if __name__ == "__main__":
print("Starting world-aware macro crew...")
print(f"World state loaded: {len(world)} characters\n")
result = crew.kickoff()
print("\n" + "=" * 60)
print("MORNING BRIEFING")
print("=" * 60)
print(result)