F3: Kimi inference pipeline + full grok cloud-surface excision

Sampler / inference (PRD F3):
- kimi_compat.rs: single adaptation point for the Kimi chat/completions
  dialect (thinking-field mapping, model_id stripping, empty-content
  tool-call message fix, stream_options.include_usage), with kimi-cli
  source citations
- Rate-limit handling reworked for Kimi/Moonshot semantics; UA kigi/{version}
- /models replaces the xAI models-v2 endpoint everywhere; idle model
  refresh carries X-Msh-* device headers only (X-XAI-Token-Auth and
  x-grok-client-mode/CLIENT_MODE_HEADER machinery deleted)

Cloud-surface excision (PRD §5, zero-egress):
- remote/ conversations lane, cli-chat-proxy-types crate, prod/ dir,
  share command, credit bar: deleted (single local session lane;
  paginate() replaces merge_and_paginate)
- Subscription/tier gate stack deleted end-to-end: AppView
  gate/tier/team/ZDR fields, app/subscription.rs watch loop,
  dispatch/billing.rs paywall + SuperGrok upsell, free-usage-exhausted
  chain, tier-restricted commands, GateInfo, RemoteSettings gate fields,
  SettingsUpdateNotification gate fields
- /privacy + coding-data-sharing setting deleted (backed by a dead xAI
  RPC; Kigi is zero-egress — nothing to share or retain remotely)

Auth UX correctness (user-reported):
- Device-flow fixtures now mirror the live Kimi payload shape
  (https://www.kimi.com/code/authorize_device?user_code=..., verified
  against auth.kimi.com); the fabricated auth.kimi.com/device?code=...
  URLs are gone
- open_browser_detached is a no-op under cfg(test): unit tests drove
  wiremock fixture URLs into the real browser (root cause of the
  "garbage mock link" ABCD-1234 tabs)
- Welcome/pager-minimal rebrand: Grok Build -> Kigi, grok.com ->
  kimi.com, "Sign in to Grok" -> "Sign in to Kimi"
