entroplain 0.1.0 → 0.2.0

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.
package/26.0.1 ADDED
File without changes
package/CONTRIBUTING.md CHANGED
@@ -1,103 +1,103 @@
1
- # Contributing to Entroplain
2
-
3
- Thanks for your interest in contributing! 🎉
4
-
5
- ## Development Setup
6
-
7
- ```bash
8
- # Clone the repo
9
- git clone https://github.com/entroplain/entroplain.git
10
- cd entroplain
11
-
12
- # Create virtual environment
13
- python -m venv .venv
14
- source .venv/bin/activate # On Windows: .venv\Scripts\activate
15
-
16
- # Install in development mode
17
- pip install -e ".[dev]"
18
-
19
- # Run tests
20
- pytest
21
- ```
22
-
23
- ## Project Structure
24
-
25
- ```
26
- entroplain/
27
- ├── entroplain/
28
- │ ├── __init__.py # Package exports
29
- │ ├── monitor.py # Core entropy monitor
30
- │ ├── providers.py # LLM provider integrations
31
- │ ├── hooks.py # Agent framework hooks
32
- │ └── cli.py # Command-line interface
33
- ├── tests/
34
- │ └── test_monitor.py # Unit tests
35
- ├── pyproject.toml # Package config
36
- ├── README.md # Documentation
37
- └── LICENSE # MIT License
38
- ```
39
-
40
- ## Adding a New Provider
41
-
42
- 1. Create a new provider class in `providers.py`:
43
-
44
- ```python
45
- class MyProvider(BaseProvider):
46
- def calculate_entropy(self, logprobs_data: Dict) -> float:
47
- # Parse provider-specific format
48
- ...
49
-
50
- def stream_with_entropy(self, **kwargs) -> Iterator[TokenWithEntropy]:
51
- # Stream tokens with entropy
52
- ...
53
- ```
54
-
55
- 2. Export it in `__init__.py`
56
-
57
- 3. Add tests in `tests/test_providers.py`
58
-
59
- ## Code Style
60
-
61
- - Use **Black** for formatting
62
- - Use **isort** for imports
63
- - Use **mypy** for type checking
64
-
65
- ```bash
66
- black entroplain/ tests/
67
- isort entroplain/ tests/
68
- mypy entroplain/
69
- ```
70
-
71
- ## Testing
72
-
73
- Run all tests:
74
-
75
- ```bash
76
- pytest
77
- ```
78
-
79
- Run with coverage:
80
-
81
- ```bash
82
- pytest --cov=entroplain
83
- ```
84
-
85
- ## Pull Request Process
86
-
87
- 1. Fork the repo
88
- 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
89
- 3. Make your changes
90
- 4. Add tests for new functionality
91
- 5. Ensure all tests pass (`pytest`)
92
- 6. Format code (`black .`)
93
- 7. Commit changes (`git commit -m 'Add amazing feature'`)
94
- 8. Push to branch (`git push origin feature/amazing-feature`)
95
- 9. Open a Pull Request
96
-
97
- ## Questions?
98
-
99
- Open an issue or join our Discord: https://discord.gg/entroplain
100
-
101
- ## License
102
-
103
- By contributing, you agree that your contributions will be licensed under the MIT License.
1
+ # Contributing to Entroplain
2
+
3
+ Thanks for your interest in contributing! 🎉
4
+
5
+ ## Development Setup
6
+
7
+ ```bash
8
+ # Clone the repo
9
+ git clone https://github.com/entroplain/entroplain.git
10
+ cd entroplain
11
+
12
+ # Create virtual environment
13
+ python -m venv .venv
14
+ source .venv/bin/activate # On Windows: .venv\Scripts\activate
15
+
16
+ # Install in development mode
17
+ pip install -e ".[dev]"
18
+
19
+ # Run tests
20
+ pytest
21
+ ```
22
+
23
+ ## Project Structure
24
+
25
+ ```
26
+ entroplain/
27
+ ├── entroplain/
28
+ │ ├── __init__.py # Package exports
29
+ │ ├── monitor.py # Core entropy monitor
30
+ │ ├── providers.py # LLM provider integrations
31
+ │ ├── hooks.py # Agent framework hooks
32
+ │ └── cli.py # Command-line interface
33
+ ├── tests/
34
+ │ └── test_monitor.py # Unit tests
35
+ ├── pyproject.toml # Package config
36
+ ├── README.md # Documentation
37
+ └── LICENSE # MIT License
38
+ ```
39
+
40
+ ## Adding a New Provider
41
+
42
+ 1. Create a new provider class in `providers.py`:
43
+
44
+ ```python
45
+ class MyProvider(BaseProvider):
46
+ def calculate_entropy(self, logprobs_data: Dict) -> float:
47
+ # Parse provider-specific format
48
+ ...
49
+
50
+ def stream_with_entropy(self, **kwargs) -> Iterator[TokenWithEntropy]:
51
+ # Stream tokens with entropy
52
+ ...
53
+ ```
54
+
55
+ 2. Export it in `__init__.py`
56
+
57
+ 3. Add tests in `tests/test_providers.py`
58
+
59
+ ## Code Style
60
+
61
+ - Use **Black** for formatting
62
+ - Use **isort** for imports
63
+ - Use **mypy** for type checking
64
+
65
+ ```bash
66
+ black entroplain/ tests/
67
+ isort entroplain/ tests/
68
+ mypy entroplain/
69
+ ```
70
+
71
+ ## Testing
72
+
73
+ Run all tests:
74
+
75
+ ```bash
76
+ pytest
77
+ ```
78
+
79
+ Run with coverage:
80
+
81
+ ```bash
82
+ pytest --cov=entroplain
83
+ ```
84
+
85
+ ## Pull Request Process
86
+
87
+ 1. Fork the repo
88
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
89
+ 3. Make your changes
90
+ 4. Add tests for new functionality
91
+ 5. Ensure all tests pass (`pytest`)
92
+ 6. Format code (`black .`)
93
+ 7. Commit changes (`git commit -m 'Add amazing feature'`)
94
+ 8. Push to branch (`git push origin feature/amazing-feature`)
95
+ 9. Open a Pull Request
96
+
97
+ ## Questions?
98
+
99
+ Open an issue
100
+
101
+ ## License
102
+
103
+ By contributing, you agree that your contributions will be licensed under the MIT License.
package/README.md CHANGED
@@ -12,7 +12,7 @@ Entroplain monitors your LLM's **predictive entropy** — the uncertainty in its
12
12
 
