ellements 0.2.0__py3-none-any.whl

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 (130) hide show
  1. ellements/__init__.py +57 -0
  2. ellements/agents/__init__.py +45 -0
  3. ellements/agents/backend.py +100 -0
  4. ellements/agents/builder.py +303 -0
  5. ellements/agents/claude_backend.py +200 -0
  6. ellements/agents/controller.py +237 -0
  7. ellements/agents/openai_backend.py +187 -0
  8. ellements/agents/py.typed +0 -0
  9. ellements/agents/runner.py +358 -0
  10. ellements/agents/tools.py +30 -0
  11. ellements/benchmarking/__init__.py +52 -0
  12. ellements/benchmarking/harness.py +342 -0
  13. ellements/benchmarking/py.typed +0 -0
  14. ellements/benchmarking/results.py +173 -0
  15. ellements/cli/__init__.py +80 -0
  16. ellements/cli/adapters.py +73 -0
  17. ellements/cli/agent_tui.py +1178 -0
  18. ellements/cli/components.py +411 -0
  19. ellements/cli/printer.py +229 -0
  20. ellements/cli/py.typed +0 -0
  21. ellements/core/__init__.py +112 -0
  22. ellements/core/async_utils.py +42 -0
  23. ellements/core/budgeting/__init__.py +43 -0
  24. ellements/core/budgeting/client.py +276 -0
  25. ellements/core/budgeting/protocol.py +51 -0
  26. ellements/core/budgeting/trackers.py +177 -0
  27. ellements/core/caching/__init__.py +51 -0
  28. ellements/core/caching/cache.py +73 -0
  29. ellements/core/caching/client.py +300 -0
  30. ellements/core/caching/disk.py +128 -0
  31. ellements/core/caching/keys.py +97 -0
  32. ellements/core/caching/memory.py +104 -0
  33. ellements/core/chunking.py +262 -0
  34. ellements/core/config.py +180 -0
  35. ellements/core/exceptions.py +145 -0
  36. ellements/core/llm/__init__.py +46 -0
  37. ellements/core/llm/client.py +1124 -0
  38. ellements/core/llm/images.py +226 -0
  39. ellements/core/llm/messages.py +202 -0
  40. ellements/core/llm/model_params.py +66 -0
  41. ellements/core/llm/protocol.py +146 -0
  42. ellements/core/llm/requests.py +100 -0
  43. ellements/core/llm/structured.py +91 -0
  44. ellements/core/llm/wrapper.py +79 -0
  45. ellements/core/observability/__init__.py +39 -0
  46. ellements/core/observability/events.py +169 -0
  47. ellements/core/observability/jsonl_logger.py +244 -0
  48. ellements/core/observability/markdown_formatter.py +197 -0
  49. ellements/core/observability/observer.py +56 -0
  50. ellements/core/prompting/__init__.py +14 -0
  51. ellements/core/prompting/context.py +185 -0
  52. ellements/core/prompting/guideline.py +133 -0
  53. ellements/core/prompting/persona.py +267 -0
  54. ellements/core/prompting/sources.py +92 -0
  55. ellements/core/py.typed +0 -0
  56. ellements/core/rate_limit/__init__.py +44 -0
  57. ellements/core/rate_limit/bucket.py +85 -0
  58. ellements/core/rate_limit/client.py +216 -0
  59. ellements/core/rate_limit/protocol.py +27 -0
  60. ellements/core/templating.py +126 -0
  61. ellements/core/tools/__init__.py +51 -0
  62. ellements/core/tools/dialects.py +136 -0
  63. ellements/core/tools/executor.py +48 -0
  64. ellements/core/tools/protocol.py +36 -0
  65. ellements/core/tools/records.py +28 -0
  66. ellements/core/tools/registry.py +205 -0
  67. ellements/core/tools/schemas.py +80 -0
  68. ellements/core/tools/simple.py +119 -0
  69. ellements/core/tools/spec.py +33 -0
  70. ellements/domain_specific/__init__.py +7 -0
  71. ellements/domain_specific/finance/__init__.py +188 -0
  72. ellements/domain_specific/finance/calculations.py +837 -0
  73. ellements/domain_specific/finance/charts.py +426 -0
  74. ellements/domain_specific/finance/portfolio.py +129 -0
  75. ellements/domain_specific/finance/quant_analysis.py +279 -0
  76. ellements/domain_specific/finance/risk.py +362 -0
  77. ellements/domain_specific/finance/technical_indicators.py +241 -0
  78. ellements/domain_specific/finance/tools.py +483 -0
  79. ellements/domain_specific/finance/valuation.py +312 -0
  80. ellements/domain_specific/finance/yahoo_finance.py +1523 -0
  81. ellements/domain_specific/finance/yahoo_finance_models.py +321 -0
  82. ellements/domain_specific/py.typed +0 -0
  83. ellements/execution/__init__.py +56 -0
  84. ellements/execution/callbacks.py +149 -0
  85. ellements/execution/catalog.py +70 -0
  86. ellements/execution/collaborative.py +191 -0
  87. ellements/execution/config.py +135 -0
  88. ellements/execution/py.typed +0 -0
  89. ellements/execution/reflection.py +156 -0
  90. ellements/execution/self_consistency.py +189 -0
  91. ellements/execution/single_call.py +48 -0
  92. ellements/execution/strategies.py +237 -0
  93. ellements/execution/tree_of_thought.py +541 -0
  94. ellements/fslm/__init__.py +108 -0
  95. ellements/fslm/builtins.py +103 -0
  96. ellements/fslm/cli.py +199 -0
  97. ellements/fslm/context.py +50 -0
  98. ellements/fslm/definition.py +163 -0
  99. ellements/fslm/det.py +173 -0
  100. ellements/fslm/dsl.py +458 -0
  101. ellements/fslm/errors.py +38 -0
  102. ellements/fslm/evaluators.py +141 -0
  103. ellements/fslm/kernel.py +603 -0
  104. ellements/fslm/loading.py +123 -0
  105. ellements/fslm/models.py +623 -0
  106. ellements/fslm/nl.py +87 -0
  107. ellements/fslm/observers.py +107 -0
  108. ellements/fslm/persistence.py +72 -0
  109. ellements/fslm/py.typed +0 -0
  110. ellements/fslm/rendering.py +551 -0
  111. ellements/fslm/visualization.py +25 -0
  112. ellements/reporting/__init__.py +12 -0
  113. ellements/reporting/charts.py +364 -0
  114. ellements/reporting/html_generation.py +132 -0
  115. ellements/reporting/py.typed +0 -0
  116. ellements/reporting/visualization.py +73 -0
  117. ellements/standard_tools/__init__.py +22 -0
  118. ellements/standard_tools/py.typed +0 -0
  119. ellements/standard_tools/terminal.py +205 -0
  120. ellements/standard_tools/web/__init__.py +37 -0
  121. ellements/standard_tools/web/browser_viewer.py +214 -0
  122. ellements/standard_tools/web/crawler.py +454 -0
  123. ellements/standard_tools/web/search.py +399 -0
  124. ellements/standard_tools/web/youtube.py +1297 -0
  125. ellements-0.2.0.dist-info/METADATA +368 -0
  126. ellements-0.2.0.dist-info/RECORD +130 -0
  127. ellements-0.2.0.dist-info/WHEEL +5 -0
  128. ellements-0.2.0.dist-info/entry_points.txt +2 -0
  129. ellements-0.2.0.dist-info/licenses/LICENSE +42 -0
  130. ellements-0.2.0.dist-info/top_level.txt +1 -0
