Skip to content

Commit dbafeb1

Browse files
committed
Use waiting room Gravity placements
1 parent 2cb41c6 commit dbafeb1

5 files changed

Lines changed: 37 additions & 9 deletions

File tree

cli/src/components/waiting-room-screen.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ export const WaitingRoomScreen: React.FC<WaitingRoomScreenProps> = ({
9090
forceStart: true,
9191
provider: 'gravity',
9292
fallbackProvider: 'carbon',
93+
surface: 'waiting_room',
9394
})
9495

9596
useFreebuffCtrlCExit()

cli/src/hooks/use-gravity-ad.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export type AdVariant = 'banner' | 'choice'
3535
* same normalized response shape, so the rest of the hook is provider-agnostic.
3636
*/
3737
export type AdProvider = 'gravity' | 'carbon'
38+
export type AdSurface = 'waiting_room'
3839

3940
export type AdData =
4041
| { variant: 'banner'; ad: AdResponse }
@@ -112,11 +113,14 @@ export const useGravityAd = (options?: {
112113
provider?: AdProvider
113114
/** Backup ad network to try when the primary returns no fill or errors. */
114115
fallbackProvider?: AdProvider
116+
/** Product surface requesting the ad. The server maps this to placements. */
117+
surface?: AdSurface
115118
}): GravityAdState => {
116119
const enabled = options?.enabled ?? true
117120
const forceStart = options?.forceStart ?? false
118121
const provider: AdProvider = options?.provider ?? 'gravity'
119122
const fallbackProvider = options?.fallbackProvider
123+
const surface = options?.surface
120124
const [ad, setAd] = useState<AdResponse | null>(null)
121125
const [adData, setAdData] = useState<AdData | null>(null)
122126
const [isLoading, setIsLoading] = useState(false)
@@ -299,6 +303,7 @@ export const useGravityAd = (options?: {
299303
messages: adMessages,
300304
sessionId: useChatStore.getState().chatSessionId,
301305
device: getDeviceInfo(),
306+
...(surface ? { surface } : {}),
302307
// Carbon requires a real browser-ish useragent for targeting/fraud
303308
// detection. Gravity ignores it. We source one centrally so every
304309
// provider that needs it sees the same value.
@@ -430,7 +435,7 @@ export const useGravityAd = (options?: {
430435
clearInterval(id)
431436
ctrlRef.current.intervalId = null
432437
}
433-
}, [shouldStart, shouldHideAds, provider, fallbackProvider])
438+
}, [shouldStart, shouldHideAds, provider, fallbackProvider, surface])
434439

435440
// Don't return ad when ads should be hidden
436441
const visible = shouldStart && !shouldHideAds

web/src/app/api/v1/ads/_post.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,14 @@ const deviceSchema = z.object({
3535
})
3636

3737
const providerSchema = z.enum(['gravity', 'carbon']).default('gravity')
38+
const surfaceSchema = z.enum(['waiting_room'])
3839

3940
const bodySchema = z.object({
4041
provider: providerSchema.optional(),
4142
messages: z.array(messageSchema).optional().default([]),
4243
sessionId: z.string().optional(),
4344
device: deviceSchema.optional(),
45+
surface: surfaceSchema.optional(),
4446
/** Browser/CLI useragent passed through to providers that require it. */
4547
userAgent: z.string().optional(),
4648
})
@@ -136,6 +138,7 @@ export async function postAds(params: {
136138
clientIp,
137139
userAgent,
138140
device: parsedBody.device,
141+
surface: parsedBody.surface,
139142
messages: parsedBody.messages,
140143
testMode: serverEnv.CB_ENVIRONMENT !== 'prod',
141144
logger,

web/src/lib/ad-providers/gravity.ts

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ const CHOICE_PLACEMENT_IDS = [
1919
'choice-ad-3',
2020
'choice-ad-4',
2121
]
22+
const WAITING_ROOM_PLACEMENT_IDS = [
23+
'waiting-room-1',
24+
'waiting-room-2',
25+
'waiting-room-3',
26+
'waiting-room-4',
27+
]
2228

2329
type GravityRawAd = {
2430
adText: string
@@ -105,16 +111,25 @@ export function createGravityProvider(config: { apiKey: string }): AdProvider {
105111
fetch,
106112
} = input
107113

108-
const variant = getGravityVariant(userId)
114+
const requestedPlacementIds =
115+
input.surface === 'waiting_room' ? WAITING_ROOM_PLACEMENT_IDS : undefined
116+
const variant = requestedPlacementIds?.length
117+
? requestedPlacementIds.length === 1
118+
? 'banner'
119+
: 'choice'
120+
: getGravityVariant(userId)
109121
const filteredMessages = prepareGravityMessages(messages)
110122

111-
const placements =
112-
variant === 'choice'
113-
? CHOICE_PLACEMENT_IDS.map((id) => ({
114-
placement: 'below_response',
115-
placement_id: id,
116-
}))
117-
: [{ placement: 'below_response', placement_id: BANNER_PLACEMENT_ID }]
123+
const placementIds = requestedPlacementIds?.length
124+
? requestedPlacementIds
125+
: variant === 'choice'
126+
? CHOICE_PLACEMENT_IDS
127+
: [BANNER_PLACEMENT_ID]
128+
129+
const placements = placementIds.map((id) => ({
130+
placement: 'below_response',
131+
placement_id: id,
132+
}))
118133

119134
const deviceBody = clientIp
120135
? {

web/src/lib/ad-providers/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ export type AdDeviceInfo = {
4141
locale?: string
4242
}
4343

44+
export type AdSurface = 'waiting_room'
45+
4446
export type FetchAdInput = {
4547
userId: string
4648
userEmail: string | null
@@ -50,6 +52,8 @@ export type FetchAdInput = {
5052
/** Browser/CLI useragent string, passed through to upstream. */
5153
userAgent?: string
5254
device?: AdDeviceInfo
55+
/** Product surface requesting the ad. Providers may map this to placements. */
56+
surface?: AdSurface
5357
/** Last user + last preceding assistant message, if any. Used by Gravity. */
5458
messages?: AdMessage[]
5559
/** Set in non-prod so providers can request test ads. */

0 commit comments

Comments
 (0)