Skip to content

Commit 1f3a36a

Browse files
committed
fix: preserve core authentication and quota guidance
1 parent 1ce08b7 commit 1f3a36a

3 files changed

Lines changed: 35 additions & 15 deletions

File tree

‎README.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,10 @@ Every run reports what it resolved, so the answer never has to be inferred from
222222
with an error annotation saying which, and in review mode the failure comment says it too.
223223
No partial analysis is published.
224224

225-
When your free CodeBoarding quota is exhausted, the failure reason links to
225+
When your CodeBoarding quota is exhausted, the failure reason links to
226226
[buy a CodeBoarding license](https://codeboarding.org/pricing) or suggests waiting for your
227-
weekly reset. Provider quota failures retain their provider billing guidance.
227+
weekly reset. If CodeBoarding's hosted provider runs out of quota, the failure reason identifies
228+
a CodeBoarding service issue. Own-provider quota failures retain their provider billing guidance.
228229

229230
## Model selection
230231

‎scripts/analyze_repository.py‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
from threading import Thread
1414

1515
PROG = "codeboarding"
16+
# Shared with CodeBoarding/codeboarding_cli/main.py; keep the prefix in sync.
17+
ENGINE_ERROR_PREFIX = "CodeBoarding: "
1618

17-
# The engine's exit codes for an LLM refusal the user has to fix, and what to tell them.
19+
# Fallback guidance for engine refusals without a recovery message.
1820
ENGINE_REFUSALS = {
1921
2: "The LLM provider rejected the API key. Check the key's secret and re-run.",
2022
3: "The LLM provider's token or credit quota is exhausted. Add credits or raise the quota, then re-run.",
@@ -109,11 +111,10 @@ def forward_stderr() -> None:
109111
stdout = "".join(stdout_lines)
110112
if return_code != 0:
111113
reason = ENGINE_REFUSALS.get(return_code)
112-
if return_code == 3:
113-
# Keep Core's quota-specific recovery guidance instead of replacing it with provider billing advice.
114+
if return_code in ENGINE_REFUSALS:
114115
for line in reversed(stderr_lines):
115-
if "CodeBoarding: " in line:
116-
reason = line.partition("CodeBoarding: ")[2].strip()
116+
if ENGINE_ERROR_PREFIX in line:
117+
reason = line.partition(ENGINE_ERROR_PREFIX)[2].strip() or reason
117118
break
118119
if reason:
119120
# Written straight to the step's outputs: the shell never sees this script's stdout on failure.

‎tests/test_analyze_repository.py‎

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,20 +89,38 @@ def test_run_command_names_an_exhausted_quota(self) -> None:
8989
self.assertIn("quota is exhausted", str(error))
9090
self.assertEqual(outputs.read_text(encoding="utf-8"), f"failure_reason={error}\n")
9191

92-
def test_quota_failure_preserves_cores_recovery_message(self) -> None:
92+
def test_engine_refusals_preserve_cores_recovery_message(self) -> None:
9393
messages = (
94-
"Your free CodeBoarding quota is exhausted. Buy a CodeBoarding license at "
95-
"https://codeboarding.org/pricing, or wait for your weekly reset.",
96-
"The LLM provider's token or credit quota is exhausted. "
97-
"Add credits or raise the quota for this provider, then re-run.",
94+
(
95+
3,
96+
"Your CodeBoarding quota is exhausted. Buy a CodeBoarding license at "
97+
"https://codeboarding.org/pricing, or wait for your weekly reset.",
98+
),
99+
(
100+
3,
101+
"The LLM provider's token or credit quota is exhausted. "
102+
"Add credits or raise the quota for this provider, then re-run.",
103+
),
104+
(
105+
3,
106+
"The hosted LLM provider's quota is exhausted. "
107+
"This is a CodeBoarding service issue. Please try again later or contact CodeBoarding support.",
108+
),
109+
(2, "Your openai API key was rejected (HTTP 401). Verify the key ending in '…a8dd' and try again."),
110+
(
111+
2,
112+
"CodeBoarding's hosted openrouter credentials were rejected (HTTP 401). This run used no key of "
113+
"yours: check that the workflow grants `id-token: write`, then re-run.",
114+
),
98115
)
99-
for message in messages:
100-
with self.subTest(message=message), tempfile.TemporaryDirectory() as tmp:
116+
for exit_code, message in messages:
117+
with self.subTest(exit_code=exit_code, message=message), tempfile.TemporaryDirectory() as tmp:
101118
outputs = Path(tmp) / "github_output"
102119
program = (
103120
"import sys; "
104121
f"print('ERROR [codeboarding_cli.main:140] CodeBoarding: ' + {message!r}, file=sys.stderr); "
105-
"sys.exit(3)"
122+
"print('Additional unprefixed guidance', file=sys.stderr); "
123+
f"sys.exit({exit_code})"
106124
)
107125
with patch.dict("os.environ", {"GITHUB_OUTPUT": str(outputs)}), patch("sys.stderr", io.StringIO()):
108126
with self.assertRaises(ar.AnalysisError) as caught:

0 commit comments

Comments
 (0)