ellements 0.2.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.
Files changed (156) hide show
  1. ellements-0.2.0/LICENSE +42 -0
  2. ellements-0.2.0/MANIFEST.in +6 -0
  3. ellements-0.2.0/PKG-INFO +368 -0
  4. ellements-0.2.0/README.md +241 -0
  5. ellements-0.2.0/ellements/__init__.py +57 -0
  6. ellements-0.2.0/ellements-agents/README.md +83 -0
  7. ellements-0.2.0/ellements-agents/src/ellements/agents/__init__.py +45 -0
  8. ellements-0.2.0/ellements-agents/src/ellements/agents/backend.py +100 -0
  9. ellements-0.2.0/ellements-agents/src/ellements/agents/builder.py +303 -0
  10. ellements-0.2.0/ellements-agents/src/ellements/agents/claude_backend.py +200 -0
  11. ellements-0.2.0/ellements-agents/src/ellements/agents/controller.py +237 -0
  12. ellements-0.2.0/ellements-agents/src/ellements/agents/openai_backend.py +187 -0
  13. ellements-0.2.0/ellements-agents/src/ellements/agents/py.typed +0 -0
  14. ellements-0.2.0/ellements-agents/src/ellements/agents/runner.py +358 -0
  15. ellements-0.2.0/ellements-agents/src/ellements/agents/tools.py +30 -0
  16. ellements-0.2.0/ellements-benchmarking/LICENSE +42 -0
  17. ellements-0.2.0/ellements-benchmarking/README.md +71 -0
  18. ellements-0.2.0/ellements-benchmarking/src/ellements/benchmarking/__init__.py +52 -0
  19. ellements-0.2.0/ellements-benchmarking/src/ellements/benchmarking/harness.py +342 -0
  20. ellements-0.2.0/ellements-benchmarking/src/ellements/benchmarking/py.typed +0 -0
  21. ellements-0.2.0/ellements-benchmarking/src/ellements/benchmarking/results.py +173 -0
  22. ellements-0.2.0/ellements-cli/LICENSE +42 -0
  23. ellements-0.2.0/ellements-cli/README.md +72 -0
  24. ellements-0.2.0/ellements-cli/src/ellements/cli/__init__.py +80 -0
  25. ellements-0.2.0/ellements-cli/src/ellements/cli/adapters.py +73 -0
  26. ellements-0.2.0/ellements-cli/src/ellements/cli/agent_tui.py +1178 -0
  27. ellements-0.2.0/ellements-cli/src/ellements/cli/components.py +411 -0
  28. ellements-0.2.0/ellements-cli/src/ellements/cli/printer.py +229 -0
  29. ellements-0.2.0/ellements-cli/src/ellements/cli/py.typed +0 -0
  30. ellements-0.2.0/ellements-core/LICENSE +42 -0
  31. ellements-0.2.0/ellements-core/README.md +87 -0
  32. ellements-0.2.0/ellements-core/src/ellements/core/__init__.py +112 -0
  33. ellements-0.2.0/ellements-core/src/ellements/core/async_utils.py +42 -0
  34. ellements-0.2.0/ellements-core/src/ellements/core/budgeting/__init__.py +43 -0
  35. ellements-0.2.0/ellements-core/src/ellements/core/budgeting/client.py +276 -0
  36. ellements-0.2.0/ellements-core/src/ellements/core/budgeting/protocol.py +51 -0
  37. ellements-0.2.0/ellements-core/src/ellements/core/budgeting/trackers.py +177 -0
  38. ellements-0.2.0/ellements-core/src/ellements/core/caching/__init__.py +51 -0
  39. ellements-0.2.0/ellements-core/src/ellements/core/caching/cache.py +73 -0
  40. ellements-0.2.0/ellements-core/src/ellements/core/caching/client.py +300 -0
  41. ellements-0.2.0/ellements-core/src/ellements/core/caching/disk.py +128 -0
  42. ellements-0.2.0/ellements-core/src/ellements/core/caching/keys.py +97 -0
  43. ellements-0.2.0/ellements-core/src/ellements/core/caching/memory.py +104 -0
  44. ellements-0.2.0/ellements-core/src/ellements/core/chunking.py +262 -0
  45. ellements-0.2.0/ellements-core/src/ellements/core/config.py +180 -0
  46. ellements-0.2.0/ellements-core/src/ellements/core/exceptions.py +145 -0
  47. ellements-0.2.0/ellements-core/src/ellements/core/llm/__init__.py +46 -0
  48. ellements-0.2.0/ellements-core/src/ellements/core/llm/client.py +1124 -0
  49. ellements-0.2.0/ellements-core/src/ellements/core/llm/images.py +226 -0
  50. ellements-0.2.0/ellements-core/src/ellements/core/llm/messages.py +202 -0
  51. ellements-0.2.0/ellements-core/src/ellements/core/llm/model_params.py +66 -0
  52. ellements-0.2.0/ellements-core/src/ellements/core/llm/protocol.py +146 -0
  53. ellements-0.2.0/ellements-core/src/ellements/core/llm/requests.py +100 -0
  54. ellements-0.2.0/ellements-core/src/ellements/core/llm/structured.py +91 -0
  55. ellements-0.2.0/ellements-core/src/ellements/core/llm/wrapper.py +79 -0
  56. ellements-0.2.0/ellements-core/src/ellements/core/observability/__init__.py +39 -0
  57. ellements-0.2.0/ellements-core/src/ellements/core/observability/events.py +169 -0
  58. ellements-0.2.0/ellements-core/src/ellements/core/observability/jsonl_logger.py +244 -0
  59. ellements-0.2.0/ellements-core/src/ellements/core/observability/markdown_formatter.py +197 -0
  60. ellements-0.2.0/ellements-core/src/ellements/core/observability/observer.py +56 -0
  61. ellements-0.2.0/ellements-core/src/ellements/core/prompting/__init__.py +14 -0
  62. ellements-0.2.0/ellements-core/src/ellements/core/prompting/context.py +185 -0
  63. ellements-0.2.0/ellements-core/src/ellements/core/prompting/guideline.py +133 -0
  64. ellements-0.2.0/ellements-core/src/ellements/core/prompting/persona.py +267 -0
  65. ellements-0.2.0/ellements-core/src/ellements/core/prompting/sources.py +92 -0
  66. ellements-0.2.0/ellements-core/src/ellements/core/py.typed +0 -0
  67. ellements-0.2.0/ellements-core/src/ellements/core/rate_limit/__init__.py +44 -0
  68. ellements-0.2.0/ellements-core/src/ellements/core/rate_limit/bucket.py +85 -0
  69. ellements-0.2.0/ellements-core/src/ellements/core/rate_limit/client.py +216 -0
  70. ellements-0.2.0/ellements-core/src/ellements/core/rate_limit/protocol.py +27 -0
  71. ellements-0.2.0/ellements-core/src/ellements/core/templating.py +126 -0
  72. ellements-0.2.0/ellements-core/src/ellements/core/tools/__init__.py +51 -0
  73. ellements-0.2.0/ellements-core/src/ellements/core/tools/dialects.py +136 -0
  74. ellements-0.2.0/ellements-core/src/ellements/core/tools/executor.py +48 -0
  75. ellements-0.2.0/ellements-core/src/ellements/core/tools/protocol.py +36 -0
  76. ellements-0.2.0/ellements-core/src/ellements/core/tools/records.py +28 -0
  77. ellements-0.2.0/ellements-core/src/ellements/core/tools/registry.py +205 -0
  78. ellements-0.2.0/ellements-core/src/ellements/core/tools/schemas.py +80 -0
  79. ellements-0.2.0/ellements-core/src/ellements/core/tools/simple.py +119 -0
  80. ellements-0.2.0/ellements-core/src/ellements/core/tools/spec.py +33 -0
  81. ellements-0.2.0/ellements-domain-specific/LICENSE +21 -0
  82. ellements-0.2.0/ellements-domain-specific/README.md +71 -0
  83. ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/__init__.py +7 -0
  84. ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/__init__.py +188 -0
  85. ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/calculations.py +837 -0
  86. ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/charts.py +426 -0
  87. ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/portfolio.py +129 -0
  88. ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/quant_analysis.py +279 -0
  89. ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/risk.py +362 -0
  90. ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/technical_indicators.py +241 -0
  91. ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/tools.py +483 -0
  92. ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/valuation.py +312 -0
  93. ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/yahoo_finance.py +1523 -0
  94. ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/yahoo_finance_models.py +321 -0
  95. ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/py.typed +0 -0
  96. ellements-0.2.0/ellements-execution/LICENSE +42 -0
  97. ellements-0.2.0/ellements-execution/README.md +80 -0
  98. ellements-0.2.0/ellements-execution/src/ellements/execution/__init__.py +56 -0
  99. ellements-0.2.0/ellements-execution/src/ellements/execution/callbacks.py +149 -0
  100. ellements-0.2.0/ellements-execution/src/ellements/execution/catalog.py +70 -0
  101. ellements-0.2.0/ellements-execution/src/ellements/execution/collaborative.py +191 -0
  102. ellements-0.2.0/ellements-execution/src/ellements/execution/config.py +135 -0
  103. ellements-0.2.0/ellements-execution/src/ellements/execution/py.typed +0 -0
  104. ellements-0.2.0/ellements-execution/src/ellements/execution/reflection.py +156 -0
  105. ellements-0.2.0/ellements-execution/src/ellements/execution/self_consistency.py +189 -0
  106. ellements-0.2.0/ellements-execution/src/ellements/execution/single_call.py +48 -0
  107. ellements-0.2.0/ellements-execution/src/ellements/execution/strategies.py +237 -0
  108. ellements-0.2.0/ellements-execution/src/ellements/execution/tree_of_thought.py +541 -0
  109. ellements-0.2.0/ellements-fslm/DESIGN.md +1597 -0
  110. ellements-0.2.0/ellements-fslm/LICENSE +42 -0
  111. ellements-0.2.0/ellements-fslm/README.md +114 -0
  112. ellements-0.2.0/ellements-fslm/src/ellements/fslm/__init__.py +108 -0
  113. ellements-0.2.0/ellements-fslm/src/ellements/fslm/builtins.py +103 -0
  114. ellements-0.2.0/ellements-fslm/src/ellements/fslm/cli.py +199 -0
  115. ellements-0.2.0/ellements-fslm/src/ellements/fslm/context.py +50 -0
  116. ellements-0.2.0/ellements-fslm/src/ellements/fslm/definition.py +163 -0
  117. ellements-0.2.0/ellements-fslm/src/ellements/fslm/det.py +173 -0
  118. ellements-0.2.0/ellements-fslm/src/ellements/fslm/dsl.py +458 -0
  119. ellements-0.2.0/ellements-fslm/src/ellements/fslm/errors.py +38 -0
  120. ellements-0.2.0/ellements-fslm/src/ellements/fslm/evaluators.py +141 -0
  121. ellements-0.2.0/ellements-fslm/src/ellements/fslm/kernel.py +603 -0
  122. ellements-0.2.0/ellements-fslm/src/ellements/fslm/loading.py +123 -0
  123. ellements-0.2.0/ellements-fslm/src/ellements/fslm/models.py +623 -0
  124. ellements-0.2.0/ellements-fslm/src/ellements/fslm/nl.py +87 -0
  125. ellements-0.2.0/ellements-fslm/src/ellements/fslm/observers.py +107 -0
  126. ellements-0.2.0/ellements-fslm/src/ellements/fslm/persistence.py +72 -0
  127. ellements-0.2.0/ellements-fslm/src/ellements/fslm/py.typed +0 -0
  128. ellements-0.2.0/ellements-fslm/src/ellements/fslm/rendering.py +551 -0
  129. ellements-0.2.0/ellements-fslm/src/ellements/fslm/visualization.py +25 -0
  130. ellements-0.2.0/ellements-reporting/LICENSE +21 -0
  131. ellements-0.2.0/ellements-reporting/README.md +44 -0
  132. ellements-0.2.0/ellements-reporting/src/ellements/reporting/__init__.py +12 -0
  133. ellements-0.2.0/ellements-reporting/src/ellements/reporting/charts.py +364 -0
  134. ellements-0.2.0/ellements-reporting/src/ellements/reporting/html_generation.py +132 -0
  135. ellements-0.2.0/ellements-reporting/src/ellements/reporting/py.typed +0 -0
  136. ellements-0.2.0/ellements-reporting/src/ellements/reporting/visualization.py +73 -0
  137. ellements-0.2.0/ellements-standard-tools/LICENSE +21 -0
  138. ellements-0.2.0/ellements-standard-tools/README.md +84 -0
  139. ellements-0.2.0/ellements-standard-tools/src/ellements/standard_tools/__init__.py +22 -0
  140. ellements-0.2.0/ellements-standard-tools/src/ellements/standard_tools/py.typed +0 -0
  141. ellements-0.2.0/ellements-standard-tools/src/ellements/standard_tools/terminal.py +205 -0
  142. ellements-0.2.0/ellements-standard-tools/src/ellements/standard_tools/web/__init__.py +37 -0
  143. ellements-0.2.0/ellements-standard-tools/src/ellements/standard_tools/web/browser_viewer.py +214 -0
  144. ellements-0.2.0/ellements-standard-tools/src/ellements/standard_tools/web/crawler.py +454 -0
  145. ellements-0.2.0/ellements-standard-tools/src/ellements/standard_tools/web/search.py +399 -0
  146. ellements-0.2.0/ellements-standard-tools/src/ellements/standard_tools/web/youtube.py +1297 -0
  147. ellements-0.2.0/ellements.egg-info/PKG-INFO +368 -0
  148. ellements-0.2.0/ellements.egg-info/SOURCES.txt +154 -0
  149. ellements-0.2.0/ellements.egg-info/dependency_links.txt +1 -0
  150. ellements-0.2.0/ellements.egg-info/entry_points.txt +2 -0
  151. ellements-0.2.0/ellements.egg-info/requires.txt +122 -0
  152. ellements-0.2.0/ellements.egg-info/top_level.txt +1 -0
  153. ellements-0.2.0/ellements_logo_transparent_crisp.png +0 -0
  154. ellements-0.2.0/pyproject.toml +286 -0
  155. ellements-0.2.0/setup.cfg +4 -0
  156. ellements-0.2.0/setup.py +46 -0
