Skip to content

fix(models): unbreak review — the provider pin 404'd every model in the chain - #120

Merged
senamakel merged 14 commits into
mainfrom
sweeper-provider-pin
Aug 23, 2026
Merged

fix(models): unbreak review — the provider pin 404'd every model in the chain#120
senamakel merged 14 commits into
mainfrom
sweeper-provider-pin

Conversation

@senamakel

Copy link
Copy Markdown
Member

What was wrong

Every review since #117 has reported nothing to review. Not a lane bug — no
model was ever called.

[models.provider] pins routing with

order = ["deepseek"]
allow_fallbacks = false

deepseek there is an OpenRouter provider, not the model vendor. DeepSeek
first-party serves the dated deepseek-v4-pro-0813 snapshot; it does not
serve deepseek-v4-flash
. #117 moved both tiers onto Flash, so from that
commit every primary call returned 404 No endpoints found.

The fallback ladder could not save it. The pin applies to the whole chain, and
neither z-ai/glm-5.2 nor minimax/minimax-m3 has a DeepSeek endpoint either,
so all three rungs failed for the same reason. Reproduced against the live API:

flash + order=[deepseek]        404 No endpoints found for deepseek/deepseek-v4-flash
glm-5.2 + order=[deepseek]      404 No endpoints found for z-ai/glm-5.2
minimax-m3 + order=[deepseek]   404 No endpoints found for minimax/minimax-m3

Those are verbatim the errors in the production pod's logs.

With every call failing, each lane's fan-out reviewed zero files, reported
skipped, and published a Neutral check reading Reviewed 0 files; 0 findings. — followed by No findings. A silent all-clear over unreviewed code,
for a week, which is the most expensive way this reviewer can be wrong.

What changed

1. The pin names providers that serve these models. order = ["streamlake", "deepinfra"] — the value that was here before it was replaced. Both serve all
four configured ids and both accept json_object; verified against the live API.

2. The ladder gets a rung that drops the pin. Every rung inherited one
order, so a wrong pin failed all of them identically and the safety net was
decoration. models.provider.last_resort_unpinned (default on) makes one final
unpinned attempt after every priced route has failed. It costs nothing on a
healthy deployment, and it is loud: reaching it logs at warn that the cost line
is now an estimate and the pin needs fixing. An unpinned review at an unpredicted
price beats no review.

3. A lane with no verdict stops claiming one. lane_summary printed No findings. whether a reviewer looked and found nothing or never ran. It now says
so explicitly when the lane reached no verdict. This is what let the outage stay
invisible.

4. Prices corrected, and the floor test made per-model. The floor was a
single $0.10 constant justified by "the cheapest endpoint is $0.392". Both
halves aged out: Flash is genuinely cheaper than the floor, so it rejected a
correct row — and a blanket floor never checks the rows it passes, so
deepseek-v4-pro-0813 sat underpriced threefold on output, the direction that
makes budget_usd_per_pr fail open. Now every row is checked against its
measured cheapest endpoint.

5. A guard against making this exact mistake again. A test rejects pinning a
name that is a model vendor rather than a hosting provider, and says how to
check.

Verification

Live, through the real code path, against a diff with two planted bugs:

config result
the pin as deployed NeutralReviewed 0 files; 0 findings. (reproduces production)
fixed defaults Failure — both bugs found, $0.0002
broken pin + new rung Failure — both bugs found, warns the pin is broken
  • cargo test1450 passed, 0 failed
  • cargo fmt --check, cargo clippy -D warnings, cargo check --all-features — clean

Also fixes CI

main has been red since #117 on a stale eval corpus. It could not be
re-recorded while every model 404'd — a recording run had nothing to record.
Both cases are re-recorded here and both guarded regressions still hold. The 94
previously-tracked cassettes were all dead; the 29 recorded here replay the
corpus on their own.

Note for the operator

The production pod is also being OOMKilled (4 restarts, 846Mi against a 1Gi
limit) while doing almost no model work. Once reviews actually run, that will get
worse. Not addressed here — it is a deployment resource change, not a code one.

