Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions common/src/__tests__/freebuff-models.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe('freebuff model availability', () => {
locale: 'en-US',
timeZone: 'America/Los_Angeles',
}),
).toBe('until 5:00 PM local')
).toBe('until 5:00 PM')
})

test('formats the next open time in the user local timezone while deployment is closed', () => {
Expand All @@ -21,16 +21,16 @@ describe('freebuff model availability', () => {
locale: 'en-US',
timeZone: 'America/Los_Angeles',
}),
).toBe('opens 6:00 AM local')
).toBe('opens 6:00 AM')
})

test('includes the weekday when the next opening is on a later local day', () => {
expect(
getFreebuffDeploymentAvailabilityLabel(new Date('2026-01-10T20:00:00Z'), {
getFreebuffDeploymentAvailabilityLabel(new Date('2026-01-11T03:00:00Z'), {
locale: 'en-US',
timeZone: 'America/Los_Angeles',
}),
).toBe('opens Mon 6:00 AM local')
).toBe('opens Sun 6:00 AM')
})

test('tracks deployment hours correctly across the open and close boundaries', () => {
Expand All @@ -46,5 +46,8 @@ describe('freebuff model availability', () => {
expect(isFreebuffDeploymentHours(new Date('2026-01-06T01:00:00Z'))).toBe(
false,
)
expect(isFreebuffDeploymentHours(new Date('2026-01-10T20:00:00Z'))).toBe(
true,
)
})
})
35 changes: 4 additions & 31 deletions common/src/constants/freebuff-models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface FreebuffModelOption {
/** Server-facing fallback copy for APIs and provider errors that can't know
* the caller's local timezone. The CLI should render
* `getFreebuffDeploymentAvailabilityLabel()` instead. */
export const FREEBUFF_DEPLOYMENT_HOURS_LABEL = '9am ET-5pm PT'
export const FREEBUFF_DEPLOYMENT_HOURS_LABEL = '9am ET-5pm PT every day'
export const FREEBUFF_GLM_MODEL_ID = 'z-ai/glm-5.1'
export const FREEBUFF_MINIMAX_MODEL_ID = 'minimax/minimax-m2.7'
const FREEBUFF_EASTERN_TIMEZONE = 'America/New_York'
Expand All @@ -30,7 +30,6 @@ interface ZonedDateParts {
year: number
month: number
day: number
weekday: string
hour: number
minute: number
}
Expand Down Expand Up @@ -96,7 +95,6 @@ function getZonedParts(date: Date, timeZone: string): ZonedDateParts {
year: 'numeric',
month: '2-digit',
day: '2-digit',
weekday: 'short',
hour: '2-digit',
minute: '2-digit',
hourCycle: 'h23',
Expand All @@ -112,7 +110,6 @@ function getZonedParts(date: Date, timeZone: string): ZonedDateParts {
year,
month,
day,
weekday: value('weekday') ?? '',
hour,
minute,
}
Expand Down Expand Up @@ -165,34 +162,11 @@ function getUtcForZonedTime(
return guess
}

function isWeekend(
parts: Pick<ZonedDateParts, 'year' | 'month' | 'day'>,
): boolean {
const weekday = getWeekdayIndex(parts)
return weekday === 0 || weekday === 6
}

function getWeekdayIndex(
parts: Pick<ZonedDateParts, 'year' | 'month' | 'day'>,
): number {
return new Date(Date.UTC(parts.year, parts.month - 1, parts.day)).getUTCDay()
}

function getNextFreebuffDeploymentStart(now: Date): Date {
const easternNow = getZonedParts(now, FREEBUFF_EASTERN_TIMEZONE)
const weekday = getWeekdayIndex(easternNow)
const isBeforeTodayOpen = easternNow.hour < 9

const offset =
weekday === 6
? 2
: weekday === 0
? 1
: isBeforeTodayOpen
? 0
: weekday === 5
? 3
: 1
const offset = isBeforeTodayOpen ? 0 : 1

return getUtcForZonedTime(
addDaysToYmd(easternNow.year, easternNow.month, easternNow.day, offset),
Expand Down Expand Up @@ -241,17 +215,16 @@ export function getFreebuffDeploymentAvailabilityLabel(
): string {
if (isFreebuffDeploymentHours(now)) {
const closesAt = getCurrentFreebuffDeploymentEnd(now)
return `until ${formatLocalTime(closesAt, now, options)} local`
return `until ${formatLocalTime(closesAt, now, options)}`
}

const opensAt = getNextFreebuffDeploymentStart(now)
return `opens ${formatLocalTime(opensAt, now, options)} local`
return `opens ${formatLocalTime(opensAt, now, options)}`
}

export function isFreebuffDeploymentHours(now: Date = new Date()): boolean {
const eastern = getZonedParts(now, FREEBUFF_EASTERN_TIMEZONE)
const pacific = getZonedParts(now, FREEBUFF_PACIFIC_TIMEZONE)
if (eastern.weekday === 'Sat' || eastern.weekday === 'Sun') return false
return (
eastern.hour * 60 + eastern.minute >= 9 * 60 &&
pacific.hour * 60 + pacific.minute < 17 * 60
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ describe('POST /api/v1/freebuff/session', () => {
expect(resp.status).toBe(409)
const body = await resp.json()
expect(body.status).toBe('model_unavailable')
expect(body.availableHours).toBe('9am ET-5pm PT')
expect(body.availableHours).toBe('9am ET-5pm PT every day')
expect(sessionDeps.rows.size).toBe(0)
})

Expand Down
6 changes: 3 additions & 3 deletions web/src/llm-api/__tests__/fireworks-deployment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ function createMockLogger(): Logger {

describe('Fireworks deployment routing', () => {
describe('deployment hours', () => {
it('is active from 9am ET until before 5pm PT on weekdays', () => {
it('is active from 9am ET until before 5pm PT every day', () => {
expect(isDeploymentHours(BEFORE_DEPLOYMENT_HOURS)).toBe(false)
expect(isDeploymentHours(IN_DEPLOYMENT_HOURS)).toBe(true)
expect(isDeploymentHours(AFTER_DEPLOYMENT_HOURS)).toBe(false)
expect(isDeploymentHours(WEEKDAY_AFTER_DEPLOYMENT_HOURS)).toBe(false)
})

it('is inactive on weekends', () => {
expect(isDeploymentHours(WEEKEND_DEPLOYMENT_HOURS)).toBe(false)
it('is active on weekends during deployment hours', () => {
expect(isDeploymentHours(WEEKEND_DEPLOYMENT_HOURS)).toBe(true)
})
})

Expand Down
2 changes: 1 addition & 1 deletion web/src/llm-api/fireworks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const FIREWORKS_MODEL_MAP: Record<string, string> = {
/** Flag to enable custom Fireworks deployments (set to false to use global API only) */
const FIREWORKS_USE_CUSTOM_DEPLOYMENT = true

/** Check if current time is within deployment hours: Mon-Fri, 9am ET to 5pm PT. */
/** Check if current time is within deployment hours: daily, 9am ET to 5pm PT. */
export function isDeploymentHours(now: Date = new Date()): boolean {
return isFreebuffDeploymentHours(now)
}
Expand Down
2 changes: 1 addition & 1 deletion web/src/server/free-session/__tests__/public-api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ describe('requestSession', () => {
expect(state).toEqual({
status: 'model_unavailable',
requestedModel: 'z-ai/glm-5.1',
availableHours: '9am ET-5pm PT',
availableHours: '9am ET-5pm PT every day',
})
expect(deps.rows.size).toBe(0)
})
Expand Down
Loading