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.
- ellements-0.2.0/LICENSE +42 -0
- ellements-0.2.0/MANIFEST.in +6 -0
- ellements-0.2.0/PKG-INFO +368 -0
- ellements-0.2.0/README.md +241 -0
- ellements-0.2.0/ellements/__init__.py +57 -0
- ellements-0.2.0/ellements-agents/README.md +83 -0
- ellements-0.2.0/ellements-agents/src/ellements/agents/__init__.py +45 -0
- ellements-0.2.0/ellements-agents/src/ellements/agents/backend.py +100 -0
- ellements-0.2.0/ellements-agents/src/ellements/agents/builder.py +303 -0
- ellements-0.2.0/ellements-agents/src/ellements/agents/claude_backend.py +200 -0
- ellements-0.2.0/ellements-agents/src/ellements/agents/controller.py +237 -0
- ellements-0.2.0/ellements-agents/src/ellements/agents/openai_backend.py +187 -0
- ellements-0.2.0/ellements-agents/src/ellements/agents/py.typed +0 -0
- ellements-0.2.0/ellements-agents/src/ellements/agents/runner.py +358 -0
- ellements-0.2.0/ellements-agents/src/ellements/agents/tools.py +30 -0
- ellements-0.2.0/ellements-benchmarking/LICENSE +42 -0
- ellements-0.2.0/ellements-benchmarking/README.md +71 -0
- ellements-0.2.0/ellements-benchmarking/src/ellements/benchmarking/__init__.py +52 -0
- ellements-0.2.0/ellements-benchmarking/src/ellements/benchmarking/harness.py +342 -0
- ellements-0.2.0/ellements-benchmarking/src/ellements/benchmarking/py.typed +0 -0
- ellements-0.2.0/ellements-benchmarking/src/ellements/benchmarking/results.py +173 -0
- ellements-0.2.0/ellements-cli/LICENSE +42 -0
- ellements-0.2.0/ellements-cli/README.md +72 -0
- ellements-0.2.0/ellements-cli/src/ellements/cli/__init__.py +80 -0
- ellements-0.2.0/ellements-cli/src/ellements/cli/adapters.py +73 -0
- ellements-0.2.0/ellements-cli/src/ellements/cli/agent_tui.py +1178 -0
- ellements-0.2.0/ellements-cli/src/ellements/cli/components.py +411 -0
- ellements-0.2.0/ellements-cli/src/ellements/cli/printer.py +229 -0
- ellements-0.2.0/ellements-cli/src/ellements/cli/py.typed +0 -0
- ellements-0.2.0/ellements-core/LICENSE +42 -0
- ellements-0.2.0/ellements-core/README.md +87 -0
- ellements-0.2.0/ellements-core/src/ellements/core/__init__.py +112 -0
- ellements-0.2.0/ellements-core/src/ellements/core/async_utils.py +42 -0
- ellements-0.2.0/ellements-core/src/ellements/core/budgeting/__init__.py +43 -0
- ellements-0.2.0/ellements-core/src/ellements/core/budgeting/client.py +276 -0
- ellements-0.2.0/ellements-core/src/ellements/core/budgeting/protocol.py +51 -0
- ellements-0.2.0/ellements-core/src/ellements/core/budgeting/trackers.py +177 -0
- ellements-0.2.0/ellements-core/src/ellements/core/caching/__init__.py +51 -0
- ellements-0.2.0/ellements-core/src/ellements/core/caching/cache.py +73 -0
- ellements-0.2.0/ellements-core/src/ellements/core/caching/client.py +300 -0
- ellements-0.2.0/ellements-core/src/ellements/core/caching/disk.py +128 -0
- ellements-0.2.0/ellements-core/src/ellements/core/caching/keys.py +97 -0
- ellements-0.2.0/ellements-core/src/ellements/core/caching/memory.py +104 -0
- ellements-0.2.0/ellements-core/src/ellements/core/chunking.py +262 -0
- ellements-0.2.0/ellements-core/src/ellements/core/config.py +180 -0
- ellements-0.2.0/ellements-core/src/ellements/core/exceptions.py +145 -0
- ellements-0.2.0/ellements-core/src/ellements/core/llm/__init__.py +46 -0
- ellements-0.2.0/ellements-core/src/ellements/core/llm/client.py +1124 -0
- ellements-0.2.0/ellements-core/src/ellements/core/llm/images.py +226 -0
- ellements-0.2.0/ellements-core/src/ellements/core/llm/messages.py +202 -0
- ellements-0.2.0/ellements-core/src/ellements/core/llm/model_params.py +66 -0
- ellements-0.2.0/ellements-core/src/ellements/core/llm/protocol.py +146 -0
- ellements-0.2.0/ellements-core/src/ellements/core/llm/requests.py +100 -0
- ellements-0.2.0/ellements-core/src/ellements/core/llm/structured.py +91 -0
- ellements-0.2.0/ellements-core/src/ellements/core/llm/wrapper.py +79 -0
- ellements-0.2.0/ellements-core/src/ellements/core/observability/__init__.py +39 -0
- ellements-0.2.0/ellements-core/src/ellements/core/observability/events.py +169 -0
- ellements-0.2.0/ellements-core/src/ellements/core/observability/jsonl_logger.py +244 -0
- ellements-0.2.0/ellements-core/src/ellements/core/observability/markdown_formatter.py +197 -0
- ellements-0.2.0/ellements-core/src/ellements/core/observability/observer.py +56 -0
- ellements-0.2.0/ellements-core/src/ellements/core/prompting/__init__.py +14 -0
- ellements-0.2.0/ellements-core/src/ellements/core/prompting/context.py +185 -0
- ellements-0.2.0/ellements-core/src/ellements/core/prompting/guideline.py +133 -0
- ellements-0.2.0/ellements-core/src/ellements/core/prompting/persona.py +267 -0
- ellements-0.2.0/ellements-core/src/ellements/core/prompting/sources.py +92 -0
- ellements-0.2.0/ellements-core/src/ellements/core/py.typed +0 -0
- ellements-0.2.0/ellements-core/src/ellements/core/rate_limit/__init__.py +44 -0
- ellements-0.2.0/ellements-core/src/ellements/core/rate_limit/bucket.py +85 -0
- ellements-0.2.0/ellements-core/src/ellements/core/rate_limit/client.py +216 -0
- ellements-0.2.0/ellements-core/src/ellements/core/rate_limit/protocol.py +27 -0
- ellements-0.2.0/ellements-core/src/ellements/core/templating.py +126 -0
- ellements-0.2.0/ellements-core/src/ellements/core/tools/__init__.py +51 -0
- ellements-0.2.0/ellements-core/src/ellements/core/tools/dialects.py +136 -0
- ellements-0.2.0/ellements-core/src/ellements/core/tools/executor.py +48 -0
- ellements-0.2.0/ellements-core/src/ellements/core/tools/protocol.py +36 -0
- ellements-0.2.0/ellements-core/src/ellements/core/tools/records.py +28 -0
- ellements-0.2.0/ellements-core/src/ellements/core/tools/registry.py +205 -0
- ellements-0.2.0/ellements-core/src/ellements/core/tools/schemas.py +80 -0
- ellements-0.2.0/ellements-core/src/ellements/core/tools/simple.py +119 -0
- ellements-0.2.0/ellements-core/src/ellements/core/tools/spec.py +33 -0
- ellements-0.2.0/ellements-domain-specific/LICENSE +21 -0
- ellements-0.2.0/ellements-domain-specific/README.md +71 -0
- ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/__init__.py +7 -0
- ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/__init__.py +188 -0
- ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/calculations.py +837 -0
- ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/charts.py +426 -0
- ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/portfolio.py +129 -0
- ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/quant_analysis.py +279 -0
- ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/risk.py +362 -0
- ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/technical_indicators.py +241 -0
- ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/tools.py +483 -0
- ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/valuation.py +312 -0
- ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/yahoo_finance.py +1523 -0
- ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/finance/yahoo_finance_models.py +321 -0
- ellements-0.2.0/ellements-domain-specific/src/ellements/domain_specific/py.typed +0 -0
- ellements-0.2.0/ellements-execution/LICENSE +42 -0
- ellements-0.2.0/ellements-execution/README.md +80 -0
- ellements-0.2.0/ellements-execution/src/ellements/execution/__init__.py +56 -0
- ellements-0.2.0/ellements-execution/src/ellements/execution/callbacks.py +149 -0
- ellements-0.2.0/ellements-execution/src/ellements/execution/catalog.py +70 -0
- ellements-0.2.0/ellements-execution/src/ellements/execution/collaborative.py +191 -0
- ellements-0.2.0/ellements-execution/src/ellements/execution/config.py +135 -0
- ellements-0.2.0/ellements-execution/src/ellements/execution/py.typed +0 -0
- ellements-0.2.0/ellements-execution/src/ellements/execution/reflection.py +156 -0
- ellements-0.2.0/ellements-execution/src/ellements/execution/self_consistency.py +189 -0
- ellements-0.2.0/ellements-execution/src/ellements/execution/single_call.py +48 -0
- ellements-0.2.0/ellements-execution/src/ellements/execution/strategies.py +237 -0
- ellements-0.2.0/ellements-execution/src/ellements/execution/tree_of_thought.py +541 -0
- ellements-0.2.0/ellements-fslm/DESIGN.md +1597 -0
- ellements-0.2.0/ellements-fslm/LICENSE +42 -0
- ellements-0.2.0/ellements-fslm/README.md +114 -0
- ellements-0.2.0/ellements-fslm/src/ellements/fslm/__init__.py +108 -0
- ellements-0.2.0/ellements-fslm/src/ellements/fslm/builtins.py +103 -0
- ellements-0.2.0/ellements-fslm/src/ellements/fslm/cli.py +199 -0
- ellements-0.2.0/ellements-fslm/src/ellements/fslm/context.py +50 -0
- ellements-0.2.0/ellements-fslm/src/ellements/fslm/definition.py +163 -0
- ellements-0.2.0/ellements-fslm/src/ellements/fslm/det.py +173 -0
- ellements-0.2.0/ellements-fslm/src/ellements/fslm/dsl.py +458 -0
- ellements-0.2.0/ellements-fslm/src/ellements/fslm/errors.py +38 -0
- ellements-0.2.0/ellements-fslm/src/ellements/fslm/evaluators.py +141 -0
- ellements-0.2.0/ellements-fslm/src/ellements/fslm/kernel.py +603 -0
- ellements-0.2.0/ellements-fslm/src/ellements/fslm/loading.py +123 -0
- ellements-0.2.0/ellements-fslm/src/ellements/fslm/models.py +623 -0
- ellements-0.2.0/ellements-fslm/src/ellements/fslm/nl.py +87 -0
- ellements-0.2.0/ellements-fslm/src/ellements/fslm/observers.py +107 -0
- ellements-0.2.0/ellements-fslm/src/ellements/fslm/persistence.py +72 -0
- ellements-0.2.0/ellements-fslm/src/ellements/fslm/py.typed +0 -0
- ellements-0.2.0/ellements-fslm/src/ellements/fslm/rendering.py +551 -0
- ellements-0.2.0/ellements-fslm/src/ellements/fslm/visualization.py +25 -0
- ellements-0.2.0/ellements-reporting/LICENSE +21 -0
- ellements-0.2.0/ellements-reporting/README.md +44 -0
- ellements-0.2.0/ellements-reporting/src/ellements/reporting/__init__.py +12 -0
- ellements-0.2.0/ellements-reporting/src/ellements/reporting/charts.py +364 -0
- ellements-0.2.0/ellements-reporting/src/ellements/reporting/html_generation.py +132 -0
- ellements-0.2.0/ellements-reporting/src/ellements/reporting/py.typed +0 -0
- ellements-0.2.0/ellements-reporting/src/ellements/reporting/visualization.py +73 -0
- ellements-0.2.0/ellements-standard-tools/LICENSE +21 -0
- ellements-0.2.0/ellements-standard-tools/README.md +84 -0
- ellements-0.2.0/ellements-standard-tools/src/ellements/standard_tools/__init__.py +22 -0
- ellements-0.2.0/ellements-standard-tools/src/ellements/standard_tools/py.typed +0 -0
- ellements-0.2.0/ellements-standard-tools/src/ellements/standard_tools/terminal.py +205 -0
- ellements-0.2.0/ellements-standard-tools/src/ellements/standard_tools/web/__init__.py +37 -0
- ellements-0.2.0/ellements-standard-tools/src/ellements/standard_tools/web/browser_viewer.py +214 -0
- ellements-0.2.0/ellements-standard-tools/src/ellements/standard_tools/web/crawler.py +454 -0
- ellements-0.2.0/ellements-standard-tools/src/ellements/standard_tools/web/search.py +399 -0
- ellements-0.2.0/ellements-standard-tools/src/ellements/standard_tools/web/youtube.py +1297 -0
- ellements-0.2.0/ellements.egg-info/PKG-INFO +368 -0
- ellements-0.2.0/ellements.egg-info/SOURCES.txt +154 -0
- ellements-0.2.0/ellements.egg-info/dependency_links.txt +1 -0
- ellements-0.2.0/ellements.egg-info/entry_points.txt +2 -0
- ellements-0.2.0/ellements.egg-info/requires.txt +122 -0
- ellements-0.2.0/ellements.egg-info/top_level.txt +1 -0
- ellements-0.2.0/ellements_logo_transparent_crisp.png +0 -0
- ellements-0.2.0/pyproject.toml +286 -0
- ellements-0.2.0/setup.cfg +4 -0
- ellements-0.2.0/setup.py +46 -0
ellements-0.2.0/LICENSE
ADDED
|
@@ -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.
|
ellements-0.2.0/PKG-INFO
ADDED
|
@@ -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).
|