Skip to content

Commit c117975

Browse files
jahoomaclaude
andcommitted
Wire Kimi K2.6 via CanopyWave through to base2-free
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 4f907c1 commit c117975

3 files changed

Lines changed: 26 additions & 33 deletions

File tree

cli/src/utils/__tests__/freebuff-model-navigation.test.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,49 +7,49 @@ import {
77

88
describe('nextSelectableFreebuffModelId', () => {
99
test('skips unavailable models when moving forward', () => {
10-
const modelIds = ['glm', 'minimax']
10+
const modelIds = ['kimi', 'minimax']
1111

1212
expect(
1313
nextSelectableFreebuffModelId({
1414
modelIds,
1515
focusedId: 'minimax',
1616
direction: 'forward',
17-
isSelectable: (id) => id !== 'glm',
17+
isSelectable: (id) => id !== 'kimi',
1818
}),
1919
).toBe('minimax')
2020
})
2121

2222
test('skips unavailable models when moving backward', () => {
23-
const modelIds = ['glm', 'minimax']
23+
const modelIds = ['kimi', 'minimax']
2424

2525
expect(
2626
nextSelectableFreebuffModelId({
2727
modelIds,
2828
focusedId: 'minimax',
2929
direction: 'backward',
30-
isSelectable: (id) => id !== 'glm',
30+
isSelectable: (id) => id !== 'kimi',
3131
}),
3232
).toBe('minimax')
3333
})
3434

3535
test('moves to the next available model when more than one is selectable', () => {
36-
const modelIds = ['glm', 'minimax', 'other']
36+
const modelIds = ['kimi', 'minimax', 'other']
3737

3838
expect(
3939
nextSelectableFreebuffModelId({
4040
modelIds,
4141
focusedId: 'minimax',
4242
direction: 'forward',
43-
isSelectable: (id) => id !== 'glm',
43+
isSelectable: (id) => id !== 'kimi',
4444
}),
4545
).toBe('other')
4646
})
4747

4848
test('returns null when no selectable model exists', () => {
4949
expect(
5050
nextSelectableFreebuffModelId({
51-
modelIds: ['glm'],
52-
focusedId: 'glm',
51+
modelIds: ['kimi'],
52+
focusedId: 'kimi',
5353
direction: 'forward',
5454
isSelectable: () => false,
5555
}),
@@ -61,10 +61,10 @@ describe('resolveFreebuffModelCommitTarget', () => {
6161
test('falls back to the selected model when focus is on a closed model', () => {
6262
expect(
6363
resolveFreebuffModelCommitTarget({
64-
focusedId: 'glm',
64+
focusedId: 'kimi',
6565
selectedId: 'minimax',
6666
committedId: null,
67-
isSelectable: (id) => id !== 'glm',
67+
isSelectable: (id) => id !== 'kimi',
6868
}),
6969
).toBe('minimax')
7070
})
@@ -73,7 +73,7 @@ describe('resolveFreebuffModelCommitTarget', () => {
7373
expect(
7474
resolveFreebuffModelCommitTarget({
7575
focusedId: 'minimax',
76-
selectedId: 'glm',
76+
selectedId: 'kimi',
7777
committedId: null,
7878
isSelectable: (id) => id === 'minimax',
7979
}),

common/src/constants/freebuff-models.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ interface LocalTimeFormatOptions {
3939
timeZone?: string
4040
}
4141

42-
export const FREEBUFF_MODELS = [
42+
export const FREEBUFF_MODELS: readonly FreebuffModelOption[] = [
4343
{
4444
id: FREEBUFF_MINIMAX_MODEL_ID,
4545
displayName: 'MiniMax M2.7',
@@ -52,9 +52,11 @@ export const FREEBUFF_MODELS = [
5252
tagline: 'Smartest',
5353
availability: 'always',
5454
},
55-
] as const satisfies readonly FreebuffModelOption[]
55+
]
5656

57-
export type FreebuffModelId = (typeof FREEBUFF_MODELS)[number]['id']
57+
export type FreebuffModelId =
58+
| typeof FREEBUFF_MINIMAX_MODEL_ID
59+
| typeof FREEBUFF_KIMI_MODEL_ID
5860

5961
/** What new freebuff users see selected in the picker. */
6062
export const DEFAULT_FREEBUFF_MODEL_ID: FreebuffModelId = FREEBUFF_KIMI_MODEL_ID

web/src/app/api/v1/chat/completions/__tests__/completions.test.ts

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { afterEach, beforeEach, describe, expect, mock, it } from 'bun:test'
22
import { NextRequest } from 'next/server'
33

4-
import { isFreebuffDeploymentHours } from '@codebuff/common/constants/freebuff-models'
54
import { formatQuotaResetCountdown, postChatCompletions } from '../_post'
65

76
import type { TrackEventFn } from '@codebuff/common/types/contracts/analytics'
@@ -556,15 +555,15 @@ describe('/api/v1/chat/completions POST endpoint', () => {
556555
expect(response.status).toBe(200)
557556
})
558557

559-
it('lets freebuff use GLM 5.1 through Fireworks availability rules', async () => {
558+
it('lets freebuff use Kimi K2.6 through CanopyWave', async () => {
560559
const fetchedBodies: Record<string, unknown>[] = []
561-
const fetchViaFireworks = mock(
560+
const fetchViaCanopyWave = mock(
562561
async (_url: string | URL | Request, init?: RequestInit) => {
563562
fetchedBodies.push(JSON.parse(init?.body as string))
564563
return new Response(
565564
JSON.stringify({
566565
id: 'test-id',
567-
model: 'accounts/james-65d217/deployments/mjb4i7ea',
566+
model: 'moonshotai/kimi-k2.6',
568567
choices: [{ message: { content: 'test response' } }],
569568
usage: {
570569
prompt_tokens: 10,
@@ -586,7 +585,7 @@ describe('/api/v1/chat/completions POST endpoint', () => {
586585
method: 'POST',
587586
headers: { Authorization: 'Bearer test-api-key-new-free' },
588587
body: JSON.stringify({
589-
model: 'z-ai/glm-5.1',
588+
model: 'moonshotai/kimi-k2.6',
590589
stream: false,
591590
codebuff_metadata: {
592591
run_id: 'run-free',
@@ -604,26 +603,18 @@ describe('/api/v1/chat/completions POST endpoint', () => {
604603
trackEvent: mockTrackEvent,
605604
getUserUsageData: mockGetUserUsageData,
606605
getAgentRunFromId: mockGetAgentRunFromId,
607-
fetch: fetchViaFireworks,
606+
fetch: fetchViaCanopyWave,
608607
insertMessageBigquery: mockInsertMessageBigquery,
609608
loggerWithContext: mockLoggerWithContext,
610609
checkSessionAdmissible: mockCheckSessionAdmissibleAllow,
611610
})
612611

613612
const body = await response.json()
614-
if (isFreebuffDeploymentHours()) {
615-
expect(response.status).toBe(200)
616-
expect(fetchedBodies).toHaveLength(1)
617-
expect(fetchedBodies[0].model).toBe(
618-
'accounts/james-65d217/deployments/mjb4i7ea',
619-
)
620-
expect(body.model).toBe('z-ai/glm-5.1')
621-
expect(body.provider).toBe('Fireworks')
622-
} else {
623-
expect(response.status).toBe(503)
624-
expect(fetchedBodies).toHaveLength(0)
625-
expect(body.error.code).toBe('DEPLOYMENT_OUTSIDE_HOURS')
626-
}
613+
expect(response.status).toBe(200)
614+
expect(fetchedBodies).toHaveLength(1)
615+
expect(fetchedBodies[0].model).toBe('moonshotai/kimi-k2.6')
616+
expect(body.model).toBe('moonshotai/kimi-k2.6')
617+
expect(body.provider).toBe('CanopyWave')
627618
})
628619

629620
it('skips credit check when in FREE mode even with 0 credits', async () => {

0 commit comments

Comments
 (0)