fahali 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.
fahali-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,117 @@
1
+ Metadata-Version: 2.4
2
+ Name: fahali
3
+ Version: 0.1.0
4
+ Summary: Market intelligence AI agents can verify - signed receipts, judged track record (misses included), Brier-calibrated forecasts. Adapters for LangChain, CrewAI, LlamaIndex, AutoGen, smolagents. MCP: mcp.fahaliai.com
5
+ Project-URL: Homepage, https://fahaliai.com/developer
6
+ Project-URL: Documentation, https://fahaliai.com/developer
7
+ Project-URL: Repository, https://github.com/BobMain-2025/fahali-integrations
8
+ Author-email: Future Legends AI <robert@futurelegendsai.com>
9
+ License-Expression: MIT
10
+ Keywords: ai-agents,crewai,crypto,function-calling,langchain,llamaindex,market-intelligence,mcp,risk
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Topic :: Office/Business :: Financial :: Investment
15
+ Requires-Python: >=3.9
16
+ Description-Content-Type: text/markdown
17
+
18
+ # fahali
19
+
20
+ **Market intelligence AI agents can verify.** Every verdict carries a signed SHA-256 receipt. Every judged signal has a public replay URL. The track record keeps its misses and publishes its methodology. Forecast probabilities are Brier-scored against realized outcomes.
21
+
22
+ Zero dependencies. Works with any agent framework. *Observation, not advice.*
23
+
24
+ ```bash
25
+ pip install fahali # Python
26
+ npm install fahali # JS/TS
27
+ ```
28
+
29
+ Free key (50 calls/day, no card): [app.fahaliai.com/developer](https://app.fahaliai.com/developer) · Docs: [fahaliai.com/developer](https://fahaliai.com/developer) · MCP: `https://mcp.fahaliai.com/mcp`
30
+
31
+ ## Direct
32
+
33
+ ```ts
34
+ import { FahaliClient } from "fahali";
35
+
36
+ const fahali = new FahaliClient({ apiKey: process.env.FAHALI_API_KEY });
37
+ const verdict = await fahali.verdict(["BTCUSDT"]); // committee read + signed receipt
38
+ const record = await fahali.symbolRecord("BTCUSDT"); // judged record, misses included
39
+ ```
40
+
41
+ ## OpenAI (and anything using function-calling format)
42
+
43
+ ```ts
44
+ import { FahaliClient, FAHALI_TOOLS, executeTool } from "fahali";
45
+
46
+ const fahali = new FahaliClient({ apiKey: process.env.FAHALI_API_KEY });
47
+ const tools = FAHALI_TOOLS.map((t) => ({ type: "function", function: t }));
48
+ // ...pass `tools` to chat.completions.create; on a tool call:
49
+ const result = await executeTool(fahali, call.function.name, JSON.parse(call.function.arguments));
50
+ ```
51
+
52
+ ## LangChain (Python)
53
+
54
+ ```python
55
+ from fahali import FahaliClient
56
+ from fahali.langchain import get_langchain_tools
57
+ tools = get_langchain_tools(FahaliClient(api_key=...))
58
+ ```
59
+
60
+ ## CrewAI
61
+
62
+ ```python
63
+ from fahali.crewai import get_crewai_tools
64
+ ```
65
+
66
+ ## LlamaIndex
67
+
68
+ ```python
69
+ from fahali.llamaindex import get_llamaindex_tools
70
+ ```
71
+
72
+ ## AutoGen / smolagents / Semantic Kernel / raw OpenAI
73
+
74
+ ```python
75
+ from fahali import FahaliClient, TOOL_SPECS, execute_tool # function-calling format
76
+ ```
77
+
78
+ ## Vercel AI SDK
79
+
80
+ ```ts
81
+ import { tool, jsonSchema, generateText } from "ai";
82
+ import { FahaliClient, toAiSdkTools } from "fahali";
83
+
84
+ const fahali = new FahaliClient({ apiKey: process.env.FAHALI_API_KEY });
85
+ const { text } = await generateText({
86
+ model,
87
+ tools: toAiSdkTools(fahali, { tool, jsonSchema }),
88
+ prompt: "Is anything threatening a BTC-heavy portfolio right now? Cite replays.",
89
+ });
90
+ ```
91
+
92
+ ## LangChain.js
93
+
94
+ ```ts
95
+ import { DynamicStructuredTool } from "@langchain/core/tools";
96
+ import { FahaliClient, toLangchainTools } from "fahali";
97
+
98
+ const fahali = new FahaliClient({ apiKey: process.env.FAHALI_API_KEY });
99
+ const tools = toLangchainTools(fahali, { DynamicStructuredTool });
100
+ ```
101
+
102
+ ## Tools
103
+
104
+ | Tool | What your agent gets |
105
+ |---|---|
106
+ | `fahali_verdict` | 18-engine committee read: agreement, dissent on the record, signed receipt, replay URL |
107
+ | `fahali_forecast_72h` | Crash/neutral/pump distribution, Brier-calibrated |
108
+ | `fahali_tape` | Latest judged calls market-wide — hits **and misses** |
109
+ | `fahali_symbol_record` | Per-symbol judged record with replay URLs |
110
+ | `fahali_track_record` | Aggregate scorecard: lift vs base rate, sample sizes, disclosed gaps |
111
+ | `fahali_recent_alerts` | Live detections across ~600 scanned instruments |
112
+
113
+ ## Why this instead of a terminal or search
114
+
115
+ Terminals were built for human eyes; search gives agents unaccountable text. Fahali's answers are **claims your agent can check**: methodology at [fahaliai.com/methodology](https://fahaliai.com/methodology), pricing free → metered at [fahaliai.com/developer](https://fahaliai.com/developer).
116
+
117
+ MIT © Future Legends AI. Nothing here is a recommendation to buy or sell anything.
fahali-0.1.0/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # fahali
2
+
3
+ **Market intelligence AI agents can verify.** Every verdict carries a signed SHA-256 receipt. Every judged signal has a public replay URL. The track record keeps its misses and publishes its methodology. Forecast probabilities are Brier-scored against realized outcomes.
4
+
5
+ Zero dependencies. Works with any agent framework. *Observation, not advice.*
6
+
7
+ ```bash
8
+ pip install fahali # Python
9
+ npm install fahali # JS/TS
10
+ ```
11
+
12
+ Free key (50 calls/day, no card): [app.fahaliai.com/developer](https://app.fahaliai.com/developer) · Docs: [fahaliai.com/developer](https://fahaliai.com/developer) · MCP: `https://mcp.fahaliai.com/mcp`
13
+
14
+ ## Direct
15
+
16
+ ```ts
17
+ import { FahaliClient } from "fahali";
18
+
19
+ const fahali = new FahaliClient({ apiKey: process.env.FAHALI_API_KEY });
20
+ const verdict = await fahali.verdict(["BTCUSDT"]); // committee read + signed receipt
21
+ const record = await fahali.symbolRecord("BTCUSDT"); // judged record, misses included
22
+ ```
23
+
24
+ ## OpenAI (and anything using function-calling format)
25
+
26
+ ```ts
27
+ import { FahaliClient, FAHALI_TOOLS, executeTool } from "fahali";
28
+
29
+ const fahali = new FahaliClient({ apiKey: process.env.FAHALI_API_KEY });
30
+ const tools = FAHALI_TOOLS.map((t) => ({ type: "function", function: t }));
31
+ // ...pass `tools` to chat.completions.create; on a tool call:
32
+ const result = await executeTool(fahali, call.function.name, JSON.parse(call.function.arguments));
33
+ ```
34
+
35
+ ## LangChain (Python)
36
+
37
+ ```python
38
+ from fahali import FahaliClient
39
+ from fahali.langchain import get_langchain_tools
40
+ tools = get_langchain_tools(FahaliClient(api_key=...))
41
+ ```
42
+
43
+ ## CrewAI
44
+
45
+ ```python
46
+ from fahali.crewai import get_crewai_tools
47
+ ```
48
+
49
+ ## LlamaIndex
50
+
51
+ ```python
52
+ from fahali.llamaindex import get_llamaindex_tools
53
+ ```
54
+
55
+ ## AutoGen / smolagents / Semantic Kernel / raw OpenAI
56
+
57
+ ```python
58
+ from fahali import FahaliClient, TOOL_SPECS, execute_tool # function-calling format
59
+ ```
60
+
61
+ ## Vercel AI SDK
62
+
63
+ ```ts
64
+ import { tool, jsonSchema, generateText } from "ai";
65
+ import { FahaliClient, toAiSdkTools } from "fahali";
66
+
67
+ const fahali = new FahaliClient({ apiKey: process.env.FAHALI_API_KEY });
68
+ const { text } = await generateText({
69
+ model,
70
+ tools: toAiSdkTools(fahali, { tool, jsonSchema }),
71
+ prompt: "Is anything threatening a BTC-heavy portfolio right now? Cite replays.",
72
+ });
73
+ ```
74
+
75
+ ## LangChain.js
76
+
77
+ ```ts
78
+ import { DynamicStructuredTool } from "@langchain/core/tools";
79
+ import { FahaliClient, toLangchainTools } from "fahali";
80
+
81
+ const fahali = new FahaliClient({ apiKey: process.env.FAHALI_API_KEY });
82
+ const tools = toLangchainTools(fahali, { DynamicStructuredTool });
83
+ ```
84
+
85
+ ## Tools
86
+
87
+ | Tool | What your agent gets |
88
+ |---|---|
89
+ | `fahali_verdict` | 18-engine committee read: agreement, dissent on the record, signed receipt, replay URL |
90
+ | `fahali_forecast_72h` | Crash/neutral/pump distribution, Brier-calibrated |
91
+ | `fahali_tape` | Latest judged calls market-wide — hits **and misses** |
92
+ | `fahali_symbol_record` | Per-symbol judged record with replay URLs |
93
+ | `fahali_track_record` | Aggregate scorecard: lift vs base rate, sample sizes, disclosed gaps |
94
+ | `fahali_recent_alerts` | Live detections across ~600 scanned instruments |
95
+
96
+ ## Why this instead of a terminal or search
97
+
98
+ Terminals were built for human eyes; search gives agents unaccountable text. Fahali's answers are **claims your agent can check**: methodology at [fahaliai.com/methodology](https://fahaliai.com/methodology), pricing free → metered at [fahaliai.com/developer](https://fahaliai.com/developer).
99
+
100
+ MIT © Future Legends AI. Nothing here is a recommendation to buy or sell anything.
@@ -0,0 +1,128 @@
1
+ """fahali — market intelligence AI agents can verify.
2
+
3
+ Signed receipts on every verdict, a judged track record that keeps its
4
+ misses, Brier-calibrated forecasts, public replays. Observation, not advice.
5
+
6
+ Free key (50 calls/day): https://app.fahaliai.com/developer
7
+ Adapters: fahali.langchain, fahali.crewai, fahali.llamaindex — plus
8
+ TOOL_SPECS (OpenAI function-calling format) for AutoGen, smolagents,
9
+ Semantic Kernel, or anything else.
10
+ """
11
+ from __future__ import annotations
12
+
13
+ import json
14
+ import urllib.request
15
+ import urllib.error
16
+ from typing import Any, Optional
17
+
18
+ __version__ = "0.1.0"
19
+ DEFAULT_BASE_URL = "https://app.fahaliai.com"
20
+
21
+
22
+ class FahaliError(RuntimeError):
23
+ pass
24
+
25
+
26
+ class FahaliClient:
27
+ """Minimal, dependency-free client for the Fahali API."""
28
+
29
+ def __init__(self, api_key: Optional[str] = None, base_url: str = DEFAULT_BASE_URL, timeout: float = 20.0):
30
+ self.api_key = api_key
31
+ self.base_url = base_url.rstrip("/")
32
+ self.timeout = timeout
33
+
34
+ def _get(self, path: str) -> Any:
35
+ req = urllib.request.Request(self.base_url + path)
36
+ if self.api_key:
37
+ req.add_header("Authorization", f"Bearer {self.api_key}")
38
+ try:
39
+ with urllib.request.urlopen(req, timeout=self.timeout) as r:
40
+ return json.loads(r.read().decode("utf-8"))
41
+ except urllib.error.HTTPError as e:
42
+ body = e.read().decode("utf-8", "ignore")[:300]
43
+ raise FahaliError(f"Fahali {e.code} on {path}: {body}") from None
44
+
45
+ def verdict(self, symbols: list[str]) -> Any:
46
+ """Committee verdict(s) with signed receipts."""
47
+ return self._get(f"/api/agent/verdict?symbols={','.join(symbols)}")
48
+
49
+ def forecast_72h(self, symbol: str) -> Any:
50
+ """72h crash/neutral/pump forecast (Brier-calibrated distribution)."""
51
+ return self._get(f"/api/forecast/72h?symbol={symbol}")
52
+
53
+ def tape(self) -> Any:
54
+ """Latest judged calls market-wide — hits AND misses. Public."""
55
+ return self._get("/api/tape")
56
+
57
+ def replay(self, signal_id: str) -> Any:
58
+ """Public replay of one judged signal — citable proof."""
59
+ return self._get(f"/api/replay/{signal_id}")
60
+
61
+ def symbol_record(self, symbol: str) -> Any:
62
+ """Per-symbol judged record (last 9 calls, misses included). Public."""
63
+ return self._get(f"/api/replay/history/{symbol}")
64
+
65
+ def track_record(self) -> Any:
66
+ """Aggregate scorecard: lift vs base rates, samples, disclosed gaps."""
67
+ return self._get("/api/track-record/scorecard")
68
+
69
+ def recent_alerts(self) -> Any:
70
+ """Latest detections across the scanned universe."""
71
+ return self._get("/api/alerts/recent")
72
+
73
+ def public_stats(self) -> Any:
74
+ """Coverage + freshness. Public, no auth."""
75
+ return self._get("/api/public/stats")
76
+
77
+
78
+ # OpenAI function-calling format — AutoGen, Semantic Kernel, raw OpenAI, etc.
79
+ TOOL_SPECS: list[dict[str, Any]] = [
80
+ {
81
+ "name": "fahali_verdict",
82
+ "description": "Committee market verdict for symbols (e.g. BTCUSDT). 18 engines vote; includes agreement, dissent kept on the record, a signed SHA-256 receipt and a public replay URL. Observation, not advice.",
83
+ "parameters": {"type": "object", "properties": {"symbols": {"type": "array", "items": {"type": "string"}}}, "required": ["symbols"]},
84
+ },
85
+ {
86
+ "name": "fahali_forecast_72h",
87
+ "description": "72-hour crash/neutral/pump probability forecast for one symbol; the distribution is Brier-scored against realized outcomes.",
88
+ "parameters": {"type": "object", "properties": {"symbol": {"type": "string"}}, "required": ["symbol"]},
89
+ },
90
+ {
91
+ "name": "fahali_tape",
92
+ "description": "The live tape: latest judged calls across the market, hits AND misses, each with a public replay URL.",
93
+ "parameters": {"type": "object", "properties": {}},
94
+ },
95
+ {
96
+ "name": "fahali_symbol_record",
97
+ "description": "Judged track record for one symbol: last 9 calls with hit/miss outcomes and replay URLs.",
98
+ "parameters": {"type": "object", "properties": {"symbol": {"type": "string"}}, "required": ["symbol"]},
99
+ },
100
+ {
101
+ "name": "fahali_track_record",
102
+ "description": "Aggregate scorecard: directional/magnitude/forecast axes with sample sizes and disclosed gap windows. Read lift vs base rate, never raw percentages.",
103
+ "parameters": {"type": "object", "properties": {}},
104
+ },
105
+ {
106
+ "name": "fahali_recent_alerts",
107
+ "description": "Latest engine detections (volume anomalies, dark-pool proxy, regime flips, whale flows...) across ~600 instruments.",
108
+ "parameters": {"type": "object", "properties": {}},
109
+ },
110
+ ]
111
+
112
+
113
+ def execute_tool(client: FahaliClient, name: str, args: Optional[dict[str, Any]] = None) -> Any:
114
+ """Execute a TOOL_SPECS call by name."""
115
+ a = args or {}
116
+ if name == "fahali_verdict":
117
+ return client.verdict(list(a.get("symbols") or []))
118
+ if name == "fahali_forecast_72h":
119
+ return client.forecast_72h(str(a.get("symbol", "")))
120
+ if name == "fahali_tape":
121
+ return client.tape()
122
+ if name == "fahali_symbol_record":
123
+ return client.symbol_record(str(a.get("symbol", "")))
124
+ if name == "fahali_track_record":
125
+ return client.track_record()
126
+ if name == "fahali_recent_alerts":
127
+ return client.recent_alerts()
128
+ raise FahaliError(f"Unknown Fahali tool: {name}")
@@ -0,0 +1,36 @@
1
+ """CrewAI adapter: `pip install fahali crewai-tools`."""
2
+ from __future__ import annotations
3
+ from . import FahaliClient, execute_tool
4
+
5
+
6
+ def get_crewai_tools(client: FahaliClient) -> list:
7
+ """BaseTool list for CrewAI agents."""
8
+ import json
9
+ from crewai.tools import tool # lazy
10
+
11
+ @tool("fahali_verdict")
12
+ def fahali_verdict(symbols: str) -> str:
13
+ """Committee market verdict for comma-separated symbols (e.g. 'BTCUSDT,ETHUSDT'). 18 engines vote; includes agreement, dissent on the record, a signed receipt and a public replay URL. Observation, not advice."""
14
+ return json.dumps(execute_tool(client, "fahali_verdict", {"symbols": symbols.split(",")}))
15
+
16
+ @tool("fahali_forecast_72h")
17
+ def fahali_forecast_72h(symbol: str) -> str:
18
+ """72-hour crash/neutral/pump probability forecast for one symbol, Brier-calibrated."""
19
+ return json.dumps(execute_tool(client, "fahali_forecast_72h", {"symbol": symbol}))
20
+
21
+ @tool("fahali_tape")
22
+ def fahali_tape() -> str:
23
+ """The live tape: latest judged calls, hits AND misses, with replay URLs."""
24
+ return json.dumps(execute_tool(client, "fahali_tape"))
25
+
26
+ @tool("fahali_symbol_record")
27
+ def fahali_symbol_record(symbol: str) -> str:
28
+ """Judged track record for one symbol - last 9 calls, misses included."""
29
+ return json.dumps(execute_tool(client, "fahali_symbol_record", {"symbol": symbol}))
30
+
31
+ @tool("fahali_track_record")
32
+ def fahali_track_record() -> str:
33
+ """Aggregate scorecard with sample sizes and disclosed gaps - read lift vs base rate."""
34
+ return json.dumps(execute_tool(client, "fahali_track_record"))
35
+
36
+ return [fahali_verdict, fahali_forecast_72h, fahali_tape, fahali_symbol_record, fahali_track_record]
@@ -0,0 +1,22 @@
1
+ """LangChain adapter: `pip install fahali langchain-core`."""
2
+ from __future__ import annotations
3
+ from typing import Any
4
+ from . import FahaliClient, TOOL_SPECS, execute_tool
5
+
6
+
7
+ def get_langchain_tools(client: FahaliClient) -> list:
8
+ """StructuredTool list for LangChain / LangGraph agents."""
9
+ from langchain_core.tools import StructuredTool # lazy
10
+
11
+ tools = []
12
+ for spec in TOOL_SPECS:
13
+ def _make(name: str):
14
+ def _run(**kwargs: Any) -> str:
15
+ import json
16
+ return json.dumps(execute_tool(client, name, kwargs))
17
+ return _run
18
+ tools.append(StructuredTool.from_function(
19
+ func=_make(spec["name"]), name=spec["name"],
20
+ description=spec["description"], args_schema=None,
21
+ ))
22
+ return tools
@@ -0,0 +1,19 @@
1
+ """LlamaIndex adapter: `pip install fahali llama-index-core`."""
2
+ from __future__ import annotations
3
+ from . import FahaliClient, TOOL_SPECS, execute_tool
4
+
5
+
6
+ def get_llamaindex_tools(client: FahaliClient) -> list:
7
+ """FunctionTool list for LlamaIndex agents."""
8
+ import json
9
+ from llama_index.core.tools import FunctionTool # lazy
10
+
11
+ tools = []
12
+ for spec in TOOL_SPECS:
13
+ def _make(name: str):
14
+ def _run(**kwargs) -> str:
15
+ return json.dumps(execute_tool(client, name, kwargs))
16
+ _run.__name__ = name
17
+ return _run
18
+ tools.append(FunctionTool.from_defaults(fn=_make(spec["name"]), name=spec["name"], description=spec["description"]))
19
+ return tools
@@ -0,0 +1,24 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "fahali"
7
+ version = "0.1.0"
8
+ description = "Market intelligence AI agents can verify - signed receipts, judged track record (misses included), Brier-calibrated forecasts. Adapters for LangChain, CrewAI, LlamaIndex, AutoGen, smolagents. MCP: mcp.fahaliai.com"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.9"
12
+ authors = [{ name = "Future Legends AI", email = "robert@futurelegendsai.com" }]
13
+ keywords = ["ai-agents", "mcp", "market-intelligence", "langchain", "crewai", "llamaindex", "function-calling", "crypto", "risk"]
14
+ classifiers = [
15
+ "Intended Audience :: Developers",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Programming Language :: Python :: 3",
18
+ "Topic :: Office/Business :: Financial :: Investment",
19
+ ]
20
+
21
+ [project.urls]
22
+ Homepage = "https://fahaliai.com/developer"
23
+ Documentation = "https://fahaliai.com/developer"
24
+ Repository = "https://github.com/BobMain-2025/fahali-integrations"