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,123 @@
1
+ """Load finite-state linguistic machine definitions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import importlib
6
+ import importlib.util
7
+ from pathlib import Path
8
+ from types import ModuleType
9
+
10
+ from .definition import MachineDefinition, RuntimeBindings, coerce_definition
11
+ from .models import MachineSpec
12
+
13
+ _DEFAULT_EXPORTS = (
14
+ "definition",
15
+ "machine_definition",
16
+ "spec",
17
+ "machine_spec",
18
+ "build",
19
+ "machine",
20
+ )
21
+
22
+
23
+ def load_machine_definition(
24
+ reference: str | Path,
25
+ *,
26
+ bindings: RuntimeBindings | None = None,
27
+ binding_modules: list[str | Path] | None = None,
28
+ ) -> MachineDefinition:
29
+ """Load a machine definition from Python, YAML, module refs, or JSON."""
30
+ text = str(reference)
31
+ path_text, attr = _split_reference(text)
32
+ path = Path(path_text)
33
+ extra = bindings or RuntimeBindings()
34
+ for module_ref in binding_modules or []:
35
+ module_path = Path(str(module_ref))
36
+ module = (
37
+ _module_from_path(module_path)
38
+ if module_path.suffix == ".py" or module_path.is_file()
39
+ else importlib.import_module(str(module_ref))
40
+ )
41
+ extra.modules[module_path.stem if module_path.is_file() else module.__name__] = module
42
+ if path.suffix == ".json" and path.is_file() and attr is None:
43
+ return coerce_definition(MachineSpec.from_json(path), bindings=extra)
44
+ if path.suffix in {".yaml", ".yml"} and path.is_file() and attr is None:
45
+ definition = _load_from_yaml(path)
46
+ return MachineDefinition(definition.spec, definition.bindings.merge(extra))
47
+ if path.suffix == ".py" or path.is_file():
48
+ return _load_from_module(_module_from_path(path), attr, bindings=extra)
49
+ return _load_from_module(importlib.import_module(path_text), attr, bindings=extra)
50
+
51
+
52
+ def load_machine_spec(reference: str | Path) -> MachineSpec:
53
+ """Load only the serializable machine spec."""
54
+ return load_machine_definition(reference).spec
55
+
56
+
57
+ def _split_reference(reference: str) -> tuple[str, str | None]:
58
+ path = Path(reference)
59
+ if path.exists():
60
+ return reference, None
61
+ if ":" not in reference:
62
+ return reference, None
63
+ path_text, attr = reference.rsplit(":", 1)
64
+ return path_text, attr
65
+
66
+
67
+ def _module_from_path(path: Path) -> ModuleType:
68
+ if not path.is_file():
69
+ raise FileNotFoundError(path)
70
+ module_name = f"_ellements_fsm_{abs(hash(path.resolve()))}"
71
+ spec = importlib.util.spec_from_file_location(module_name, path)
72
+ if spec is None or spec.loader is None:
73
+ raise ImportError(f"cannot load machine module from {path}")
74
+ module = importlib.util.module_from_spec(spec)
75
+ spec.loader.exec_module(module)
76
+ return module
77
+
78
+
79
+ def _load_from_module(
80
+ module: ModuleType,
81
+ attr: str | None,
82
+ *,
83
+ bindings: RuntimeBindings | None = None,
84
+ ) -> MachineDefinition:
85
+ if attr is not None:
86
+ if not hasattr(module, attr):
87
+ raise AttributeError(f"{module.__name__!r} has no export {attr!r}")
88
+ return coerce_definition(getattr(module, attr), bindings=bindings)
89
+ for candidate in _DEFAULT_EXPORTS:
90
+ if hasattr(module, candidate):
91
+ return coerce_definition(getattr(module, candidate), bindings=bindings)
92
+ names = ", ".join(_DEFAULT_EXPORTS)
93
+ raise AttributeError(
94
+ f"{module.__name__!r} must export one of {names}, or use module:export"
95
+ )
96
+
97
+
98
+ def _load_from_yaml(path: Path) -> MachineDefinition:
99
+ try:
100
+ import yaml
101
+ except ImportError as exc:
102
+ raise ImportError("PyYAML is required to load FSLM YAML specs.") from exc
103
+ data = yaml.safe_load(path.read_text(encoding="utf-8"))
104
+ if not isinstance(data, dict):
105
+ raise ValueError(f"YAML machine spec must be a mapping: {path}")
106
+ bindings_data = data.pop("bindings", {}) or {}
107
+ bindings = RuntimeBindings()
108
+ imports = bindings_data.get("imports", {}) if isinstance(bindings_data, dict) else {}
109
+ if not isinstance(imports, dict):
110
+ raise ValueError("bindings.imports must be a mapping")
111
+ for alias, module_ref in imports.items():
112
+ ref_text = str(module_ref)
113
+ module_path = (path.parent / ref_text).resolve()
114
+ module = (
115
+ _module_from_path(module_path)
116
+ if module_path.suffix == ".py" and module_path.is_file()
117
+ else importlib.import_module(ref_text)
118
+ )
119
+ bindings.modules[str(alias)] = module
120
+ return MachineDefinition(MachineSpec.model_validate(data), bindings)
121
+
122
+
123
+ __all__ = ["load_machine_definition", "load_machine_spec"]