Skip to content

Commit cec8d17

Browse files
Yeachan-Heoclaude
andcommitted
Implement US-023: Add automatic routing for kimi models to DashScope
Changes in rust/crates/api/src/providers/mod.rs: - Add 'kimi' alias to MODEL_REGISTRY resolving to 'kimi-k2.5' with DashScope config - Add kimi/kimi- prefix routing to DashScope endpoint in metadata_for_model() - Add resolve_model_alias() handling for kimi -> kimi-k2.5 - Add unit tests: kimi_prefix_routes_to_dashscope, kimi_alias_resolves_to_kimi_k2_5 Users can now use: - --model kimi (resolves to kimi-k2.5) - --model kimi-k2.5 (auto-routes to DashScope) - --model kimi/kimi-k2.5 (explicit provider prefix) All 127 tests pass, clippy clean. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 4cb1db9 commit cec8d17

2 files changed

Lines changed: 67 additions & 3 deletions

File tree

prd.json

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,13 +315,27 @@
315315
],
316316
"passes": true,
317317
"priority": "P1"
318+
},
319+
{
320+
"id": "US-023",
321+
"title": "Add automatic routing for kimi models to DashScope",
322+
"description": "Based on dogfood findings with kimi-k2.5 testing, users must manually prefix with dashscope/kimi-k2.5 instead of just using kimi-k2.5. Add automatic routing for kimi/ and kimi- prefixed models to DashScope (similar to qwen models), and add a 'kimi' alias to the model registry.",
323+
"acceptanceCriteria": [
324+
"kimi/ and kimi- prefix routing to DashScope in metadata_for_model()",
325+
"'kimi' alias in MODEL_REGISTRY that resolves to 'kimi-k2.5'",
326+
"resolve_model_alias() handles the kimi alias correctly",
327+
"Unit tests for kimi routing (similar to qwen routing tests)",
328+
"All tests pass and clippy is clean"
329+
],
330+
"passes": true,
331+
"priority": "P1"
318332
}
319333
],
320334
"metadata": {
321335
"lastUpdated": "2026-04-16",
322336
"completedStories": ["US-001", "US-002", "US-003", "US-004", "US-005", "US-006", "US-007", "US-008", "US-009", "US-010", "US-011", "US-012", "US-013", "US-014", "US-015", "US-016", "US-017", "US-018", "US-019", "US-020", "US-021", "US-022"],
323-
"inProgressStories": [],
324-
"totalStories": 22,
337+
"inProgressStories": ["US-023"],
338+
"totalStories": 23,
325339
"status": "in_progress"
326340
}
327341
}

rust/crates/api/src/providers/mod.rs

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,15 @@ const MODEL_REGISTRY: &[(&str, ProviderMetadata)] = &[
122122
default_base_url: openai_compat::DEFAULT_XAI_BASE_URL,
123123
},
124124
),
125+
(
126+
"kimi",
127+
ProviderMetadata {
128+
provider: ProviderKind::OpenAi,
129+
auth_env: "DASHSCOPE_API_KEY",
130+
base_url_env: "DASHSCOPE_BASE_URL",
131+
default_base_url: openai_compat::DEFAULT_DASHSCOPE_BASE_URL,
132+
},
133+
),
125134
];
126135

127136
#[must_use]
@@ -144,7 +153,10 @@ pub fn resolve_model_alias(model: &str) -> String {
144153
"grok-2" => "grok-2",
145154
_ => trimmed,
146155
},
147-
ProviderKind::OpenAi => trimmed,
156+
ProviderKind::OpenAi => match *alias {
157+
"kimi" => "kimi-k2.5",
158+
_ => trimmed,
159+
},
148160
})
149161
})
150162
.map_or_else(|| trimmed.to_string(), ToOwned::to_owned)
@@ -194,6 +206,16 @@ pub fn metadata_for_model(model: &str) -> Option<ProviderMetadata> {
194206
default_base_url: openai_compat::DEFAULT_DASHSCOPE_BASE_URL,
195207
});
196208
}
209+
// Kimi models (kimi-k2.5, kimi-k1.5, etc.) via DashScope compatible-mode.
210+
// Routes kimi/* and kimi-* model names to DashScope endpoint.
211+
if canonical.starts_with("kimi/") || canonical.starts_with("kimi-") {
212+
return Some(ProviderMetadata {
213+
provider: ProviderKind::OpenAi,
214+
auth_env: "DASHSCOPE_API_KEY",
215+
base_url_env: "DASHSCOPE_BASE_URL",
216+
default_base_url: openai_compat::DEFAULT_DASHSCOPE_BASE_URL,
217+
});
218+
}
197219
None
198220
}
199221

@@ -554,6 +576,34 @@ mod tests {
554576
);
555577
}
556578

579+
#[test]
580+
fn kimi_prefix_routes_to_dashscope() {
581+
// Kimi models via DashScope (kimi-k2.5, kimi-k1.5, etc.)
582+
let meta = super::metadata_for_model("kimi-k2.5")
583+
.expect("kimi-k2.5 must resolve to DashScope metadata");
584+
assert_eq!(meta.auth_env, "DASHSCOPE_API_KEY");
585+
assert_eq!(meta.base_url_env, "DASHSCOPE_BASE_URL");
586+
assert!(meta.default_base_url.contains("dashscope.aliyuncs.com"));
587+
assert_eq!(meta.provider, ProviderKind::OpenAi);
588+
589+
// With provider prefix
590+
let meta2 = super::metadata_for_model("kimi/kimi-k2.5")
591+
.expect("kimi/kimi-k2.5 must resolve to DashScope metadata");
592+
assert_eq!(meta2.auth_env, "DASHSCOPE_API_KEY");
593+
assert_eq!(meta2.provider, ProviderKind::OpenAi);
594+
595+
// Different kimi variants
596+
let meta3 = super::metadata_for_model("kimi-k1.5")
597+
.expect("kimi-k1.5 must resolve to DashScope metadata");
598+
assert_eq!(meta3.auth_env, "DASHSCOPE_API_KEY");
599+
}
600+
601+
#[test]
602+
fn kimi_alias_resolves_to_kimi_k2_5() {
603+
assert_eq!(super::resolve_model_alias("kimi"), "kimi-k2.5");
604+
assert_eq!(super::resolve_model_alias("KIMI"), "kimi-k2.5"); // case insensitive
605+
}
606+
557607
#[test]
558608
fn keeps_existing_max_token_heuristic() {
559609
assert_eq!(max_tokens_for_model("opus"), 32_000);

0 commit comments

Comments
 (0)