Skip to content

Commit 20a3090

Browse files
jahoomaclaude
andcommitted
Enable OpenCode Zen for minimax + kimi; add buffbench agents
Wires the OpenCode Zen scaffold into the chat-completions router for opencode/minimax-m2.7 and opencode/kimi-k2.6, replacing the disabled rejection. Adds two buffbench agents (base2-free-opencode-kimi, base2-free-opencode-minimax) and points buffbench main.ts at the minimax variant. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 63caaac commit 20a3090

5 files changed

Lines changed: 169 additions & 169 deletions

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { openCodeZenModels } from '@codebuff/common/constants/model-config'
2+
3+
import { createBase2 } from './base2'
4+
5+
const definition = {
6+
...createBase2('free', {
7+
noAskUser: true,
8+
model: openCodeZenModels.opencode_kimi_k2_6,
9+
}),
10+
id: 'base2-free-opencode-kimi',
11+
displayName: 'Buffy the Kimi (OpenCode) Free Orchestrator',
12+
}
13+
14+
export default definition
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { openCodeZenModels } from '@codebuff/common/constants/model-config'
2+
3+
import { createBase2 } from './base2'
4+
5+
const definition = {
6+
...createBase2('free', {
7+
noAskUser: true,
8+
model: openCodeZenModels.opencode_minimax_m2_7,
9+
}),
10+
id: 'base2-free-opencode-minimax',
11+
displayName: 'Buffy the MiniMax (OpenCode) Free Orchestrator',
12+
}
13+
14+
export default definition

evals/buffbench/main.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ async function main() {
1111
// Use 'external:opencode' for OpenCode CLI
1212
await runBuffBench({
1313
evalDataPaths: [path.join(__dirname, 'eval-codebuff.json')],
14-
agents: ['base2-free-evals'],
14+
agents: ['base2-free-opencode-minimax'],
1515
taskConcurrency: 6,
1616
saveTraces,
1717
})

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

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -854,15 +854,44 @@ describe('/api/v1/chat/completions POST endpoint', () => {
854854
)
855855

856856
it(
857-
'rejects OpenCode Zen models while the Zen integration is disabled',
857+
'routes OpenCode Zen models to the direct OpenCode Zen provider',
858858
async () => {
859-
const fetchViaOpenCodeZen = mock(
860-
async (_url: string | URL | Request, _init?: RequestInit) => {
861-
throw new Error('OpenCode Zen should not be called')
862-
},
863-
) as unknown as typeof globalThis.fetch
859+
const expectedUpstreamModel: Record<string, string> = {
860+
'opencode/minimax-m2.7': 'minimax-m2.7',
861+
'opencode/kimi-k2.6': 'kimi-k2.6',
862+
}
864863

865864
for (const codebuffModel of Object.values(openCodeZenModels)) {
865+
const fetchedBodies: Record<string, unknown>[] = []
866+
const fetchedUrls: string[] = []
867+
const fetchViaOpenCodeZen = mock(
868+
async (url: string | URL | Request, init?: RequestInit) => {
869+
if (String(url).startsWith('https://api.ipinfo.io/lookup/')) {
870+
return Response.json({})
871+
}
872+
873+
fetchedUrls.push(String(url))
874+
fetchedBodies.push(JSON.parse(init?.body as string))
875+
return new Response(
876+
JSON.stringify({
877+
id: 'test-id',
878+
model: expectedUpstreamModel[codebuffModel],
879+
choices: [{ message: { content: 'test response' } }],
880+
usage: {
881+
prompt_tokens: 10,
882+
prompt_tokens_details: { cached_tokens: 4 },
883+
completion_tokens: 20,
884+
total_tokens: 30,
885+
},
886+
}),
887+
{
888+
status: 200,
889+
headers: { 'Content-Type': 'application/json' },
890+
},
891+
)
892+
},
893+
) as unknown as typeof globalThis.fetch
894+
866895
const req = new NextRequest(
867896
'http://localhost:3000/api/v1/chat/completions',
868897
{
@@ -921,13 +950,14 @@ describe('/api/v1/chat/completions POST endpoint', () => {
921950
})
922951

923952
const body = await response.json()
924-
expect(response.status).toBe(400)
925-
expect(body).toEqual({
926-
error: 'opencode_zen_disabled',
927-
message: 'OpenCode Zen models are currently disabled.',
928-
})
953+
expect(response.status).toBe(200)
954+
expect(fetchedUrls[0]).toBe(
955+
'https://opencode.ai/zen/v1/chat/completions',
956+
)
957+
expect(fetchedBodies[0].model).toBe(expectedUpstreamModel[codebuffModel])
958+
expect(body.model).toBe(codebuffModel)
959+
expect(body.provider).toBe('OpenCode Zen')
929960
}
930-
expect(fetchViaOpenCodeZen).not.toHaveBeenCalled()
931961
},
932962
FETCH_PATH_TEST_TIMEOUT_MS,
933963
)

0 commit comments

Comments
 (0)