13
13
  ```text
14
14
  High entropy → Model is searching, exploring, uncertain
15
- Low entropy → Model is confident, converged, ready to output
15
+ Low entropy → Model is confident, converged, ready to output
16
16
  ```
17
17
 
18
18
  **Key insight:** Reasoning follows a multi-modal entropy trajectory. Local minima ("valleys") mark reasoning milestones. Exit at the right valley, save 40-60% compute with minimal accuracy loss.
@@ -38,6 +38,7 @@ npm install entroplain
38
38
  **Node.js:** 18+
39
39
 
40
40
  **For cloud providers:** Set API keys via environment variables:
41
+
41
42
  ```bash
42
43
  export OPENAI_API_KEY=sk-...
43
44
  export ANTHROPIC_API_KEY=sk-ant-...
@@ -46,20 +47,127 @@ export NVIDIA_API_KEY=nvapi-...
46
47
 
47
48
  **For local models:** Install [Ollama](https://ollama.ai) or [llama.cpp](https://github.com/ggerganov/llama.cpp)
48
49
 
49
- ### Use with Any Agent
50
+ ---
51
+
52
+ ## 🚀 Works With Any Agent (Proxy Method)
53
+
54
+ The **proxy** is the easiest way to use Entroplain with OpenClaw, Claude Code, or any other agent framework:
55
+
56
+ ### How It Works
57
+
58
+ ```
59
+ Your Agent → Proxy (localhost:8765) → Real API
60
+
61
+
62
+ Entropy Monitor
63
+
64
+
65
+ Early Exit Check
66
+ ```
67
+
68
+ The proxy intercepts all LLM API calls, monitors entropy, and terminates streams when reasoning converges.
69
+
70
+ ### Setup (One-Time)
71
+
72
+ ```bash
73
+ # Install with proxy support
74
+ pip install entroplain[proxy]
75
+
76
+ # Start the proxy
77
+ entroplain-proxy --port 8765 --log-entropy
78
+
79
+ # Point your agent to the proxy
80
+ export OPENAI_BASE_URL=http://localhost:8765/v1
81
+
82
+ # or for NVIDIA:
83
+ export NVIDIA_BASE_URL=http://localhost:8765/v1
84
+
85
+ # or for Anthropic:
86
+ export ANTHROPIC_BASE_URL=http://localhost:8765/v1
87
+ ```
88
+
89
+ That's it! Now run your agent normally and entropy monitoring is automatic.
90
+
91
+ ### Proxy Options
92
+
93
+ ```bash
94
+ # Monitor only, don't exit early
95
+ entroplain-proxy --port 8765 --no-early-exit
96
+
97
+ # Custom thresholds
98
+ entroplain-proxy --port 8765 --entropy-threshold 0.2 --min-valleys 3
99
+
100
+ # Enable cost tracking
101
+ entroplain-proxy --port 8765 --model gpt-4o --log-entropy
102
+
103
+ # Launch dashboard
104
+ entroplain-dashboard --port 8050
105
+ ```
106
+
107
+ ---
108
+
109
+ ## 🎯 Dashboard
110
+
111
+ Real-time entropy visualization:
112
+
113
+ ```bash
114
+ # Start the dashboard
115
+ entroplain-dashboard --port 8050
116
+
117
+ # Open in browser
118
+ open http://localhost:8050
119
+ ```
120
+
121
+ The dashboard shows:
122
+ - **Live entropy curve** with valley markers
123
+ - **Token count** and valleys detected
124
+ - **Cost savings** in real-time
125
+ - **Status badges** (active/idle/exited)
126
+
127
+ ---
128
+
129
+ ## 💰 Cost Tracking
130
+
131
+ Track actual savings from early exit:
50
132
 
51
133
  ```python