senamakel and others added 14 commits August 23, 2026 15:01
The provider order was changed from `["deepseek"]` to `["streamlake", "deepinfra"]` because DeepSeek first-party does not serve the `deepseek-v4-flash` model, causing every call to return `404 No endpoints found` and all lanes to go neutral. StreamLake and DeepInfra both serve all four model IDs the deployment can request and accept `json_object`, with StreamLake leading as the cheaper option and DeepInfra as a fallback to degrade price rather than review during an outage.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The comment explaining the cost comparison between flash and pro tiers was updated to remove the specific mention of DeepSeek as the endpoint provider, replacing it with a reference to StreamLake/DeepInfra. A note was added to explain that this distinction matters because a previous endpoint change caused all reviews to fail, directing readers to the `[models.provider]` section for context.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Update the hardcoded price for the `deepseek/deepseek-v4-flash` model to reflect the dearer of the two providers listed in the configuration, rather than DeepSeek's own rates which are no longer applicable. The previous values of $0.14/$0.28 were based on first-party pricing, but DeepSeek no longer serves this model directly, so the fallback provider's rates of $0.09/$0.18 are used instead. The cached read price is also corrected from a fiftieth to a fifth of the input price, matching the actual discount applied by the active provider.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add a `reached_a_verdict` parameter to `lane_summary` so that a lane which was disabled, skipped as a draft, or whose model calls all failed can report that it has no opinion rather than emitting a misleading "No findings." message. Previously an empty finding list was always displayed as a clean result, which could falsely imply that unreviewed code had been checked.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The `lane_summary` function now accepts a boolean parameter indicating whether a reviewer produced a verdict. When a lane never ran due to provider failures, passing `false` suppresses the "No findings." message that previously made skipped lanes appear clean. All existing call sites are updated to pass `true` to preserve current behaviour.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add a `last_resort_unpinned` field to `ProviderRouting` that, when enabled, allows the model ladder to drop the pin entirely on its final rung. This addresses a design gap where every rung carried the same provider pin, making the fallback ladder ineffective against provider-specific model unavailability. The new field defaults to `true`, and a corresponding `unpinned()` constructor provides a routing configuration with no pin and fallbacks enabled for use as the ladder's last resort.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The `harness` and `call` methods now accept a `ProviderRouting` parameter, which is forwarded to `provider_options` instead of the previously used `self.provider`. This allows the caller to specify routing preferences per request rather than relying on a fixed provider configuration.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
When every model in the configured provider pin fails, the gateway now retries the request with an unpinned provider. This prevents a deployment outage when the pinned provider cannot serve any of the configured models, for example when a pin to DeepSeek is active but the models are only available through other providers. The fallback is only reached after all priced routes have failed, so it adds no cost during normal operation, but it logs a warning because unpinned calls may incur unexpected billing.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Adds a `last_resort_unpinned` setting to the provider configuration that, when enabled, makes one final unpinned model call after all priced routes have failed. This prevents a single pin from becoming a single point of failure that could cause reviews to return empty. The option defaults to true because a recoverable cost estimate is preferable to silent unreviewed code, and it only activates after everything else has failed, so it costs nothing on a healthy deployment.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add four tests that verify the last-resort unpinned rung is enabled by default, sends no provider block, cannot recurse, and is absent when the deployment is already unpinned. These tests document and protect the invariant that the fallback rung exists to prevent every ladder rung inheriting a broken pin.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
…test

The DeepSeek V4 Pro and V4 Pro 0813 model prices were significantly underpriced because they assumed a single DeepSeek first-party endpoint that this deployment cannot route to, when in fact the models have multiple endpoints with higher prices. The input price for the dated model was raised from $0.435 to $1.32 and output from $0.87 to $3.96, while the floating alias was updated to $1.30/$2.60 based on the dearer of the two pinned providers. The test that checks for underpriced models was also strengthened from a single $0.10 floor for all models to a per-model floor using freshly measured cheapest endpoint prices, which would have caught the previous mispricing.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The shipped defaults previously pinned only DeepSeek as the provider order, but every configured model was served by StreamLake and DeepInfra, causing all requests to fail with "No endpoints found". This change adds a test that verifies the provider order does not contain names that are model vendors rather than hosting providers, and ensures the ladder has an unpinned fallback rung to make such mistakes survivable.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Remove 94 cassette JSON files that were recorded during earlier evaluation runs for the kernel-bypass-hallucination and description-anchored-to-code test suites. These cassettes are no longer needed because the evaluation harness has been updated to use a different recording strategy, and keeping them would only add noise to the repository.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown

Warning

Your free Security trial is over. An organization admin can activate billing to continue.

@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Your included review limit has been reached.

You’re in a promotional period — use the checkbox below to run this review for free:

  • Run review for free

On-demand reviews are free for the next 28 days. After that, they cost $0.25 per reviewed file.

How can I continue?

Run this review now using the option above, or comment @coderabbitai review --use-credits.

You can also wait for the limit to reset, then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d53c66d4-5984-4851-8bfe-a2a42d3f6f8f

📥 Commits

Reviewing files that changed from the base of the PR and between 5070415 and 2fec2b5.

📒 Files selected for processing (130)
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0001-48409bc6fd25f99c.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0001-5d5f08dc06f14946.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0001-68b7ad38f2397deb.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0002-17541401c04d839b.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0002-86f2a405ae5e917d.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0002-c312a6bd2f611374.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0002-e90ec1d2def4d0bd.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0003-1c93c25d9aadd0a7.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0003-908b8d5671bc4efe.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0003-b31533cbc185afb5.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0003-d79975eaecc88e58.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0004-01b577a5fa03b6a3.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0004-3df0bb3a4c9249d9.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0004-508455793c710ced.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0004-71cddd72c75d2722.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0005-183c4d7693b78647.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0005-2269be87e5446f3d.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0005-9dcf52aa6a97d3bd.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0005-b867d8949a942d78.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0006-548c6658c51e5f85.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0006-78bfb662caf7b753.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0006-7fd8433c8c3dcc5b.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0006-86efd049e0b944eb.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0007-46f4d1a79f482cab.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0007-abbb7a6b9db04578.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0007-c5de1dac54c27232.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0007-fa1f7ac7ffabd355.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0008-12ef78c1f6c205ef.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0008-87d1384e18c9d053.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0008-bbaf0cb9ee51f766.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0008-f8ee04ae981b9121.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0009-2310062d1ab2ba6a.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0009-2d53b24abad09d41.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0009-6088af22011645cb.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0009-976d996747c9e480.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0010-0a7b31caad337548.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0010-3ef1e4ebacbe0381.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0010-51cbaf94131edeb2.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0010-d6bf343291f4be03.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0011-324a651e69b6c33a.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0011-6c1f6e3ffb9626df.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0011-7c0e6d892204ca20.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0011-f67467cb64fe2258.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0012-324e39bcc10103cd.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0012-b5380fa68e6677d3.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0012-d4663b5b7171ece8.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0012-d60090c3108a8bc7.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0013-3d5e8e65650775c9.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0013-6e98aa73235b777f.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0013-85f1803a0e941767.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0013-8ac85a2f4f827918.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0014-13bed2303116481d.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0014-41ed18e32c1b3bd3.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0014-877af0253e3927ce.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0014-fb11783005e5e9fd.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0015-0fdeb27f432cc6dd.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0015-3651492c72f6983f.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0015-7d0a235486943283.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0015-b136475a5e9b393f.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0016-24edd5723968eefd.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0016-89683e319847d619.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0016-96d6b84e54ee3b43.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0016-fdcd6803e0c62746.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0017-1f308da0fcce4684.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0017-2dc7e57b83706c42.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0017-67216aa5018d3c92.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0017-da2bcfbc6612fc4f.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0018-3e0fe1f1ab7eef77.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0018-7efb557b9ec78cdc.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0019-2a193226a83b428a.json
  • evals/cassettes/ts-0045-kernel-bypass-hallucination/0019-e8c2df70b7f557d4.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0001-8d8a52bdbefb3833.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0001-9d30d123b285e22c.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0001-ef777313b984ca71.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0002-4ab89b29c04e3569.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0002-6b522b9d6ed10738.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0002-a48956a905cbdfcf.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0002-e91f6f655e66852e.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0003-103003f05e8c9269.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0003-d44795407ec1e3eb.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0003-e2a5ced825a44efc.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0003-ec3338063d329eeb.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0004-08578bcd9582f891.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0004-2908e203d01996cc.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0004-3ebbd6a0fecdb0db.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0004-d772af2ca812230d.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0005-5e5e6e07b224bd0e.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0005-8c7dc6fedf29f06f.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0005-8cec32f46b7c9c01.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0005-dca3571c4f7994b8.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0006-188d9a53900dfbce.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0006-9f306866be576df3.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0006-c0050c76a554fe21.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0006-f4392b8951c5a340.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0007-0a29688e1cc61e19.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0007-353d2a1fbdf240b0.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0007-5d5c31938dc865de.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0007-97d607cd8180b2b8.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0008-1665583b223eb633.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0008-40d73aadf4587bd0.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0008-cdd9c81d90654ca1.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0008-ec37163789e29c2d.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0009-23736351a1125283.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0009-5fd8ceb66d310e3f.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0009-64f5967d5015765f.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0009-9f3a263d8d7c3f65.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0010-8f032c383f3cd7ce.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0010-95abf2e743a888f9.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0010-c861c8ec196f73ea.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0010-d8a6ea9d1612bf43.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0011-093689929f9f5cdf.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0011-41900b70dd0627fd.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0011-99e578a2574f6d7a.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0011-de8143183d9a6731.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0012-124e3ad01415e1c2.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0012-32974d59dd73473c.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0012-7042f2628e522625.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0012-7bde9d206ba49dcc.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0013-2d1bd1de53c9ba41.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0013-6a2e2ad299636656.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0013-e9b356c74601f13b.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0014-7519cc81b4847f86.json
  • evals/cassettes/ts-0068-description-anchored-to-code/0014-e9702f894c13c6ba.json
  • src/app/apply.rs
  • src/config/defaults.toml
  • src/config/test.rs
  • src/config/types.rs
  • src/findings/render.rs
  • src/harness/openrouter.rs
  • src/harness/pricing.rs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@tinysweeper

