instar 1.3.63 → 1.3.65
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/dist/commands/reflect.d.ts.map +1 -1
- package/dist/commands/reflect.js +2 -1
- package/dist/commands/reflect.js.map +1 -1
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +16 -4
- package/dist/commands/server.js.map +1 -1
- package/dist/core/CircuitBreakingIntelligenceProvider.d.ts +40 -0
- package/dist/core/CircuitBreakingIntelligenceProvider.d.ts.map +1 -0
- package/dist/core/CircuitBreakingIntelligenceProvider.js +72 -0
- package/dist/core/CircuitBreakingIntelligenceProvider.js.map +1 -0
- package/dist/core/ClaudeCliIntelligenceProvider.d.ts.map +1 -1
- package/dist/core/ClaudeCliIntelligenceProvider.js +5 -2
- package/dist/core/ClaudeCliIntelligenceProvider.js.map +1 -1
- package/dist/core/CodexCliIntelligenceProvider.d.ts.map +1 -1
- package/dist/core/CodexCliIntelligenceProvider.js +3 -1
- package/dist/core/CodexCliIntelligenceProvider.js.map +1 -1
- package/dist/core/LlmCircuitBreaker.d.ts +137 -0
- package/dist/core/LlmCircuitBreaker.d.ts.map +1 -0
- package/dist/core/LlmCircuitBreaker.js +236 -0
- package/dist/core/LlmCircuitBreaker.js.map +1 -0
- package/dist/core/intelligenceProviderFactory.d.ts.map +1 -1
- package/dist/core/intelligenceProviderFactory.js +8 -3
- package/dist/core/intelligenceProviderFactory.js.map +1 -1
- package/dist/core/types.d.ts +22 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/monitoring/RevertDetector.d.ts +52 -0
- package/dist/monitoring/RevertDetector.d.ts.map +1 -0
- package/dist/monitoring/RevertDetector.js +219 -0
- package/dist/monitoring/RevertDetector.js.map +1 -0
- package/dist/server/AgentServer.d.ts +1 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +35 -0
- package/dist/server/AgentServer.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +3 -3
- package/upgrades/1.3.61.md +9 -14
- package/upgrades/1.3.64.md +27 -0
- package/upgrades/1.3.65.md +67 -0
- package/upgrades/side-effects/failure-learning-revert-source.md +41 -0
- package/upgrades/side-effects/llm-ratelimit-circuit-breaker.md +75 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Side-effects review — account-global LLM rate-limit circuit breaker
|
|
2
|
+
|
|
3
|
+
**Scope**: Stop the runaway credit-burn failure mode where an LLM-call loop
|
|
4
|
+
keeps invoking the provider after the account is over its usage/spend limit.
|
|
5
|
+
Motivating incident (2026-05-28): a wild agent burned $452/$455 because
|
|
6
|
+
PromptGate's per-tick Haiku detection loop kept spawning `claude -p` against
|
|
7
|
+
the weekly-limit screen with no backoff on the rate-limit error; the account's
|
|
8
|
+
auto-reload refueled the burn each cycle.
|
|
9
|
+
|
|
10
|
+
Distinct from — and complementary to — the existing volume-based
|
|
11
|
+
token-burn-detection system (BurnDetector + LlmRateGate, ~30-min statistical
|
|
12
|
+
reaction). This breaker reacts in milliseconds to the provider's OWN rate-limit
|
|
13
|
+
signal: once the provider says "over limit," every further call is wasted
|
|
14
|
+
(rejected) or harmful (auto-reload), so we stop immediately.
|
|
15
|
+
|
|
16
|
+
**Files touched**:
|
|
17
|
+
- `src/core/LlmCircuitBreaker.ts` — NEW. Account-global breaker
|
|
18
|
+
(closed/open/half-open, single-probe invariant, configurable open window,
|
|
19
|
+
default 15 min) + the pure exported `isRateLimitError()` classifier + typed
|
|
20
|
+
`RateLimitError` / `LlmCircuitOpenError` + process singleton + `configure()`.
|
|
21
|
+
- `src/core/CircuitBreakingIntelligenceProvider.ts` — NEW. Decorator that gates
|
|
22
|
+
every `evaluate()` on the breaker BEFORE delegating; trips on rate-limit,
|
|
23
|
+
closes on any other outcome; `wrapIntelligenceWithCircuitBreaker()` helper
|
|
24
|
+
(null-safe, idempotent).
|
|
25
|
+
- `src/core/intelligenceProviderFactory.ts` — wrap every provider the factory
|
|
26
|
+
returns (the single chokepoint).
|
|
27
|
+
- `src/commands/server.ts` — `configureLlmCircuitBreaker()` from config at
|
|
28
|
+
startup; wrap the three direct `new ClaudeCliIntelligenceProvider` fallback
|
|
29
|
+
sites.
|
|
30
|
+
- `src/commands/reflect.ts` — wrap its direct fallback site.
|
|
31
|
+
- `src/core/ClaudeCliIntelligenceProvider.ts` / `CodexCliIntelligenceProvider.ts`
|
|
32
|
+
— widen the captured stderr slice 200 → 600 so the rate-limit phrase isn't
|
|
33
|
+
truncated before classification.
|
|
34
|
+
- `src/core/types.ts` — optional `intelligence.circuitBreaker` config block.
|
|
35
|
+
- Tests: `tests/unit/LlmCircuitBreaker.test.ts` (31),
|
|
36
|
+
`tests/unit/CircuitBreakingIntelligenceProvider.test.ts` (6),
|
|
37
|
+
`tests/integration/llm-circuit-breaker-chokepoint.test.ts` (2, real subprocess
|
|
38
|
+
spawn-counter proof of account-global short-circuit).
|
|
39
|
+
|
|
40
|
+
**Under-block** (does it fail to stop something it should?): The breaker only
|
|
41
|
+
trips on errors the classifier recognizes as usage/rate/spend limits. If a
|
|
42
|
+
provider emits limit language the classifier doesn't match, the loop is not
|
|
43
|
+
stopped by THIS layer — but the volume-based BurnDetector remains the backstop.
|
|
44
|
+
The classifier is deliberately broad (429/402, "rate limit", "usage limit",
|
|
45
|
+
"quota", "limit reached/resets", "credit balance too low", "payment required",
|
|
46
|
+
"exceeded …"), and the stderr-slice widening reduces truncation misses.
|
|
47
|
+
|
|
48
|
+
**Over-block** (does it stop something it shouldn't?): A false positive trips
|
|
49
|
+
the breaker and degrades ALL LLM-backed features (PromptGate, PresenceProxy,
|
|
50
|
+
PromiseBeacon, sentinels, reviewers) to heuristic-only for one open window
|
|
51
|
+
(default 15 min), after which a single probe self-heals. The classifier
|
|
52
|
+
excludes generic error/timeout/ENOENT/parse text to avoid this. Worst case from
|
|
53
|
+
a false trip is bounded, reversible, and self-healing — and is strictly safer
|
|
54
|
+
than the unbounded credit burn it prevents. A non-rate-limit error during a
|
|
55
|
+
probe closes the breaker (does not keep features down on unrelated errors).
|
|
56
|
+
|
|
57
|
+
**Level-of-abstraction fit**: The breaker is wired at the IntelligenceProvider
|
|
58
|
+
construction chokepoint, so every current and future consumer is covered without
|
|
59
|
+
per-consumer code (Structure > Willpower). Consumers that already swallow
|
|
60
|
+
provider errors (PromptGate's silent fallback) swallow `LlmCircuitOpenError`
|
|
61
|
+
too — the desired behaviour: skip the LLM step at zero subprocess cost.
|
|
62
|
+
|
|
63
|
+
**Signal vs authority**: No new blocking authority over jobs/messages/sessions.
|
|
64
|
+
The breaker only gates LLM dispatch in reaction to the provider's own response.
|
|
65
|
+
It does not decide policy; it enforces "the provider said no."
|
|
66
|
+
|
|
67
|
+
**Migration / fleet reach**: Pure `src/` code shipped via the normal release →
|
|
68
|
+
AutoUpdater path. The protection is default-ON and reads config defensively with
|
|
69
|
+
built-in defaults, so it reaches every existing agent on the version bump with
|
|
70
|
+
NO config migration required. No agent-installed file (hooks/settings/CLAUDE.md
|
|
71
|
+
template/skills) changed → no PostUpdateMigrator entry needed.
|
|
72
|
+
|
|
73
|
+
**Rollback**: `intelligence.circuitBreaker.enabled: false` in `.instar/config.json`
|
|
74
|
+
makes the breaker a transparent passthrough. Full revert is a code revert of the
|
|
75
|
+
additive files.
|