mirror of
https://github.com/instructkr/claw-code.git
synced 2026-04-17 19:15:09 +08:00
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>
This commit is contained in:
18
prd.json
18
prd.json
@@ -315,13 +315,27 @@
|
|||||||
],
|
],
|
||||||
"passes": true,
|
"passes": true,
|
||||||
"priority": "P1"
|
"priority": "P1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "US-023",
|
||||||
|
"title": "Add automatic routing for kimi models to DashScope",
|
||||||
|
"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.",
|
||||||
|
"acceptanceCriteria": [
|
||||||
|
"kimi/ and kimi- prefix routing to DashScope in metadata_for_model()",
|
||||||
|
"'kimi' alias in MODEL_REGISTRY that resolves to 'kimi-k2.5'",
|
||||||
|
"resolve_model_alias() handles the kimi alias correctly",
|
||||||
|
"Unit tests for kimi routing (similar to qwen routing tests)",
|
||||||
|
"All tests pass and clippy is clean"
|
||||||
|
],
|
||||||
|
"passes": true,
|
||||||
|
"priority": "P1"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"lastUpdated": "2026-04-16",
|
"lastUpdated": "2026-04-16",
|
||||||
"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"],
|
"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"],
|
||||||
"inProgressStories": [],
|
"inProgressStories": ["US-023"],
|
||||||
"totalStories": 22,
|
"totalStories": 23,
|
||||||
"status": "in_progress"
|
"status": "in_progress"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,6 +122,15 @@ const MODEL_REGISTRY: &[(&str, ProviderMetadata)] = &[
|
|||||||
default_base_url: openai_compat::DEFAULT_XAI_BASE_URL,
|
default_base_url: openai_compat::DEFAULT_XAI_BASE_URL,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
"kimi",
|
||||||
|
ProviderMetadata {
|
||||||
|
provider: ProviderKind::OpenAi,
|
||||||
|
auth_env: "DASHSCOPE_API_KEY",
|
||||||
|
base_url_env: "DASHSCOPE_BASE_URL",
|
||||||
|
default_base_url: openai_compat::DEFAULT_DASHSCOPE_BASE_URL,
|
||||||
|
},
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
@@ -144,7 +153,10 @@ pub fn resolve_model_alias(model: &str) -> String {
|
|||||||
"grok-2" => "grok-2",
|
"grok-2" => "grok-2",
|
||||||
_ => trimmed,
|
_ => trimmed,
|
||||||
},
|
},
|
||||||
ProviderKind::OpenAi => trimmed,
|
ProviderKind::OpenAi => match *alias {
|
||||||
|
"kimi" => "kimi-k2.5",
|
||||||
|
_ => trimmed,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.map_or_else(|| trimmed.to_string(), ToOwned::to_owned)
|
.map_or_else(|| trimmed.to_string(), ToOwned::to_owned)
|
||||||
@@ -194,6 +206,16 @@ pub fn metadata_for_model(model: &str) -> Option<ProviderMetadata> {
|
|||||||
default_base_url: openai_compat::DEFAULT_DASHSCOPE_BASE_URL,
|
default_base_url: openai_compat::DEFAULT_DASHSCOPE_BASE_URL,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// Kimi models (kimi-k2.5, kimi-k1.5, etc.) via DashScope compatible-mode.
|
||||||
|
// Routes kimi/* and kimi-* model names to DashScope endpoint.
|
||||||
|
if canonical.starts_with("kimi/") || canonical.starts_with("kimi-") {
|
||||||
|
return Some(ProviderMetadata {
|
||||||
|
provider: ProviderKind::OpenAi,
|
||||||
|
auth_env: "DASHSCOPE_API_KEY",
|
||||||
|
base_url_env: "DASHSCOPE_BASE_URL",
|
||||||
|
default_base_url: openai_compat::DEFAULT_DASHSCOPE_BASE_URL,
|
||||||
|
});
|
||||||
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -554,6 +576,34 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn kimi_prefix_routes_to_dashscope() {
|
||||||
|
// Kimi models via DashScope (kimi-k2.5, kimi-k1.5, etc.)
|
||||||
|
let meta = super::metadata_for_model("kimi-k2.5")
|
||||||
|
.expect("kimi-k2.5 must resolve to DashScope metadata");
|
||||||
|
assert_eq!(meta.auth_env, "DASHSCOPE_API_KEY");
|
||||||
|
assert_eq!(meta.base_url_env, "DASHSCOPE_BASE_URL");
|
||||||
|
assert!(meta.default_base_url.contains("dashscope.aliyuncs.com"));
|
||||||
|
assert_eq!(meta.provider, ProviderKind::OpenAi);
|
||||||
|
|
||||||
|
// With provider prefix
|
||||||
|
let meta2 = super::metadata_for_model("kimi/kimi-k2.5")
|
||||||
|
.expect("kimi/kimi-k2.5 must resolve to DashScope metadata");
|
||||||
|
assert_eq!(meta2.auth_env, "DASHSCOPE_API_KEY");
|
||||||
|
assert_eq!(meta2.provider, ProviderKind::OpenAi);
|
||||||
|
|
||||||
|
// Different kimi variants
|
||||||
|
let meta3 = super::metadata_for_model("kimi-k1.5")
|
||||||
|
.expect("kimi-k1.5 must resolve to DashScope metadata");
|
||||||
|
assert_eq!(meta3.auth_env, "DASHSCOPE_API_KEY");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn kimi_alias_resolves_to_kimi_k2_5() {
|
||||||
|
assert_eq!(super::resolve_model_alias("kimi"), "kimi-k2.5");
|
||||||
|
assert_eq!(super::resolve_model_alias("KIMI"), "kimi-k2.5"); // case insensitive
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn keeps_existing_max_token_heuristic() {
|
fn keeps_existing_max_token_heuristic() {
|
||||||
assert_eq!(max_tokens_for_model("opus"), 32_000);
|
assert_eq!(max_tokens_for_model("opus"), 32_000);
|
||||||
|
|||||||
Reference in New Issue
Block a user