tinysweeper Bot commented Aug 23, 2026

Copy link
Copy Markdown

How this change flows

5 changed behaviours across 10 relationships. 6 surrounding behaviours are shown (60 graph nodes walked). 39 further behaviours left out to keep the diagram readable.

flowchart LR
  n0["...hipped_defaults_pin_the_upstream_provider<br/>changed"]:::changed
  n1["Labels<br/>changed"]:::changed
  n2["ProviderRouting<br/>changed"]:::changed
  n3["GatewayModel<br/>changed"]:::changed
  n4["langfuse_client<br/>changed"]:::changed
  n5["iter"]:::impacted
  n6["publishing_also_triages_the_pull_request"]:::impacted
  n7["Config"]:::impacted
  n8["call"]:::impacted
  n9["Result"]:::impacted
  n10["from_config"]:::impacted
  n0 -->|uses| n7
  n3 -->|uses| n2
  n4 -->|calls| n5
  n6 -->|uses| n1
  n7 -->|uses| n1
  n8 -->|uses| n2
  n8 -->|calls| n5
  n8 -->|uses| n9
  n10 -->|calls| n4
  n10 -->|uses| n9
  classDef changed fill:#0d4429,stroke:#238636,color:#e6edf3
  classDef impacted fill:#161b22,stroke:#6e7681,color:#c9d1d9
  classDef flagged fill:#5a1e02,stroke:#d93f0b,color:#ffffff
  classDef blocking fill:#67060c,stroke:#f85149,color:#ffffff
Loading

Green: changed behaviour. Grey: surrounding behaviour. Arrows name the call, use, implementation, or test relationship. Orange: has findings. Red: has a finding that blocks the merge.

tinysweeper 0.1.0

@tinysweeper tinysweeper Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tinysweeper found nothing blocking. Approving.

$0.0000 · 0 in / 0 out · 847 embedded · openrouter/openai/text-embedding-3-small

@tinysweeper tinysweeper Bot added the priority: p3 Whenever. Cosmetic, a nicety, or a cleanup with no user visible effect. label Aug 23, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2fec2b5856

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/harness/openrouter.rs
Comment on lines +639 to +641
match self
.call_until_complete(&request.model, &request, &unpinned)
.await

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Account for paid failures before the unpinned retry

When the pinned models return billable but unusable responses—for example truncated output or invalid JSON—this new unpinned call adds another charge without accounting for the earlier attempts. ModelCapability checks the budget only before entering GatewayModel::complete (src/flows/caps.rs:126-138), while call constructs Usage only after validation succeeds, so all failed-attempt usage is discarded and the successful unpinned response reports only its own cost. A chain of paid failures followed by this retry can therefore exceed budget_usd_per_pr while the recorded spend remains below it; carry usage through failed attempts and check the remaining budget before making this extra call.

Useful? React with 👍 / 👎.

@senamakel
senamakel merged commit fef5ab0 into main Aug 23, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: p3 Whenever. Cosmetic, a nicety, or a cleanup with no user visible effect.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant