Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
4ca9bd6
feat(kimi): add K3 context variants
jatmn Jul 16, 2026
696345b
fix(moonshot): default K3 to 1M
jatmn Jul 16, 2026
a2c1683
fix(kimi): restore K3 model name
jatmn Jul 16, 2026
06db340
fix(kimi): preserve K3 route metadata
jatmn Jul 16, 2026
5cbb8f4
fix(kimi): recommend the selected context variant
jatmn Jul 16, 2026
12d4929
fix(kimi): preserve max shim reasoning effort
jatmn Jul 16, 2026
1dc3e77
fix(kimi): validate K3 reasoning levels
jatmn Jul 17, 2026
a018d6c
fix(kimi): reconcile K3 route metadata
jatmn Jul 17, 2026
3918aad
test(integrations): accept catalog default ids
jatmn Jul 17, 2026
f241893
fix(kimi): preserve K3 runtime limits and effort aliases
jatmn Jul 17, 2026
c2596a4
fix(kimi): preserve override context limits
jatmn Jul 17, 2026
1a31297
fix(kimi): canonicalize K3 reasoning to max
jatmn Jul 17, 2026
08ad24f
fix(moonshot): preserve K3 query reasoning
jatmn Jul 17, 2026
765efa7
fix(effort): scope K3 xhigh normalization
jatmn Jul 17, 2026
14f2425
fix(kimi): scope max-only override effort
jatmn Jul 17, 2026
0c7462e
docs(kimi): qualify HighSpeed plan claim
jatmn Jul 17, 2026
067b98d
fix(kimi): preserve documented K3 effort levels
jatmn Jul 17, 2026
6c2e81b
fix(kimi): preserve disabled thinking for K3
jatmn Jul 17, 2026
60dc56c
fix(kimi): avoid disabled-thinking fallback
jatmn Jul 19, 2026
96a9693
fix(compact): honor route runtime output limits
jatmn Jul 19, 2026
b06ab5f
fix(rebase): preserve transport compression routing
jatmn Jul 20, 2026
b63adf0
fix(kimi): preserve route defaults and runtime controls
jatmn Jul 20, 2026
67aa643
fix(kimi): retain selected runtime limits for overrides
jatmn Jul 20, 2026
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
15 changes: 15 additions & 0 deletions docs/integrations/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,21 @@ fields. Only add `reasoning` metadata when the exact route/model request shape,
accepted levels, and disable behavior have been verified. See
`docs/integrations/reasoning-effort.md`.

### Moonshot and Kimi K3 catalogs

The direct Moonshot API exposes Kimi K3 as `kimi-k3`, with a 1,048,576-token
context window, 32,768 maximum output tokens, and `reasoning_effort` levels
`low`, `high`, and `max` (defaulting to `max`). Kimi Code K3 uses the same
controls for two catalog selections: `k3` provides the 1M Allegretto+ window, while
`k3-256k` keeps Moderato+ sessions within their 256K limit.

