loopgain 0.4.0__tar.gz → 0.4.1__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.
- {loopgain-0.4.0 → loopgain-0.4.1}/PKG-INFO +13 -23
- {loopgain-0.4.0 → loopgain-0.4.1}/README.md +11 -21
- {loopgain-0.4.0 → loopgain-0.4.1}/loopgain/_version.py +1 -1
- {loopgain-0.4.0 → loopgain-0.4.1}/loopgain.egg-info/PKG-INFO +13 -23
- {loopgain-0.4.0 → loopgain-0.4.1}/pyproject.toml +9 -2
- {loopgain-0.4.0 → loopgain-0.4.1}/LICENSE +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/loopgain/__init__.py +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/loopgain/__main__.py +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/loopgain/classifier.py +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/loopgain/cli.py +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/loopgain/core.py +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/loopgain/funnel.py +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/loopgain/integrations/__init__.py +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/loopgain/integrations/autogen.py +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/loopgain/integrations/claude_agent_sdk.py +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/loopgain/integrations/crewai.py +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/loopgain/integrations/langchain.py +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/loopgain/integrations/langgraph.py +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/loopgain/integrations/openai_agents.py +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/loopgain/telemetry.py +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/loopgain.egg-info/SOURCES.txt +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/loopgain.egg-info/dependency_links.txt +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/loopgain.egg-info/entry_points.txt +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/loopgain.egg-info/requires.txt +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/loopgain.egg-info/top_level.txt +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/setup.cfg +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/tests/test_classifier_mock_validation.py +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/tests/test_classifier_synthetic.py +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/tests/test_core.py +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/tests/test_funnel.py +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/tests/test_integrations.py +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/tests/test_stress.py +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/tests/test_telemetry.py +0 -0
- {loopgain-0.4.0 → loopgain-0.4.1}/tests/test_termination_safety.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: loopgain
|
|
3
|
-
Version: 0.4.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.4.1
|
|
4
|
+
Summary: An open-source cost controller for AI agent loops. Stops a loop when it has actually converged and rolls back before it degrades — replacing the max_iterations guess with a real-time loop-gain (Aβ) monitor with five named threshold bands and best-so-far rollback.
|
|
5
5
|
Author-email: Dave Fitzsimmons <hello@loopgain.ai>
|
|
6
6
|
License: Apache-2.0
|
|
7
7
|
Project-URL: Homepage, https://loopgain.ai
|
|
@@ -49,14 +49,16 @@ Dynamic: license-file
|
|
|
49
49
|
|
|
50
50
|
# LoopGain
|
|
51
51
|
|
|
52
|
-
**
|
|
52
|
+
**An open-source cost controller for AI agent loops.**
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
AI agent loops waste time and money when they don't know when to stop. LoopGain measures the loop in real time and stops it the moment it has actually converged — and rolls back before it degrades — instead of running to a fixed `max_iterations` cap.
|
|
55
|
+
|
|
56
|
+
> **Across 2,000 paired trials over 10 cells**, LoopGain reduced total API spend by **92.8%** vs `max_iter=20`, dropped median wall-clock latency from 30.9s to 2.1s (**~15×**), preserved output quality on natural-distribution workloads (W1–W4: judge winrate 0.50–0.63, CI excluding null on most cells), and improved output quality on engineered-failure workloads (W5: winrate 0.92–0.95 across three adapters). Weighted-average pairwise preference for LG vs B20 across 1,800 judge comparisons: **0.678**. Zero of six kill criteria fired.
|
|
55
57
|
|
|
56
58
|
[](https://pypi.org/project/loopgain/)
|
|
57
59
|
[](https://pypi.org/project/loopgain/)
|
|
58
60
|
[](LICENSE)
|
|
59
|
-
[](tests/)
|
|
60
62
|
|
|
61
63
|
**Home:** [loopgain.ai](https://loopgain.ai)
|
|
62
64
|
|
|
@@ -68,7 +70,7 @@ Works for **any iterative AI workflow with a measurable error signal** — verif
|
|
|
68
70
|
|
|
69
71
|
## Why
|
|
70
72
|
|
|
71
|
-
Production agent loops universally use `max_iterations=N` as their termination policy. It's the embarrassing default of agentic AI: you either waste compute (loop stops too late) or ship bad output (loop stops too early). LoopGain replaces it with a control-theoretic
|
|
73
|
+
Production agent loops universally use `max_iterations=N` as their termination policy. It's the embarrassing default of agentic AI: you either waste compute (loop stops too late) or ship bad output (loop stops too early). LoopGain replaces it with a control-theoretic stop-and-rollback policy grounded in the **Barkhausen criterion** — a foundational result from electrical-engineering feedback-oscillator analysis (1921).
|
|
72
74
|
|
|
73
75
|
---
|
|
74
76
|
|
|
@@ -145,7 +147,7 @@ It routes the trajectory into one of five named states:
|
|
|
145
147
|
|
|
146
148
|
| State | Condition | Action |
|
|
147
149
|
| --- | --- | --- |
|
|
148
|
-
| `FAST_CONVERGE` | cumulative reduction to ≤ 10% of E_first | Continue
|
|
150
|
+
| `FAST_CONVERGE` | cumulative reduction to ≤ 10% of E_first | Continue |
|
|
149
151
|
| `CONVERGING` | negative slope with `p < 0.05`, OR cumulative ≤ 50% | Continue, watch for upward drift |
|
|
150
152
|
| `STALLING` | no significant slope, no detectable oscillation | Stop after 2 consecutive readings — return best-so-far |
|
|
151
153
|
| `OSCILLATING` | high residual variance with flat trend | Stop — return best-so-far |
|
|
@@ -161,18 +163,6 @@ The decision is **conservative by design**: requiring both statistical significa
|
|
|
161
163
|
|
|
162
164
|
---
|
|
163
165
|
|
|
164
|
-
## ETA prediction
|
|
165
|
-
|
|
166
|
-
When the loop is converging (`Aβ_smooth < 1`), LoopGain produces a closed-form prediction of iterations remaining:
|
|
167
|
-
|
|
168
|
-
```
|
|
169
|
-
n_remaining = log(E_target / E_current) / log(Aβ_smooth)
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
Available as `lg.eta` mid-loop. Returns `None` when the prediction isn't well-defined (no Aβ yet, target zero, or non-converging gain).
|
|
173
|
-
|
|
174
|
-
---
|
|
175
|
-
|
|
176
166
|
## Best-so-far rollback
|
|
177
167
|
|
|
178
168
|
LoopGain keeps a buffer of all observed outputs paired with their error scores. On termination it returns `argmin(error)`, not the last iteration:
|
|
@@ -189,10 +179,10 @@ This transforms divergence detection from "abort with garbage" into "abort with
|
|
|
189
179
|
|
|
190
180
|
## What LoopGain does and doesn't guarantee
|
|
191
181
|
|
|
192
|
-
LoopGain saves money by stopping a loop once it stops improving — fewer iterations, fewer tokens. In our [public benchmark](https://github.com/loopgain-ai/loopgain-bench), that was a **
|
|
182
|
+
LoopGain saves money by stopping a loop once it stops improving — fewer iterations, fewer tokens. In our [public benchmark](https://github.com/loopgain-ai/loopgain-bench), that was a **92.8% median cut in API spend** vs `max_iterations=20`, with output quality preserved. Two honest limits:
|
|
193
183
|
|
|
194
|
-
- **Savings depend on your workload.** Loops that usually succeed fast save the most (~96%); adversarial, failure-prone loops save less (~84%). The headline is a blend — run the benchmark on your own loops before quoting a number.
|
|
195
|
-
- **LoopGain detects convergence, not correctness.** It stops when your error signal stops improving — which means more iterations won't help, *not* that the loop succeeded. On the benchmark this preserved quality (it rarely stopped early on a worse output; false-stop rate ≤
|
|
184
|
+
- **Savings depend on your workload.** Loops that usually succeed fast save the most (~96%); adversarial, failure-prone loops save less (~78–84%). The headline is a blend — run the benchmark on your own loops before quoting a number.
|
|
185
|
+
- **LoopGain detects convergence, not correctness.** It stops when your error signal stops improving — which means more iterations won't help, *not* that the loop succeeded. On the benchmark this preserved quality (it rarely stopped early on a worse output; false-stop rate ≤4.5%), but a loop can stall with the error still above zero — a plateau at, say, 2 failing tests. So check `result.best_error` (or your own pass/fail) before you trust the output: if it plateaued short of your target, that's a quality gap LoopGain can't see, and a false stop that forces a rerun is the one way it eats into the savings. LoopGain decides *when to stop*; you decide *whether the answer is good enough*.
|
|
196
186
|
|
|
197
187
|
---
|
|
198
188
|
|
|
@@ -224,7 +214,7 @@ Current state name. One of `INIT`, `FAST_CONVERGE`, `CONVERGING`, `STALLING`, `O
|
|
|
224
214
|
|
|
225
215
|
### `lg.eta -> int | None`
|
|
226
216
|
|
|
227
|
-
|
|
217
|
+
Best-effort closed-form estimate of iterations remaining, exposed for instrumentation. Returns `None` whenever it isn't well-defined — which is most of the time on real, jump-dominated loops, so don't depend on it for control.
|
|
228
218
|
|
|
229
219
|
### `lg.gain_margin -> float | None`
|
|
230
220
|
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
# LoopGain
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**An open-source cost controller for AI agent loops.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
AI agent loops waste time and money when they don't know when to stop. LoopGain measures the loop in real time and stops it the moment it has actually converged — and rolls back before it degrades — instead of running to a fixed `max_iterations` cap.
|
|
6
|
+
|
|
7
|
+
> **Across 2,000 paired trials over 10 cells**, LoopGain reduced total API spend by **92.8%** vs `max_iter=20`, dropped median wall-clock latency from 30.9s to 2.1s (**~15×**), preserved output quality on natural-distribution workloads (W1–W4: judge winrate 0.50–0.63, CI excluding null on most cells), and improved output quality on engineered-failure workloads (W5: winrate 0.92–0.95 across three adapters). Weighted-average pairwise preference for LG vs B20 across 1,800 judge comparisons: **0.678**. Zero of six kill criteria fired.
|
|
6
8
|
|
|
7
9
|
[](https://pypi.org/project/loopgain/)
|
|
8
10
|
[](https://pypi.org/project/loopgain/)
|
|
9
11
|
[](LICENSE)
|
|
10
|
-
[](tests/)
|
|
11
13
|
|
|
12
14
|
**Home:** [loopgain.ai](https://loopgain.ai)
|
|
13
15
|
|
|
@@ -19,7 +21,7 @@ Works for **any iterative AI workflow with a measurable error signal** — verif
|
|
|
19
21
|
|
|
20
22
|
## Why
|
|
21
23
|
|
|
22
|
-
Production agent loops universally use `max_iterations=N` as their termination policy. It's the embarrassing default of agentic AI: you either waste compute (loop stops too late) or ship bad output (loop stops too early). LoopGain replaces it with a control-theoretic
|
|
24
|
+
Production agent loops universally use `max_iterations=N` as their termination policy. It's the embarrassing default of agentic AI: you either waste compute (loop stops too late) or ship bad output (loop stops too early). LoopGain replaces it with a control-theoretic stop-and-rollback policy grounded in the **Barkhausen criterion** — a foundational result from electrical-engineering feedback-oscillator analysis (1921).
|
|
23
25
|
|
|
24
26
|
---
|
|
25
27
|
|
|
@@ -96,7 +98,7 @@ It routes the trajectory into one of five named states:
|
|
|
96
98
|
|
|
97
99
|
| State | Condition | Action |
|
|
98
100
|
| --- | --- | --- |
|
|
99
|
-
| `FAST_CONVERGE` | cumulative reduction to ≤ 10% of E_first | Continue
|
|
101
|
+
| `FAST_CONVERGE` | cumulative reduction to ≤ 10% of E_first | Continue |
|
|
100
102
|
| `CONVERGING` | negative slope with `p < 0.05`, OR cumulative ≤ 50% | Continue, watch for upward drift |
|
|
101
103
|
| `STALLING` | no significant slope, no detectable oscillation | Stop after 2 consecutive readings — return best-so-far |
|
|
102
104
|
| `OSCILLATING` | high residual variance with flat trend | Stop — return best-so-far |
|
|
@@ -112,18 +114,6 @@ The decision is **conservative by design**: requiring both statistical significa
|
|
|
112
114
|
|
|
113
115
|
---
|
|
114
116
|
|
|
115
|
-
## ETA prediction
|
|
116
|
-
|
|
117
|
-
When the loop is converging (`Aβ_smooth < 1`), LoopGain produces a closed-form prediction of iterations remaining:
|
|
118
|
-
|
|
119
|
-
```
|
|
120
|
-
n_remaining = log(E_target / E_current) / log(Aβ_smooth)
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
Available as `lg.eta` mid-loop. Returns `None` when the prediction isn't well-defined (no Aβ yet, target zero, or non-converging gain).
|
|
124
|
-
|
|
125
|
-
---
|
|
126
|
-
|
|
127
117
|
## Best-so-far rollback
|
|
128
118
|
|
|
129
119
|
LoopGain keeps a buffer of all observed outputs paired with their error scores. On termination it returns `argmin(error)`, not the last iteration:
|
|
@@ -140,10 +130,10 @@ This transforms divergence detection from "abort with garbage" into "abort with
|
|
|
140
130
|
|
|
141
131
|
## What LoopGain does and doesn't guarantee
|
|
142
132
|
|
|
143
|
-
LoopGain saves money by stopping a loop once it stops improving — fewer iterations, fewer tokens. In our [public benchmark](https://github.com/loopgain-ai/loopgain-bench), that was a **
|
|
133
|
+
LoopGain saves money by stopping a loop once it stops improving — fewer iterations, fewer tokens. In our [public benchmark](https://github.com/loopgain-ai/loopgain-bench), that was a **92.8% median cut in API spend** vs `max_iterations=20`, with output quality preserved. Two honest limits:
|
|
144
134
|
|
|
145
|
-
- **Savings depend on your workload.** Loops that usually succeed fast save the most (~96%); adversarial, failure-prone loops save less (~84%). The headline is a blend — run the benchmark on your own loops before quoting a number.
|
|
146
|
-
- **LoopGain detects convergence, not correctness.** It stops when your error signal stops improving — which means more iterations won't help, *not* that the loop succeeded. On the benchmark this preserved quality (it rarely stopped early on a worse output; false-stop rate ≤
|
|
135
|
+
- **Savings depend on your workload.** Loops that usually succeed fast save the most (~96%); adversarial, failure-prone loops save less (~78–84%). The headline is a blend — run the benchmark on your own loops before quoting a number.
|
|
136
|
+
- **LoopGain detects convergence, not correctness.** It stops when your error signal stops improving — which means more iterations won't help, *not* that the loop succeeded. On the benchmark this preserved quality (it rarely stopped early on a worse output; false-stop rate ≤4.5%), but a loop can stall with the error still above zero — a plateau at, say, 2 failing tests. So check `result.best_error` (or your own pass/fail) before you trust the output: if it plateaued short of your target, that's a quality gap LoopGain can't see, and a false stop that forces a rerun is the one way it eats into the savings. LoopGain decides *when to stop*; you decide *whether the answer is good enough*.
|
|
147
137
|
|
|
148
138
|
---
|
|
149
139
|
|
|
@@ -175,7 +165,7 @@ Current state name. One of `INIT`, `FAST_CONVERGE`, `CONVERGING`, `STALLING`, `O
|
|
|
175
165
|
|
|
176
166
|
### `lg.eta -> int | None`
|
|
177
167
|
|
|
178
|
-
|
|
168
|
+
Best-effort closed-form estimate of iterations remaining, exposed for instrumentation. Returns `None` whenever it isn't well-defined — which is most of the time on real, jump-dominated loops, so don't depend on it for control.
|
|
179
169
|
|
|
180
170
|
### `lg.gain_margin -> float | None`
|
|
181
171
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: loopgain
|
|
3
|
-
Version: 0.4.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.4.1
|
|
4
|
+
Summary: An open-source cost controller for AI agent loops. Stops a loop when it has actually converged and rolls back before it degrades — replacing the max_iterations guess with a real-time loop-gain (Aβ) monitor with five named threshold bands and best-so-far rollback.
|
|
5
5
|
Author-email: Dave Fitzsimmons <hello@loopgain.ai>
|
|
6
6
|
License: Apache-2.0
|
|
7
7
|
Project-URL: Homepage, https://loopgain.ai
|
|
@@ -49,14 +49,16 @@ Dynamic: license-file
|
|
|
49
49
|
|
|
50
50
|
# LoopGain
|
|
51
51
|
|
|
52
|
-
**
|
|
52
|
+
**An open-source cost controller for AI agent loops.**
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
AI agent loops waste time and money when they don't know when to stop. LoopGain measures the loop in real time and stops it the moment it has actually converged — and rolls back before it degrades — instead of running to a fixed `max_iterations` cap.
|
|
55
|
+
|
|
56
|
+
> **Across 2,000 paired trials over 10 cells**, LoopGain reduced total API spend by **92.8%** vs `max_iter=20`, dropped median wall-clock latency from 30.9s to 2.1s (**~15×**), preserved output quality on natural-distribution workloads (W1–W4: judge winrate 0.50–0.63, CI excluding null on most cells), and improved output quality on engineered-failure workloads (W5: winrate 0.92–0.95 across three adapters). Weighted-average pairwise preference for LG vs B20 across 1,800 judge comparisons: **0.678**. Zero of six kill criteria fired.
|
|
55
57
|
|
|
56
58
|
[](https://pypi.org/project/loopgain/)
|
|
57
59
|
[](https://pypi.org/project/loopgain/)
|
|
58
60
|
[](LICENSE)
|
|
59
|
-
[](tests/)
|
|
60
62
|
|
|
61
63
|
**Home:** [loopgain.ai](https://loopgain.ai)
|
|
62
64
|
|
|
@@ -68,7 +70,7 @@ Works for **any iterative AI workflow with a measurable error signal** — verif
|
|
|
68
70
|
|
|
69
71
|
## Why
|
|
70
72
|
|
|
71
|
-
Production agent loops universally use `max_iterations=N` as their termination policy. It's the embarrassing default of agentic AI: you either waste compute (loop stops too late) or ship bad output (loop stops too early). LoopGain replaces it with a control-theoretic
|
|
73
|
+
Production agent loops universally use `max_iterations=N` as their termination policy. It's the embarrassing default of agentic AI: you either waste compute (loop stops too late) or ship bad output (loop stops too early). LoopGain replaces it with a control-theoretic stop-and-rollback policy grounded in the **Barkhausen criterion** — a foundational result from electrical-engineering feedback-oscillator analysis (1921).
|
|
72
74
|
|
|
73
75
|
---
|
|
74
76
|
|
|
@@ -145,7 +147,7 @@ It routes the trajectory into one of five named states:
|
|
|
145
147
|
|
|
146
148
|
| State | Condition | Action |
|
|
147
149
|
| --- | --- | --- |
|
|
148
|
-
| `FAST_CONVERGE` | cumulative reduction to ≤ 10% of E_first | Continue
|
|
150
|
+
| `FAST_CONVERGE` | cumulative reduction to ≤ 10% of E_first | Continue |
|
|
149
151
|
| `CONVERGING` | negative slope with `p < 0.05`, OR cumulative ≤ 50% | Continue, watch for upward drift |
|
|
150
152
|
| `STALLING` | no significant slope, no detectable oscillation | Stop after 2 consecutive readings — return best-so-far |
|
|
151
153
|
| `OSCILLATING` | high residual variance with flat trend | Stop — return best-so-far |
|
|
@@ -161,18 +163,6 @@ The decision is **conservative by design**: requiring both statistical significa
|
|
|
161
163
|
|
|
162
164
|
---
|
|
163
165
|
|
|
164
|
-
## ETA prediction
|
|
165
|
-
|
|
166
|
-
When the loop is converging (`Aβ_smooth < 1`), LoopGain produces a closed-form prediction of iterations remaining:
|
|
167
|
-
|
|
168
|
-
```
|
|
169
|
-
n_remaining = log(E_target / E_current) / log(Aβ_smooth)
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
Available as `lg.eta` mid-loop. Returns `None` when the prediction isn't well-defined (no Aβ yet, target zero, or non-converging gain).
|
|
173
|
-
|
|
174
|
-
---
|
|
175
|
-
|
|
176
166
|
## Best-so-far rollback
|
|
177
167
|
|
|
178
168
|
LoopGain keeps a buffer of all observed outputs paired with their error scores. On termination it returns `argmin(error)`, not the last iteration:
|
|
@@ -189,10 +179,10 @@ This transforms divergence detection from "abort with garbage" into "abort with
|
|
|
189
179
|
|
|
190
180
|
## What LoopGain does and doesn't guarantee
|
|
191
181
|
|
|
192
|
-
LoopGain saves money by stopping a loop once it stops improving — fewer iterations, fewer tokens. In our [public benchmark](https://github.com/loopgain-ai/loopgain-bench), that was a **
|
|
182
|
+
LoopGain saves money by stopping a loop once it stops improving — fewer iterations, fewer tokens. In our [public benchmark](https://github.com/loopgain-ai/loopgain-bench), that was a **92.8% median cut in API spend** vs `max_iterations=20`, with output quality preserved. Two honest limits:
|
|
193
183
|
|
|
194
|
-
- **Savings depend on your workload.** Loops that usually succeed fast save the most (~96%); adversarial, failure-prone loops save less (~84%). The headline is a blend — run the benchmark on your own loops before quoting a number.
|
|
195
|
-
- **LoopGain detects convergence, not correctness.** It stops when your error signal stops improving — which means more iterations won't help, *not* that the loop succeeded. On the benchmark this preserved quality (it rarely stopped early on a worse output; false-stop rate ≤
|
|
184
|
+
- **Savings depend on your workload.** Loops that usually succeed fast save the most (~96%); adversarial, failure-prone loops save less (~78–84%). The headline is a blend — run the benchmark on your own loops before quoting a number.
|
|
185
|
+
- **LoopGain detects convergence, not correctness.** It stops when your error signal stops improving — which means more iterations won't help, *not* that the loop succeeded. On the benchmark this preserved quality (it rarely stopped early on a worse output; false-stop rate ≤4.5%), but a loop can stall with the error still above zero — a plateau at, say, 2 failing tests. So check `result.best_error` (or your own pass/fail) before you trust the output: if it plateaued short of your target, that's a quality gap LoopGain can't see, and a false stop that forces a rerun is the one way it eats into the savings. LoopGain decides *when to stop*; you decide *whether the answer is good enough*.
|
|
196
186
|
|
|
197
187
|
---
|
|
198
188
|
|
|
@@ -224,7 +214,7 @@ Current state name. One of `INIT`, `FAST_CONVERGE`, `CONVERGING`, `STALLING`, `O
|
|
|
224
214
|
|
|
225
215
|
### `lg.eta -> int | None`
|
|
226
216
|
|
|
227
|
-
|
|
217
|
+
Best-effort closed-form estimate of iterations remaining, exposed for instrumentation. Returns `None` whenever it isn't well-defined — which is most of the time on real, jump-dominated loops, so don't depend on it for control.
|
|
228
218
|
|
|
229
219
|
### `lg.gain_margin -> float | None`
|
|
230
220
|
|
|
@@ -4,8 +4,10 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "loopgain"
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
# Single source of truth: loopgain/_version.py (read dynamically below).
|
|
8
|
+
# Bump the version in that one file per release; this no longer duplicates it.
|
|
9
|
+
dynamic = ["version"]
|
|
10
|
+
description = "An open-source cost controller for AI agent loops. Stops a loop when it has actually converged and rolls back before it degrades — replacing the max_iterations guess with a real-time loop-gain (Aβ) monitor with five named threshold bands and best-so-far rollback."
|
|
9
11
|
authors = [{name = "Dave Fitzsimmons", email = "hello@loopgain.ai"}]
|
|
10
12
|
readme = "README.md"
|
|
11
13
|
license = {text = "Apache-2.0"}
|
|
@@ -100,6 +102,11 @@ all = [
|
|
|
100
102
|
# zero-dep. Install with `pip install 'loopgain[examples]'`.
|
|
101
103
|
examples = ["anthropic>=0.40.0"]
|
|
102
104
|
|
|
105
|
+
[tool.setuptools.dynamic]
|
|
106
|
+
# Reads the literal ``__version__ = "x.y.z"`` from loopgain/_version.py via AST
|
|
107
|
+
# (no import), so pyproject.toml never duplicates the version string.
|
|
108
|
+
version = {attr = "loopgain._version.__version__"}
|
|
109
|
+
|
|
103
110
|
[tool.setuptools.packages.find]
|
|
104
111
|
where = ["."]
|
|
105
112
|
include = ["loopgain*"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|