52
- from entroplain import EntropyMonitor
134
+ from entroplain import CostTracker
135
+
136
+ tracker = CostTracker(model="gpt-4o")
137
+ tracker.track_input(100) # 100 input tokens
138
+ tracker.track_output(50) # 50 output tokens
139
+ tracker.set_full_estimate(150) # Would have been 150
140
+
141
+ estimate = tracker.get_estimate()
142
+ print(f"Saved ${estimate.cost_saved_usd:.4f} ({estimate.savings_percent:.1f}%)")
143
+ ```
144
+
145
+ **Supported pricing:** GPT-4o, GPT-4-turbo, Claude 4, Llama 3.1 (NVIDIA), or custom rates.
146
+
147
+ ---
148
+
149
+ ## Direct Usage (Python)
150
+
151
+ If you want more control, use Entroplain directly:
152
+
153
+ ```python
154
+ from entroplain import EntropyMonitor, NVIDIAProvider
53
155
 
54
156
  monitor = EntropyMonitor()
157
+ provider = NVIDIAProvider()
158
+
159
+ for token in provider.stream_with_entropy(
160
+ model="meta/llama-3.1-70b-instruct",
161
+ messages=[{"role": "user", "content": "Solve: x^2 = 16"}]
162
+ ):
163
+ monitor.track(token.token, token.entropy)
164
+ print(token.token, end="")
55
165
 