@@ -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,130 @@
1
+ ellements/__init__.py,sha256=eEqQ2qTN96lX0bBxd7w4laJyrxS_Vxoaj0xXft_lkf0,1809
2
+ ellements/agents/__init__.py,sha256=F-Qp1An65F36UVsZpJ0U5svqZy10LDtttjfUCqxg1wA,1353
3
+ ellements/agents/backend.py,sha256=yU3pcKzG-upIA3Mvax1EaC6GeSluYaT6sBo9aU7YETQ,3145
4
+ ellements/agents/builder.py,sha256=YnsGIHRZN3iwjdGX9h8PkFlAO3_eSUHH2RIKeh0c3-o,11832
5
+ ellements/agents/claude_backend.py,sha256=lQdmaxiq_98jXw0h21tk_RhqAr7OUa0OlB_mAIyPt0Q,6621
6
+ ellements/agents/controller.py,sha256=MP1__5-S2QQ3bY_UvEjKzEM6PLdBl77o2esgNli4DaQ,8662
7
+ ellements/agents/openai_backend.py,sha256=0sNAIoHT9Kl9nCg4SPt_klIgf2jH19ViiXB1KnpLefk,5915
8
+ ellements/agents/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ ellements/agents/runner.py,sha256=qOWPzQc40qkVwpUkj8o0RiWKUy2Kuh6QvoUEJVRD-GI,11734
10
+ ellements/agents/tools.py,sha256=f3E0-luYupryzt7BKpBqnhBRYc51EjLOjAKAuV_fA0w,822
11
+ ellements/benchmarking/__init__.py,sha256=8gSgGHIijsJpwUOdIsTqACNm7T920Qbs7QBet6ny2RE,1362
12
+ ellements/benchmarking/harness.py,sha256=QbNxWEUxMLRnlpeu3Z7eEzrYAELQe_z27snRl4kUrPY,11937
13
+ ellements/benchmarking/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ ellements/benchmarking/results.py,sha256=_DG0exEpuKDrUJbx897IsgUnw4NrEE23IqU-WAIVvHM,5802
15
+ ellements/cli/__init__.py,sha256=ICGPMA2RI_HD_VlUtjWhsBIgikq1CEgIoFlNkyn-qIk,1539
16
+ ellements/cli/adapters.py,sha256=oWglljmXOcZ2KLna6_maf634C5DO4PH-JW3Cl_Zi8eI,2377
17
+ ellements/cli/agent_tui.py,sha256=XHnoXlbApxxXtpizzNpBCH4WRUKQyHN0OazLvWHR62k,43648
18
+ ellements/cli/components.py,sha256=Fg5uIUHciHFNBDbxnj9t6hvoXz7Y5mKclGV1O8FDPMQ,12046
19
+ ellements/cli/printer.py,sha256=ZbJ4It64GD5KMEUl8i9InPwdITkrDRkN3N4TLz2kwak,7656
20
+ ellements/cli/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
+ ellements/core/__init__.py,sha256=QNC9L5buyYjfJTgC8_HIJCk1ZKzAR1a_-bfycl_TqoU,3767
22
+ ellements/core/async_utils.py,sha256=0FrR1nckgNKk4yyAbBrwEDcelq4Wpce_f3u50eLMmPs,1185
23
+ ellements/core/chunking.py,sha256=R_Q4j2iKVVa9lDnae0TjZ--fETuCQODrflWPzyLhffA,9010
24
+ ellements/core/config.py,sha256=9V6CFVOIVMI53VOFikAB0DCMkNC9u7qK00MCajd-GR8,6255
25
+ ellements/core/exceptions.py,sha256=B9wkar90GgD-_NzQaL6iw_ZZOfplFDsjr72uRAraU3g,4562
26
+ ellements/core/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
+ ellements/core/templating.py,sha256=MsbNUlfllNrZcU5vCokudmbqfSKlz0XQUv1gFVFLRQE,4471
28
+ ellements/core/budgeting/__init__.py,sha256=lQNMvKlm6ytqdf-UOQCYC0pFTqqQyKGQuWJYurNtjYU,1759
29
+ ellements/core/budgeting/client.py,sha256=ItQIJFjIGTahjqKD4jnLYnuSkf1oRHdEC5eGjoOmW18,9459
30
+ ellements/core/budgeting/protocol.py,sha256=vu29st2yOH62Ar-sPxv8BqVt5rx1VLvUzRKabGF4AY0,2043
31
+ ellements/core/budgeting/trackers.py,sha256=Fb7ucWmw9lplRe4sK1K0pU9kMCSPCm4JwpWGDAj-jH4,6719
32
+ ellements/core/caching/__init__.py,sha256=qr1-G9QyO1YcFsgh-JvTuERIRmiOOs3hGTS33kgipmQ,1781
33
+ ellements/core/caching/cache.py,sha256=Epben09j5TB5F7bHcljQpg6HBa5drqMtZ6FzXRl3bsg,2356
34
+ ellements/core/caching/client.py,sha256=eYu3ftEsFZAhQ0vWGRB9zLtpEXqDMFXR3hd_zzEByHE,10627
35
+ ellements/core/caching/disk.py,sha256=9UDo18rhSPd2H1cdtd2bhDius5jg6EJlp4EHip6KHEk,4325
36
+ ellements/core/caching/keys.py,sha256=liIaZTxSyEEvcFpWAO5m7PH9muCSvA8k9oc3uVLu4eA,3347
37
+ ellements/core/caching/memory.py,sha256=ZlDrA1i-YTGOq7RimilluLqrR_2mnUHouudYRZl6PXI,3410
38
+ ellements/core/llm/__init__.py,sha256=31ecgROWPBwXDj_Mt-uOlvwyWLXnODo6ktQariIDSFI,1098
39
+ ellements/core/llm/client.py,sha256=IurgRH2S6MXh6pc0t0xRAWx5nCnIJ6IJ25mxPD1Zh0A,40478
40
+ ellements/core/llm/images.py,sha256=Efvpj8KHB95wAOgFSE5S7JIXujcAYOdYg4euD5RKpRM,7748
41
+ ellements/core/llm/messages.py,sha256=a9GMqjpsXWFy7ckVa6fo3C71J_HqJ-jEd-iKxTnbyuI,6936
42
+ ellements/core/llm/model_params.py,sha256=XGwFh8SII08y9_dMJCYeFHbM8p9tz7R9S02_B5Eajn4,1849
43
+ ellements/core/llm/protocol.py,sha256=YcOZM9yuIjy62SRJ9-VeHstntrPS5AceVfCn1G-OEj4,4858
44
+ ellements/core/llm/requests.py,sha256=Wd4zNyBaGQVKq90HikOYqmy90pFgGHEMEkFJzGxCQZA,2940
45
+ ellements/core/llm/structured.py,sha256=csihK2AtY7rrDnTX-COCwigfv_64qaH6aEQGFot69wc,3138
46
+ ellements/core/llm/wrapper.py,sha256=scK9lpkIGzpmPBBJUhtOoq51eMyTmp6Vlt3NG5It6hU,2657
47
+ ellements/core/observability/__init__.py,sha256=frQC8FmlG5s0iN2SuGEZaSd_Pep9Qtufg7HKEekS8bw,1202
48
+ ellements/core/observability/events.py,sha256=j54Yy3lc0ARdWxm9DvY48V5_KGTOGTQVNSuN5ae95Tk,6298
49
+ ellements/core/observability/jsonl_logger.py,sha256=um-POS8zVwlHTI8wBxNe7UgyelxXnv1KV6IHxF67QMY,10054
50
+ ellements/core/observability/markdown_formatter.py,sha256=WgKaOFUfYp0eczVa2VCA0fiQIVwpJCHIElnzH0Feocg,6929
51
+ ellements/core/observability/observer.py,sha256=nhpFYQGA7VlB4mXOlyleFw_MthkyJrDV1Iqjgf-hBSY,2208
52
+ ellements/core/prompting/__init__.py,sha256=mj6KQkysO4yqAqomvUZzySvl0bAh5f_p_5haylpT9qU,331
53
+ ellements/core/prompting/context.py,sha256=wOPU09HubDYFXv8TU0FI0QllIr4pKXT02RBZUnbPCvk,8002
54
+ ellements/core/prompting/guideline.py,sha256=kIhhEhYsEkw31NsJfuJXX9a4x0L4j20KhUu6nfkef8A,5223
55
+ ellements/core/prompting/persona.py,sha256=eR0Lf_RN8U96a5jCPmJxJh6_uARDEqS9US0Y3AG1y_Q,10070
56
+ ellements/core/prompting/sources.py,sha256=3rehKLynBpk6w5n3c-QTY1jzQySTbvcFZPVOHk9hJDI,3263
57
+ ellements/core/rate_limit/__init__.py,sha256=TXNROb_QAhN_hrA6k5s9QhVOst01pg8Cam76tMsQwMY,1326
58
+ ellements/core/rate_limit/bucket.py,sha256=Jt_xjgWxV1jNoknf7-GyJ-Q0QSqVxPx25tARgDwDhBQ,2998
59
+ ellements/core/rate_limit/client.py,sha256=qHieuFs4zGRHYsYVQDGpPO9bam2Vwucw9Czn6CxXG-c,7005
60
+ ellements/core/rate_limit/protocol.py,sha256=_yZMhxncEmC458GIJj19z2y6LNa9qs-A2rqNTHFKHLc,878
61
+ ellements/core/tools/__init__.py,sha256=ZhLTC4Igs-BxnI1fMfAvURYyAUQs9LoZIIGfkNZZ6uE,1519
62
+ ellements/core/tools/dialects.py,sha256=aKo5SZ2ICO3A6NOR8gY94kxvYtEzhxRcVlJv715q7bo,4086
63
+ ellements/core/tools/executor.py,sha256=7OAgXn8hvWp-PIUhBKRfSDj4Nooma3cf1Ze6ZdhRPKQ,1510
64
+ ellements/core/tools/protocol.py,sha256=oHYR7zBci_wF79z3hYXhANl4Q4nP0ECwO5jXqwB2L94,1132
65
+ ellements/core/tools/records.py,sha256=hcOXn6i3AQu546LfzLEE2JrWp8uFH77iqxZBd84ctwQ,898
66
+ ellements/core/tools/registry.py,sha256=K5v4otWxdB8ZynZBNh2RH0A_2AFm3jbGjKuZU6PCbyM,7571
67
+ ellements/core/tools/schemas.py,sha256=OcpxkADgBWAiAJ91i97H3ZtDTQs2xF66mUyMFkMgDUY,2725
68
+ ellements/core/tools/simple.py,sha256=mFyjuMjn_BGsCHC5Sj9zb3citDIhxPsm-f_YGI2t_g8,4079
69
+ ellements/core/tools/spec.py,sha256=ZLG3NZR2R526AFp5FoQCFsriJK6C9n9B5z97a61fZJg,998
70
+ ellements/domain_specific/__init__.py,sha256=LseblmaZ9ZST_dZy4bg1il3Cx3H98lWT5VBbZmOxzs4,238
71
+ ellements/domain_specific/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
+ ellements/domain_specific/finance/__init__.py,sha256=zO_RnDzVkpDhY4CU2v3uIHevYzpbAkakzNNVq0cLOUM,4336
73
+ ellements/domain_specific/finance/calculations.py,sha256=0FUczrcO4o3SrD7qzMpVpC3Jxl7kLCJcONKzsvzU8P4,28469
74
+ ellements/domain_specific/finance/charts.py,sha256=U1K0rCvQR3VSamsksmfxhZZVWVtqcaDi5iF8Ur8OmnM,13164
75
+ ellements/domain_specific/finance/portfolio.py,sha256=zHFCt_VLLWo_B7iO0aAIBMAzi92qAofxRq03mrRvDwQ,3468
76
+ ellements/domain_specific/finance/quant_analysis.py,sha256=kufkdYyWLsx0rybvjzHlEDY8G9gTASgznGjQJdoPvuc,9538
77
+ ellements/domain_specific/finance/risk.py,sha256=71F8wEk6SHpu1E4teUP_7KPsNnrfXro_pak7-uvtrok,11101
78
+ ellements/domain_specific/finance/technical_indicators.py,sha256=UKafSD_KA3bqnqzsC2p4350YbhJ-c1SdJnj4dqhu2FQ,8272
79
+ ellements/domain_specific/finance/tools.py,sha256=QFQ5yH58ms5JnnDyhsu2zY6Zfwco0doE4HFpJ0t69vs,20259
80
+ ellements/domain_specific/finance/valuation.py,sha256=9CkGoXk_iY9lrRXEB3_XByRVtNFSuvCpHhpXEdq-H80,10262
81
+ ellements/domain_specific/finance/yahoo_finance.py,sha256=biWhxklYo0CNouE7jaYe4Z8mMZFwKRnap0DFaGlDLJw,56415
82
+ ellements/domain_specific/finance/yahoo_finance_models.py,sha256=9ZYBoSax6jKKBkfANZj0rBkMXyHEfL7pZQe_xTRfXRQ,15075
83
+ ellements/execution/__init__.py,sha256=Y9lzf2uwBIyThnf0XIWngHRourT-_dNClTvhygTLkPg,1562
84
+ ellements/execution/callbacks.py,sha256=DY5orD6_xOyTKEEwl9ECYLCx4zImh8D2w2BSJFTEf78,4766
85
+ ellements/execution/catalog.py,sha256=n1otlpd8Dag1HehOSPr2hIHj6qzibF7zWDhUyVNbMFo,1929
86
+ ellements/execution/collaborative.py,sha256=EH7VxJac8bp3NBK9RTsYQeQ1FMHjA7nRwoR-2opi7xA,6804
87
+ ellements/execution/config.py,sha256=7lWxwI4SLBfiAc5sTBi7WqleihIPPeqZKaxjzaGck6w,4242
88
+ ellements/execution/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
89
+ ellements/execution/reflection.py,sha256=HyJSNqFxKWKnuAxNp49Dt7cNxqM8DHWkNMRe_B9ILDM,5417
90
+ ellements/execution/self_consistency.py,sha256=MxDhYvlSk0XSx_mbJlWSXQc2JceQNEXP31sLh4IhSGY,6423
91
+ ellements/execution/single_call.py,sha256=3FoAAVQb8CtcGldIfoRUp2scozZRIAw-Syyoma7MrkA,1531
92
+ ellements/execution/strategies.py,sha256=Pnh-xyZ6rzZmozOQFevAbmVipWR1blqvv58_3FBxoCw,7543
93
+ ellements/execution/tree_of_thought.py,sha256=2iJiVJp8e65PgVC5RPsgThnAPFnBKS_k-lTN4qqYsTk,18422
94
+ ellements/fslm/__init__.py,sha256=XRIhNdr6x_nTJunv0E1Tj5MmTYq_2tSAlftV07J3sEU,2545
95
+ ellements/fslm/builtins.py,sha256=whjcn7O1sgVtLGlngzK3abSrnTb_k8nCvKrxq_3e6Ws,3565
96
+ ellements/fslm/cli.py,sha256=L3P0jYDfs81CV9yxN2hxC-BFIkDzilTFJUibqqExsBU,6930
97
+ ellements/fslm/context.py,sha256=hW_duwpWAbT-aOieUv8t-W5i0RMB0xOcc_e_VTD3vG4,1373
98
+ ellements/fslm/definition.py,sha256=6JjRr4aJu6vk8TxsbhL_Sy6uc9kdZ-kQJmuVgfviICg,5689
99
+ ellements/fslm/det.py,sha256=5DNYOtkPgK224e08NA0UejSKK4PCUGtjGA0KexGOb1k,4034
100
+ ellements/fslm/dsl.py,sha256=6sSMHwKcigX2omCWl81iqjVMAMrVOSgXmIYESFmN5QY,15385
101
+ ellements/fslm/errors.py,sha256=GM4sUTjOLuMHLCub2F2qJC1NJ2cKnGPbWPfQX5lll_Q,873
102
+ ellements/fslm/evaluators.py,sha256=lq6mN-Jt8xpoMo1oJJJ9rMmx-ceCm8isO9CHkBc-N_k,4263
103
+ ellements/fslm/kernel.py,sha256=3D1pOGbCl_auwDWJhoCXz0eM0dnXVhhrAhDHciHdKvo,21621
104
+ ellements/fslm/loading.py,sha256=zgeETgHLy62zMXQekDfIPDYDeFQALzD-zsxDC0YPLg0,4516
105
+ ellements/fslm/models.py,sha256=E2lQoKtmNKZdZlvKFL0z76MjY9p7a6h88jeSAkLyBto,20354
106
+ ellements/fslm/nl.py,sha256=PwfIwCAFRQ2slfN4w3pcT8swar1x_O-0eX5paLoecNo,2025
107
+ ellements/fslm/observers.py,sha256=5_YGV6_Z_6ZBubilY8iV6gvuJb-iwTeNtL7duoLWiQE,3406
108
+ ellements/fslm/persistence.py,sha256=rWicOpiXVwp2vOjntF9Uc4bUkgWI0TK9ZptEcLOio5E,2512
109
+ ellements/fslm/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
110
+ ellements/fslm/rendering.py,sha256=VDo219nvewbSvKzXdDSVadDNX0iTZAz2NjcJ3U3e-T4,16312
111
+ ellements/fslm/visualization.py,sha256=Y51SR8u_2cOAa4QnmWFA2Taw-1JWhBJHHqLCz6Finhg,805
112
+ ellements/reporting/__init__.py,sha256=3W-mEX0WEEUDmaFLB3wiGvOXIbpTfo-Q8ABFLsF2eC0,343
113
+ ellements/reporting/charts.py,sha256=H-esXZyTTw_8AnIjHGR2kk-J2k7pycDyarY77AWTb9I,14841
114
+ ellements/reporting/html_generation.py,sha256=Qjg7FO5inTXrS2ObxY0FTYktbwudyKkV1ikXCPrs5LY,4288
115
+ ellements/reporting/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
116
+ ellements/reporting/visualization.py,sha256=qsZrNTnYepJo_cifr07xZzfERmXhxTP-rwujea62B50,2350
117
+ ellements/standard_tools/__init__.py,sha256=N9FNJGPmVgBVs2dgNsq2_9885evZkwHGi7KlMoBXihg,576
118
+ ellements/standard_tools/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
119
+ ellements/standard_tools/terminal.py,sha256=__-_tsCYWuvvy10uvMsT-qlDtJe3QxNpFdtukPih0E0,6607
120
+ ellements/standard_tools/web/__init__.py,sha256=J2R2RB8N5FFGDxItVdvQ1PkRnicTvqHoKvy_cXGWL9U,908
121
+ ellements/standard_tools/web/browser_viewer.py,sha256=SRPm7l-3Ycangotig33UhJ1o86UQTCDResYih1sSVXc,6931
122
+ ellements/standard_tools/web/crawler.py,sha256=nScEjtapUhVSB1lOOwMBPpVnFET47KMYTn6Qn2fg1bs,15774
123
+ ellements/standard_tools/web/search.py,sha256=UCYOkjy7iDGA8jgPZ5H7DKVNlRbgP73KMhmyT1OdhZw,13346
124
+ ellements/standard_tools/web/youtube.py,sha256=301IGJg1kvleG4P-CHOKMZtRqVHnpc5cX8PxjCuirLs,48870
125
+ ellements-0.2.0.dist-info/licenses/LICENSE,sha256=TpTEUreapnHWYl3-ZzyR2s6h9iby1Z7KjYvCTkpUEXY,2200
126
+ ellements-0.2.0.dist-info/METADATA,sha256=IikrAfQ5KbNnbXUQYhpk2XEW-3LwYWDlH-XU_3ixoU8,15760
127
+ ellements-0.2.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
128
+ ellements-0.2.0.dist-info/entry_points.txt,sha256=UQ2ikSlzbqstNb8uzJWrFfLHChBND8T50ZP4rvugVkk,49
129
+ ellements-0.2.0.dist-info/top_level.txt,sha256=n3Rnr2WVKrpusrU6YNgm5_nNLNCjkstl9bZG0jOIu54,10
130
+ ellements-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (83.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ fslm = ellements.fslm.cli:main
@@ -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 @@
1
+ ellements