diff --git a/common/src/__tests__/freebuff-models.test.ts b/common/src/__tests__/freebuff-models.test.ts index c4ff0bb3e..0d01d2762 100644 --- a/common/src/__tests__/freebuff-models.test.ts +++ b/common/src/__tests__/freebuff-models.test.ts @@ -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', () => { @@ -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', () => { @@ -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, + ) }) }) diff --git a/common/src/constants/freebuff-models.ts b/common/src/constants/freebuff-models.ts index a4ddd6f41..8b3e9d82d 100644 --- a/common/src/constants/freebuff-models.ts +++ b/common/src/constants/freebuff-models.ts @@ -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' @@ -30,7 +30,6 @@ interface ZonedDateParts { year: number month: number day: number - weekday: string hour: number minute: number } @@ -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', @@ -112,7 +110,6 @@ function getZonedParts(date: Date, timeZone: string): ZonedDateParts { year, month, day, - weekday: value('weekday') ?? '', hour, minute, } @@ -165,34 +162,11 @@ function getUtcForZonedTime( return guess } -function isWeekend( - parts: Pick, -): boolean { - const weekday = getWeekdayIndex(parts) - return weekday === 0 || weekday === 6 -} - -function getWeekdayIndex( - parts: Pick, -): 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), @@ -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 diff --git a/web/src/app/api/v1/freebuff/session/__tests__/session.test.ts b/web/src/app/api/v1/freebuff/session/__tests__/session.test.ts index e4675e488..7ed29ec4b 100644 --- a/web/src/app/api/v1/freebuff/session/__tests__/session.test.ts +++ b/web/src/app/api/v1/freebuff/session/__tests__/session.test.ts @@ -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) }) diff --git a/web/src/llm-api/__tests__/fireworks-deployment.test.ts b/web/src/llm-api/__tests__/fireworks-deployment.test.ts index be17a6e2e..8ffd3cbca 100644 --- a/web/src/llm-api/__tests__/fireworks-deployment.test.ts +++ b/web/src/llm-api/__tests__/fireworks-deployment.test.ts @@ -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) }) }) diff --git a/web/src/llm-api/fireworks.ts b/web/src/llm-api/fireworks.ts index a2f4f80a8..c39daa2a1 100644 --- a/web/src/llm-api/fireworks.ts +++ b/web/src/llm-api/fireworks.ts @@ -41,7 +41,7 @@ const FIREWORKS_MODEL_MAP: Record = { /** 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) } diff --git a/web/src/server/free-session/__tests__/public-api.test.ts b/web/src/server/free-session/__tests__/public-api.test.ts index 8b08d63df..44d516c12 100644 --- a/web/src/server/free-session/__tests__/public-api.test.ts +++ b/web/src/server/free-session/__tests__/public-api.test.ts @@ -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) })