56
- # Stream tokens with entropy tracking
57
- async for token, entropy in monitor.stream(agent.generate()):
58
- print(f"{token} (entropy: {entropy:.3f})")
59
-
60
- # Detect reasoning convergence
61
- if monitor.is_converged():
62
- break # Early exit — reasoning complete
166
+ if monitor.should_exit():
167
+ print("\n[Early exit - reasoning converged]")
168
+ break
169
+
170
+ print(f"\nStats: {monitor.get_stats()}")
63
171
  ```
64
172
 
65
173
  ---
@@ -80,8 +188,8 @@ Local minima in the entropy trajectory indicate reasoning milestones:
80
188
 
81
189
  ```text
82
190
  Entropy: 0.8 → 0.6 → 0.3* → 0.5 → 0.2* → 0.1*
83
-
84
- Valley 1 Valley 2
191
+
192
+ Valley 1 Valley 2
85
193
  ```
86
194
 
87
195
  ### 3. Exit at the Right Moment
@@ -90,6 +198,28 @@ When valley count plateaus and velocity stabilizes, reasoning is complete.
90
198
 
91
199
  ---
92
200
 
201
+ ## Exit Strategies
202
+
203
+ Choose how Entroplain detects convergence:
204
+
205
+ | Strategy | Description |
206
+ |----------|-------------|
207
+ | `combined` | Entropy low OR valleys plateau, AND velocity stable (default) |
208
+ | `valleys_plateau` | Exit when reasoning milestones stabilize |
209
+ | `entropy_drop` | Exit when model confidence is high |
210
+ | `velocity_zero` | Exit when entropy stops changing |
211
+ | `repetition` | Exit when model starts repeating itself |
212
+ | `confidence` | Exit when top token prob > 95% for N tokens |
213
+
214
+ ```python
215
+ monitor = EntropyMonitor(
216
+ exit_condition="repetition", # or "confidence", "combined", etc.
217
+ repetition_threshold=0.3, # Exit when 30% of recent tokens repeat
218
+ )
219
+ ```
220
+
221
+ ---
222
+
93
223
  ## Experimental Evidence
94
224
 
95
225
  Tested on Llama-3.1-70b via NVIDIA API:
@@ -140,11 +270,11 @@ for chunk in response:
140
270
  if chunk.choices[0].delta.content:
141
271
  token = chunk.choices[0].delta.content
142
272
  entropy = monitor.calculate_entropy(chunk.choices[0].logprobs)
143
-
273
+
144
274
  if monitor.should_exit():
145
275
  print("\n[Early exit — reasoning converged]")
146
276
  break
147
-
277
+
148
278
  print(token, end="")
149
279
  ```
150
280
 
@@ -156,14 +286,12 @@ from entroplain import EntropyMonitor
156
286
 
157
287
  monitor = EntropyMonitor()
158
288
 
159
- # Ollama exposes logits for local models
160
289
  response = ollama.generate(
161
290
  model="llama3.1",
162
291
  prompt="Think through this carefully...",
163
292
  options={"num_ctx": 4096}
164
293
  )
165
294
 
166
- # Direct access to token probabilities
167
295
  for token_data in response.get("token_probs", []):
168
296
  entropy = monitor.calculate_from_logits(token_data["logits"])
169
297
  monitor.track(token_data["token"], entropy)
@@ -185,88 +313,32 @@ with client.messages.stream(
185
313
  ) as stream:
186
314
  for text in stream.text_stream:
187
315
  entropy = monitor.get_entropy()
316
+
188
317
  if monitor.should_exit():
189
318
  break
190
- print(text, end="", flush=True)
191
- ```
192
-
193
- ### Agent Frameworks
194
-
195
- **OpenClaw:**
196
-
197
- ```python
198
- # In your agent config
199
- entropy_monitor:
200
- enabled: true
201
- exit_threshold: 0.15 # Exit when entropy drops below this
202
- min_valleys: 3 # Require at least N reasoning milestones
203
- ```
204
-
205
- **Claude Code:**
206
319
 
207
- ```json
208
- {
209
- "hooks": {
210
- "on_token": "entroplain.hooks.track_entropy",
211
- "on_converge": "entroplain.hooks.early_exit"
212
- }
213
- }
214
- ```
215
-
216
- ---
217
-
218
- ## Configuration
219
-
220
- ### Environment Variables
221
-
222
- ```bash
223
- # For cloud providers
224
- ENTROPPLAIN_OPENAI_API_KEY=sk-...
225
- ENTROPPLAIN_ANTHROPIC_API_KEY=sk-ant-...
226
- ENTROPPLAIN_NVIDIA_API_KEY=nvapi-...
227
-
228
- # For local models
229
- ENTROPPLAIN_LOCAL_PROVIDER=ollama # or llama.cpp
230
- ENTROPPLAIN_LOCAL_MODEL=llama3.1
231
- ```
232
-
233
- ### Exit Conditions
234
-
235
- ```python
236
- monitor = EntropyMonitor(
237
- # Exit when entropy drops below threshold
238
- entropy_threshold=0.15,
239
-
240
- # Require minimum valleys before exit
241
- min_valleys=2,
242
-
243
- # Exit when velocity stabilizes (change < this)
244
- velocity_threshold=0.05,
245
-
246
- # Don't exit before N tokens
247
- min_tokens=50,
248
-
249
- # Custom exit condition
250
- exit_condition="valleys_plateau" # or "entropy_drop", "velocity_zero"
251
- )
320
+ print(text, end="", flush=True)
252
321
  ```
253
322
 
254
323
  ---
255
324
 
256
- ## CLI Usage
325
+ ## CLI
257
326
 
258
327
  ```bash
259
328
  # Analyze a prompt's entropy trajectory
260
329
  entroplain analyze "What is 2+2?" --model gpt-4o
261
330
 
262
331
  # Stream with early exit
263
- entroplain stream "Solve this step by step: x^2 = 16" --exit-on-converge
332
+ entroplain stream "Explain quantum computing" --exit-on-converge
333
+
334
+ # Run the proxy (works with any agent)
335
+ entroplain-proxy --port 8765 --log-entropy --model gpt-4o
336
+
337
+ # Launch the dashboard
338
+ entroplain-dashboard --port 8050
264
339
 
265
340
  # Benchmark entropy patterns
266
341
  entroplain benchmark --problems gsm8k --output results.json
267
-
268
- # Visualize entropy trajectory
269
- entroplain visualize results.json --output entropy_plot.png
270
342
  ```
271
343
 
272
344
  ---
@@ -282,45 +354,60 @@ class EntropyMonitor:
282
354
  entropy_threshold: float = 0.15,
283
355
  min_valleys: int = 2,
284
356
  velocity_threshold: float = 0.05,
285
- min_tokens: int = 50
286
- ): ...
287
-
288
- def calculate_entropy(self, logprobs: List[float]) -> float:
289
- """Calculate Shannon entropy from log probabilities."""
290
-
291
- def track(self, token: str, entropy: float) -> None:
357
+ min_tokens: int = 50,
358
+ exit_condition: str = "combined"
359
+ ):
360
+ ...
361
+
362
+ def track(self, token: str, entropy: float, confidence: float = 0.0) -> EntropyPoint:
292
363
  """Track a token and its entropy value."""
293
-
294
- def get_valleys(self) -> List[Tuple[int, float]]:
295
- """Get all entropy valleys (local minima)."""
296
-
297
- def get_velocity(self) -> float:
298
- """Get current entropy velocity (rate of change)."""
299
-
364
+
300
365
  def should_exit(self) -> bool:
301
366
  """Determine if reasoning has converged."""
302
-
303
- def is_converged(self) -> bool:
304
- """Alias for should_exit()."""
305
-
306
- def get_trajectory(self) -> List[float]:
307
- """Get full entropy trajectory."""
308
-
367
+
368
+ def get_valleys(self) -> List[Tuple[int, float]]:
369
+ """Get all entropy valleys (local minima)."""
370
+
371
+ def get_stats(self) -> Dict:
372
+ """Get current statistics."""
373
+
309
374
  def reset(self) -> None:
310
375
  """Clear all tracked data."""
311
376
  ```
