mirror of
https://github.com/CyberSecurityUP/NeuroSploit.git
synced 2026-09-30 21:19:49 +02:00
fix(models): treat subscription session/usage-limit stdout as exhaustion
Subscription CLIs (claude) report a hit session limit as ordinary stdout with a ZERO exit code — 'You've hit your session limit · resets …'. Left as Ok it became a 'response' each agent then failed to parse, and the run burned every remaining agent against a dead session instead of pausing. Now the sentinel is caught (length-guarded so a real finding mentioning 'rate limit' is not misread) and surfaced as exhaustion, so the pool parks the run for /continue — the pause-on-quota path that already existed but this case never reached. Found during a live benchmark when run B collapsed to 0 findings mid-run. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
b23fae7318
commit
d2ec0a112d
2 files changed
+15
No files matched your search
@@ -351,6 +351,20 @@ impl ChatClient {
|
|||||||
if stdout.is_empty() {
|
if stdout.is_empty() {
|
||||||
return Err(anyhow!("{} subscription CLI returned empty output", bin));
|
return Err(anyhow!("{} subscription CLI returned empty output", bin));
|
||||||
}
|
}
|
||||||
|
// Subscription CLIs report a hit session/usage limit as ordinary stdout
|
||||||
|
// with a ZERO exit code — a short sentence, not an error. Left as Ok it
|
||||||
|
// becomes a "response" the agent then fails to parse, and the run burns
|
||||||
|
// every remaining agent against a dead session instead of pausing. Catch
|
||||||
|
// the sentinel (kept short so a real finding that merely mentions "rate
|
||||||
|
// limit" is not misread) and surface it as exhaustion so the pool parks.
|
||||||
|
let low = stdout.to_lowercase();
|
||||||
|
let session_dead = stdout.len() < 300 && [
|
||||||
|
"session limit", "you've hit your", "you have hit your", "usage limit",
|
||||||
|
"resets ", "reset at", "try again later", "come back later",
|
||||||
|
].iter().any(|k| low.contains(k));
|
||||||
|
if session_dead {
|
||||||
|
return Err(anyhow!("{} subscription session/usage limit reached: {}", bin, truncate(&stdout, 160)));
|
||||||
|
}
|
||||||
Ok(stdout)
|
Ok(stdout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ pub fn is_exhaustion(e: &anyhow::Error) -> bool {
|
|||||||
"quota", "insufficient_quota", "insufficient quota", "out of credit",
|
"quota", "insufficient_quota", "insufficient quota", "out of credit",
|
||||||
"credit balance", "billing", "exhausted", "overloaded", "capacity",
|
"credit balance", "billing", "exhausted", "overloaded", "capacity",
|
||||||
"usage limit", "resource_exhausted", "resource exhausted",
|
"usage limit", "resource_exhausted", "resource exhausted",
|
||||||
|
"session limit", "session/usage limit", "you've hit your",
|
||||||
]
|
]
|
||||||
.iter()
|
.iter()
|
||||||
.any(|k| s.contains(k))
|
.any(|k| s.contains(k))
|
||||||
|
|||||||
Reference in new issue
Block a user