mirror of
https://github.com/garrytan/gbrain.git
synced 2026-07-27 22:15:33 +00:00
feat(ai): add Moonshot Kimi provider recipe (#2378)
This commit is contained in:
@@ -23,6 +23,7 @@ import { zhipu } from './zhipu.ts';
|
||||
import { azureOpenAI } from './azure-openai.ts';
|
||||
import { zeroentropyai } from './zeroentropyai.ts';
|
||||
import { llamaServerReranker } from './llama-server-reranker.ts';
|
||||
import { moonshot } from './moonshot.ts';
|
||||
|
||||
const ALL: Recipe[] = [
|
||||
openai,
|
||||
@@ -42,6 +43,7 @@ const ALL: Recipe[] = [
|
||||
zhipu,
|
||||
azureOpenAI,
|
||||
zeroentropyai,
|
||||
moonshot,
|
||||
];
|
||||
|
||||
/** Map from `provider:id` key to recipe. */
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import type { Recipe } from '../types.ts';
|
||||
|
||||
/**
|
||||
* Moonshot AI / Kimi Open Platform. Kimi exposes an OpenAI-compatible
|
||||
* /v1/chat/completions API at https://api.moonshot.ai/v1.
|
||||
*
|
||||
* Verified against Kimi API docs and live /v1/models on 2026-06-23.
|
||||
* The recipe is local-production glue until upstream GBrain carries a native
|
||||
* Moonshot recipe; keep it registered in the local patch registry.
|
||||
*/
|
||||
export const moonshot: Recipe = {
|
||||
id: 'moonshot',
|
||||
name: 'Moonshot AI / Kimi',
|
||||
tier: 'openai-compat',
|
||||
implementation: 'openai-compatible',
|
||||
base_url_default: 'https://api.moonshot.ai/v1',
|
||||
auth_env: {
|
||||
required: ['MOONSHOT_API_KEY'],
|
||||
setup_url: 'https://platform.kimi.ai/console/api-keys',
|
||||
},
|
||||
touchpoints: {
|
||||
expansion: {
|
||||
models: ['kimi-k2.7-code', 'kimi-k2.7-code-highspeed', 'kimi-k2.6', 'kimi-k2.5'],
|
||||
// Kimi pricing varies by current promotional/account terms; do not use
|
||||
// this advisory field for budget enforcement. Canonical budget pricing
|
||||
// belongs in src/core/model-pricing.ts when verified for the account.
|
||||
price_last_verified: '2026-06-23',
|
||||
},
|
||||
chat: {
|
||||
models: ['kimi-k2.7-code', 'kimi-k2.7-code-highspeed', 'kimi-k2.6', 'kimi-k2.5'],
|
||||
supports_tools: true,
|
||||
// Kimi tool calling is enough for ordinary chat/tool calls. GBrain's
|
||||
// subagent loop remains Anthropic-pinned because upstream requires stable
|
||||
// Anthropic-style tool_use_id behavior across crashes/replays.
|
||||
supports_subagent_loop: false,
|
||||
supports_prompt_cache: false,
|
||||
max_context_tokens: 256000,
|
||||
price_last_verified: '2026-06-23',
|
||||
},
|
||||
},
|
||||
setup_hint: 'Get an API key at https://platform.kimi.ai/console/api-keys, then `export MOONSHOT_API_KEY=...` and use `moonshot:kimi-k2.7-code`.',
|
||||
};
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Moonshot/Kimi local recipe smoke.
|
||||
*
|
||||
* This pins the governed production exception GBrain-Local-003: GBrain can
|
||||
* route configured Kimi chat/expansion IDs through Moonshot's OpenAI-compatible
|
||||
* endpoint without treating `moonshot` as an unknown provider.
|
||||
*/
|
||||
|
||||
import { describe, expect, test } from 'bun:test';
|
||||
import { getRecipe } from '../../src/core/ai/recipes/index.ts';
|
||||
import { defaultResolveAuth } from '../../src/core/ai/gateway.ts';
|
||||
import { assertTouchpoint } from '../../src/core/ai/model-resolver.ts';
|
||||
import { AIConfigError } from '../../src/core/ai/errors.ts';
|
||||
|
||||
describe('recipe: moonshot', () => {
|
||||
test('registered with expected OpenAI-compatible shape', () => {
|
||||
const r = getRecipe('moonshot');
|
||||
expect(r).toBeDefined();
|
||||
expect(r!.id).toBe('moonshot');
|
||||
expect(r!.tier).toBe('openai-compat');
|
||||
expect(r!.implementation).toBe('openai-compatible');
|
||||
expect(r!.base_url_default).toBe('https://api.moonshot.ai/v1');
|
||||
expect(r!.auth_env?.required).toEqual(['MOONSHOT_API_KEY']);
|
||||
});
|
||||
|
||||
test('chat and expansion touchpoints include Kimi K2.7 Code', () => {
|
||||
const r = getRecipe('moonshot')!;
|
||||
expect(r.touchpoints.chat).toBeDefined();
|
||||
expect(r.touchpoints.expansion).toBeDefined();
|
||||
expect(r.touchpoints.chat!.models).toContain('kimi-k2.7-code');
|
||||
expect(r.touchpoints.expansion!.models).toContain('kimi-k2.7-code');
|
||||
expect(r.touchpoints.chat!.supports_tools).toBe(true);
|
||||
expect(r.touchpoints.chat!.supports_subagent_loop).toBe(false);
|
||||
});
|
||||
|
||||
test('configured Kimi model is accepted for chat and expansion', () => {
|
||||
const r = getRecipe('moonshot')!;
|
||||
expect(() => assertTouchpoint(r, 'chat', 'kimi-k2.7-code')).not.toThrow();
|
||||
expect(() => assertTouchpoint(r, 'expansion', 'kimi-k2.7-code')).not.toThrow();
|
||||
});
|
||||
|
||||
test('default auth: MOONSHOT_API_KEY set -> Bearer token', () => {
|
||||
const r = getRecipe('moonshot')!;
|
||||
const auth = defaultResolveAuth(r, { MOONSHOT_API_KEY: 'fake-moonshot-key' }, 'chat');
|
||||
expect(auth.headerName).toBe('Authorization');
|
||||
expect(auth.token).toBe('Bearer fake-moonshot-key');
|
||||
});
|
||||
|
||||
test('default auth: missing MOONSHOT_API_KEY -> AIConfigError', () => {
|
||||
const r = getRecipe('moonshot')!;
|
||||
expect(() => defaultResolveAuth(r, {}, 'chat')).toThrow(AIConfigError);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user