mirror of
https://github.com/tiennm99/ccs.git
synced 2026-09-02 08:19:59 +00:00
Merge pull request #585 from kaitranntt/kai/fix/kimi-missing-models
fix(cliproxy): add Kimi model catalog, sync, and pricing to dashboard
This commit is contained in:
@@ -23,6 +23,7 @@ const CHANNEL_TO_PROVIDER: Record<string, CLIProxyProvider> = {
|
||||
codex: 'codex',
|
||||
qwen: 'qwen',
|
||||
iflow: 'iflow',
|
||||
kimi: 'kimi',
|
||||
};
|
||||
|
||||
/** CCS provider → channel name mapping (reverse) */
|
||||
@@ -31,7 +32,7 @@ export const PROVIDER_TO_CHANNEL: Record<string, string> = Object.fromEntries(
|
||||
);
|
||||
|
||||
/** Providers to sync from CLIProxyAPI */
|
||||
export const SYNCABLE_PROVIDERS: CLIProxyProvider[] = ['agy', 'gemini', 'codex', 'claude'];
|
||||
export const SYNCABLE_PROVIDERS: CLIProxyProvider[] = ['agy', 'gemini', 'codex', 'claude', 'kimi'];
|
||||
|
||||
function getCacheFilePath(): string {
|
||||
return path.join(getCcsDir(), CACHE_FILE_NAME);
|
||||
|
||||
@@ -205,7 +205,7 @@ export const MODEL_CATALOG: Partial<Record<CLIProxyProvider, ProviderCatalog>> =
|
||||
{
|
||||
id: 'kimi-k2.5',
|
||||
name: 'Kimi K2.5',
|
||||
description: 'Latest Moonshot coding model',
|
||||
description: 'Latest multimodal model (262K context)',
|
||||
thinking: {
|
||||
type: 'budget',
|
||||
min: 1024,
|
||||
|
||||
@@ -450,37 +450,50 @@ const PRICING_REGISTRY: Record<string, ModelPricing> = {
|
||||
},
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Kimi Models (Moonshot AI) - Source: better-ccusage
|
||||
// Kimi Models (Moonshot AI) - Source: Official Kimi Platform pricing
|
||||
// inputPerMillion = cache miss price, cacheReadPerMillion = cache hit price
|
||||
// ---------------------------------------------------------------------------
|
||||
'kimi-for-coding': {
|
||||
inputPerMillion: 0.15,
|
||||
outputPerMillion: 0.6,
|
||||
'kimi-k2.5': {
|
||||
inputPerMillion: 0.6,
|
||||
outputPerMillion: 3.0,
|
||||
cacheCreationPerMillion: 0.0,
|
||||
cacheReadPerMillion: 0.0,
|
||||
cacheReadPerMillion: 0.1,
|
||||
},
|
||||
'kimi-for-coding': {
|
||||
inputPerMillion: 0.6,
|
||||
outputPerMillion: 2.5,
|
||||
cacheCreationPerMillion: 0.0,
|
||||
cacheReadPerMillion: 0.15,
|
||||
},
|
||||
'kimi-k2-0905-preview': {
|
||||
inputPerMillion: 0.15,
|
||||
outputPerMillion: 0.6,
|
||||
inputPerMillion: 0.6,
|
||||
outputPerMillion: 2.5,
|
||||
cacheCreationPerMillion: 0.0,
|
||||
cacheReadPerMillion: 0.0,
|
||||
cacheReadPerMillion: 0.15,
|
||||
},
|
||||
'kimi-k2-turbo-preview': {
|
||||
inputPerMillion: 0.15,
|
||||
outputPerMillion: 1.15,
|
||||
inputPerMillion: 1.15,
|
||||
outputPerMillion: 8.0,
|
||||
cacheCreationPerMillion: 0.0,
|
||||
cacheReadPerMillion: 0.0,
|
||||
cacheReadPerMillion: 0.15,
|
||||
},
|
||||
'kimi-k2-thinking': {
|
||||
inputPerMillion: 0.15,
|
||||
outputPerMillion: 0.6,
|
||||
inputPerMillion: 0.6,
|
||||
outputPerMillion: 2.5,
|
||||
cacheCreationPerMillion: 0.0,
|
||||
cacheReadPerMillion: 0.0,
|
||||
cacheReadPerMillion: 0.15,
|
||||
},
|
||||
'kimi-k2-thinking-turbo': {
|
||||
inputPerMillion: 0.15,
|
||||
outputPerMillion: 1.15,
|
||||
inputPerMillion: 1.15,
|
||||
outputPerMillion: 8.0,
|
||||
cacheCreationPerMillion: 0.0,
|
||||
cacheReadPerMillion: 0.0,
|
||||
cacheReadPerMillion: 0.15,
|
||||
},
|
||||
'kimi-k2': {
|
||||
inputPerMillion: 0.6,
|
||||
outputPerMillion: 2.5,
|
||||
cacheCreationPerMillion: 0.0,
|
||||
cacheReadPerMillion: 0.15,
|
||||
},
|
||||
'kimi-k2-instruct': {
|
||||
inputPerMillion: 1.0,
|
||||
|
||||
@@ -36,6 +36,33 @@ describe('Model Catalog', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Kimi models', () => {
|
||||
it('contains Kimi provider catalog', () => {
|
||||
const { MODEL_CATALOG } = modelCatalog;
|
||||
assert(MODEL_CATALOG.kimi, 'Should have kimi provider');
|
||||
assert.strictEqual(MODEL_CATALOG.kimi.provider, 'kimi');
|
||||
assert.strictEqual(MODEL_CATALOG.kimi.displayName, 'Kimi (Moonshot)');
|
||||
});
|
||||
|
||||
it('has correct default model', () => {
|
||||
const { MODEL_CATALOG } = modelCatalog;
|
||||
assert.strictEqual(MODEL_CATALOG.kimi.defaultModel, 'kimi-k2.5');
|
||||
});
|
||||
|
||||
it('includes K2.5, K2 Thinking, K2', () => {
|
||||
const { MODEL_CATALOG } = modelCatalog;
|
||||
const ids = MODEL_CATALOG.kimi.models.map((m) => m.id);
|
||||
assert(ids.includes('kimi-k2.5'), 'Should include kimi-k2.5');
|
||||
assert(ids.includes('kimi-k2-thinking'), 'Should include kimi-k2-thinking');
|
||||
assert(ids.includes('kimi-k2'), 'Should include kimi-k2');
|
||||
});
|
||||
|
||||
it('has 3 models total', () => {
|
||||
const { MODEL_CATALOG } = modelCatalog;
|
||||
assert.strictEqual(MODEL_CATALOG.kimi.models.length, 3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('AGY models', () => {
|
||||
it('has correct default model', () => {
|
||||
const { MODEL_CATALOG } = modelCatalog;
|
||||
@@ -126,6 +153,11 @@ describe('Model Catalog', () => {
|
||||
assert.strictEqual(supportsModelConfig('codex'), true);
|
||||
});
|
||||
|
||||
it('returns true for kimi', () => {
|
||||
const { supportsModelConfig } = modelCatalog;
|
||||
assert.strictEqual(supportsModelConfig('kimi'), true);
|
||||
});
|
||||
|
||||
it('returns false for qwen', () => {
|
||||
const { supportsModelConfig } = modelCatalog;
|
||||
assert.strictEqual(supportsModelConfig('qwen'), false);
|
||||
@@ -155,6 +187,14 @@ describe('Model Catalog', () => {
|
||||
assert.strictEqual(catalog.provider, 'codex');
|
||||
assert(Array.isArray(catalog.models));
|
||||
});
|
||||
|
||||
it('returns catalog for kimi', () => {
|
||||
const { getProviderCatalog } = modelCatalog;
|
||||
const catalog = getProviderCatalog('kimi');
|
||||
assert(catalog, 'Should return catalog');
|
||||
assert.strictEqual(catalog.provider, 'kimi');
|
||||
assert(Array.isArray(catalog.models));
|
||||
});
|
||||
});
|
||||
|
||||
describe('findModel', () => {
|
||||
|
||||
@@ -70,6 +70,7 @@ export function ProviderEditor({
|
||||
iflow: ['iflow'],
|
||||
kiro: ['kiro', 'aws'],
|
||||
ghcp: ['github', 'copilot'],
|
||||
kimi: ['kimi', 'moonshot'],
|
||||
};
|
||||
const owners = ownerMap[modelFilterProvider.toLowerCase()] || [
|
||||
modelFilterProvider.toLowerCase(),
|
||||
|
||||
@@ -275,6 +275,40 @@ export const MODEL_CATALOGS: Record<string, ProviderCatalog> = {
|
||||
},
|
||||
],
|
||||
},
|
||||
kimi: {
|
||||
provider: 'kimi',
|
||||
displayName: 'Kimi (Moonshot)',
|
||||
defaultModel: 'kimi-k2.5',
|
||||
models: [
|
||||
{
|
||||
id: 'kimi-k2.5',
|
||||
name: 'Kimi K2.5',
|
||||
description: 'Latest multimodal model (262K context)',
|
||||
presetMapping: {
|
||||
default: 'kimi-k2.5',
|
||||
opus: 'kimi-k2.5',
|
||||
sonnet: 'kimi-k2-thinking',
|
||||
haiku: 'kimi-k2',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'kimi-k2-thinking',
|
||||
name: 'Kimi K2 Thinking',
|
||||
description: 'Extended reasoning model',
|
||||
presetMapping: {
|
||||
default: 'kimi-k2-thinking',
|
||||
opus: 'kimi-k2.5',
|
||||
sonnet: 'kimi-k2-thinking',
|
||||
haiku: 'kimi-k2',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'kimi-k2',
|
||||
name: 'Kimi K2',
|
||||
description: 'Flagship coding model',
|
||||
},
|
||||
],
|
||||
},
|
||||
kiro: {
|
||||
provider: 'kiro',
|
||||
displayName: 'Kiro (AWS)',
|
||||
|
||||
Reference in New Issue
Block a user