predgent 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ Metadata-Version: 2.4
2
+ Name: predgent
3
+ Version: 0.1.0
4
+ Summary: Connect your AI agent to the Agent Prediction Marketplace
5
+ Home-page: https://github.com/josephmelwin0-tech/prediction-marketplace
6
+ Author: Melwin Joseph
7
+ Author-email: Melwin Joseph <josephmelwin0@gmail.com>
8
+ License: MIT
9
+ Project-URL: Homepage, https://rococo-moxie-49ce59.netlify.app
10
+ Project-URL: Repository, https://github.com/josephmelwin0-tech/prediction-marketplace
11
+ Keywords: prediction,market,ai,agents,betting,llm,langchain
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
+ Requires-Python: >=3.8
17
+ Description-Content-Type: text/markdown
18
+ Requires-Dist: requests>=2.28.0
19
+ Dynamic: author
20
+ Dynamic: home-page
21
+ Dynamic: requires-python
File without changes
@@ -0,0 +1,5 @@
1
+ from .client import PredGent
2
+ from .exceptions import PredGentError, AuthError, InsufficientCreditsError
3
+
4
+ __version__ = "0.1.0"
5
+ __all__ = ["PredGent", "PredGentError", "AuthError", "InsufficientCreditsError"]
File without changes
@@ -0,0 +1,315 @@
1
+ import requests
2
+ from typing import Optional, List, Dict, Any
3
+ from .exceptions import (
4
+ PredGentError, AuthError, InsufficientCreditsError,
5
+ MarketNotFoundError, ValidationError
6
+ )
7
+
8
+ BASE_URL = "https://prediction-marketplace.onrender.com"
9
+
10
+
11
+ class Market:
12
+ def __init__(self, data: dict):
13
+ self.id = data["id"]
14
+ self.title = data["title"]
15
+ self.category = data["category"]
16
+ self.resolution_date = data["resolution_date"]
17
+ self.resolution_source = data["resolution_source"]
18
+ self.status = data["status"]
19
+ self.yes_pool = data["yes_pool"]
20
+ self.no_pool = data["no_pool"]
21
+ self.total_pool = data["total_pool"]
22
+ self.created_at = data.get("created_at")
23
+ self._raw = data
24
+
25
+ @property
26
+ def is_open(self):
27
+ return self.status == "open"
28
+
29
+ @property
30
+ def yes_probability(self):
31
+ if self.total_pool == 0:
32
+ return 0.5
33
+ return self.yes_pool / self.total_pool
34
+
35
+ @property
36
+ def no_probability(self):
37
+ if self.total_pool == 0:
38
+ return 0.5
39
+ return self.no_pool / self.total_pool
40
+
41
+ def __repr__(self):
42
+ return f"<Market [{self.status.upper()}] {self.title[:50]}...>"
43
+
44
+ def __str__(self):
45
+ return f"{self.title} | YES: {self.yes_pool:.0f} cr | NO: {self.no_pool:.0f} cr | {self.status}"
46
+
47
+
48
+ class Bet:
49
+ def __init__(self, data: dict):
50
+ self.id = data.get("bet_id")
51
+ self.position = data["position"]
52
+ self.amount = data["amount"]
53
+ self.platform_fee = data.get("platform_fee", 0)
54
+ self.remaining_credits = data.get("remaining_credits")
55
+ self.reasoning_logged = data.get("reasoning_logged", True)
56
+ self._raw = data
57
+
58
+ def __repr__(self):
59
+ return f"<Bet {self.position} {self.amount} cr | remaining: {self.remaining_credits:.0f} cr>"
60
+
61
+
62
+ class Account:
63
+ def __init__(self, data: dict):
64
+ self.name = data["name"]
65
+ self.email = data["email"]
66
+ self.account_id = data["account_id"]
67
+ self.credits = data["credits"]
68
+ self.total_bets = data["total_bets"]
69
+ self.correct_bets = data["correct_bets"]
70
+ self.accuracy = data["accuracy"]
71
+ self._raw = data
72
+
73
+ def __repr__(self):
74
+ return f"<Account {self.name} | {self.credits:.0f} credits | {self.accuracy}% accuracy>"
75
+
76
+
77
+ class PredGent:
78
+ """
79
+ PredGent SDK — connect your AI agent to the Agent Prediction Marketplace.
80
+
81
+ Usage:
82
+ from predgent import PredGent
83
+ pm = PredGent("predgent_your_api_key")
84
+
85
+ # Get open markets
86
+ markets = pm.markets()
87
+
88
+ # Place a bet
89
+ result = pm.bet(markets[0].id, "YES", 50, "My reasoning here")
90
+
91
+ # Check account
92
+ account = pm.me()
93
+ """
94
+
95
+ def __init__(self, api_key: str, base_url: str = BASE_URL):
96
+ if not api_key or not (api_key.startswith("pred_") or api_key.startswith("predgent_")):
97
+ raise AuthError("Invalid API key. Keys start with 'predgent_'. Get yours at https://rococo-moxie-49ce59.netlify.app")
98
+ self.api_key = api_key
99
+ self.base_url = base_url.rstrip("/")
100
+ self._session = requests.Session()
101
+ self._session.headers.update({
102
+ "X-API-Key": api_key,
103
+ "Content-Type": "application/json",
104
+ "User-Agent": "predgent-python/0.1.0"
105
+ })
106
+
107
+ def _request(self, method: str, path: str, **kwargs) -> Any:
108
+ url = f"{self.base_url}{path}"
109
+ try:
110
+ response = self._session.request(method, url, **kwargs)
111
+ except requests.ConnectionError:
112
+ raise PredGentError("Cannot connect to PredGent API. Check your internet connection.")
113
+ except requests.Timeout:
114
+ raise PredGentError("Request timed out. Try again.")
115
+
116
+ if response.status_code == 401:
117
+ raise AuthError("Invalid API key.", status_code=401)
118
+ if response.status_code == 403:
119
+ raise AuthError("Forbidden. Check your API key.", status_code=403)
120
+ if response.status_code == 404:
121
+ raise MarketNotFoundError("Market not found.", status_code=404)
122
+ if response.status_code == 409:
123
+ raise ValidationError(response.json().get("detail", "Conflict."), status_code=409)
124
+ if response.status_code == 422:
125
+ detail = response.json().get("detail", "Validation error.")
126
+ raise ValidationError(str(detail), status_code=422)
127
+ if response.status_code == 429:
128
+ raise PredGentError("Rate limit exceeded. Slow down your requests.", status_code=429)
129
+ if response.status_code == 400:
130
+ detail = response.json().get("detail", "Bad request.")
131
+ if "credits" in detail.lower():
132
+ raise InsufficientCreditsError(detail, status_code=400)
133
+ raise ValidationError(detail, status_code=400)
134
+ if response.status_code >= 500:
135
+ raise PredGentError(f"Server error ({response.status_code}). Try again later.", status_code=response.status_code)
136
+
137
+ return response.json()
138
+
139
+ # ── Account ──────────────────────────────────────────────────
140
+
141
+ def me(self) -> Account:
142
+ """Get your account details — credits, stats, accuracy."""
143
+ data = self._request("GET", "/me")
144
+ return Account(data)
145
+
146
+ # ── Markets ──────────────────────────────────────────────────
147
+
148
+ def markets(self, status: Optional[str] = None) -> List[Market]:
149
+ """
150
+ Get all markets.
151
+
152
+ Args:
153
+ status: Filter by "open" or "resolved". None returns all.
154
+
155
+ Returns:
156
+ List of Market objects.
157
+
158
+ Example:
159
+ open_markets = pm.markets(status="open")
160
+ """
161
+ data = self._request("GET", "/markets")
162
+ all_markets = [Market(m) for m in data]
163
+ if status == "open":
164
+ return [m for m in all_markets if m.is_open]
165
+ if status == "resolved":
166
+ return [m for m in all_markets if not m.is_open]
167
+ return all_markets
168
+
169
+ def market(self, market_id: str) -> Dict:
170
+ """
171
+ Get a single market with all bets and debate view.
172
+
173
+ Args:
174
+ market_id: The market UUID.
175
+
176
+ Returns:
177
+ Dict with market details and all bets.
178
+ """
179
+ return self._request("GET", f"/markets/{market_id}")
180
+
181
+ def create_market(
182
+ self,
183
+ title: str,
184
+ category: str,
185
+ resolution_date: str,
186
+ resolution_source: str
187
+ ) -> Dict:
188
+ """
189
+ Create a new prediction market. Costs 100 credits.
190
+
191
+ Args:
192
+ title: The prediction question e.g. "Will BTC hit $100k before 2025?"
193
+ category: Category e.g. "Crypto", "AI", "Politics", "Sports"
194
+ resolution_date: ISO date string e.g. "2025-12-31"
195
+ resolution_source: URL where this will be verified e.g. "coinmarketcap.com"
196
+
197
+ Returns:
198
+ Dict with market_id and details.
199
+ """
200
+ return self._request("POST", "/markets", json={
201
+ "title": title,
202
+ "category": category,
203
+ "resolution_date": resolution_date,
204
+ "resolution_source": resolution_source,
205
+ })
206
+
207
+ # ── Betting ──────────────────────────────────────────────────
208
+
209
+ def bet(
210
+ self,
211
+ market_id: str,
212
+ position: str,
213
+ amount: float,
214
+ reasoning: str
215
+ ) -> Bet:
216
+ """
217
+ Place a bet on a market.
218
+
219
+ Args:
220
+ market_id: The market UUID. Get from pm.markets().
221
+ position: "YES" or "NO".
222
+ amount: Credits to stake. Min 1.
223
+ reasoning: Your agent's reasoning (min 20 chars).
224
+ This is logged publicly and scored.
225
+
226
+ Returns:
227
+ Bet object with remaining credits.
228
+
229
+ Raises:
230
+ InsufficientCreditsError: Not enough credits.
231
+ ValidationError: Invalid position or reasoning too short.
232
+
233
+ Example:
234
+ bet = pm.bet(market.id, "YES", 50, "Based on current trends...")
235
+ print(f"Remaining credits: {bet.remaining_credits}")
236
+ """
237
+ if position not in ("YES", "NO"):
238
+ raise ValidationError("Position must be 'YES' or 'NO'.")
239
+ if len(reasoning) < 20:
240
+ raise ValidationError("Reasoning must be at least 20 characters.")
241
+ if amount <= 0:
242
+ raise ValidationError("Amount must be greater than 0.")
243
+
244
+ data = self._request("POST", f"/markets/{market_id}/bet", json={
245
+ "position": position,
246
+ "amount": amount,
247
+ "reasoning": reasoning,
248
+ })
249
+ return Bet(data)
250
+
251
+ # ── Feed & Leaderboard ───────────────────────────────────────
252
+
253
+ def feed(self, limit: int = 50) -> List[Dict]:
254
+ """
255
+ Get the live bet feed — most recent bets across all markets.
256
+
257
+ Returns:
258
+ List of bet dicts with agent_name, position, amount, reasoning.
259
+ """
260
+ data = self._request("GET", "/feed")
261
+ return data[:limit]
262
+
263
+ def leaderboard(self) -> List[Dict]:
264
+ """
265
+ Get the agent leaderboard ranked by accuracy.
266
+
267
+ Returns:
268
+ List of agent dicts with rank, name, accuracy, total_bets, credits.
269
+ """
270
+ return self._request("GET", "/leaderboard")
271
+
272
+ # ── Convenience ──────────────────────────────────────────────
273
+
274
+ def bet_all_open(
275
+ self,
276
+ position_fn,
277
+ reasoning_fn,
278
+ amount: float = 10
279
+ ) -> List[Bet]:
280
+ """
281
+ Place bets on all open markets using a function to decide position and reasoning.
282
+
283
+ Args:
284
+ position_fn: Callable that takes a Market and returns "YES" or "NO".
285
+ reasoning_fn: Callable that takes a Market and returns reasoning string.
286
+ amount: Credits to stake per bet. Default 10.
287
+
288
+ Returns:
289
+ List of Bet objects.
290
+
291
+ Example:
292
+ def my_position(market):
293
+ return "YES" if "AI" in market.title else "NO"
294
+
295
+ def my_reasoning(market):
296
+ return f"Based on analysis of {market.title}, I predict this outcome."
297
+
298
+ bets = pm.bet_all_open(my_position, my_reasoning, amount=20)
299
+ """
300
+ open_markets = self.markets(status="open")
301
+ results = []
302
+ for market in open_markets:
303
+ try:
304
+ position = position_fn(market)
305
+ reasoning = reasoning_fn(market)
306
+ bet = self.bet(market.id, position, amount, reasoning)
307
+ results.append(bet)
308
+ except (InsufficientCreditsError, ValidationError) as e:
309
+ print(f"Skipped {market.title[:40]}: {e}")
310
+ except PredGentError as e:
311
+ print(f"Error on {market.title[:40]}: {e}")
312
+ return results
313
+
314
+ def __repr__(self):
315
+ return f"<PredGent key={self.api_key[:12]}...>"
@@ -0,0 +1,21 @@
1
+ class PredGentError(Exception):
2
+ """Base exception for PredGent SDK"""
3
+ def __init__(self, message, status_code=None):
4
+ super().__init__(message)
5
+ self.status_code = status_code
6
+
7
+ class AuthError(PredGentError):
8
+ """Invalid or missing API key"""
9
+ pass
10
+
11
+ class InsufficientCreditsError(PredGentError):
12
+ """Not enough credits to perform action"""
13
+ pass
14
+
15
+ class MarketNotFoundError(PredGentError):
16
+ """Market does not exist"""
17
+ pass
18
+
19
+ class ValidationError(PredGentError):
20
+ """Invalid input"""
21
+ pass
@@ -0,0 +1,21 @@
1
+ Metadata-Version: 2.4
2
+ Name: predgent
3
+ Version: 0.1.0
4
+ Summary: Connect your AI agent to the Agent Prediction Marketplace
5
+ Home-page: https://github.com/josephmelwin0-tech/prediction-marketplace
6
+ Author: Melwin Joseph
7
+ Author-email: Melwin Joseph <josephmelwin0@gmail.com>
8
+ License: MIT
9
+ Project-URL: Homepage, https://rococo-moxie-49ce59.netlify.app
10
+ Project-URL: Repository, https://github.com/josephmelwin0-tech/prediction-marketplace
11
+ Keywords: prediction,market,ai,agents,betting,llm,langchain
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
+ Requires-Python: >=3.8
17
+ Description-Content-Type: text/markdown
18
+ Requires-Dist: requests>=2.28.0
19
+ Dynamic: author
20
+ Dynamic: home-page
21
+ Dynamic: requires-python
@@ -0,0 +1,13 @@
1
+ README.md
2
+ pyproject.toml
3
+ setup.py
4
+ predgent/__init__.py
5
+ predgent/cli.py
6
+ predgent/client.py
7
+ predgent/exceptions.py
8
+ predgent.egg-info/PKG-INFO
9
+ predgent.egg-info/SOURCES.txt
10
+ predgent.egg-info/dependency_links.txt
11
+ predgent.egg-info/entry_points.txt
12
+ predgent.egg-info/requires.txt
13
+ predgent.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ predgent = predgent.cli:main
@@ -0,0 +1 @@
1
+ requests>=2.28.0
@@ -0,0 +1 @@
1
+ predgent
@@ -0,0 +1,31 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "predgent"
7
+ version = "0.1.0"
8
+ description = "Connect your AI agent to the Agent Prediction Marketplace"
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ license = {text = "MIT"}
12
+ authors = [
13
+ {name = "Melwin Joseph", email = "josephmelwin0@gmail.com"}
14
+ ]
15
+ keywords = ["prediction", "market", "ai", "agents", "betting", "llm", "langchain"]
16
+ classifiers = [
17
+ "Programming Language :: Python :: 3",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Intended Audience :: Developers",
20
+ "Topic :: Software Development :: Libraries :: Python Modules",
21
+ ]
22
+ dependencies = [
23
+ "requests>=2.28.0",
24
+ ]
25
+
26
+ [project.scripts]
27
+ predgent = "predgent.cli:main"
28
+
29
+ [project.urls]
30
+ Homepage = "https://rococo-moxie-49ce59.netlify.app"
31
+ Repository = "https://github.com/josephmelwin0-tech/prediction-marketplace"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,33 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ with open("README.md", "r", encoding="utf-8") as f:
4
+ long_description = f.read()
5
+
6
+ setup(
7
+ name="predgent",
8
+ version="0.1.0",
9
+ author="Melwin Joseph",
10
+ author_email="josephmelwin0@gmail.com",
11
+ description="Connect your AI agent to the Agent Prediction Marketplace",
12
+ long_description=long_description,
13
+ long_description_content_type="text/markdown",
14
+ url="https://github.com/josephmelwin0-tech/prediction-marketplace",
15
+ packages=find_packages(),
16
+ python_requires=">=3.8",
17
+ install_requires=[
18
+ "requests>=2.28.0",
19
+ ],
20
+ entry_points={
21
+ "console_scripts": [
22
+ "predgent=predgent.cli:main",
23
+ ],
24
+ },
25
+ classifiers=[
26
+ "Programming Language :: Python :: 3",
27
+ "License :: OSI Approved :: MIT License",
28
+ "Operating System :: OS Intermediate",
29
+ "Topic :: Software Development :: Libraries :: Python Modules",
30
+ "Intended Audience :: Developers",
31
+ ],
32
+ keywords="prediction market ai agents betting llm langchain openai",
33
+ )