This commit is contained in:
2026-07-17 16:05:51 -04:00
parent fe1f885bb3
commit ea0ce9d15f
231 changed files with 4730 additions and 26358 deletions
+24 -40
View File
@@ -56,19 +56,19 @@ fn matches_trusted_base_url(candidate: &str, trusted_base: &str) -> bool {
/// True for subscription coding-API URLs (the compiled production endpoint;
/// deliberately NOT the env-overridable [`kigi_env::coding_api_base_url`] so a
/// runtime override can't widen this trust set).
pub fn is_cli_chat_proxy_url(url: &str) -> bool {
pub fn is_production_coding_api_url(url: &str) -> bool {
matches_trusted_base_url(url, kigi_env::PRODUCTION_ENDPOINTS.coding_api_base_url)
}
/// True for URLs the idle model-metadata refresh may re-fetch from: the
/// *effective* subscription coding endpoint (the `KIGI_CODE_BASE_URL`
/// override when set, else the compiled production endpoint), plus loopback
/// hosts (local dev proxies and test mocks). Unlike [`is_cli_chat_proxy_url`]
/// hosts (local dev proxies and test mocks). Unlike [`is_production_coding_api_url`]
/// this honours the env override and loopback, so use it only to gate traffic
/// that already flows to the session's configured base URL (the refresh
/// re-fetches from the same host the session samples against); it must never
/// widen a security trust set.
pub fn is_effective_coding_endpoint_url(url: &str) -> bool {
if is_cli_chat_proxy_url(url) {
if is_production_coding_api_url(url) {
return true;
}
if matches_trusted_base_url(url, &kigi_env::coding_api_base_url()) {
@@ -83,18 +83,11 @@ pub fn is_effective_coding_endpoint_url(url: &str) -> bool {
None => false,
})
}
/// True for first-party xAI endpoints (`*.x.ai`, cli-chat-proxy, and optional
/// non-production first-party hosts when that feature is enabled).
/// `disable_api_key_auth` refuses keys only for these; other hosts are BYOK and
/// exempt. Safe against invalid URLs and suffix attacks (`evil-x.ai.example`).
pub fn is_first_party_xai_url(url: &str) -> bool {
if is_cli_chat_proxy_url(url) {
return true;
}
reqwest::Url::parse(url)
.ok()
.and_then(|u| u.host_str().map(|h| h.to_owned()))
.is_some_and(|host| host == "x.ai" || host.ends_with(".x.ai"))
/// True for first-party endpoints: the Kimi subscription coding API. The
/// session-token 401-refresh gate only refreshes against these; other hosts
/// are BYOK and exempt. Safe against invalid URLs and suffix attacks.
pub fn is_first_party_url(url: &str) -> bool {
is_production_coding_api_url(url)
}
/// Truncate a string to at most `max_chars` characters.
/// Slices at char boundaries so multi-byte UTF-8 never panics.
@@ -229,18 +222,18 @@ pub fn is_grok_process(pid: u32) -> bool {
mod tests {
use super::*;
#[test]
fn test_is_cli_chat_proxy_url_accepts_proxy_subpath() {
assert!(is_cli_chat_proxy_url(
fn test_is_production_coding_api_url_accepts_proxy_subpath() {
assert!(is_production_coding_api_url(
"https://api.kimi.com/coding/v1/chat/completions"
));
}
#[test]
fn test_is_cli_chat_proxy_url_rejects_public_api() {
assert!(!is_cli_chat_proxy_url("https://api.x.ai/v1"));
fn test_is_production_coding_api_url_rejects_public_api() {
assert!(!is_production_coding_api_url("https://api.x.ai/v1"));
}
#[test]
fn test_is_cli_chat_proxy_url_rejects_spoofed_hostname() {
assert!(!is_cli_chat_proxy_url(
fn test_is_production_coding_api_url_rejects_spoofed_hostname() {
assert!(!is_production_coding_api_url(
"https://api.kimi.com.evil.example/coding/v1"
));
}
@@ -261,31 +254,22 @@ mod tests {
));
}
#[test]
fn test_is_cli_chat_proxy_url_rejects_v11_prefix_confusion() {
assert!(!is_cli_chat_proxy_url(
fn test_is_production_coding_api_url_rejects_v11_prefix_confusion() {
assert!(!is_production_coding_api_url(
"https://api.kimi.com/coding/v11/chat/completions"
));
}
#[test]
fn test_is_first_party_xai_url() {
assert!(is_first_party_xai_url("https://api.x.ai/v1"));
assert!(is_first_party_xai_url(
"https://api.x.ai/v1/chat/completions"
));
assert!(is_first_party_xai_url("https://x.ai"));
assert!(is_first_party_xai_url(
fn test_is_first_party_url() {
assert!(is_first_party_url(
"https://api.kimi.com/coding/v1/chat/completions"
));
assert!(!is_first_party_xai_url("https://api.openai.com/v1"));
assert!(!is_first_party_xai_url("https://api.anthropic.com/v1"));
assert!(!is_first_party_xai_url(
"https://generativelanguage.googleapis.com"
));
assert!(!is_first_party_xai_url("https://api.x.ai.evil.example/v1"));
assert!(!is_first_party_xai_url("https://evil-x.ai.attacker.com/v1"));
assert!(!is_first_party_xai_url("https://prefixx.ai/v1"));
assert!(!is_first_party_xai_url("not-a-url"));
assert!(!is_first_party_xai_url(""));
assert!(!is_first_party_url("https://api.x.ai/v1"));
assert!(!is_first_party_url("https://api.openai.com/v1"));
assert!(!is_first_party_url("https://api.anthropic.com/v1"));
assert!(!is_first_party_url("https://api.kimi.com.evil.example/v1"));
assert!(!is_first_party_url("not-a-url"));
assert!(!is_first_party_url(""));
}
#[test]
fn test_truncate() {