Kimi Code also lists `kimi-for-coding-highspeed` for eligible Allegretto+
subscriptions. [Kimi documents](https://www.kimi.com/code/docs/en/kimi-code/models.html)
it as HighSpeed with approximately 6× output speed and 3× quota usage; plan
availability can vary. Retain the selected catalog ID in client-side routing so
its route-specific limits and capabilities are not lost when the outbound API
model is normalized.

## Descriptor Authoring Pattern

Normal descriptor files should:
Expand Down
5 changes: 5 additions & 0 deletions src/integrations/gateways/kimi-code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export default defineGateway({
label: 'Moonshot AI - Kimi Code',
category: 'hosted',
defaultBaseUrl: 'https://api.kimi.com/coding/v1',
// K3 requires a Moderato subscription. Keep the all-members K2.7 model as
// the default; eligible users can explicitly select either K3 variant.
defaultModel: 'kimi-for-coding',
supportsModelRouting: true,
setup: {
Expand Down Expand Up @@ -33,8 +35,11 @@ export default defineGateway({
catalog: {
source: 'static',
models: [
{ id: 'k3', apiName: 'k3', label: 'Kimi K3 (1M)', modelDescriptorId: 'k3', contextWindow: 1_048_576, maxOutputTokens: 32_768, capabilities: { supportsVision: true, supportsFunctionCalling: true, supportsJsonMode: true, supportsReasoning: true }, reasoning: { mode: 'levels', levels: ['low', 'high', 'max'], defaultLevel: 'max', wireFormat: 'reasoning_effort', disableFormat: 'thinking_type_disabled' }, notes: 'Allegretto+' },
{ id: 'k3-256k', apiName: 'k3', label: 'Kimi K3 (256K)', modelDescriptorId: 'k3', contextWindow: 262_144, maxOutputTokens: 32_768, capabilities: { supportsVision: true, supportsFunctionCalling: true, supportsJsonMode: true, supportsReasoning: true }, reasoning: { mode: 'levels', levels: ['low', 'high', 'max'], defaultLevel: 'max', wireFormat: 'reasoning_effort', disableFormat: 'thinking_type_disabled' }, notes: 'Moderato+' },
{ id: 'kimi-k2.7-code', apiName: 'kimi-k2.7-code', aliases: ['moonshotai/kimi-k2.7-code'], label: 'Kimi K2.7 Code', modelDescriptorId: 'kimi-k2.7-code', contextWindow: 262_144, maxOutputTokens: 32_768, capabilities: { supportsVision: true, supportsFunctionCalling: true, supportsJsonMode: true, supportsReasoning: true }, reasoning: { mode: 'levels', levels: ['low', 'medium', 'high'], defaultLevel: 'medium', wireFormat: 'reasoning_effort' } },
{ id: 'kimi-for-coding', apiName: 'kimi-for-coding', label: 'Kimi for Coding', modelDescriptorId: 'kimi-for-coding', contextWindow: 262_144, maxOutputTokens: 32_768, capabilities: { supportsVision: true, supportsFunctionCalling: true, supportsJsonMode: true, supportsReasoning: true }, reasoning: { mode: 'levels', levels: ['low', 'medium', 'high'], defaultLevel: 'medium', wireFormat: 'reasoning_effort' } },
{ id: 'kimi-for-coding-highspeed', apiName: 'kimi-for-coding-highspeed', label: 'Kimi K2.7 Code HighSpeed (Allegretto+)', modelDescriptorId: 'kimi-for-coding', contextWindow: 262_144, maxOutputTokens: 32_768, capabilities: { supportsVision: true, supportsFunctionCalling: true, supportsJsonMode: true, supportsReasoning: true }, reasoning: { mode: 'levels', levels: ['low', 'medium', 'high'], defaultLevel: 'medium', wireFormat: 'reasoning_effort' }, notes: 'Requires Allegretto or above; 6x speed and 3x quota usage.' },
],
},
usage: { supported: false },
Expand Down
1 change: 1 addition & 0 deletions src/integrations/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ describe('loaded registry validation', () => {
const defaultModel = gateway.defaultModel?.trim()
return !(gateway.catalog?.models ?? []).some(
entry =>
entry.id === defaultModel ||
entry.apiName === defaultModel ||
entry.modelDescriptorId === defaultModel,
)
Expand Down
8 changes: 8 additions & 0 deletions src/integrations/models/kimi.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { expect, test } from 'bun:test'

import { getModel, getModelsForBrand } from '../index.js'

test('K3 belongs to the Kimi brand', () => {
expect(getModel('k3')?.brandId).toBe('kimi')
expect(getModelsForBrand('kimi').map(model => model.id)).toContain('k3')
})
1 change: 1 addition & 0 deletions src/integrations/models/kimi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ function kimiModel(
}

export default [
kimiModel('k3', 'Kimi K3', 1_048_576, 32_768),
kimiModel('kimi-for-coding', 'Kimi for Coding', 262_144, 32_768),
kimiModel('kimi-k2.7-code', 'Kimi K2.7 Code', 262_144, 262_144),
kimiModel('kimi-k2.6', 'Kimi K2.6', 262_144, 32_768),
Expand Down
40 changes: 40 additions & 0 deletions src/integrations/runtimeMetadata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,14 @@ describe('resolveOpenAIShimRuntimeContext - NVIDIA NIM GLM-5.2 (regression #1950

describe('resolveOpenAIShimRuntimeContext - Moonshot and Kimi Code catalog metadata', () => {
it('uses Moonshot direct catalog order, limits, and reasoning controls', () => {
expect(
resolveModelRuntimeLimits({
model: 'kimi-k3',
baseUrl: 'https://api.moonshot.ai/v1',
processEnv: { CLAUDE_CODE_USE_OPENAI: '1' },
}),
).toEqual({ contextWindow: 1_048_576, maxOutputTokens: 32_768 })

expect(
resolveModelRuntimeLimits({
model: 'kimi-k2.7-code',
Expand Down Expand Up @@ -336,6 +344,7 @@ describe('resolveOpenAIShimRuntimeContext - Moonshot and Kimi Code catalog metad

expect(result.routeId).toBe('moonshot')
expect(result.descriptor?.catalog?.models?.map(model => model.id)).toEqual([
'k3',
'kimi-k2.7-code',
'kimi-k2.6',
'kimi-k2.5',
Expand Down Expand Up @@ -374,9 +383,40 @@ describe('resolveOpenAIShimRuntimeContext - Moonshot and Kimi Code catalog metad

expect(result.routeId).toBe('kimi-code')
expect(result.descriptor?.catalog?.models?.map(model => model.id)).toEqual([
'k3',
'k3-256k',
'kimi-k2.7-code',
'kimi-for-coding',
'kimi-for-coding-highspeed',
])
Comment thread
coderabbitai[bot] marked this conversation as resolved.
const k3 = resolveOpenAIShimRuntimeContext({
model: 'k3',
baseUrl: 'https://api.kimi.com/coding/v1',
processEnv: { CLAUDE_CODE_USE_OPENAI: '1' },
})
expect(k3.catalogEntry).toMatchObject({
id: 'k3',
contextWindow: 1_048_576,
label: 'Kimi K3 (1M)',
})
expect(k3.catalogEntry?.reasoning?.levels).toEqual(['low', 'high', 'max'])
expect(resolveModelRuntimeLimits({
model: 'k3-256k',
baseUrl: 'https://api.kimi.com/coding/v1',
processEnv: { CLAUDE_CODE_USE_OPENAI: '1' },
})).toEqual({ contextWindow: 262_144, maxOutputTokens: 32_768 })
const highspeed = resolveOpenAIShimRuntimeContext({
model: 'kimi-for-coding-highspeed',
baseUrl: 'https://api.kimi.com/coding/v1',
processEnv: { CLAUDE_CODE_USE_OPENAI: '1' },
})
expect(highspeed.catalogEntry).toMatchObject({
id: 'kimi-for-coding-highspeed',
apiName: 'kimi-for-coding-highspeed',
contextWindow: 262_144,
maxOutputTokens: 32_768,
})
expect(highspeed.catalogEntry?.reasoning?.levels).toEqual(['low', 'medium', 'high'])
expect(result.catalogEntry?.id).toBe('kimi-for-coding')
expect(result.catalogEntry?.reasoning?.levels).toEqual(['low', 'medium', 'high'])
expect(result.catalogEntry?.reasoning?.defaultLevel).toBe('medium')
Expand Down
5 changes: 4 additions & 1 deletion src/integrations/runtimeMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ function matchesCatalogEntryModel(
entry: ModelCatalogEntry,
modelApiName: string,
): boolean {
if (entry.apiName.trim().toLowerCase() === modelApiName) {
if (
entry.apiName.trim().toLowerCase() === modelApiName ||
entry.id.trim().toLowerCase() === modelApiName
) {
return true
}

Expand Down
1 change: 1 addition & 0 deletions src/integrations/vendors/moonshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export default defineVendor({
catalog: {
source: 'static',
models: [
{ id: 'k3', apiName: 'kimi-k3', label: 'Kimi K3', modelDescriptorId: 'k3', contextWindow: 1_048_576, maxOutputTokens: 32_768, capabilities: { supportsVision: true, supportsFunctionCalling: true, supportsJsonMode: true, supportsReasoning: true }, reasoning: { mode: 'levels', levels: ['low', 'high', 'max'], defaultLevel: 'max', wireFormat: 'reasoning_effort' } },
{ id: 'kimi-k2.7-code', apiName: 'kimi-k2.7-code', aliases: ['moonshotai/kimi-k2.7-code'], label: 'Kimi K2.7 Code', modelDescriptorId: 'kimi-k2.7-code', contextWindow: 262_144, maxOutputTokens: 32_768, capabilities: { supportsVision: true, supportsFunctionCalling: true, supportsJsonMode: true, supportsReasoning: true }, reasoning: { mode: 'levels', levels: ['low', 'medium', 'high'], defaultLevel: 'medium', wireFormat: 'reasoning_effort' } },
{ id: 'kimi-k2.6', apiName: 'kimi-k2.6', aliases: ['moonshotai/kimi-k2.6'], label: 'Kimi K2.6', modelDescriptorId: 'kimi-k2.6', contextWindow: 262_144, maxOutputTokens: 262_144, capabilities: { supportsVision: true, supportsFunctionCalling: true, supportsJsonMode: true, supportsReasoning: true }, reasoning: { mode: 'levels', levels: ['low', 'medium', 'high'], defaultLevel: 'medium', wireFormat: 'reasoning_effort' } },
{ id: 'kimi-k2.5', apiName: 'kimi-k2.5', aliases: ['moonshotai/kimi-k2.5'], label: 'Kimi K2.5', modelDescriptorId: 'kimi-k2.5', contextWindow: 262_144, maxOutputTokens: 262_144, capabilities: { supportsVision: true, supportsFunctionCalling: true, supportsJsonMode: true, supportsReasoning: true }, reasoning: { mode: 'levels', levels: ['low', 'medium', 'high'], defaultLevel: 'medium', wireFormat: 'reasoning_effort' } },
Expand Down
Loading