@@ -0,0 +1,42 @@
1
+ Project Status and Maintenance Notice
2
+
3
+ This repository is in constant flux. It is maintained primarily for my own
4
+ research, extreme experimentation, and personal tooling, and it exists to
5
+ support my other projects. Probably nobody other than me should take a
6
+ dependency on it. The point is to keep extending it as new ideas become useful,
7
+ not to provide a stable dependency surface. APIs, package boundaries, behavior,
8
+ and release cadence may change abruptly whenever that helps my projects.
9
+
10
+ The project is unlikely to accept pull requests. It is published for
11
+ transparency and my own reuse, not as a community-maintained library or a
12
+ general-purpose package roadmap.
13
+
14
+ This repository is maintained almost entirely through AI-assisted programming
15
+ and automated agentic refactoring/review workflows, under my direction. I myself
16
+ understand only a fraction of it at any given time. That maintenance model can
17
+ produce fast-paced changes, abrupt clean breaks, and both good and bad surprises.
18
+ The software remains provided "as is" under the MIT License below.
19
+
20
+ This notice is informational and is not an additional license condition.
21
+
22
+ MIT License
23
+
24
+ Copyright (c) 2026 Paulo Salem
25
+
26
+ Permission is hereby granted, free of charge, to any person obtaining a copy
27
+ of this software and associated documentation files (the "Software"), to deal
28
+ in the Software without restriction, including without limitation the rights
29
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
30
+ copies of the Software, and to permit persons to whom the Software is
31
+ furnished to do so, subject to the following conditions:
32
+
33
+ The above copyright notice and this permission notice shall be included in all
34
+ copies or substantial portions of the Software.
35
+
36
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
37
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
38
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
39
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
40
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
41
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
42
+ SOFTWARE.
@@ -0,0 +1,6 @@
1
+ include README.md
2
+ include LICENSE
3
+ include ellements_logo_transparent_crisp.png
4
+ include ellements-*/README.md
5
+ include ellements-*/DESIGN.md
6
+ include ellements-*/LICENSE
@@ -0,0 +1,368 @@
1
+ Metadata-Version: 2.4
2
+ Name: ellements
3
+ Version: 0.2.0
4
+ Summary: Public Ellements primitives for LLM calls, execution strategies, finite-state linguistic machines, benchmarking, and CLI presentation.
5
+ Author-email: Paulo Salem <paulosalem@paulosalem.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/paulosalem/ellements
8
+ Project-URL: Documentation, https://github.com/paulosalem/ellements
9
+ Project-URL: Repository, https://github.com/paulosalem/ellements
10
+ Project-URL: Bug Tracker, https://github.com/paulosalem/ellements/issues
11
+ Keywords: llm,ai,prompting,benchmarking,cli,tooling
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Requires-Python: >=3.11
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: chevron<1,>=0.14.0
23
+ Requires-Dist: litellm<2,>=1.0.0
24
+ Requires-Dist: pydantic<3,>=2.0.0
25
+ Requires-Dist: pyyaml<7,>=6.0
26
+ Requires-Dist: rich<15,>=13.0.0
27
+ Requires-Dist: tiktoken<1,>=0.7.0
28
+ Requires-Dist: typing-extensions<5,>=4.8.0
29
+ Provides-Extra: core
30
+ Provides-Extra: execution
31
+ Requires-Dist: chevron<1,>=0.14.0; extra == "execution"
32
+ Provides-Extra: fslm
33
+ Provides-Extra: benchmarking
34
+ Requires-Dist: lm-eval<0.5,>=0.4.0; extra == "benchmarking"
35
+ Provides-Extra: cli
36
+ Requires-Dist: rich<15,>=13.0.0; extra == "cli"
37
+ Requires-Dist: textual<7,>=0.40.0; extra == "cli"
38
+ Provides-Extra: agents
39
+ Requires-Dist: openai-agents<1,>=0.0.1; extra == "agents"
40
+ Provides-Extra: reporting
41
+ Requires-Dist: jinja2<4,>=3.1.0; extra == "reporting"
42
+ Requires-Dist: matplotlib<4,>=3.7.0; extra == "reporting"
43
+ Requires-Dist: pandas<4,>=2.0.0; extra == "reporting"
44
+ Provides-Extra: finance
45
+ Requires-Dist: numpy<3,>=1.26.0; extra == "finance"
46
+ Requires-Dist: numpy-financial<2,>=1.0.0; extra == "finance"
47
+ Requires-Dist: pandas<4,>=2.0.0; extra == "finance"
48
+ Requires-Dist: yfinance<1,>=0.2.0; extra == "finance"
49
+ Provides-Extra: finance-technical
50
+ Requires-Dist: jinja2<4,>=3.1.0; extra == "finance-technical"
51
+ Requires-Dist: matplotlib<4,>=3.7.0; extra == "finance-technical"
52
+ Requires-Dist: mplfinance<1,>=0.12.10b0; extra == "finance-technical"
53
+ Requires-Dist: numpy<3,>=1.26.0; extra == "finance-technical"
54
+ Requires-Dist: pandas<4,>=2.0.0; extra == "finance-technical"
55
+ Requires-Dist: TA-Lib<1,>=0.6.5; extra == "finance-technical"
56
+ Requires-Dist: yfinance<1,>=0.2.0; extra == "finance-technical"
57
+ Provides-Extra: finance-quant
58
+ Requires-Dist: numpy<3,>=1.26.0; extra == "finance-quant"
59
+ Requires-Dist: pandas<4,>=2.0.0; extra == "finance-quant"
60
+ Requires-Dist: quantstats<1,>=0.0.62; extra == "finance-quant"
61
+ Provides-Extra: domain-specific
62
+ Requires-Dist: jinja2<4,>=3.1.0; extra == "domain-specific"
63
+ Requires-Dist: matplotlib<4,>=3.7.0; extra == "domain-specific"
64
+ Requires-Dist: mplfinance<1,>=0.12.10b0; extra == "domain-specific"
65
+ Requires-Dist: numpy<3,>=1.26.0; extra == "domain-specific"
66
+ Requires-Dist: numpy-financial<2,>=1.0.0; extra == "domain-specific"
67
+ Requires-Dist: pandas<4,>=2.0.0; extra == "domain-specific"
68
+ Requires-Dist: quantstats<1,>=0.0.62; extra == "domain-specific"
69
+ Requires-Dist: TA-Lib<1,>=0.6.5; extra == "domain-specific"
70
+ Requires-Dist: yfinance<1,>=0.2.0; extra == "domain-specific"
71
+ Provides-Extra: web-search
72
+ Requires-Dist: duckduckgo-search<9,>=6.0.0; extra == "web-search"
73
+ Provides-Extra: web-crawl
74
+ Requires-Dist: crawl4ai<1,>=0.3.0; extra == "web-crawl"
75
+ Requires-Dist: nest-asyncio<2,>=1.6.0; extra == "web-crawl"
76
+ Requires-Dist: playwright<2,>=1.40.0; extra == "web-crawl"
77
+ Provides-Extra: web-youtube
78
+ Requires-Dist: httpx<0.28.0,>=0.24.0; extra == "web-youtube"
79
+ Requires-Dist: youtube-search-python<2,>=1.6.0; extra == "web-youtube"
80
+ Requires-Dist: youtube-transcript-api<2,>=1.2.4; extra == "web-youtube"
81
+ Provides-Extra: web
82
+ Requires-Dist: crawl4ai<1,>=0.3.0; extra == "web"
83
+ Requires-Dist: duckduckgo-search<9,>=6.0.0; extra == "web"
84
+ Requires-Dist: httpx<0.28.0,>=0.24.0; extra == "web"
85
+ Requires-Dist: nest-asyncio<2,>=1.6.0; extra == "web"
86
+ Requires-Dist: playwright<2,>=1.40.0; extra == "web"
87
+ Requires-Dist: youtube-search-python<2,>=1.6.0; extra == "web"
88
+ Requires-Dist: youtube-transcript-api<2,>=1.2.4; extra == "web"
89
+ Provides-Extra: standard-tools
90
+ Requires-Dist: crawl4ai<1,>=0.3.0; extra == "standard-tools"
91
+ Requires-Dist: duckduckgo-search<9,>=6.0.0; extra == "standard-tools"
92
+ Requires-Dist: httpx<0.28.0,>=0.24.0; extra == "standard-tools"
93
+ Requires-Dist: nest-asyncio<2,>=1.6.0; extra == "standard-tools"
94
+ Requires-Dist: playwright<2,>=1.40.0; extra == "standard-tools"
95
+ Requires-Dist: youtube-search-python<2,>=1.6.0; extra == "standard-tools"
96
+ Requires-Dist: youtube-transcript-api<2,>=1.2.4; extra == "standard-tools"
97
+ Provides-Extra: all
98
+ Requires-Dist: chevron<1,>=0.14.0; extra == "all"
99
+ Requires-Dist: crawl4ai<1,>=0.3.0; extra == "all"
100
+ Requires-Dist: duckduckgo-search<9,>=6.0.0; extra == "all"
101
+ Requires-Dist: httpx<0.28.0,>=0.24.0; extra == "all"
102
+ Requires-Dist: jinja2<4,>=3.1.0; extra == "all"
103
+ Requires-Dist: lm-eval<0.5,>=0.4.0; extra == "all"
104
+ Requires-Dist: matplotlib<4,>=3.7.0; extra == "all"
105
+ Requires-Dist: mplfinance<1,>=0.12.10b0; extra == "all"
106
+ Requires-Dist: nest-asyncio<2,>=1.6.0; extra == "all"
107
+ Requires-Dist: numpy<3,>=1.26.0; extra == "all"
108
+ Requires-Dist: numpy-financial<2,>=1.0.0; extra == "all"
109
+ Requires-Dist: openai-agents<1,>=0.0.1; extra == "all"
110
+ Requires-Dist: pandas<4,>=2.0.0; extra == "all"
111
+ Requires-Dist: playwright<2,>=1.40.0; extra == "all"
112
+ Requires-Dist: quantstats<1,>=0.0.62; extra == "all"
113
+ Requires-Dist: rich<15,>=13.0.0; extra == "all"
114
+ Requires-Dist: TA-Lib<1,>=0.6.5; extra == "all"
115
+ Requires-Dist: textual<7,>=0.40.0; extra == "all"
116
+ Requires-Dist: yfinance<1,>=0.2.0; extra == "all"
117
+ Requires-Dist: youtube-search-python<2,>=1.6.0; extra == "all"
118
+ Requires-Dist: youtube-transcript-api<2,>=1.2.4; extra == "all"
119
+ Provides-Extra: dev
120
+ Requires-Dist: black<27,>=23.0.0; extra == "dev"
121
+ Requires-Dist: mypy<2,>=1.7.0; extra == "dev"
122
+ Requires-Dist: pre-commit<5,>=3.0.0; extra == "dev"
123
+ Requires-Dist: pytest<9,>=7.0.0; extra == "dev"
124
+ Requires-Dist: pytest-asyncio<2,>=0.21.0; extra == "dev"
125
+ Requires-Dist: ruff<1,>=0.1.0; extra == "dev"
126
+ Dynamic: license-file
127
+
128
+ <p align="center">
129
+ <img src="./ellements_logo_transparent_crisp.png" alt="Ellements logo" width="360">
130
+ </p>
131
+
132
+ <h1>Ellements</h1>
133
+
134
+ <p >
135
+ <strong>A Python toolkit for extreme experimentation with LLM systems.</strong>
136
+ </p>
137
+
138
+ **Ellements** is best understood as a continuously extended set of building
139
+ blocks for LLM experimentation: model clients, prompt context, execution
140
+ strategies, agent abstractions, benchmarking harnesses, and terminal UI
141
+ primitives. The repository is organized into focused source roots, but ships as
142
+ a single PyPI package, `ellements`, containing every public `ellements.*`
143
+ subpackage.
144
+
145
+ > [!WARNING]
146
+ > **Do not treat this as a normal dependency.** This repository exists to support
147
+ > my own projects, experiments, and tooling. Probably nobody other than me should
148
+ > depend on it directly.
149
+
150
+ > [!NOTE]
151
+ > Almost all of it is created with AI assistance, and I myself understand only a
152
+ > fraction of it at any given time. This can produce fast-paced changes, as well
153
+ > as both good and bad surprises. Pull requests are unlikely to be accepted. This
154
+ > is published for transparency and my own reuse, not as a community-maintained
155
+ > library or a general-purpose package roadmap.
156
+
157
+ ## Why yet another LLM library?
158
+
159
+ True, there are many other similar libraries. This one, however, is mine. It exists so I can keep extending it,
160
+ test ideas, change direction, delete abstractions, and rebuild APIs as I see fit:
161
+ not by committee, not by roadmap, not by community consensus.
162
+
163
+ ## Design principles
164
+
165
+ The practical consequences are the following:
166
+
167
+ - **One install, focused internals.** `pip install ellements` installs the full
168
+ namespace: `ellements.core`, `ellements.execution`, `ellements.agents`,
169
+ `ellements.benchmarking`, `ellements.cli`, `ellements.domain_specific`,
170
+ `ellements.reporting`, `ellements.standard_tools`, and `ellements.fslm`.
171
+ - **Extension before stabilization.** The point is to keep adding mechanisms as
172
+ they become useful in my projects. Stability comes later, if it comes at all.
173
+ - **Async-only public API.** No hidden sync wrappers. Callers keep explicit
174
+ control of concurrency.
175
+ - **Explicit model selection.** `LLMClient(model=...)` is required. There is no
176
+ hidden default.
177
+ - **Structured observability.** Every LLM call emits request, response, and
178
+ error events. `JsonlPromptLogger` writes durable JSON-lines traces.
179
+ - **Composable strategy layer.** Single-call, reflection, self-consistency,
180
+ tree-of-thought, and collaborative editing all conform to one `Strategy`
181
+ protocol.
182
+ - **Backend-agnostic agents.** `ellements.agents` is an abstraction layer over
183
+ external agent libraries. OpenAI Agents and Claude Agents are adapters; they
184
+ are not the identity of the module.
185
+ - **Finite-state linguistic machines.** `ellements.fslm` keeps agentic workflows
186
+ bounded by explicit state graphs while still allowing natural-language guards,
187
+ invariants, actions, and outputs where they are useful. The `L` is deliberate:
188
+ language is part of the control surface, not a decorative interface.
189
+
190
+ ## Install
191
+
192
+ ```bash
193
+ pip install ellements
194
+ ```
195
+
196
+ Optional extras install integration-specific dependencies. They do **not** split
197
+ the package or change which modules ship in the wheel.
198
+
199
+ ```bash
200
+ pip install "ellements[agents]" # declared agent-adapter dependencies
201
+ pip install "ellements[benchmarking]" # lm-eval integration
202
+ pip install "ellements[cli]" # Textual-powered terminal UI helpers
203
+ pip install "ellements[fslm]>=0.2.0" # finite-state linguistic machines
204
+ pip install "ellements[finance]" # Yahoo Finance asset tools
205
+ pip install "ellements[web]" # web search, crawl, and YouTube tools
206
+ pip install "ellements[reporting]" # chart/report export helpers
207
+ pip install "ellements[all]" # all declared optional integrations
208
+ ```
209
+
210
+ In particular, the agents module is not OpenAI-specific. It defines shared
211
+ builder, controller, runner, and event abstractions over external agent
212
+ libraries. The OpenAI adapter has declared optional dependencies; the Claude
213
+ adapter is included in the wheel, but its upstream SDK is still evolving, so
214
+ install it separately when using that backend.
215
+
216
+ ## What ships
217
+
218
+ | Import package | Purpose |
219
+ | --- | --- |
220
+ | `ellements.core` | `LLMClient`, conversations, multimodal inputs, tools, prompt context, templating, observers, caching, rate limiting, budgeting, and config helpers |
221
+ | `ellements.execution` | Prompting strategies: `SingleCallStrategy`, `ReflectionStrategy`, `SelfConsistencyStrategy`, `TreeOfThoughtStrategy`, `CollaborativeEditingStrategy` |
222
+ | `ellements.agents` | Backend-agnostic layer over external agent libraries: runner, controller, fluent `AgentBuilder`, event surface, and OpenAI/Claude adapters |
223
+ | `ellements.benchmarking` | Async benchmark harnesses, model runners, dataset adapters, and comparison helpers |
224
+ | `ellements.cli` | Terminal presentation primitives, agent TUI components, and slash-command building blocks |
225
+ | `ellements.domain_specific` | Domain tools, currently including finance calculators, Yahoo Finance asset data, valuation, technical indicators, and risk helpers |
226
+ | `ellements.reporting` | Chart artifacts, HTML report generation, and multi-format presentation helpers |
227
+ | `ellements.standard_tools` | Reusable tool surfaces for terminal execution, web search, web crawl/read, and YouTube search/transcript access |
228
+ | `ellements.fslm` | Finite-state linguistic machines: explicit graphs, deterministic kernel, natural-language evaluators, persistence, observers, and `fslm` CLI |
229
+
230
+ ## Quick start
231
+
232
+ ```python
233
+ import asyncio
234
+
235
+ from ellements.core import JsonlPromptLogger, LLMClient
236
+
237
+
238
+ async def main() -> None:
239
+ client = LLMClient(
240
+ model="openai/gpt-5.5",
241
+ observers=[JsonlPromptLogger("./logs")],
242
+ )
243
+
244
+ answer = await client.complete("Explain attention in one paragraph.")
245
+ print(answer)
246
+
247
+
248
+ asyncio.run(main())
249
+ ```
250
+
251
+ ## Run a strategy
252
+
253
+ ```python
254
+ from ellements.execution import ReflectionConfig, ReflectionStrategy
255
+
256
+ strategy = ReflectionStrategy()
257
+
258
+ result = await strategy.execute(
259
+ prompts={
260
+ "generate": "Draft a haiku about distributed systems.",
261
+ "critique": "Review this draft and return a CritiqueResult:\n\n{{response}}",
262
+ "revise": (
263
+ "Revise the draft using the issues below.\n\n"
264
+ "Draft:\n{{response}}\n\nIssues:\n{{issues}}"
265
+ ),
266
+ },
267
+ client=client,
268
+ config=ReflectionConfig(max_rounds=3),
269
+ )
270
+
271
+ print(result.output)
272
+ ```
273
+
274
+ Runtime strategy templates accept both Mustache placeholders such as
275
+ `{{response}}` and PromptSpec-style placeholders such as `@{response}`.
276
+
277
+ ## Build an agent
278
+
279
+ OpenAI is shown here as one concrete adapter; the builder targets the
280
+ backend-agnostic `AgentBackend` protocol.
281
+
282
+ ```python
283
+ from ellements.agents import AgentBuilder, OpenAIAgentsBackend
284
+
285
+ agent = (
286
+ AgentBuilder("researcher", backend=OpenAIAgentsBackend())
287
+ .with_model("gpt-4.1")
288
+ .with_instructions("Research carefully, cite evidence, and be concise.")
289
+ .with_tool("search", my_search_tool)
290
+ .build()
291
+ )
292
+ ```
293
+
294
+ ## Use finance and web tools
295
+
296
+ Finance and web tools expose canonical `ToolRegistry` surfaces, so LLM clients,
297
+ agents, and PromptSpec examples can bind the same tools without local adapters.
298
+
299
+ ```bash
300
+ pip install "ellements[finance,web]"
301
+ playwright install chromium # required by crawl4ai-backed page crawling
302
+ ```
303
+
304
+ ```python
305
+ from ellements.domain_specific.finance.yahoo_finance import finance_tools
306
+ from ellements.standard_tools.web.crawler import web_crawler_tools
307
+ from ellements.standard_tools.web.search import web_search_tools
308
+
309
+ tools = (
310
+ finance_tools()
311
+ .merge(web_search_tools())
312
+ .merge(web_crawler_tools(max_content_tokens=4000))
313
+ )
314
+
315
+ print(sorted(tools))
316
+ ```
317
+
318
+ Typical stock-research tools include `search_asset`, `get_asset_quote`,
319
+ `get_asset_profile`, `get_financial_metrics`, `search_web`, `search_news`, and
320
+ `crawl_url`.
321
+
322
+ ## Packaging model
323
+
324
+ The repo is modular at the filesystem level:
325
+
326
+ ```text
327
+ ellements-core/src/ellements/core
328
+ ellements-execution/src/ellements/execution
329
+ ellements-agents/src/ellements/agents
330
+ ellements-benchmarking/src/ellements/benchmarking
331
+ ellements-cli/src/ellements/cli
332
+ ellements-domain-specific/src/ellements/domain_specific
333
+ ellements-fslm/src/ellements/fslm
334
+ ellements-reporting/src/ellements/reporting
335
+ ellements-standard-tools/src/ellements/standard_tools
336
+ ```
337
+
338
+ Those source roots are discovered into a single wheel,
339
+ `ellements-<version>-py3-none-any.whl`. Users install one PyPI project and
340
+ import the modules they need:
341
+
342
+ ```python
343
+ from ellements.core import LLMClient
344
+ from ellements.domain_specific.finance.yahoo_finance import finance_tools
345
+ from ellements.execution import TreeOfThoughtStrategy
346
+ from ellements.agents import AgentBuilder
347
+ from ellements.fslm import FSLMKernel
348
+ from ellements.standard_tools.web.search import web_search_tools
349
+ ```
350
+
351
+ This gives the repo clean internal boundaries without creating multiple PyPI
352
+ entries to publish, document, secure, and maintain.
353
+
354
+ ## Local development
355
+
356
+ ```bash
357
+ pip install -e ".[dev,all]"
358
+ python -m pytest -q
359
+ python -m ruff check .
360
+ python -m mypy --strict ellements-core/src ellements-execution/src \
361
+ ellements-agents/src ellements-benchmarking/src ellements-cli/src \
362
+ ellements-domain-specific/src ellements-fslm/src ellements-reporting/src \
363
+ ellements-standard-tools/src
364
+ ```
365
+
366
+ ## License
367
+
368
+ MIT, with the project status and maintenance notice in [`LICENSE`](LICENSE).
@@ -0,0 +1,241 @@
1
+ <p align="center">
2
+ <img src="./ellements_logo_transparent_crisp.png" alt="Ellements logo" width="360">
3
+ </p>
4
+
5
+ <h1>Ellements</h1>
6
+
7
+ <p >
8
+ <strong>A Python toolkit for extreme experimentation with LLM systems.</strong>
9
+ </p>
10
+
11
+ **Ellements** is best understood as a continuously extended set of building
12
+ blocks for LLM experimentation: model clients, prompt context, execution
13
+ strategies, agent abstractions, benchmarking harnesses, and terminal UI
14
+ primitives. The repository is organized into focused source roots, but ships as
15
+ a single PyPI package, `ellements`, containing every public `ellements.*`
16
+ subpackage.
17
+
18
+ > [!WARNING]
19
+ > **Do not treat this as a normal dependency.** This repository exists to support
20
+ > my own projects, experiments, and tooling. Probably nobody other than me should
21
+ > depend on it directly.
22
+
23
+ > [!NOTE]
24
+ > Almost all of it is created with AI assistance, and I myself understand only a
25
+ > fraction of it at any given time. This can produce fast-paced changes, as well
26
+ > as both good and bad surprises. Pull requests are unlikely to be accepted. This
27
+ > is published for transparency and my own reuse, not as a community-maintained
28
+ > library or a general-purpose package roadmap.
29
+
30
+ ## Why yet another LLM library?
31
+
32
+ True, there are many other similar libraries. This one, however, is mine. It exists so I can keep extending it,
33
+ test ideas, change direction, delete abstractions, and rebuild APIs as I see fit:
34
+ not by committee, not by roadmap, not by community consensus.
35
+
36
+ ## Design principles
37
+
38
+ The practical consequences are the following:
39
+
40
+ - **One install, focused internals.** `pip install ellements` installs the full
41
+ namespace: `ellements.core`, `ellements.execution`, `ellements.agents`,
42
+ `ellements.benchmarking`, `ellements.cli`, `ellements.domain_specific`,
43
+ `ellements.reporting`, `ellements.standard_tools`, and `ellements.fslm`.
44
+ - **Extension before stabilization.** The point is to keep adding mechanisms as
45
+ they become useful in my projects. Stability comes later, if it comes at all.
46
+ - **Async-only public API.** No hidden sync wrappers. Callers keep explicit
47
+ control of concurrency.
48
+ - **Explicit model selection.** `LLMClient(model=...)` is required. There is no
49
+ hidden default.
50
+ - **Structured observability.** Every LLM call emits request, response, and
51
+ error events. `JsonlPromptLogger` writes durable JSON-lines traces.
52
+ - **Composable strategy layer.** Single-call, reflection, self-consistency,
53
+ tree-of-thought, and collaborative editing all conform to one `Strategy`
54
+ protocol.
55
+ - **Backend-agnostic agents.** `ellements.agents` is an abstraction layer over
56
+ external agent libraries. OpenAI Agents and Claude Agents are adapters; they
57
+ are not the identity of the module.
58
+ - **Finite-state linguistic machines.** `ellements.fslm` keeps agentic workflows
59
+ bounded by explicit state graphs while still allowing natural-language guards,
60
+ invariants, actions, and outputs where they are useful. The `L` is deliberate:
61
+ language is part of the control surface, not a decorative interface.
62
+
63
+ ## Install
64
+
65
+ ```bash
66
+ pip install ellements
67
+ ```
68
+
69
+ Optional extras install integration-specific dependencies. They do **not** split
70
+ the package or change which modules ship in the wheel.
71
+
72
+ ```bash
73
+ pip install "ellements[agents]" # declared agent-adapter dependencies
74
+ pip install "ellements[benchmarking]" # lm-eval integration
75
+ pip install "ellements[cli]" # Textual-powered terminal UI helpers
76
+ pip install "ellements[fslm]>=0.2.0" # finite-state linguistic machines
77
+ pip install "ellements[finance]" # Yahoo Finance asset tools
78
+ pip install "ellements[web]" # web search, crawl, and YouTube tools
79
+ pip install "ellements[reporting]" # chart/report export helpers
80
+ pip install "ellements[all]" # all declared optional integrations
81
+ ```
82
+
83
+ In particular, the agents module is not OpenAI-specific. It defines shared
84
+ builder, controller, runner, and event abstractions over external agent
85
+ libraries. The OpenAI adapter has declared optional dependencies; the Claude
86
+ adapter is included in the wheel, but its upstream SDK is still evolving, so
87
+ install it separately when using that backend.
88
+
89
+ ## What ships
90
+
91
+ | Import package | Purpose |
92
+ | --- | --- |
93
+ | `ellements.core` | `LLMClient`, conversations, multimodal inputs, tools, prompt context, templating, observers, caching, rate limiting, budgeting, and config helpers |
94
+ | `ellements.execution` | Prompting strategies: `SingleCallStrategy`, `ReflectionStrategy`, `SelfConsistencyStrategy`, `TreeOfThoughtStrategy`, `CollaborativeEditingStrategy` |
95
+ | `ellements.agents` | Backend-agnostic layer over external agent libraries: runner, controller, fluent `AgentBuilder`, event surface, and OpenAI/Claude adapters |
96
+ | `ellements.benchmarking` | Async benchmark harnesses, model runners, dataset adapters, and comparison helpers |
97
+ | `ellements.cli` | Terminal presentation primitives, agent TUI components, and slash-command building blocks |
98
+ | `ellements.domain_specific` | Domain tools, currently including finance calculators, Yahoo Finance asset data, valuation, technical indicators, and risk helpers |
99
+ | `ellements.reporting` | Chart artifacts, HTML report generation, and multi-format presentation helpers |
100
+ | `ellements.standard_tools` | Reusable tool surfaces for terminal execution, web search, web crawl/read, and YouTube search/transcript access |
101
+ | `ellements.fslm` | Finite-state linguistic machines: explicit graphs, deterministic kernel, natural-language evaluators, persistence, observers, and `fslm` CLI |
102
+
103
+ ## Quick start
104
+
105
+ ```python
106
+ import asyncio
107
+
108
+ from ellements.core import JsonlPromptLogger, LLMClient
109
+
110
+
111
+ async def main() -> None:
112
+ client = LLMClient(
113
+ model="openai/gpt-5.5",
114
+ observers=[JsonlPromptLogger("./logs")],
115
+ )
116
+
117
+ answer = await client.complete("Explain attention in one paragraph.")
118
+ print(answer)
119
+
120
+
121
+ asyncio.run(main())
122
+ ```
123
+
124
+ ## Run a strategy
125
+
126
+ ```python
127
+ from ellements.execution import ReflectionConfig, ReflectionStrategy
128
+
129
+ strategy = ReflectionStrategy()
130
+
131
+ result = await strategy.execute(
132
+ prompts={
133
+ "generate": "Draft a haiku about distributed systems.",
134
+ "critique": "Review this draft and return a CritiqueResult:\n\n{{response}}",
135
+ "revise": (
136
+ "Revise the draft using the issues below.\n\n"
137
+ "Draft:\n{{response}}\n\nIssues:\n{{issues}}"
138
+ ),
139
+ },
140
+ client=client,
141
+ config=ReflectionConfig(max_rounds=3),
142
+ )
143
+
144
+ print(result.output)
145
+ ```
146
+
147
+ Runtime strategy templates accept both Mustache placeholders such as
148
+ `{{response}}` and PromptSpec-style placeholders such as `@{response}`.
149
+
150
+ ## Build an agent
151
+
152
+ OpenAI is shown here as one concrete adapter; the builder targets the
153
+ backend-agnostic `AgentBackend` protocol.
154
+
155
+ ```python
156
+ from ellements.agents import AgentBuilder, OpenAIAgentsBackend
157
+
158
+ agent = (
159
+ AgentBuilder("researcher", backend=OpenAIAgentsBackend())
160
+ .with_model("gpt-4.1")
161
+ .with_instructions("Research carefully, cite evidence, and be concise.")
162
+ .with_tool("search", my_search_tool)
163
+ .build()
164
+ )
165
+ ```
166
+
167
+ ## Use finance and web tools
168
+
169
+ Finance and web tools expose canonical `ToolRegistry` surfaces, so LLM clients,
170
+ agents, and PromptSpec examples can bind the same tools without local adapters.
171
+
172
+ ```bash
173
+ pip install "ellements[finance,web]"
174
+ playwright install chromium # required by crawl4ai-backed page crawling
175
+ ```
176
+
177
+ ```python
178
+ from ellements.domain_specific.finance.yahoo_finance import finance_tools
179
+ from ellements.standard_tools.web.crawler import web_crawler_tools
180
+ from ellements.standard_tools.web.search import web_search_tools
181
+
182
+ tools = (
183
+ finance_tools()
184
+ .merge(web_search_tools())
185
+ .merge(web_crawler_tools(max_content_tokens=4000))
186
+ )
187
+
188
+ print(sorted(tools))
189
+ ```
190
+
191
+ Typical stock-research tools include `search_asset`, `get_asset_quote`,
192
+ `get_asset_profile`, `get_financial_metrics`, `search_web`, `search_news`, and
193
+ `crawl_url`.
194
+
195
+ ## Packaging model
196
+
197
+ The repo is modular at the filesystem level:
198
+
199
+ ```text
200
+ ellements-core/src/ellements/core
201
+ ellements-execution/src/ellements/execution
202
+ ellements-agents/src/ellements/agents
203
+ ellements-benchmarking/src/ellements/benchmarking
204
+ ellements-cli/src/ellements/cli
205
+ ellements-domain-specific/src/ellements/domain_specific
206
+ ellements-fslm/src/ellements/fslm
207
+ ellements-reporting/src/ellements/reporting
208
+ ellements-standard-tools/src/ellements/standard_tools
209
+ ```
210
+
211
+ Those source roots are discovered into a single wheel,
212
+ `ellements-<version>-py3-none-any.whl`. Users install one PyPI project and
213
+ import the modules they need:
214
+
215
+ ```python
216
+ from ellements.core import LLMClient
217
+ from ellements.domain_specific.finance.yahoo_finance import finance_tools
218
+ from ellements.execution import TreeOfThoughtStrategy
219
+ from ellements.agents import AgentBuilder
220
+ from ellements.fslm import FSLMKernel
221
+ from ellements.standard_tools.web.search import web_search_tools
222
+ ```
223
+
224
+ This gives the repo clean internal boundaries without creating multiple PyPI
225
+ entries to publish, document, secure, and maintain.
226
+
227
+ ## Local development
228
+
229
+ ```bash
230
+ pip install -e ".[dev,all]"
231
+ python -m pytest -q
232
+ python -m ruff check .
233
+ python -m mypy --strict ellements-core/src ellements-execution/src \
234
+ ellements-agents/src ellements-benchmarking/src ellements-cli/src \
235
+ ellements-domain-specific/src ellements-fslm/src ellements-reporting/src \
236
+ ellements-standard-tools/src
237
+ ```
238
+
239
+ ## License
240
+
241
+ MIT, with the project status and maintenance notice in [`LICENSE`](LICENSE).