Skip to content

Commit f71af55

Browse files
Merge remote-tracking branch 'upstream/main' into dev
2 parents 56055ce + 00d0eb6 commit f71af55

2 files changed

Lines changed: 87 additions & 3 deletions

File tree

prd.json

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -329,13 +329,28 @@
329329
],
330330
"passes": true,
331331
"priority": "P1"
332+
},
333+
{
334+
"id": "US-024",
335+
"title": "Add token limit metadata for kimi models",
336+
"description": "The model_token_limit() function has no entries for kimi-k2.5 or kimi-k1.5, causing preflight context window validation to skip these models. Add token limit metadata to enable preflight checks and accurate max token defaults. Per Moonshot AI documentation, kimi-k2.5 supports 256K context window and 16K max output tokens.",
337+
"acceptanceCriteria": [
338+
"model_token_limit('kimi-k2.5') returns Some(ModelTokenLimit { max_output_tokens: 16384, context_window_tokens: 256000 })",
339+
"model_token_limit('kimi-k1.5') returns appropriate limits",
340+
"model_token_limit('kimi') follows alias chain (kimi → kimi-k2.5) and returns k2.5 limits",
341+
"preflight_message_request() validates context window for kimi models (via generic preflight, no provider-specific code needed)",
342+
"Unit tests verify limits and preflight behavior for kimi models",
343+
"All tests pass and clippy is clean"
344+
],
345+
"passes": true,
346+
"priority": "P1"
332347
}
333348
],
334349
"metadata": {
335-
"lastUpdated": "2026-04-16",
336-
"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", "US-023"],
350+
"lastUpdated": "2026-04-17",
351+
"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", "US-023", "US-024"],
337352
"inProgressStories": [],
338-
"totalStories": 23,
353+
"totalStories": 24,
339354
"status": "completed"
340355
}
341356
}

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

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,12 @@ pub fn model_token_limit(model: &str) -> Option<ModelTokenLimit> {
292292
max_output_tokens: 64_000,
293293
context_window_tokens: 131_072,
294294
}),
295+
// Kimi models via DashScope (Moonshot AI)
296+
// Source: https://platform.moonshot.cn/docs/intro
297+
"kimi-k2.5" | "kimi-k1.5" => Some(ModelTokenLimit {
298+
max_output_tokens: 16_384,
299+
context_window_tokens: 256_000,
300+
}),
295301
_ => None,
296302
}
297303
}
@@ -747,6 +753,69 @@ mod tests {
747753
.expect("models without context metadata should skip the guarded preflight");
748754
}
749755

756+
#[test]
757+
fn returns_context_window_metadata_for_kimi_models() {
758+
// kimi-k2.5
759+
let k25_limit = model_token_limit("kimi-k2.5")
760+
.expect("kimi-k2.5 should have token limit metadata");
761+
assert_eq!(k25_limit.max_output_tokens, 16_384);
762+
assert_eq!(k25_limit.context_window_tokens, 256_000);
763+
764+
// kimi-k1.5
765+
let k15_limit = model_token_limit("kimi-k1.5")
766+
.expect("kimi-k1.5 should have token limit metadata");
767+
assert_eq!(k15_limit.max_output_tokens, 16_384);
768+
assert_eq!(k15_limit.context_window_tokens, 256_000);
769+
}
770+
771+
#[test]
772+
fn kimi_alias_resolves_to_kimi_k25_token_limits() {
773+
// The "kimi" alias resolves to "kimi-k2.5" via resolve_model_alias()
774+
let alias_limit = model_token_limit("kimi")
775+
.expect("kimi alias should resolve to kimi-k2.5 limits");
776+
let direct_limit = model_token_limit("kimi-k2.5")
777+
.expect("kimi-k2.5 should have limits");
778+
assert_eq!(alias_limit.max_output_tokens, direct_limit.max_output_tokens);
779+
assert_eq!(
780+
alias_limit.context_window_tokens,
781+
direct_limit.context_window_tokens
782+
);
783+
}
784+
785+
#[test]
786+
fn preflight_blocks_oversized_requests_for_kimi_models() {
787+
let request = MessageRequest {
788+
model: "kimi-k2.5".to_string(),
789+
max_tokens: 16_384,
790+
messages: vec![InputMessage {
791+
role: "user".to_string(),
792+
content: vec![InputContentBlock::Text {
793+
text: "x".repeat(1_000_000), // Large input to exceed context window
794+
}],
795+
}],
796+
system: Some("Keep the answer short.".to_string()),
797+
tools: None,
798+
tool_choice: None,
799+
stream: true,
800+
..Default::default()
801+
};
802+
803+
let error = preflight_message_request(&request)
804+
.expect_err("oversized request should be rejected for kimi models");
805+
806+
match error {
807+
ApiError::ContextWindowExceeded {
808+
model,
809+
context_window_tokens,
810+
..
811+
} => {
812+
assert_eq!(model, "kimi-k2.5");
813+
assert_eq!(context_window_tokens, 256_000);
814+
}
815+
other => panic!("expected context-window preflight failure, got {other:?}"),
816+
}
817+
}
818+
750819
#[test]
751820
fn parse_dotenv_extracts_keys_handles_comments_quotes_and_export_prefix() {
752821
// given

0 commit comments

Comments
 (0)