Skip to content

[codex] Add Carbon fallback for CLI ads#541

Merged
jahooma merged 1 commit intomainfrom
jahooma/ad-fallbacks
Apr 24, 2026
Merged

[codex] Add Carbon fallback for CLI ads#541
jahooma merged 1 commit intomainfrom
jahooma/ad-fallbacks

Conversation

@brandonkachen
Copy link
Copy Markdown
Collaborator

Summary

  • add fallbackProvider support to useGravityAd so the CLI retries a secondary ad network when the primary returns no fill or errors
  • switch chat ads and the freebuff waiting room to try Gravity first and fall back to Carbon
  • keep the existing banner/choice rendering and rotation behavior while broadening fill coverage

Validation

  • bun x tsc --noEmit -p cli/tsconfig.json

@jahooma jahooma marked this pull request as ready for review April 24, 2026 22:44
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 24, 2026

Greptile Summary

Adds a fallbackProvider option to useGravityAd so the CLI sequentially tries a secondary ad network when the primary returns no fill or an HTTP error. Both call-sites (chat.tsx and waiting-room-screen.tsx) are updated to use Gravity as primary and Carbon as fallback.

Confidence Score: 5/5

Safe to merge — fallback logic is correct, dependency array is properly updated, and all remaining comments are P2 style suggestions.

The core retry loop correctly uses continue on HTTP errors and implicit fall-through on no-fill, both of which advance to the fallback provider. The useEffect dependency array now includes provider and fallbackProvider, so the interval resets properly if they ever change. No correctness issues were found; only minor observability and style suggestions remain.

No files require special attention.

Important Files Changed

Filename Overview
cli/src/hooks/use-gravity-ad.ts Adds fallbackProvider param; wraps single fetch in a for-loop over [provider, fallbackProvider]; adds both to the useEffect dependency array. Logic is correct — continue on HTTP error and implicit fall-through on no-fill both advance to the fallback provider.
cli/src/chat.tsx Adds provider: 'gravity' and fallbackProvider: 'carbon' to the existing useGravityAd call; no other logic changes.
cli/src/components/waiting-room-screen.tsx Switches waiting-room from Carbon-only (provider: 'carbon') to Gravity-first with Carbon fallback; comment updated to match.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: cli/src/hooks/use-gravity-ad.ts
Line: 284-287

Comment:
**Simplify `providersToTry` construction**

The dedup check (`fallbackProvider !== provider`) can be collapsed using `Set`, which also handles the `undefined` case more naturally without the extra boolean guard:

```suggestion
    const providersToTry = [...new Set([provider, fallbackProvider].filter((p): p is AdProvider => p != null))]
```

This removes the nested ternary and makes the intent ("unique, defined providers in priority order") immediately clear.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: cli/src/hooks/use-gravity-ad.ts
Line: 309-319

Comment:
**Silent no-fill fallback makes debugging harder**

When the primary provider returns a 200 with no ad content (neither `data.ad` nor a valid `data.ads` array), the loop falls through to the fallback silently — no log line is emitted. Adding a brief `logger.debug` here would make it easy to spot "primary returned no fill, trying fallback" in logs without changing behaviour:

```suggestion
        if (data.ad) {
          return { variant: 'banner', ad: data.ad as AdResponse }
        }

        // No fill from this provider; try the next one if available
        logger.debug({ provider: providerToTry }, '[ads] No fill, trying next provider')
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "Add Carbon fallback for ads" | Re-trigger Greptile

Comment on lines +284 to +287
const providersToTry =
fallbackProvider && fallbackProvider !== provider
? [provider, fallbackProvider]
: [provider]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Simplify providersToTry construction

The dedup check (fallbackProvider !== provider) can be collapsed using Set, which also handles the undefined case more naturally without the extra boolean guard:

Suggested change
const providersToTry =
fallbackProvider && fallbackProvider !== provider
? [provider, fallbackProvider]
: [provider]
const providersToTry = [...new Set([provider, fallbackProvider].filter((p): p is AdProvider => p != null))]

This removes the nested ternary and makes the intent ("unique, defined providers in priority order") immediately clear.

Prompt To Fix With AI
This is a comment left during a code review.
Path: cli/src/hooks/use-gravity-ad.ts
Line: 284-287

Comment:
**Simplify `providersToTry` construction**

The dedup check (`fallbackProvider !== provider`) can be collapsed using `Set`, which also handles the `undefined` case more naturally without the extra boolean guard:

```suggestion
    const providersToTry = [...new Set([provider, fallbackProvider].filter((p): p is AdProvider => p != null))]
```

This removes the nested ternary and makes the intent ("unique, defined providers in priority order") immediately clear.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +309 to +319
if (!response.ok) {
logger.warn(
{
provider: providerToTry,
status: response.status,
response: await response.json(),
},
'[ads] Web API returned error',
)
continue
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Silent no-fill fallback makes debugging harder

When the primary provider returns a 200 with no ad content (neither data.ad nor a valid data.ads array), the loop falls through to the fallback silently — no log line is emitted. Adding a brief logger.debug here would make it easy to spot "primary returned no fill, trying fallback" in logs without changing behaviour:

Suggested change
if (!response.ok) {
logger.warn(
{
provider: providerToTry,
status: response.status,
response: await response.json(),
},
'[ads] Web API returned error',
)
continue
}
if (data.ad) {
return { variant: 'banner', ad: data.ad as AdResponse }
}
// No fill from this provider; try the next one if available
logger.debug({ provider: providerToTry }, '[ads] No fill, trying next provider')
Prompt To Fix With AI
This is a comment left during a code review.
Path: cli/src/hooks/use-gravity-ad.ts
Line: 309-319

Comment:
**Silent no-fill fallback makes debugging harder**

When the primary provider returns a 200 with no ad content (neither `data.ad` nor a valid `data.ads` array), the loop falls through to the fallback silently — no log line is emitted. Adding a brief `logger.debug` here would make it easy to spot "primary returned no fill, trying fallback" in logs without changing behaviour:

```suggestion
        if (data.ad) {
          return { variant: 'banner', ad: data.ad as AdResponse }
        }

        // No fill from this provider; try the next one if available
        logger.debug({ provider: providerToTry }, '[ads] No fill, trying next provider')
```

How can I resolve this? If you propose a fix, please make it concise.

@jahooma jahooma merged commit 6d2e60d into main Apr 24, 2026
34 checks passed
@jahooma jahooma deleted the jahooma/ad-fallbacks branch April 24, 2026 22:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants