entropic-engine 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. entropic_engine-1.0.0/PKG-INFO +220 -0
  2. entropic_engine-1.0.0/README.md +164 -0
  3. entropic_engine-1.0.0/pyproject.toml +135 -0
  4. entropic_engine-1.0.0/setup.cfg +4 -0
  5. entropic_engine-1.0.0/src/entropic/__init__.py +93 -0
  6. entropic_engine-1.0.0/src/entropic/__main__.py +8 -0
  7. entropic_engine-1.0.0/src/entropic/app.py +983 -0
  8. entropic_engine-1.0.0/src/entropic/cli.py +292 -0
  9. entropic_engine-1.0.0/src/entropic/cli_download.py +137 -0
  10. entropic_engine-1.0.0/src/entropic/config/__init__.py +13 -0
  11. entropic_engine-1.0.0/src/entropic/config/loader.py +497 -0
  12. entropic_engine-1.0.0/src/entropic/config/schema.py +508 -0
  13. entropic_engine-1.0.0/src/entropic/core/__init__.py +86 -0
  14. entropic_engine-1.0.0/src/entropic/core/base.py +265 -0
  15. entropic_engine-1.0.0/src/entropic/core/commands.py +760 -0
  16. entropic_engine-1.0.0/src/entropic/core/compaction.py +448 -0
  17. entropic_engine-1.0.0/src/entropic/core/context.py +334 -0
  18. entropic_engine-1.0.0/src/entropic/core/directives.py +265 -0
  19. entropic_engine-1.0.0/src/entropic/core/engine.py +1459 -0
  20. entropic_engine-1.0.0/src/entropic/core/logging.py +144 -0
  21. entropic_engine-1.0.0/src/entropic/core/parser.py +172 -0
  22. entropic_engine-1.0.0/src/entropic/core/queue.py +369 -0
  23. entropic_engine-1.0.0/src/entropic/core/session.py +517 -0
  24. entropic_engine-1.0.0/src/entropic/core/tasks.py +530 -0
  25. entropic_engine-1.0.0/src/entropic/core/todos.py +335 -0
  26. entropic_engine-1.0.0/src/entropic/core/tool_validation.py +131 -0
  27. entropic_engine-1.0.0/src/entropic/data/default_config.yaml +108 -0
  28. entropic_engine-1.0.0/src/entropic/data/prompts/app_context.md +29 -0
  29. entropic_engine-1.0.0/src/entropic/data/prompts/constitution.md +32 -0
  30. entropic_engine-1.0.0/src/entropic/data/prompts/identity_code.md +28 -0
  31. entropic_engine-1.0.0/src/entropic/data/prompts/identity_normal.md +22 -0
  32. entropic_engine-1.0.0/src/entropic/data/prompts/identity_simple.md +26 -0
  33. entropic_engine-1.0.0/src/entropic/data/prompts/identity_thinking.md +54 -0
  34. entropic_engine-1.0.0/src/entropic/data/tools/bash/execute.json +18 -0
  35. entropic_engine-1.0.0/src/entropic/data/tools/diagnostics/check_errors.json +14 -0
  36. entropic_engine-1.0.0/src/entropic/data/tools/diagnostics/diagnostics.json +14 -0
  37. entropic_engine-1.0.0/src/entropic/data/tools/entropic/handoff.json +24 -0
  38. entropic_engine-1.0.0/src/entropic/data/tools/entropic/prune_context.json +13 -0
  39. entropic_engine-1.0.0/src/entropic/data/tools/entropic/todo_write.json +64 -0
  40. entropic_engine-1.0.0/src/entropic/data/tools/filesystem/edit_file.json +30 -0
  41. entropic_engine-1.0.0/src/entropic/data/tools/filesystem/read_file.json +14 -0
  42. entropic_engine-1.0.0/src/entropic/data/tools/filesystem/write_file.json +18 -0
  43. entropic_engine-1.0.0/src/entropic/data/tools/git/add.json +14 -0
  44. entropic_engine-1.0.0/src/entropic/data/tools/git/branch.json +14 -0
  45. entropic_engine-1.0.0/src/entropic/data/tools/git/checkout.json +14 -0
  46. entropic_engine-1.0.0/src/entropic/data/tools/git/commit.json +18 -0
  47. entropic_engine-1.0.0/src/entropic/data/tools/git/diff.json +18 -0
  48. entropic_engine-1.0.0/src/entropic/data/tools/git/log.json +18 -0
  49. entropic_engine-1.0.0/src/entropic/data/tools/git/reset.json +14 -0
  50. entropic_engine-1.0.0/src/entropic/data/tools/git/status.json +9 -0
  51. entropic_engine-1.0.0/src/entropic/inference/__init__.py +14 -0
  52. entropic_engine-1.0.0/src/entropic/inference/adapters/__init__.py +29 -0
  53. entropic_engine-1.0.0/src/entropic/inference/adapters/base.py +538 -0
  54. entropic_engine-1.0.0/src/entropic/inference/adapters/falcon.py +60 -0
  55. entropic_engine-1.0.0/src/entropic/inference/adapters/qwen2.py +286 -0
  56. entropic_engine-1.0.0/src/entropic/inference/adapters/qwen3.py +127 -0
  57. entropic_engine-1.0.0/src/entropic/inference/adapters/router.py +44 -0
  58. entropic_engine-1.0.0/src/entropic/inference/adapters/smollm3.py +31 -0
  59. entropic_engine-1.0.0/src/entropic/inference/backend.py +53 -0
  60. entropic_engine-1.0.0/src/entropic/inference/llama_cpp.py +457 -0
  61. entropic_engine-1.0.0/src/entropic/inference/orchestrator.py +627 -0
  62. entropic_engine-1.0.0/src/entropic/lsp/__init__.py +21 -0
  63. entropic_engine-1.0.0/src/entropic/lsp/base.py +294 -0
  64. entropic_engine-1.0.0/src/entropic/lsp/clangd_client.py +42 -0
  65. entropic_engine-1.0.0/src/entropic/lsp/manager.py +173 -0
  66. entropic_engine-1.0.0/src/entropic/lsp/pyright_client.py +81 -0
  67. entropic_engine-1.0.0/src/entropic/mcp/__init__.py +10 -0
  68. entropic_engine-1.0.0/src/entropic/mcp/bridge.py +181 -0
  69. entropic_engine-1.0.0/src/entropic/mcp/client.py +187 -0
  70. entropic_engine-1.0.0/src/entropic/mcp/manager.py +396 -0
  71. entropic_engine-1.0.0/src/entropic/mcp/provider.py +119 -0
  72. entropic_engine-1.0.0/src/entropic/mcp/servers/__init__.py +16 -0
  73. entropic_engine-1.0.0/src/entropic/mcp/servers/base.py +211 -0
  74. entropic_engine-1.0.0/src/entropic/mcp/servers/bash.py +166 -0
  75. entropic_engine-1.0.0/src/entropic/mcp/servers/diagnostics.py +154 -0
  76. entropic_engine-1.0.0/src/entropic/mcp/servers/entropic.py +199 -0
  77. entropic_engine-1.0.0/src/entropic/mcp/servers/external.py +750 -0
  78. entropic_engine-1.0.0/src/entropic/mcp/servers/file_tracker.py +124 -0
  79. entropic_engine-1.0.0/src/entropic/mcp/servers/filesystem.py +622 -0
  80. entropic_engine-1.0.0/src/entropic/mcp/servers/git.py +172 -0
  81. entropic_engine-1.0.0/src/entropic/mcp/tools.py +137 -0
  82. entropic_engine-1.0.0/src/entropic/prompts/__init__.py +261 -0
  83. entropic_engine-1.0.0/src/entropic/py.typed +0 -0
  84. entropic_engine-1.0.0/src/entropic/quality/__init__.py +8 -0
  85. entropic_engine-1.0.0/src/entropic/quality/analyzers/__init__.py +17 -0
  86. entropic_engine-1.0.0/src/entropic/quality/analyzers/base.py +88 -0
  87. entropic_engine-1.0.0/src/entropic/quality/analyzers/complexity.py +131 -0
  88. entropic_engine-1.0.0/src/entropic/quality/analyzers/docstrings.py +123 -0
  89. entropic_engine-1.0.0/src/entropic/quality/analyzers/structure.py +122 -0
  90. entropic_engine-1.0.0/src/entropic/quality/analyzers/typing.py +70 -0
  91. entropic_engine-1.0.0/src/entropic/quality/enforcer.py +239 -0
  92. entropic_engine-1.0.0/src/entropic/storage/__init__.py +16 -0
  93. entropic_engine-1.0.0/src/entropic/storage/backend.py +205 -0
  94. entropic_engine-1.0.0/src/entropic/storage/database.py +211 -0
  95. entropic_engine-1.0.0/src/entropic/storage/models.py +140 -0
  96. entropic_engine-1.0.0/src/entropic/storage/session.py +668 -0
  97. entropic_engine-1.0.0/src/entropic/ui/__init__.py +48 -0
  98. entropic_engine-1.0.0/src/entropic/ui/components.py +303 -0
  99. entropic_engine-1.0.0/src/entropic/ui/entropic.tcss +276 -0
  100. entropic_engine-1.0.0/src/entropic/ui/headless.py +324 -0
  101. entropic_engine-1.0.0/src/entropic/ui/presenter.py +318 -0
  102. entropic_engine-1.0.0/src/entropic/ui/themes.py +91 -0
  103. entropic_engine-1.0.0/src/entropic/ui/tui.py +1363 -0
  104. entropic_engine-1.0.0/src/entropic/ui/tui_presenter.py +178 -0
  105. entropic_engine-1.0.0/src/entropic/ui/voice_screen.py +680 -0
  106. entropic_engine-1.0.0/src/entropic/ui/voice_widgets.py +472 -0
  107. entropic_engine-1.0.0/src/entropic/ui/widgets.py +785 -0
  108. entropic_engine-1.0.0/src/entropic/voice/__init__.py +30 -0
  109. entropic_engine-1.0.0/src/entropic/voice/audio_io.py +837 -0
  110. entropic_engine-1.0.0/src/entropic/voice/client.py +514 -0
  111. entropic_engine-1.0.0/src/entropic/voice/context_compactor.py +500 -0
  112. entropic_engine-1.0.0/src/entropic/voice/controller.py +868 -0
  113. entropic_engine-1.0.0/src/entropic/voice/server.py +561 -0
  114. entropic_engine-1.0.0/src/entropic/voice/thinking_audio.py +255 -0
  115. entropic_engine-1.0.0/src/entropic_engine.egg-info/PKG-INFO +220 -0
  116. entropic_engine-1.0.0/src/entropic_engine.egg-info/SOURCES.txt +118 -0
  117. entropic_engine-1.0.0/src/entropic_engine.egg-info/dependency_links.txt +1 -0
  118. entropic_engine-1.0.0/src/entropic_engine.egg-info/entry_points.txt +3 -0
  119. entropic_engine-1.0.0/src/entropic_engine.egg-info/requires.txt +44 -0
  120. entropic_engine-1.0.0/src/entropic_engine.egg-info/top_level.txt +1 -0
@@ -0,0 +1,220 @@
1
+ Metadata-Version: 2.4
2
+ Name: entropic-engine
3
+ Version: 1.0.0
4
+ Summary: Local-first agentic inference engine with tier-based model routing
5
+ Author: Tristan VanFossen
6
+ License: Apache-2.0
7
+ Keywords: ai,coding,assistant,llm,local
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: Apache Software License
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Topic :: Software Development
15
+ Requires-Python: >=3.11
16
+ Description-Content-Type: text/markdown
17
+ Requires-Dist: llama-cpp-python>=0.2.0
18
+ Requires-Dist: mcp>=1.0.0
19
+ Requires-Dist: pydantic>=2.0.0
20
+ Requires-Dist: pydantic-settings>=2.0.0
21
+ Requires-Dist: pyyaml>=6.0.0
22
+ Provides-Extra: tui
23
+ Requires-Dist: textual>=0.47.0; extra == "tui"
24
+ Requires-Dist: rich>=13.0.0; extra == "tui"
25
+ Requires-Dist: click>=8.0.0; extra == "tui"
26
+ Requires-Dist: pylspclient>=0.0.7; extra == "tui"
27
+ Provides-Extra: app
28
+ Requires-Dist: entropic-engine[tui]; extra == "app"
29
+ Requires-Dist: aiosqlite>=0.19.0; extra == "app"
30
+ Requires-Dist: httpx>=0.25.0; extra == "app"
31
+ Provides-Extra: all
32
+ Requires-Dist: entropic-engine[app,voice]; extra == "all"
33
+ Provides-Extra: dev
34
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
35
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
36
+ Requires-Dist: pytest-bdd>=7.0.0; extra == "dev"
37
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
38
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
39
+ Requires-Dist: black>=23.0.0; extra == "dev"
40
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
41
+ Requires-Dist: pre-commit>=3.0.0; extra == "dev"
42
+ Requires-Dist: types-pyyaml>=6.0.0; extra == "dev"
43
+ Provides-Extra: voice
44
+ Requires-Dist: numpy<2.2,>=1.26; extra == "voice"
45
+ Requires-Dist: safetensors<0.5,>=0.4.0; extra == "voice"
46
+ Requires-Dist: huggingface-hub<0.28,>=0.24; extra == "voice"
47
+ Requires-Dist: einops==0.7; extra == "voice"
48
+ Requires-Dist: sentencepiece==0.2; extra == "voice"
49
+ Requires-Dist: sounddevice==0.5; extra == "voice"
50
+ Requires-Dist: sphn<0.2,>=0.1.4; extra == "voice"
51
+ Requires-Dist: torch>=2.2.0; extra == "voice"
52
+ Requires-Dist: aiohttp<3.12,>=3.10.5; extra == "voice"
53
+ Requires-Dist: websockets<14.0,>=12.0; extra == "voice"
54
+ Requires-Dist: accelerate>=0.30.0; extra == "voice"
55
+ Requires-Dist: torchao>=0.4.0; extra == "voice"
56
+
57
+ # Entropic
58
+
59
+ > Local-first agentic inference engine with tier-based model routing
60
+
61
+ This started as "I want to build a local-first Claude Code" — which turned out
62
+ to be quite the undertaking. The initial build was a tightly coupled TUI, but it
63
+ became clear pretty quickly that I was duplicating the same core inference engine
64
+ across other local projects wrapping llama-cpp-python. So it evolved into a
65
+ library: the inference engine, model orchestration, agentic loop, and tool
66
+ framework are all importable and reusable without dragging in a UI. The TUI ships
67
+ alongside it as one consumer, and doubles as a testbed for new ideas. There's also
68
+ a very broken voice interface via PersonaPlex that I'll get to eventually.
69
+
70
+ The name is a nod to how this actually works. Every handoff — human intent to
71
+ prompt, prompt to model, model to model across tiers — is a lossy translation.
72
+ Information decays at each boundary. That's the entropic process this engine tries
73
+ to manage: structured routing, context management, and tool-augmented reasoning to
74
+ lose as little as possible along the way. A bit of a nihilistic naming convention,
75
+ but the tier routing and model management do earn their keep in practice. There's
76
+ optimization work ahead, but the foundation is solid and I'm always open to new
77
+ directions.
78
+
79
+ ## Architecture
80
+
81
+ Entropic is a **library first, application second**. The inference engine
82
+ (orchestrator, agentic loop, adapters, tool providers) is fully separable from
83
+ any UI. The bundled TUI is one consumer; headless automation, CI/CD agents, and
84
+ custom applications are equally supported.
85
+
86
+ ```
87
+ pip install entropic-engine # Core library (inference, engine, tools)
88
+ pip install entropic-engine[app] # TUI application (includes tui + storage deps)
89
+ pip install entropic-engine[voice] # Voice interface (PersonaPlex)
90
+ pip install entropic-engine[all] # Everything
91
+ ```
92
+
93
+ ```
94
+ +-----------------------------------------------------+
95
+ | Application Layer (TUI / Headless / Custom) |
96
+ +-----------------------------------------------------+
97
+ | Engine | Orchestrator | Tools |
98
+ | - Agentic loop | - Tier routing | - Filesystem |
99
+ | - Directives | - Model swap | - Bash |
100
+ | - Compaction | - VRAM mgmt | - Diagnostics |
101
+ | - Context mgmt | - Adapters | - Git / Todo |
102
+ +-----------------------------------------------------+
103
+ | Inference Backend (llama-cpp-python) |
104
+ | - GGUF models, single-GPU, in-process |
105
+ +-----------------------------------------------------+
106
+ ```
107
+
108
+ ### Tier-Based Routing
109
+
110
+ A lightweight router model classifies each prompt and routes to the appropriate
111
+ tier. Only one main model is loaded at a time (VRAM constraint) — the
112
+ orchestrator handles dynamic swapping with lock-protected state transitions.
113
+
114
+ | Tier | Purpose | Typical Model |
115
+ |------|---------|---------------|
116
+ | **Thinking** | Complex reasoning, architecture, multi-step analysis | Qwen3-14B Q4_K_M |
117
+ | **Normal** | General conversation and tasks | Falcon-H1R-7B Q8_0 |
118
+ | **Code** | Code generation, editing, refactoring | Falcon-H1R-7B Q8_0 |
119
+ | **Simple** | Greetings, acknowledgments, short responses | (shares normal model) |
120
+ | **Router** | Prompt classification only | Qwen3-0.6B Q8_0 |
121
+
122
+ ### Agentic Loop
123
+
124
+ The engine runs an autonomous tool-calling loop: generate -> parse tool calls ->
125
+ execute tools -> feed results back -> generate again. The loop continues until
126
+ the model produces a complete response or hits the iteration limit.
127
+
128
+ Tools communicate back to the engine via **directives** — structured signals
129
+ embedded in tool results that can trigger tier handoffs, context anchoring, and
130
+ state management without the model needing to orchestrate these concerns.
131
+
132
+ ## Features
133
+
134
+ - **Fully Local** — All inference on your hardware via llama-cpp-python. No API keys.
135
+ - **Library API** — Embed the engine in your own application with `LibraryConfig`
136
+ - **Intelligent Routing** — Sub-second prompt classification routes to the right model tier
137
+ - **Single-GPU Orchestration** — Dynamic model swapping with VRAM-aware loading
138
+ - **Per-Model Adapters** — Model-specific chat templates, tool parsing, thinking block handling
139
+ - **Auto-Compaction** — Context summarization for long conversations
140
+ - **MCP Tools** — Filesystem, bash, diagnostics, git, and extensible tool servers
141
+ - **Headless Mode** — Full engine without TUI for automation and testing
142
+ - **TUI** — Terminal interface built on Textual with streaming, tool approval, voice input
143
+
144
+ ## Requirements
145
+
146
+ - Linux (tested on Ubuntu 24.04)
147
+ - NVIDIA GPU with 16GB+ VRAM
148
+ - CUDA 12.4+
149
+ - Python 3.11+
150
+
151
+ ## Quick Start
152
+
153
+ ```bash
154
+ git clone https://github.com/tvanfossen/entropic.git
155
+ cd entropic
156
+ ./install.sh app
157
+ ```
158
+
159
+ The install script creates a virtual environment, detects CUDA, and installs
160
+ with the `[app]` extras (TUI + storage dependencies).
161
+
162
+ ```bash
163
+ # Place GGUF models in ~/models/gguf/ (or configure paths in .entropic/config.local.yaml)
164
+
165
+ # Run interactive TUI
166
+ .venv/bin/entropic
167
+
168
+ # Or headless
169
+ .venv/bin/entropic --headless
170
+ ```
171
+
172
+ ## CLI
173
+
174
+ ```bash
175
+ entropic # Interactive TUI
176
+ entropic --headless # Headless mode (automation/testing)
177
+ entropic status # Show model and system status
178
+ entropic ask "question" # Single-shot question
179
+ entropic init # Initialize .entropic/ in current directory
180
+ entropic download <model> # Download model files
181
+ ```
182
+
183
+ ## Configuration
184
+
185
+ Configuration loads in priority order (highest wins):
186
+
187
+ 1. Built-in defaults
188
+ 2. Global config (`~/.entropic/config.yaml`)
189
+ 3. Project config (`.entropic/config.local.yaml`)
190
+ 4. CLI arguments
191
+
192
+ Project context is provided via `.entropic/ENTROPIC.md` — a markdown file
193
+ describing the project that gets included in the system prompt.
194
+
195
+ ## Library Usage
196
+
197
+ ```python
198
+ from entropic import LibraryConfig, Orchestrator, Engine, ServerManager
199
+
200
+ config = LibraryConfig(
201
+ config_dir=Path("~/.myapp").expanduser(),
202
+ tiers={"normal": {"path": "model.gguf", "adapter": "qwen3"}},
203
+ )
204
+
205
+ orchestrator = Orchestrator(config.to_app_config())
206
+ await orchestrator.initialize()
207
+
208
+ server_manager = ServerManager(config.to_app_config())
209
+ await server_manager.initialize()
210
+
211
+ engine = Engine(orchestrator=orchestrator, server_manager=server_manager)
212
+ async for message in engine.run("Hello"):
213
+ print(message.content)
214
+ ```
215
+
216
+ See `examples/hello-world/` and `examples/pychess/` for complete integrations.
217
+
218
+ ## License
219
+
220
+ Apache-2.0
@@ -0,0 +1,164 @@
1
+ # Entropic
2
+
3
+ > Local-first agentic inference engine with tier-based model routing
4
+
5
+ This started as "I want to build a local-first Claude Code" — which turned out
6
+ to be quite the undertaking. The initial build was a tightly coupled TUI, but it
7
+ became clear pretty quickly that I was duplicating the same core inference engine
8
+ across other local projects wrapping llama-cpp-python. So it evolved into a
9
+ library: the inference engine, model orchestration, agentic loop, and tool
10
+ framework are all importable and reusable without dragging in a UI. The TUI ships
11
+ alongside it as one consumer, and doubles as a testbed for new ideas. There's also
12
+ a very broken voice interface via PersonaPlex that I'll get to eventually.
13
+
14
+ The name is a nod to how this actually works. Every handoff — human intent to
15
+ prompt, prompt to model, model to model across tiers — is a lossy translation.
16
+ Information decays at each boundary. That's the entropic process this engine tries
17
+ to manage: structured routing, context management, and tool-augmented reasoning to
18
+ lose as little as possible along the way. A bit of a nihilistic naming convention,
19
+ but the tier routing and model management do earn their keep in practice. There's
20
+ optimization work ahead, but the foundation is solid and I'm always open to new
21
+ directions.
22
+
23
+ ## Architecture
24
+
25
+ Entropic is a **library first, application second**. The inference engine
26
+ (orchestrator, agentic loop, adapters, tool providers) is fully separable from
27
+ any UI. The bundled TUI is one consumer; headless automation, CI/CD agents, and
28
+ custom applications are equally supported.
29
+
30
+ ```
31
+ pip install entropic-engine # Core library (inference, engine, tools)
32
+ pip install entropic-engine[app] # TUI application (includes tui + storage deps)
33
+ pip install entropic-engine[voice] # Voice interface (PersonaPlex)
34
+ pip install entropic-engine[all] # Everything
35
+ ```
36
+
37
+ ```
38
+ +-----------------------------------------------------+
39
+ | Application Layer (TUI / Headless / Custom) |
40
+ +-----------------------------------------------------+
41
+ | Engine | Orchestrator | Tools |
42
+ | - Agentic loop | - Tier routing | - Filesystem |
43
+ | - Directives | - Model swap | - Bash |
44
+ | - Compaction | - VRAM mgmt | - Diagnostics |
45
+ | - Context mgmt | - Adapters | - Git / Todo |
46
+ +-----------------------------------------------------+
47
+ | Inference Backend (llama-cpp-python) |
48
+ | - GGUF models, single-GPU, in-process |
49
+ +-----------------------------------------------------+
50
+ ```
51
+
52
+ ### Tier-Based Routing
53
+
54
+ A lightweight router model classifies each prompt and routes to the appropriate
55
+ tier. Only one main model is loaded at a time (VRAM constraint) — the
56
+ orchestrator handles dynamic swapping with lock-protected state transitions.
57
+
58
+ | Tier | Purpose | Typical Model |
59
+ |------|---------|---------------|
60
+ | **Thinking** | Complex reasoning, architecture, multi-step analysis | Qwen3-14B Q4_K_M |
61
+ | **Normal** | General conversation and tasks | Falcon-H1R-7B Q8_0 |
62
+ | **Code** | Code generation, editing, refactoring | Falcon-H1R-7B Q8_0 |
63
+ | **Simple** | Greetings, acknowledgments, short responses | (shares normal model) |
64
+ | **Router** | Prompt classification only | Qwen3-0.6B Q8_0 |
65
+
66
+ ### Agentic Loop
67
+
68
+ The engine runs an autonomous tool-calling loop: generate -> parse tool calls ->
69
+ execute tools -> feed results back -> generate again. The loop continues until
70
+ the model produces a complete response or hits the iteration limit.
71
+
72
+ Tools communicate back to the engine via **directives** — structured signals
73
+ embedded in tool results that can trigger tier handoffs, context anchoring, and
74
+ state management without the model needing to orchestrate these concerns.
75
+
76
+ ## Features
77
+
78
+ - **Fully Local** — All inference on your hardware via llama-cpp-python. No API keys.
79
+ - **Library API** — Embed the engine in your own application with `LibraryConfig`
80
+ - **Intelligent Routing** — Sub-second prompt classification routes to the right model tier
81
+ - **Single-GPU Orchestration** — Dynamic model swapping with VRAM-aware loading
82
+ - **Per-Model Adapters** — Model-specific chat templates, tool parsing, thinking block handling
83
+ - **Auto-Compaction** — Context summarization for long conversations
84
+ - **MCP Tools** — Filesystem, bash, diagnostics, git, and extensible tool servers
85
+ - **Headless Mode** — Full engine without TUI for automation and testing
86
+ - **TUI** — Terminal interface built on Textual with streaming, tool approval, voice input
87
+
88
+ ## Requirements
89
+
90
+ - Linux (tested on Ubuntu 24.04)
91
+ - NVIDIA GPU with 16GB+ VRAM
92
+ - CUDA 12.4+
93
+ - Python 3.11+
94
+
95
+ ## Quick Start
96
+
97
+ ```bash
98
+ git clone https://github.com/tvanfossen/entropic.git
99
+ cd entropic
100
+ ./install.sh app
101
+ ```
102
+
103
+ The install script creates a virtual environment, detects CUDA, and installs
104
+ with the `[app]` extras (TUI + storage dependencies).
105
+
106
+ ```bash
107
+ # Place GGUF models in ~/models/gguf/ (or configure paths in .entropic/config.local.yaml)
108
+
109
+ # Run interactive TUI
110
+ .venv/bin/entropic
111
+
112
+ # Or headless
113
+ .venv/bin/entropic --headless
114
+ ```
115
+
116
+ ## CLI
117
+
118
+ ```bash
119
+ entropic # Interactive TUI
120
+ entropic --headless # Headless mode (automation/testing)
121
+ entropic status # Show model and system status
122
+ entropic ask "question" # Single-shot question
123
+ entropic init # Initialize .entropic/ in current directory
124
+ entropic download <model> # Download model files
125
+ ```
126
+
127
+ ## Configuration
128
+
129
+ Configuration loads in priority order (highest wins):
130
+
131
+ 1. Built-in defaults
132
+ 2. Global config (`~/.entropic/config.yaml`)
133
+ 3. Project config (`.entropic/config.local.yaml`)
134
+ 4. CLI arguments
135
+
136
+ Project context is provided via `.entropic/ENTROPIC.md` — a markdown file
137
+ describing the project that gets included in the system prompt.
138
+
139
+ ## Library Usage
140
+
141
+ ```python
142
+ from entropic import LibraryConfig, Orchestrator, Engine, ServerManager
143
+
144
+ config = LibraryConfig(
145
+ config_dir=Path("~/.myapp").expanduser(),
146
+ tiers={"normal": {"path": "model.gguf", "adapter": "qwen3"}},
147
+ )
148
+
149
+ orchestrator = Orchestrator(config.to_app_config())
150
+ await orchestrator.initialize()
151
+
152
+ server_manager = ServerManager(config.to_app_config())
153
+ await server_manager.initialize()
154
+
155
+ engine = Engine(orchestrator=orchestrator, server_manager=server_manager)
156
+ async for message in engine.run("Hello"):
157
+ print(message.content)
158
+ ```
159
+
160
+ See `examples/hello-world/` and `examples/pychess/` for complete integrations.
161
+
162
+ ## License
163
+
164
+ Apache-2.0
@@ -0,0 +1,135 @@
1
+ [project]
2
+ name = "entropic-engine"
3
+ version = "1.0.0"
4
+ description = "Local-first agentic inference engine with tier-based model routing"
5
+ readme = "README.md"
6
+ license = {text = "Apache-2.0"}
7
+ requires-python = ">=3.11"
8
+ authors = [
9
+ {name = "Tristan VanFossen"}
10
+ ]
11
+ keywords = ["ai", "coding", "assistant", "llm", "local"]
12
+ classifiers = [
13
+ "Development Status :: 3 - Alpha",
14
+ "Environment :: Console",
15
+ "Intended Audience :: Developers",
16
+ "License :: OSI Approved :: Apache Software License",
17
+ "Programming Language :: Python :: 3.11",
18
+ "Programming Language :: Python :: 3.12",
19
+ "Topic :: Software Development",
20
+ ]
21
+
22
+ dependencies = [
23
+ "llama-cpp-python>=0.2.0",
24
+ "mcp>=1.0.0",
25
+ "pydantic>=2.0.0",
26
+ "pydantic-settings>=2.0.0",
27
+ "pyyaml>=6.0.0",
28
+ ]
29
+
30
+ [project.optional-dependencies]
31
+ tui = [
32
+ "textual>=0.47.0",
33
+ "rich>=13.0.0",
34
+ "click>=8.0.0",
35
+ "pylspclient>=0.0.7",
36
+ ]
37
+ app = [
38
+ "entropic-engine[tui]",
39
+ "aiosqlite>=0.19.0",
40
+ "httpx>=0.25.0",
41
+ ]
42
+ all = ["entropic-engine[app,voice]"]
43
+ dev = [
44
+ "pytest>=7.0.0",
45
+ "pytest-asyncio>=0.21.0",
46
+ "pytest-bdd>=7.0.0",
47
+ "pytest-cov>=4.0.0",
48
+ "mypy>=1.0.0",
49
+ "black>=23.0.0",
50
+ "ruff>=0.1.0",
51
+ "pre-commit>=3.0.0",
52
+ "types-pyyaml>=6.0.0",
53
+ ]
54
+ voice = [
55
+ # From PersonaPlex requirements
56
+ "numpy>=1.26,<2.2",
57
+ "safetensors>=0.4.0,<0.5",
58
+ "huggingface-hub>=0.24,<0.28",
59
+ "einops==0.7",
60
+ "sentencepiece==0.2",
61
+ "sounddevice==0.5",
62
+ "sphn>=0.1.4,<0.2",
63
+ "torch>=2.2.0",
64
+ "aiohttp>=3.10.5,<3.12",
65
+ "websockets>=12.0,<14.0",
66
+ # Optional for INT8 quantization
67
+ "accelerate>=0.30.0",
68
+ "torchao>=0.4.0",
69
+ ]
70
+
71
+ [project.scripts]
72
+ entropic = "entropic.cli:main"
73
+ entropic-voice-server = "entropic.voice.server:main"
74
+
75
+ [build-system]
76
+ requires = ["setuptools>=61.0", "wheel"]
77
+ build-backend = "setuptools.build_meta"
78
+
79
+ [tool.setuptools.packages.find]
80
+ where = ["src"]
81
+
82
+ [tool.setuptools.package-data]
83
+ entropic = ["data/*.yaml", "data/prompts/*.md", "data/grammars/*.gbnf", "data/tools/**/*.json", "ui/*.tcss"]
84
+
85
+ [tool.black]
86
+ line-length = 100
87
+ target-version = ["py311", "py312"]
88
+
89
+ [tool.ruff]
90
+ line-length = 100
91
+ extend-exclude = ["vendor"]
92
+
93
+ [tool.ruff.lint]
94
+ select = ["E", "F", "W", "I", "N", "UP", "B", "C4"]
95
+ ignore = ["E501"]
96
+
97
+ [tool.mypy]
98
+ python_version = "3.12"
99
+ strict = true
100
+ ignore_missing_imports = true
101
+
102
+ [[tool.mypy.overrides]]
103
+ module = "tests.*"
104
+ strict = false
105
+ disallow_untyped_defs = false
106
+ disallow_untyped_calls = false
107
+ disallow_incomplete_defs = false
108
+
109
+ [[tool.mypy.overrides]]
110
+ module = ["entropic.cli", "entropic.cli_download"]
111
+ disallow_untyped_decorators = false
112
+
113
+ [[tool.mypy.overrides]]
114
+ module = "entropic.mcp.servers.base"
115
+ disallow_untyped_decorators = false
116
+
117
+ [[tool.mypy.overrides]]
118
+ module = "entropic.ui.tui"
119
+ disallow_untyped_decorators = false
120
+
121
+ [tool.pytest.ini_options]
122
+ asyncio_mode = "auto"
123
+ testpaths = ["tests"]
124
+ python_files = ["test_*.py"]
125
+ python_functions = ["test_*"]
126
+ # Markers for categorizing tests
127
+ markers = [
128
+ "unit: Fast tests without external dependencies",
129
+ "integration: Tests requiring external services (docker, etc)",
130
+ "model: Tests requiring actual model inference (GPU recommended)",
131
+ "slow: Tests that take a long time to run",
132
+ ]
133
+ # Run all tests by default including model tests
134
+ # Skip model tests with: pytest -m "not model"
135
+ # Run only model tests: pytest -m model
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,93 @@
1
+ """
2
+ Entropi - Local AI inference engine with multi-tier model orchestration.
3
+
4
+ Public API for library consumers. Install extras for additional features:
5
+ pip install entropic-engine # Core inference engine
6
+ pip install entropic-engine[tui] # Terminal UI application
7
+ pip install entropic-engine[voice] # Voice interface
8
+ """
9
+
10
+ from entropic.config.loader import ConfigLoader, save_permission, validate_config
11
+ from entropic.config.schema import (
12
+ CompactionConfig,
13
+ EntropyConfig,
14
+ GenerationConfig,
15
+ LibraryConfig,
16
+ ModelConfig,
17
+ ModelsConfig,
18
+ RoutingConfig,
19
+ TierConfig,
20
+ )
21
+ from entropic.core.base import (
22
+ GenerationResult,
23
+ Message,
24
+ ModelBackend,
25
+ ModelTier,
26
+ ToolCall,
27
+ ToolProvider,
28
+ ToolResult,
29
+ )
30
+ from entropic.core.engine import AgentEngine, AgentState, EngineCallbacks, LoopConfig
31
+ from entropic.core.logging import setup_logging, setup_model_logger
32
+ from entropic.core.tool_validation import ToolValidationError
33
+ from entropic.inference.adapters import ChatAdapter, get_adapter, register_adapter
34
+ from entropic.inference.orchestrator import BackendFactory, ModelOrchestrator, RoutingResult
35
+ from entropic.mcp.manager import ServerManager
36
+ from entropic.mcp.provider import InProcessProvider
37
+ from entropic.mcp.servers.base import BaseMCPServer, ServerResponse, load_tool_definition
38
+ from entropic.mcp.tools import BaseTool, ToolRegistry
39
+ from entropic.prompts import TierIdentity, load_tier_identity
40
+
41
+ __version__ = "1.0.0"
42
+ __author__ = "Tristan VanFossen"
43
+
44
+ __all__ = [
45
+ # Core types
46
+ "GenerationResult",
47
+ "Message",
48
+ "ModelBackend",
49
+ "ModelTier",
50
+ "ToolCall",
51
+ "ToolProvider",
52
+ "ToolResult",
53
+ # Engine
54
+ "AgentEngine",
55
+ "AgentState",
56
+ "EngineCallbacks",
57
+ "LoopConfig",
58
+ # Logging
59
+ "setup_logging",
60
+ "setup_model_logger",
61
+ # Config
62
+ "ConfigLoader",
63
+ "save_permission",
64
+ "validate_config",
65
+ "CompactionConfig",
66
+ "EntropyConfig",
67
+ "GenerationConfig",
68
+ "LibraryConfig",
69
+ "ModelConfig",
70
+ "ModelsConfig",
71
+ "RoutingConfig",
72
+ "TierConfig",
73
+ # Orchestrator
74
+ "BackendFactory",
75
+ "ModelOrchestrator",
76
+ "RoutingResult",
77
+ # Adapters
78
+ "ChatAdapter",
79
+ "get_adapter",
80
+ "register_adapter",
81
+ # MCP
82
+ "BaseMCPServer",
83
+ "BaseTool",
84
+ "InProcessProvider",
85
+ "ServerManager",
86
+ "ServerResponse",
87
+ "ToolRegistry",
88
+ "ToolValidationError",
89
+ "load_tool_definition",
90
+ # Prompts
91
+ "TierIdentity",
92
+ "load_tier_identity",
93
+ ]
@@ -0,0 +1,8 @@
1
+ """
2
+ Allow running as `python -m entropic`.
3
+ """
4
+
5
+ from entropic.cli import main
6
+
7
+ if __name__ == "__main__":
8
+ main()