312
377
 
313
- ### `calculate_entropy(logprobs)`
378
+ ### `CostTracker`
314
379
 
315
380
  ```python
316
- from entroplain import calculate_entropy
381
+ class CostTracker:
382
+ def __init__(self, model: str = "default"):
383
+ ...
384
+
385
+ def track_input(self, tokens: int):
386
+ """Track input tokens."""
317
387
 
318
- # From log probabilities
319
- entropy = calculate_entropy([-0.5, -2.1, -0.1, -5.2])
320
- # Returns: 0.847
388
+ def track_output(self, tokens: int):
389
+ """Track output tokens."""
321
390
 
322
- # From probabilities
323
- entropy = calculate_entropy([0.6, 0.125, 0.9, 0.005], from_probs=True)
391
+ def set_full_estimate(self, tokens: int):
392
+ """Set estimated output if no early exit."""
393
+
394
+ def get_estimate(self) -> CostEstimate:
395
+ """Get cost estimate with savings."""
396
+ ```
397
+
398
+ ### `EntropyProxy`
399
+
400
+ ```bash
401
+ # Run the proxy
402
+ entroplain-proxy --port 8765 --log-entropy --model gpt-4o
403
+
404
+ # Options
405
+ --entropy-threshold 0.15 # Exit threshold
406
+ --min-valleys 2 # Minimum valleys
407
+ --no-early-exit # Monitor only, don't exit
408
+ --log-entropy # Log entropy values
409
+ --model gpt-4o # Model for cost tracking
410
+ --no-cost-tracking # Disable cost tracking
324
411
  ```
325
412
 
326
413
  ---
@@ -329,7 +416,9 @@ entropy = calculate_entropy([0.6, 0.125, 0.9, 0.005], from_probs=True)
329
416
 
330
417
  ### Paper
331
418
 
332
- See [`paper.md`](./paper.md) for the full research proposal: **"Entropy-Based Early Exit for Efficient Agent Reasoning"**
419
+ See [`paper.md`](./paper.md) for the full research proposal:
420
+
421
+ **"Entropy-Based Early Exit for Efficient Agent Reasoning"**
333
422
 
334
423
  ### Key Findings
335
424
 
@@ -350,17 +439,6 @@ See [`paper.md`](./paper.md) for the full research proposal: **"Entropy-Based Ea
350
439
 
351
440
  ---
352
441
 
353
- ## Roadmap
354
-
355
- - [ ] v0.1.0 — Core entropy tracking (Python)
356
- - [ ] v0.2.0 — Multi-provider support (OpenAI, Anthropic, Gemini, NVIDIA)
357
- - [ ] v0.3.0 — Local model support (llama.cpp, Ollama)
358
- - [ ] v0.4.0 — Agent framework integrations (OpenClaw, Claude Code)
359
- - [ ] v0.5.0 — JavaScript/Node.js SDK
360
- - [ ] v1.0.0 — Production release with benchmarks
361
-
362
- ---
363
-
364
442
  ## Contributing
365
443
 
366
444
  We welcome contributions! See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
@@ -382,6 +460,15 @@ MIT License — see [LICENSE](./LICENSE) for details.
382
460
 
383
461
  ---
384
462
 
463
+ ## Links
464
+
465
+ - **PyPI:** https://pypi.org/project/entroplain/
466
+ - **npm:** https://www.npmjs.com/package/entroplain
467
+ - **GitHub:** https://github.com/entroplain/entroplain
468
+ - **Issues:** https://github.com/entroplain/entroplain/issues
469
+
470
+ ---
471
+
385
472
  ## Acknowledgments
386
473
 
387
474
  - Research inspired by early exit architectures in transformers
Binary file