Skip to content

Commit 7648f87

Browse files
Merge latest upstream main into fix/freebuff-disable-chat-logo-animation
2 parents d2dc221 + 93dce35 commit 7648f87

6 files changed

Lines changed: 160 additions & 61 deletions

File tree

bun.lock

Lines changed: 26 additions & 50 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli/release/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "codebuff",
3-
"version": "1.0.685",
3+
"version": "1.0.686",
44
"description": "AI coding agent",
55
"license": "MIT",
66
"bin": {

common/src/__tests__/freebuff-models.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,46 @@ describe('freebuff model availability', () => {
487487
expect(FREEBUFF_MODELS.find((m) => m.id === id)?.availability).toBe('always')
488488
})
489489

490+
test('the desktop concurrency bucket is a PRICE claim, not a metering one', () => {
491+
// These two lists are deliberately separate, and deriving one from the
492+
// other has already cost real users: when Flash entered the quota list on
493+
// 2026-08-18 the derivation silently made the DEFAULT model one-tab-only,
494+
// and ~1k accounts a day met "Another tab is using the hosted model".
495+
//
496+
// So this asserts the bucket's OWN criterion — "a bill we would not want to
497+
// underwrite at three at once" — by pinning the ordering that criterion
498+
// implies: no row may sit in the one-tab bucket while a CHEAPER row per
499+
// message runs three at once. GLM 5.3 Flash failed exactly that test on
500+
// 2026-08-28, being the cheapest row we serve and still capped at one tab.
501+
const COST_PER_MSG: Record<string, number> = {
502+
[FREEBUFF_GLM_V53_FLASH_MODEL_ID]: 0.000249,
503+
[FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID]: 0.002223,
504+
[FREEBUFF_MIMO_V25_MODEL_ID]: 0.001151,
505+
}
506+
const inBucket = (id: string) =>
507+
(FREEBUFF_DESKTOP_PREMIUM_BUCKET_MODEL_IDS as readonly string[]).includes(id)
508+
const dearestMultiTab = Math.max(
509+
...Object.entries(COST_PER_MSG)
510+
.filter(([id]) => !inBucket(id))
511+
.map(([, cost]) => cost),
512+
)
513+
for (const [id, cost] of Object.entries(COST_PER_MSG)) {
514+
if (!inBucket(id)) continue
515+
expect({ id, capped: true, dearerThanSomeMultiTabRow: cost > dearestMultiTab })
516+
.toEqual({ id, capped: true, dearerThanSomeMultiTabRow: true })
517+
}
518+
519+
// And the invariant the bucket's own doc ends on: nothing may be metered
520+
// AND multi-tab until admit rows are keyed by instance id, because
521+
// buildAdmitStampStatement pairs on (user, model, access_tier, admitted_at)
522+
// and two same-millisecond tabs make that pairing arbitrary.
523+
for (const model of FREEBUFF_MODELS) {
524+
if (inBucket(model.id)) continue
525+
expect({ id: model.id, meteredAndMultiTab: Boolean(model.premium) })
526+
.toEqual({ id: model.id, meteredAndMultiTab: false })
527+
}
528+
})
529+
490530
test('every model is premium-listed and premium-flagged, or neither', () => {
491531
// THE INVARIANT THAT REPLACED "a premium row must be in some pool".
492532
// `isFreebuffPremiumModelId` reads FREEBUFF_PREMIUM_MODEL_IDS while

common/src/constants/freebuff-models.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2116,15 +2116,23 @@ export const FREEBUFF_GLM_V52_MODEL_IDS = [FREEBUFF_GLM_V52_MODEL_ID] as const
21162116
export const FREEBUFF_DESKTOP_PREMIUM_BUCKET_MODEL_IDS = [
21172117
FREEBUFF_GPT_5_6_LUNA_MODEL_ID,
21182118
FREEBUFF_GLM_V52_MODEL_ID,
2119-
// V4 Pro left with its withdrawal (2026-08-26); GLM 5.3 Flash takes the slot.
2120-
// Here for the CONCURRENCY reason the doc above insists on deciding
2121-
// separately — but note it is also the one row that is metered AND would
2122-
// otherwise be multi-tab, which the last paragraph above forbids outright:
2123-
// `buildAdmitStampStatement` pairs a window to its admit row on
2124-
// `(user, model, access_tier, admitted_at)`, so two tabs of one metered row
2125-
// admitted in the same millisecond make that pairing arbitrary. Until admit
2126-
// rows are keyed by instance id, a metered row belongs in this bucket.
2127-
FREEBUFF_GLM_V53_FLASH_MODEL_ID,
2119+
// GLM 5.3 Flash LEFT on 2026-08-29, and on this list's own criterion rather
2120+
// than as a side effect of unmetering it the day before. Membership is "a
2121+
// bill we would not want to underwrite at three at once", and measured
2122+
// production spend puts it at $0.000249/msg — the CHEAPEST row we serve:
2123+
//
2124+
// glm-5.3-flash $0.000249/msg $0.0196/session <- 3 tabs, now
2125+
// mimo-v2.5 $0.001151/msg $0.0907/session <- 3 tabs already
2126+
// deepseek-v4-flash $0.002223/msg $0.1752/session <- 3 tabs already
2127+
//
2128+
// Three concurrent tabs of it is a smaller bill than three of either row this
2129+
// list has always allowed, so keeping it here failed the test on its face.
2130+
//
2131+
// The OTHER reason it sat here — that it was metered, and the last paragraph
2132+
// above forbids metered-and-multi-tab because `buildAdmitStampStatement`
2133+
// pairs a window to its admit row on `(user, model, access_tier,
2134+
// admitted_at)` — expired with the unmetering. "Nothing is metered and
2135+
// multi-tab today" still holds after this change.
21282136
// Metered, so the same rule puts it here.
21292137
FREEBUFF_SOLAR_PRO_4_MODEL_ID,
21302138
] as const

common/src/constants/freebuff-topups.ts

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,84 @@ export const AD_PROMO_REFERRAL_PROGRAM = 'placements_launch_2026'
7979
*/
8080
export const AD_PLACEMENT_COLLECTION_RETENTION_DAYS = 180
8181

82+
/**
83+
* Advertiser trust score / derived credit line (COD-268).
84+
*
85+
* The line is expressed as DAYS OF OBSERVED BURN, not as a raw multiple of a
86+
* 30-day total. Collection is nightly (plus a $100 threshold sweep), so the
87+
* only question the line has to answer is "how many days of this advertiser's
88+
* spend are we willing to have outstanding between sweeps". Three days covers
89+
* a weekend plus one failed retry; ten days is the most we extend to anybody
90+
* on payment history alone, and it is still an order of magnitude under the
91+
* global ceiling for a large spender.
92+
*/
93+
export const AD_CREDIT_LINE_WINDOW_DAYS = 30
94+
export const AD_CREDIT_LINE_MIN_DAYS = 3
95+
export const AD_CREDIT_LINE_MAX_DAYS = 10
96+
97+
/**
98+
* The absolute per-advertiser cap on a DERIVED line. An operator may hand-set
99+
* a higher floor; nothing computed here may exceed this on its own.
100+
*/
101+
export const AD_CREDIT_LINE_CEILING_CENTS = 500_000
102+
103+
/** No growth at all before the account has this much settled history. */
104+
export const AD_CREDIT_LINE_MIN_ACCOUNT_AGE_DAYS = 14
105+
export const AD_CREDIT_LINE_MIN_SUCCESSFUL_COLLECTIONS = 3
106+
107+
/**
108+
* Per-run move limits. Growth may at most double the live line (or add one
109+
* default line, whichever is larger, so a $0 line is not permanently stuck at
110+
* zero); a decrease may take at most 25% in one run, matching the repricer's
111+
* clamp. The dispute cut is deliberately EXEMPT from the decrease clamp.
112+
*/
113+
export const AD_CREDIT_LINE_MAX_GROWTH_BPS = 10_000
114+
export const AD_CREDIT_LINE_MIN_GROWTH_STEP_CENTS =
115+
AD_POSTPAID_DEFAULT_CREDIT_LINE_CENTS
116+
export const AD_CREDIT_LINE_MAX_DECREASE_BPS = 2_500
117+
82118
/** Direct placements never sell below one dollar per billable click. */
83119
export const AD_PLACEMENT_CPC_FLOOR_CENTS = 100
84120

121+
/**
122+
* An operator-set floor exemption for ONE campaign
123+
* (`ad_placement_campaign.cpc_floor_override_cents`). It may only lower the
124+
* rate-card floor, and never to zero -- a zero price looks like a working
125+
* integration while billing nothing.
126+
*/
127+
export function isValidPlacementCpcFloorOverride(
128+
value: unknown,
129+
): value is number {
130+
return (
131+
Number.isInteger(value) &&
132+
(value as number) >= 1 &&
133+
(value as number) <= AD_PLACEMENT_CPC_FLOOR_CENTS
134+
)
135+
}
136+
137+
/**
138+
* The floor that actually binds a campaign.
139+
*
140+
* Anything other than a valid exemption resolves to the global floor, so an
141+
* out-of-range or malformed value fails SAFE (it raises the floor back to $1)
142+
* rather than opening it.
143+
*
144+
* This lives beside the constant, and not next to any one of its callers,
145+
* because four separate layers have to agree on it -- the admission
146+
* validators, the `/r/` click-recording guard, the reprice clamp, and the
147+
* table CHECK. Two of those are in `packages/internal` and two in
148+
* `freebuff/web`, and a second copy of this predicate is exactly how the
149+
* price a campaign serves at drifts from the price an automatic run will
150+
* clamp it to.
151+
*/
152+
export function effectivePlacementCpcFloorCents(
153+
overrideCents: unknown,
154+
): number {
155+
return isValidPlacementCpcFloorOverride(overrideCents)
156+
? overrideCents
157+
: AD_PLACEMENT_CPC_FLOOR_CENTS
158+
}
159+
85160
/** A single automatic reprice may move at most 25% in either direction. */
86161
export const AD_PLACEMENT_CPC_REPRICE_MAX_MOVE_BPS = 2_500
87162

freebuff/cli/release/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "freebuff",
3-
"version": "0.0.161",
3+
"version": "0.0.162",
44
"description": "The world's strongest free coding agent",
55
"license": "MIT",
66
"bin": {

0 commit comments

Comments
 (0)