simplefunctions-ai 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,7 @@
1
+ __pycache__/
2
+ *.pyc
3
+ dist/
4
+ *.egg-info/
5
+ .eggs/
6
+ build/
7
+ .env
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SimpleFunctions
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,186 @@
1
+ Metadata-Version: 2.4
2
+ Name: simplefunctions-ai
3
+ Version: 0.1.0
4
+ Summary: Calibrated world model for AI agents. Real-time probabilities from 9,706 prediction markets.
5
+ Project-URL: Homepage, https://simplefunctions.dev
6
+ Project-URL: Documentation, https://simplefunctions.dev/docs/guide
7
+ Project-URL: Repository, https://github.com/spfunctions/simplefunctions-python
8
+ Project-URL: World State API, https://simplefunctions.dev/api/agent/world
9
+ Project-URL: MCP Server, https://simplefunctions.dev/api/mcp/mcp
10
+ Author-email: SimpleFunctions <hello@simplefunctions.dev>
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: agent-context,ai-agents,anthropic,geopolitics,kalshi,langchain,mcp,openai,polymarket,prediction-markets,probabilities,real-time-data,world-model,world-state
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Requires-Python: >=3.9
25
+ Requires-Dist: requests>=2.28.0
26
+ Description-Content-Type: text/markdown
27
+
28
+ # SimpleFunctions
29
+
30
+ Calibrated world model for AI agents. Real-time probabilities from 9,706 prediction markets.
31
+
32
+ Your agent doesn't know what's happening in the world. Web search returns narratives ("tensions remain elevated"). SimpleFunctions returns calibrated numbers backed by real money: `Iran invasion: 53% (+5c, $225K volume)`.
33
+
34
+ ## Install
35
+
36
+ ```bash
37
+ pip install simplefunctions
38
+ ```
39
+
40
+ ## Quick Start
41
+
42
+ ```python
43
+ from simplefunctions import world, delta, scan
44
+
45
+ # What's happening in the world right now? (~800 tokens, markdown)
46
+ print(world())
47
+
48
+ # What changed in the last hour? (~30-50 tokens)
49
+ print(delta(since="1h"))
50
+
51
+ # Search prediction markets
52
+ results = scan("fed rate cut")
53
+ for m in results["markets"][:5]:
54
+ print(f"{m['title']}: {m['price']}c")
55
+ ```
56
+
57
+ No API key needed. Free. Data from Kalshi (CFTC-regulated) and Polymarket, updated every 15 minutes.
58
+
59
+ ## Give Your Agent World Awareness
60
+
61
+ ### System prompt injection (simplest)
62
+
63
+ ```python
64
+ from simplefunctions import world
65
+ import anthropic
66
+
67
+ client = anthropic.Anthropic()
68
+ state = world()
69
+
70
+ response = client.messages.create(
71
+ model="claude-sonnet-4-20250514",
72
+ max_tokens=1024,
73
+ system=f"You are a research analyst.\n\n{state}",
74
+ messages=[{"role": "user", "content": "What's the recession probability?"}],
75
+ )
76
+ # Agent cites "33%" instead of hallucinating
77
+ ```
78
+
79
+ ### Tool definitions (one line per framework)
80
+
81
+ ```python
82
+ from simplefunctions.integrations import openai_tools, anthropic_tools, mistral_tools
83
+
84
+ # OpenAI Agents SDK / Responses API
85
+ tools = openai_tools()
86
+
87
+ # Anthropic Claude
88
+ tools = anthropic_tools()
89
+
90
+ # Mistral
91
+ tools = mistral_tools()
92
+ ```
93
+
94
+ ### Tool execution (framework-agnostic)
95
+
96
+ ```python
97
+ from simplefunctions.integrations import execute_tool
98
+
99
+ # Works with any framework's tool call output
100
+ result = execute_tool("get_world_state", {"focus": "energy,geopolitics"})
101
+ result = execute_tool("search_prediction_markets", {"query": "iran oil"})
102
+ result = execute_tool("get_world_delta", {"since": "1h"})
103
+ ```
104
+
105
+ ## API Reference
106
+
107
+ ### World State
108
+
109
+ | Function | Description | Tokens |
110
+ |----------|-------------|--------|
111
+ | `world()` | Full world state — 6 topics, anchor contracts, edges, divergences | ~800 |
112
+ | `world(focus="energy,geo")` | Same budget, concentrated on fewer topics | ~800 |
113
+ | `delta(since="1h")` | Only what changed since timestamp | ~30-50 |
114
+
115
+ ### Market Data
116
+
117
+ | Function | Description |
118
+ |----------|-------------|
119
+ | `scan("iran oil")` | Cross-venue market search with relevance ranking |
120
+ | `market("KXRECESSION-26DEC31")` | Single market profile with optional orderbook |
121
+ | `contagion(window="6h")` | Cross-market anomaly detection |
122
+ | `index()` | SF Prediction Market Index (uncertainty, geo risk, momentum) |
123
+ | `query("fed rate cut?")` | LLM-synthesized answer with live data |
124
+ | `edges()` | Top mispriced markets across all theses |
125
+ | `briefing(topic="iran")` | Daily topic briefing with X sentiment |
126
+ | `diff(topic="energy")` | Market derivatives over time |
127
+ | `changes(type="price_move")` | Recent price moves, new contracts, settlements |
128
+ | `context()` | Global market intelligence snapshot |
129
+
130
+ ### Focused World State
131
+
132
+ ```python
133
+ # Default: 4 contracts per topic across 6 topics
134
+ world()
135
+
136
+ # Focused: 10 contracts per topic across 2 topics
137
+ world(focus="geopolitics,energy")
138
+
139
+ # All topics: geopolitics, economy, energy, elections, crypto, tech
140
+ ```
141
+
142
+ ### Incremental Updates
143
+
144
+ ```python
145
+ # Full state at session start
146
+ state = world()
147
+
148
+ # Periodic refresh — only changes (~30-50 tokens)
149
+ changes = delta(since="1h")
150
+ changes = delta(since="6h")
151
+ changes = delta(since="2026-04-02T08:00:00Z")
152
+ ```
153
+
154
+ ## MCP Server
155
+
156
+ For Claude Code, Cursor, or any MCP-compatible agent:
157
+
158
+ ```bash
159
+ claude mcp add simplefunctions --url https://simplefunctions.dev/api/mcp/mcp
160
+ ```
161
+
162
+ 40 tools, no API key needed for public endpoints.
163
+
164
+ ## Why Prediction Markets?
165
+
166
+ A prediction market price of 53c on "Iran invasion" encodes the aggregate judgment of everyone with money at risk on that question. Get it wrong, lose money. This punishment mechanism produces calibrated probabilities more reliable than any analyst report, news summary, or LLM reasoning.
167
+
168
+ | | Web Search | News API | SimpleFunctions |
169
+ |---|---|---|---|
170
+ | **Output** | Narrative text | Headlines | Calibrated probabilities |
171
+ | **Token cost** | 2,000-5,000 | 500-1,000 | ~800 for everything |
172
+ | **Latency** | 2-5 seconds | 500ms | ~200ms (cached) |
173
+ | **Calibration** | None | None | Real money at risk |
174
+
175
+ ## Links
176
+
177
+ - [World State API](https://simplefunctions.dev/api/agent/world) — try it now
178
+ - [Interactive demo](https://simplefunctions.dev/world)
179
+ - [Documentation](https://simplefunctions.dev/docs/guide)
180
+ - [All endpoints](https://simplefunctions.dev/api/tools)
181
+ - [MCP Server](https://simplefunctions.dev/api/mcp/mcp)
182
+ - [npm CLI](https://www.npmjs.com/package/@spfunctions/cli) — `npm install -g @spfunctions/cli`
183
+
184
+ ## License
185
+
186
+ MIT
@@ -0,0 +1,159 @@
1
+ # SimpleFunctions
2
+
3
+ Calibrated world model for AI agents. Real-time probabilities from 9,706 prediction markets.
4
+
5
+ Your agent doesn't know what's happening in the world. Web search returns narratives ("tensions remain elevated"). SimpleFunctions returns calibrated numbers backed by real money: `Iran invasion: 53% (+5c, $225K volume)`.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pip install simplefunctions
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```python
16
+ from simplefunctions import world, delta, scan
17
+
18
+ # What's happening in the world right now? (~800 tokens, markdown)
19
+ print(world())
20
+
21
+ # What changed in the last hour? (~30-50 tokens)
22
+ print(delta(since="1h"))
23
+
24
+ # Search prediction markets
25
+ results = scan("fed rate cut")
26
+ for m in results["markets"][:5]:
27
+ print(f"{m['title']}: {m['price']}c")
28
+ ```
29
+
30
+ No API key needed. Free. Data from Kalshi (CFTC-regulated) and Polymarket, updated every 15 minutes.
31
+
32
+ ## Give Your Agent World Awareness
33
+
34
+ ### System prompt injection (simplest)
35
+
36
+ ```python
37
+ from simplefunctions import world
38
+ import anthropic
39
+
40
+ client = anthropic.Anthropic()
41
+ state = world()
42
+
43
+ response = client.messages.create(
44
+ model="claude-sonnet-4-20250514",
45
+ max_tokens=1024,
46
+ system=f"You are a research analyst.\n\n{state}",
47
+ messages=[{"role": "user", "content": "What's the recession probability?"}],
48
+ )
49
+ # Agent cites "33%" instead of hallucinating
50
+ ```
51
+
52
+ ### Tool definitions (one line per framework)
53
+
54
+ ```python
55
+ from simplefunctions.integrations import openai_tools, anthropic_tools, mistral_tools
56
+
57
+ # OpenAI Agents SDK / Responses API
58
+ tools = openai_tools()
59
+
60
+ # Anthropic Claude
61
+ tools = anthropic_tools()
62
+
63
+ # Mistral
64
+ tools = mistral_tools()
65
+ ```
66
+
67
+ ### Tool execution (framework-agnostic)
68
+
69
+ ```python
70
+ from simplefunctions.integrations import execute_tool
71
+
72
+ # Works with any framework's tool call output
73
+ result = execute_tool("get_world_state", {"focus": "energy,geopolitics"})
74
+ result = execute_tool("search_prediction_markets", {"query": "iran oil"})
75
+ result = execute_tool("get_world_delta", {"since": "1h"})
76
+ ```
77
+
78
+ ## API Reference
79
+
80
+ ### World State
81
+
82
+ | Function | Description | Tokens |
83
+ |----------|-------------|--------|
84
+ | `world()` | Full world state — 6 topics, anchor contracts, edges, divergences | ~800 |
85
+ | `world(focus="energy,geo")` | Same budget, concentrated on fewer topics | ~800 |
86
+ | `delta(since="1h")` | Only what changed since timestamp | ~30-50 |
87
+
88
+ ### Market Data
89
+
90
+ | Function | Description |
91
+ |----------|-------------|
92
+ | `scan("iran oil")` | Cross-venue market search with relevance ranking |
93
+ | `market("KXRECESSION-26DEC31")` | Single market profile with optional orderbook |
94
+ | `contagion(window="6h")` | Cross-market anomaly detection |
95
+ | `index()` | SF Prediction Market Index (uncertainty, geo risk, momentum) |
96
+ | `query("fed rate cut?")` | LLM-synthesized answer with live data |
97
+ | `edges()` | Top mispriced markets across all theses |
98
+ | `briefing(topic="iran")` | Daily topic briefing with X sentiment |
99
+ | `diff(topic="energy")` | Market derivatives over time |
100
+ | `changes(type="price_move")` | Recent price moves, new contracts, settlements |
101
+ | `context()` | Global market intelligence snapshot |
102
+
103
+ ### Focused World State
104
+
105
+ ```python
106
+ # Default: 4 contracts per topic across 6 topics
107
+ world()
108
+
109
+ # Focused: 10 contracts per topic across 2 topics
110
+ world(focus="geopolitics,energy")
111
+
112
+ # All topics: geopolitics, economy, energy, elections, crypto, tech
113
+ ```
114
+
115
+ ### Incremental Updates
116
+
117
+ ```python
118
+ # Full state at session start
119
+ state = world()
120
+
121
+ # Periodic refresh — only changes (~30-50 tokens)
122
+ changes = delta(since="1h")
123
+ changes = delta(since="6h")
124
+ changes = delta(since="2026-04-02T08:00:00Z")
125
+ ```
126
+
127
+ ## MCP Server
128
+
129
+ For Claude Code, Cursor, or any MCP-compatible agent:
130
+
131
+ ```bash
132
+ claude mcp add simplefunctions --url https://simplefunctions.dev/api/mcp/mcp
133
+ ```
134
+
135
+ 40 tools, no API key needed for public endpoints.
136
+
137
+ ## Why Prediction Markets?
138
+
139
+ A prediction market price of 53c on "Iran invasion" encodes the aggregate judgment of everyone with money at risk on that question. Get it wrong, lose money. This punishment mechanism produces calibrated probabilities more reliable than any analyst report, news summary, or LLM reasoning.
140
+
141
+ | | Web Search | News API | SimpleFunctions |
142
+ |---|---|---|---|
143
+ | **Output** | Narrative text | Headlines | Calibrated probabilities |
144
+ | **Token cost** | 2,000-5,000 | 500-1,000 | ~800 for everything |
145
+ | **Latency** | 2-5 seconds | 500ms | ~200ms (cached) |
146
+ | **Calibration** | None | None | Real money at risk |
147
+
148
+ ## Links
149
+
150
+ - [World State API](https://simplefunctions.dev/api/agent/world) — try it now
151
+ - [Interactive demo](https://simplefunctions.dev/world)
152
+ - [Documentation](https://simplefunctions.dev/docs/guide)
153
+ - [All endpoints](https://simplefunctions.dev/api/tools)
154
+ - [MCP Server](https://simplefunctions.dev/api/mcp/mcp)
155
+ - [npm CLI](https://www.npmjs.com/package/@spfunctions/cli) — `npm install -g @spfunctions/cli`
156
+
157
+ ## License
158
+
159
+ MIT
@@ -0,0 +1,44 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "simplefunctions-ai"
7
+ version = "0.1.0"
8
+ description = "Calibrated world model for AI agents. Real-time probabilities from 9,706 prediction markets."
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.9"
12
+ authors = [
13
+ { name = "SimpleFunctions", email = "hello@simplefunctions.dev" },
14
+ ]
15
+ keywords = [
16
+ "prediction-markets", "world-model", "ai-agents", "real-time-data",
17
+ "kalshi", "polymarket", "langchain", "openai", "anthropic", "mcp",
18
+ "agent-context", "world-state", "probabilities", "geopolitics",
19
+ ]
20
+ classifiers = [
21
+ "Development Status :: 4 - Beta",
22
+ "Intended Audience :: Developers",
23
+ "License :: OSI Approved :: MIT License",
24
+ "Programming Language :: Python :: 3",
25
+ "Programming Language :: Python :: 3.9",
26
+ "Programming Language :: Python :: 3.10",
27
+ "Programming Language :: Python :: 3.11",
28
+ "Programming Language :: Python :: 3.12",
29
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
30
+ "Topic :: Software Development :: Libraries :: Python Modules",
31
+ ]
32
+ dependencies = [
33
+ "requests>=2.28.0",
34
+ ]
35
+
36
+ [project.urls]
37
+ Homepage = "https://simplefunctions.dev"
38
+ Documentation = "https://simplefunctions.dev/docs/guide"
39
+ Repository = "https://github.com/spfunctions/simplefunctions-python"
40
+ "World State API" = "https://simplefunctions.dev/api/agent/world"
41
+ "MCP Server" = "https://simplefunctions.dev/api/mcp/mcp"
42
+
43
+ [tool.hatch.build.targets.wheel]
44
+ packages = ["simplefunctions"]
@@ -0,0 +1,57 @@
1
+ """
2
+ SimpleFunctions — Calibrated world model for AI agents.
3
+
4
+ Real-time probabilities from 9,706 prediction markets (Kalshi + Polymarket).
5
+ No API key needed for public endpoints. Data updated every 15 minutes.
6
+
7
+ Quick start:
8
+
9
+ from simplefunctions import world, delta, scan
10
+
11
+ # Get the current state of the world (~800 tokens, markdown)
12
+ print(world())
13
+
14
+ # What changed in the last hour? (~30-50 tokens)
15
+ print(delta(since="1h"))
16
+
17
+ # Search prediction markets
18
+ print(scan("iran oil"))
19
+
20
+ For LLM tool definitions:
21
+
22
+ from simplefunctions.integrations import openai_tools, anthropic_tools
23
+
24
+ Source: SimpleFunctions World Model — 9,706 markets, calibrated by real money.
25
+ https://simplefunctions.dev
26
+ """
27
+
28
+ from simplefunctions.client import (
29
+ world,
30
+ delta,
31
+ scan,
32
+ market,
33
+ contagion,
34
+ index,
35
+ query,
36
+ edges,
37
+ context,
38
+ briefing,
39
+ diff,
40
+ changes,
41
+ )
42
+
43
+ __version__ = "0.1.0"
44
+ __all__ = [
45
+ "world",
46
+ "delta",
47
+ "scan",
48
+ "market",
49
+ "contagion",
50
+ "index",
51
+ "query",
52
+ "edges",
53
+ "context",
54
+ "briefing",
55
+ "diff",
56
+ "changes",
57
+ ]
@@ -0,0 +1,278 @@
1
+ """
2
+ HTTP client for SimpleFunctions API.
3
+
4
+ All public endpoints require no authentication.
5
+ Authenticated endpoints (thesis, trading) require an API key from
6
+ https://simplefunctions.dev/dashboard/keys
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from typing import Any, Optional
12
+ import requests
13
+
14
+ BASE_URL = "https://simplefunctions.dev"
15
+
16
+ _session: Optional[requests.Session] = None
17
+
18
+
19
+ def _get_session() -> requests.Session:
20
+ global _session
21
+ if _session is None:
22
+ _session = requests.Session()
23
+ _session.headers["User-Agent"] = "simplefunctions-python/0.1.0"
24
+ return _session
25
+
26
+
27
+ def _get(path: str, params: Optional[dict[str, Any]] = None) -> requests.Response:
28
+ resp = _get_session().get(f"{BASE_URL}{path}", params=params, timeout=30)
29
+ resp.raise_for_status()
30
+ return resp
31
+
32
+
33
+ # ── World State ────────────────────────────────────────────────────────────────
34
+
35
+
36
+ def world(
37
+ focus: str = "",
38
+ format: str = "markdown",
39
+ ) -> str:
40
+ """Real-time world model for AI agents.
41
+
42
+ Returns ~800 tokens covering geopolitics, economy, energy, elections,
43
+ crypto, tech. Anchor contracts (recession, Fed, Iran invasion) always
44
+ present. Calibrated by prediction markets — real money at risk.
45
+
46
+ Args:
47
+ focus: Comma-separated topics for deeper coverage. Same token budget,
48
+ concentrated on fewer topics. Options: geopolitics, economy,
49
+ energy, elections, crypto, tech.
50
+ format: "markdown" (default, optimized for LLM context) or "json".
51
+
52
+ Returns:
53
+ Markdown string (default) or JSON string.
54
+
55
+ Example:
56
+ >>> from simplefunctions import world
57
+ >>> print(world()) # full panorama
58
+ >>> print(world(focus="energy,geopolitics")) # deeper on 2 topics
59
+ >>> data = world(format="json") # structured JSON
60
+ """
61
+ params: dict[str, str] = {}
62
+ if focus:
63
+ params["focus"] = focus
64
+ if format != "markdown":
65
+ params["format"] = format
66
+ return _get("/api/agent/world", params or None).text
67
+
68
+
69
+ def delta(since: str = "1h", format: str = "markdown") -> str:
70
+ """Incremental world state update — only what changed.
71
+
72
+ Returns ~30-50 tokens instead of 800. For agents in long-running
73
+ sessions that need periodic world awareness refresh.
74
+
75
+ Args:
76
+ since: Relative ("30m", "1h", "6h", "24h") or ISO timestamp.
77
+ format: "markdown" or "json".
78
+
79
+ Example:
80
+ >>> from simplefunctions import delta
81
+ >>> print(delta(since="1h")) # what changed in the last hour
82
+ >>> print(delta(since="6h")) # last 6 hours
83
+ """
84
+ params: dict[str, str] = {"since": since}
85
+ if format != "markdown":
86
+ params["format"] = format
87
+ return _get("/api/agent/world/delta", params).text
88
+
89
+
90
+ # ── Market Data ────────────────────────────────────────────────────────────────
91
+
92
+
93
+ def scan(q: str, venue: str = "", limit: int = 20) -> dict[str, Any]:
94
+ """Search prediction markets across Kalshi + Polymarket.
95
+
96
+ Returns prices, spreads, volumes with relevance ranking.
97
+
98
+ Args:
99
+ q: Natural language query, e.g. "iran oil", "fed rate cut", "bitcoin".
100
+ venue: Filter by venue: "kalshi" or "polymarket". Empty for both.
101
+ limit: Max results (default 20, max 50).
102
+
103
+ Example:
104
+ >>> from simplefunctions import scan
105
+ >>> results = scan("recession")
106
+ >>> for m in results["markets"][:5]:
107
+ ... print(f"{m['title']}: {m['price']}c")
108
+ """
109
+ params: dict[str, Any] = {"q": q, "limit": limit}
110
+ if venue:
111
+ params["venue"] = venue
112
+ return _get("/api/public/scan", params).json()
113
+
114
+
115
+ def market(ticker: str, depth: bool = False) -> dict[str, Any]:
116
+ """Complete market profile for a single contract.
117
+
118
+ Price, bid/ask, spread, volume, status, description.
119
+ Optional 5-level orderbook depth.
120
+
121
+ Args:
122
+ ticker: Kalshi ticker (e.g. "KXIRANINVASION") or Polymarket conditionId.
123
+ depth: Include 5-level orderbook (default False).
124
+
125
+ Example:
126
+ >>> from simplefunctions import market
127
+ >>> m = market("KXRECESSION-26DEC31", depth=True)
128
+ >>> print(f"Price: {m['price']}c, Spread: {m['spread']}c")
129
+ """
130
+ params: dict[str, Any] = {}
131
+ if depth:
132
+ params["depth"] = "true"
133
+ return _get(f"/api/public/market/{ticker}", params or None).json()
134
+
135
+
136
+ def contagion(window: str = "6h") -> dict[str, Any]:
137
+ """Cross-market anomaly detection.
138
+
139
+ When market A moves, which causally connected markets SHOULD move
140
+ but haven't? The gap is a potential edge.
141
+
142
+ Args:
143
+ window: Lookback window: "1h", "6h", "24h", "3d".
144
+
145
+ Example:
146
+ >>> from simplefunctions import contagion
147
+ >>> data = contagion(window="24h")
148
+ >>> for signal in data["signals"][:3]:
149
+ ... print(f"Trigger: {signal['trigger']['ticker']} → {len(signal['lagging'])} lagging")
150
+ """
151
+ return _get("/api/public/contagion", {"window": window}).json()
152
+
153
+
154
+ def index(history: bool = False) -> dict[str, Any]:
155
+ """SF Prediction Market Index.
156
+
157
+ Uncertainty (0-100), Geopolitical Risk (0-100), Momentum (-1 to +1),
158
+ Activity (0-100). Computed from 548 orderbook-tracked tickers.
159
+
160
+ Args:
161
+ history: Include 24h hourly trajectory (default False).
162
+
163
+ Example:
164
+ >>> from simplefunctions import index
165
+ >>> idx = index()
166
+ >>> print(f"Geo Risk: {idx['geopolitical']}/100")
167
+ """
168
+ params: dict[str, Any] = {}
169
+ if history:
170
+ params["history"] = "true"
171
+ return _get("/api/public/index", params or None).json()
172
+
173
+
174
+ def query(q: str, mode: str = "full", depth: bool = False) -> dict[str, Any]:
175
+ """Ask any question about future events or probabilities.
176
+
177
+ Returns live contract prices from Kalshi + Polymarket, X/Twitter
178
+ sentiment, traditional market prices, and an LLM-synthesized answer.
179
+
180
+ Args:
181
+ q: Natural language query.
182
+ mode: "full" (LLM synthesis, default) or "raw" (data only, fastest).
183
+ depth: Include orderbook depth for top markets.
184
+
185
+ Example:
186
+ >>> from simplefunctions import query
187
+ >>> result = query("fed rate cut probability 2026")
188
+ >>> print(result["answer"])
189
+ """
190
+ params: dict[str, Any] = {"q": q, "mode": mode}
191
+ if depth:
192
+ params["depth"] = "true"
193
+ return _get("/api/public/query", params).json()
194
+
195
+
196
+ def edges() -> dict[str, Any]:
197
+ """Aggregated edges across all public theses.
198
+
199
+ Sorted by |adjustedEdge|. Each edge = model price vs market price.
200
+
201
+ Example:
202
+ >>> from simplefunctions import edges
203
+ >>> for e in edges()["edges"][:5]:
204
+ ... print(f"{e['title']}: {e['edge']}c edge")
205
+ """
206
+ return _get("/api/edges").json()
207
+
208
+
209
+ def context(compact: bool = False, q: str = "") -> dict[str, Any]:
210
+ """Global market intelligence snapshot.
211
+
212
+ Top edges, price movers, highlights, traditional markets.
213
+
214
+ Args:
215
+ compact: Edges + highlights + traditional only.
216
+ q: Filter by keyword.
217
+ """
218
+ params: dict[str, Any] = {}
219
+ if compact:
220
+ params["compact"] = "true"
221
+ if q:
222
+ params["q"] = q
223
+ return _get("/api/public/context", params or None).json()
224
+
225
+
226
+ def briefing(topic: str, window: str = "24h") -> dict[str, Any]:
227
+ """Daily topic briefing: what changed, key movers, X sentiment, outlook.
228
+
229
+ Args:
230
+ topic: One of: iran, oil, fed, economy, elections, crypto, china,
231
+ ukraine, tech, climate.
232
+ window: Time window (default "24h").
233
+ """
234
+ return _get("/api/public/briefing", {"topic": topic, "window": window}).json()
235
+
236
+
237
+ def diff(
238
+ tickers: str = "",
239
+ topic: str = "",
240
+ window: str = "24h",
241
+ ) -> dict[str, Any]:
242
+ """Market derivatives: price/volume/spread deltas over time.
243
+
244
+ Detects divergence signals (volume spike + flat price, liquidity exit).
245
+
246
+ Args:
247
+ tickers: Comma-separated tickers.
248
+ topic: Or use topic to auto-resolve tickers.
249
+ window: Time window (default "24h").
250
+ """
251
+ params: dict[str, Any] = {"window": window}
252
+ if tickers:
253
+ params["tickers"] = tickers
254
+ if topic:
255
+ params["topic"] = topic
256
+ return _get("/api/public/diff", params).json()
257
+
258
+
259
+ def changes(
260
+ since: str = "",
261
+ q: str = "",
262
+ type: str = "",
263
+ ) -> dict[str, Any]:
264
+ """Server-side detected price moves, new contracts, settlements.
265
+
266
+ Args:
267
+ since: ISO timestamp (default: 1h ago).
268
+ q: Filter by keyword.
269
+ type: "price_move", "new_contract", or "removed_contract".
270
+ """
271
+ params: dict[str, Any] = {}
272
+ if since:
273
+ params["since"] = since
274
+ if q:
275
+ params["q"] = q
276
+ if type:
277
+ params["type"] = type
278
+ return _get("/api/changes", params or None).json()
@@ -0,0 +1,195 @@
1
+ """
2
+ Ready-to-use LLM tool definitions for major frameworks.
3
+
4
+ from simplefunctions.integrations import openai_tools, anthropic_tools, langchain_tools
5
+
6
+ Each returns tool definitions in the format expected by that framework.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from typing import Any
12
+
13
+
14
+ # ── Shared tool specs ──────────────────────────────────────────────────────────
15
+
16
+ _TOOLS = [
17
+ {
18
+ "name": "get_world_state",
19
+ "description": "Get the current state of the world from prediction markets. Returns ~800 tokens of calibrated probabilities covering geopolitics, economy, energy, elections, crypto, tech. Anchor contracts (recession, Fed, Iran invasion) always present. Use focus parameter to concentrate token budget on fewer topics for deeper coverage. Source: SimpleFunctions World Model.",
20
+ "params": {
21
+ "focus": {
22
+ "type": "string",
23
+ "description": "Comma-separated topics for deeper coverage: geopolitics, economy, energy, elections, crypto, tech. Empty for all topics.",
24
+ "required": False,
25
+ },
26
+ },
27
+ "fn": "world",
28
+ },
29
+ {
30
+ "name": "get_world_delta",
31
+ "description": "Get only what changed in the world since a given time. Returns ~30-50 tokens vs 800 for full state. Use for periodic refresh during long-running tasks.",
32
+ "params": {
33
+ "since": {
34
+ "type": "string",
35
+ "description": "Relative time (30m, 1h, 6h, 24h) or ISO timestamp.",
36
+ "required": True,
37
+ },
38
+ },
39
+ "fn": "delta",
40
+ },
41
+ {
42
+ "name": "search_prediction_markets",
43
+ "description": "Search prediction markets for specific contracts across Kalshi and Polymarket. Returns prices, volumes, and spreads with relevance ranking.",
44
+ "params": {
45
+ "query": {
46
+ "type": "string",
47
+ "description": "Natural language search query, e.g. 'iran oil', 'fed rate cut', 'bitcoin price'.",
48
+ "required": True,
49
+ },
50
+ },
51
+ "fn": "scan",
52
+ },
53
+ {
54
+ "name": "get_market_detail",
55
+ "description": "Get detailed data for a specific prediction market contract. Includes price, spread, volume, orderbook depth, and thesis edges.",
56
+ "params": {
57
+ "ticker": {
58
+ "type": "string",
59
+ "description": "Kalshi ticker (e.g. KXRECESSION-26DEC31) or Polymarket condition ID.",
60
+ "required": True,
61
+ },
62
+ },
63
+ "fn": "market",
64
+ },
65
+ {
66
+ "name": "get_cross_market_contagion",
67
+ "description": "Detect cross-market anomalies: what should have moved but hasn't. When causally connected markets diverge, the gap is a potential edge.",
68
+ "params": {
69
+ "window": {
70
+ "type": "string",
71
+ "description": "Lookback window: 1h, 6h, 24h, 3d.",
72
+ "required": False,
73
+ },
74
+ },
75
+ "fn": "contagion",
76
+ },
77
+ ]
78
+
79
+
80
+ # ── OpenAI function calling ───────────────────────────────────────────────────
81
+
82
+
83
+ def openai_tools() -> list[dict[str, Any]]:
84
+ """Return tool definitions for OpenAI function calling (Responses API / Agents SDK).
85
+
86
+ Example:
87
+ from simplefunctions.integrations import openai_tools
88
+ tools = openai_tools()
89
+ response = client.responses.create(model="gpt-4o", tools=tools, ...)
90
+ """
91
+ result = []
92
+ for t in _TOOLS:
93
+ properties = {}
94
+ required = []
95
+ for pname, pspec in t["params"].items():
96
+ properties[pname] = {
97
+ "type": pspec["type"],
98
+ "description": pspec["description"],
99
+ }
100
+ if pspec.get("required"):
101
+ required.append(pname)
102
+
103
+ result.append({
104
+ "type": "function",
105
+ "function": {
106
+ "name": t["name"],
107
+ "description": t["description"],
108
+ "parameters": {
109
+ "type": "object",
110
+ "properties": properties,
111
+ **({"required": required} if required else {}),
112
+ },
113
+ },
114
+ })
115
+ return result
116
+
117
+
118
+ # ── Anthropic tool use ─────────────────────────────────────────────────────────
119
+
120
+
121
+ def anthropic_tools() -> list[dict[str, Any]]:
122
+ """Return tool definitions for Anthropic Claude tool use.
123
+
124
+ Example:
125
+ from simplefunctions.integrations import anthropic_tools
126
+ tools = anthropic_tools()
127
+ response = client.messages.create(model="claude-sonnet-4-20250514", tools=tools, ...)
128
+ """
129
+ result = []
130
+ for t in _TOOLS:
131
+ properties = {}
132
+ required = []
133
+ for pname, pspec in t["params"].items():
134
+ properties[pname] = {
135
+ "type": pspec["type"],
136
+ "description": pspec["description"],
137
+ }
138
+ if pspec.get("required"):
139
+ required.append(pname)
140
+
141
+ result.append({
142
+ "name": t["name"],
143
+ "description": t["description"],
144
+ "input_schema": {
145
+ "type": "object",
146
+ "properties": properties,
147
+ **({"required": required} if required else {}),
148
+ },
149
+ })
150
+ return result
151
+
152
+
153
+ # ── Mistral function calling ──────────────────────────────────────────────────
154
+
155
+
156
+ def mistral_tools() -> list[dict[str, Any]]:
157
+ """Return tool definitions for Mistral function calling.
158
+
159
+ Example:
160
+ from simplefunctions.integrations import mistral_tools
161
+ tools = mistral_tools()
162
+ response = client.chat.complete(model="mistral-large-latest", tools=tools, ...)
163
+ """
164
+ # Same format as OpenAI
165
+ return openai_tools()
166
+
167
+
168
+ # ── Tool executor ──────────────────────────────────────────────────────────────
169
+
170
+
171
+ def execute_tool(name: str, arguments: dict[str, Any]) -> str:
172
+ """Execute a SimpleFunctions tool call and return the result as a string.
173
+
174
+ Works with any framework's tool calling output.
175
+
176
+ Example:
177
+ from simplefunctions.integrations import execute_tool
178
+ result = execute_tool("get_world_state", {"focus": "energy,geopolitics"})
179
+ result = execute_tool("search_prediction_markets", {"query": "iran"})
180
+ """
181
+ import json
182
+ from simplefunctions import client
183
+
184
+ if name == "get_world_state":
185
+ return client.world(focus=arguments.get("focus", ""))
186
+ elif name == "get_world_delta":
187
+ return client.delta(since=arguments.get("since", "1h"))
188
+ elif name == "search_prediction_markets":
189
+ return json.dumps(client.scan(q=arguments["query"]), indent=2)
190
+ elif name == "get_market_detail":
191
+ return json.dumps(client.market(ticker=arguments["ticker"]), indent=2)
192
+ elif name == "get_cross_market_contagion":
193
+ return json.dumps(client.contagion(window=arguments.get("window", "6h")), indent=2)
194
+ else:
195
+ return f"Unknown tool: {name}"
File without changes