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
@@ -850,15 +850,11 @@ async fn set_session_model_invalidates_byok_memo_for_same_model_id() {
auth_scheme: Default::default(),
extra_headers: Default::default(),
context_window: 256_000,
client_version: None,
force_http1: false,
max_retries: None,
stream_tool_calls: false,
idle_timeout_secs: None,
client_identifier: None,
reasoning_effort: None,
deployment_id: None,
user_id: None,
origin_client: None,
attribution_callback: None,
bearer_resolver: None,
@@ -47,15 +47,11 @@ async fn persist_ack_waits_for_disk_flush_before_success() {
auth_scheme: Default::default(),
extra_headers: Default::default(),
context_window: 100_000,
client_version: None,
force_http1: false,
max_retries: None,
stream_tool_calls: false,
idle_timeout_secs: None,
client_identifier: None,
reasoning_effort: None,
deployment_id: None,
user_id: None,
origin_client: None,
attribution_callback: None,
bearer_resolver: None,
@@ -193,7 +189,6 @@ async fn persist_ack_waits_for_disk_flush_before_success() {
client_identifier: None,
origin_client: None,
feedback_manager: Arc::new(FeedbackManager::local_only("test-session")),
sync_loop_cancel: None,
agent: std::cell::RefCell::new(test_agent_default().await),
last_reported_branch: std::sync::Arc::new(parking_lot::Mutex::new(None)),
git_head_enabled: false,
@@ -338,15 +333,11 @@ async fn first_turn_memory_injection_persists_to_chat_history() {
api_backend: Default::default(),
auth_scheme: Default::default(),
context_window: 100_000,
client_version: None,
force_http1: false,
max_retries: None,
stream_tool_calls: false,
idle_timeout_secs: None,
client_identifier: None,
reasoning_effort: None,
deployment_id: None,
user_id: None,
origin_client: None,
attribution_callback: None,
bearer_resolver: None,
@@ -470,15 +461,11 @@ async fn first_turn_memory_injection_disabled_does_not_persist_to_chat_history()
api_backend: Default::default(),
auth_scheme: Default::default(),
context_window: 100_000,
client_version: None,
force_http1: false,
max_retries: None,
stream_tool_calls: false,
idle_timeout_secs: None,
client_identifier: None,
reasoning_effort: None,
deployment_id: None,
user_id: None,
origin_client: None,
attribution_callback: None,
bearer_resolver: None,
@@ -641,7 +628,6 @@ async fn first_turn_memory_injection_disabled_does_not_persist_to_chat_history()
client_identifier: None,
origin_client: None,
feedback_manager: Arc::new(FeedbackManager::local_only("test-session")),
sync_loop_cancel: None,
agent: std::cell::RefCell::new(test_agent_default().await),
last_reported_branch: std::sync::Arc::new(parking_lot::Mutex::new(None)),
git_head_enabled: false,
@@ -890,7 +876,6 @@ async fn cancel_running_task_teardown_clears_running_and_pending_work() {
client_identifier: None,
origin_client: None,
feedback_manager: Arc::new(FeedbackManager::local_only("test-session")),
sync_loop_cancel: None,
agent: std::cell::RefCell::new(agent),
last_reported_branch: std::sync::Arc::new(parking_lot::Mutex::new(None)),
git_head_enabled: false,
@@ -1729,15 +1714,11 @@ async fn cancel_propagates_to_sampler_handle_so_no_further_emission() {
auth_scheme: Default::default(),
extra_headers: Default::default(),
context_window: 100_000,
client_version: None,
force_http1: false,
max_retries: Some(0),
stream_tool_calls: false,
idle_timeout_secs: Some(60),
client_identifier: None,
reasoning_effort: None,
deployment_id: None,
user_id: None,
origin_client: None,
attribution_callback: None,
bearer_resolver: None,
@@ -1876,7 +1857,6 @@ async fn cancel_propagates_to_sampler_handle_so_no_further_emission() {
client_identifier: None,
origin_client: None,
feedback_manager: Arc::new(FeedbackManager::local_only("test-session")),
sync_loop_cancel: None,
agent: std::cell::RefCell::new(agent),
last_reported_branch: std::sync::Arc::new(parking_lot::Mutex::new(None)),
git_head_enabled: false,
@@ -43,7 +43,7 @@ async fn test_last_api_request_at_idle_detection() {
/// End-to-end test for `maybe_refresh_model_metadata_on_resume`.
///
/// Simulates a session idle for >10 minutes, then verifies the function
/// fetches `/models-v2`, parses the response, and updates `context_window`
/// fetches `/models`, parses the response, and updates `context_window`
/// and `max_completion_tokens` in the sampling config.
#[tokio::test(flavor = "current_thread")]
async fn test_e2e_idle_resume_refreshes_model_metadata() {
@@ -52,7 +52,7 @@ async fn test_e2e_idle_resume_refreshes_model_metadata() {
local
.run_until(async {
let app = axum::Router::new().route(
"/v1/models-v2",
"/v1/models",
get(|| async {
axum::Json(serde_json::json!(
{ "data" : [{ "model" : "test-model", "name" : "Test Model",
@@ -117,7 +117,6 @@ async fn test_e2e_idle_resume_refreshes_model_metadata() {
api_key: Some("test-key".to_string()),
auth_type: Default::default(),
alpha_test_key: None,
client_version: None,
});
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
let actor = SessionActor {
@@ -219,7 +218,6 @@ async fn test_e2e_idle_resume_refreshes_model_metadata() {
client_identifier: None,
origin_client: None,
feedback_manager: Arc::new(FeedbackManager::local_only("test-session")),
sync_loop_cancel: None,
agent: std::cell::RefCell::new(test_agent_default().await),
last_reported_branch: std::sync::Arc::new(parking_lot::Mutex::new(None)),
git_head_enabled: false,
@@ -321,12 +319,12 @@ async fn test_e2e_idle_resume_refreshes_model_metadata() {
assert_eq!(
cfg_after.context_window,
std::num::NonZeroU64::new(300_000).unwrap(),
"context_window should be updated to 300K from /models-v2"
"context_window should be updated to 300K from /models"
);
assert_eq!(
cfg_after.max_completion_tokens,
Some(16384),
"max_completion_tokens should be updated to 16384 from /models-v2"
"max_completion_tokens should be updated to 16384 from /models"
);
})
.await;
@@ -152,7 +152,6 @@ async fn create_test_actor(
client_identifier: None,
origin_client: None,
feedback_manager: Arc::new(FeedbackManager::local_only("test-session")),
sync_loop_cancel: None,
agent: std::cell::RefCell::new(test_agent_default().await),
last_reported_branch: std::sync::Arc::new(parking_lot::Mutex::new(None)),
git_head_enabled: false,
@@ -591,7 +590,6 @@ async fn create_test_actor_with_memory(
client_identifier: None,
origin_client: None,
feedback_manager: Arc::new(FeedbackManager::local_only("test-memory")),
sync_loop_cancel: None,
agent: std::cell::RefCell::new(test_agent_default().await),
last_reported_branch: std::sync::Arc::new(parking_lot::Mutex::new(None)),
git_head_enabled: false,
@@ -1168,7 +1166,7 @@ async fn test_compact_on_error_no_trigger_when_tokens_within_new_window() {
/// End-to-end test for `maybe_refresh_model_metadata_on_resume`.
///
/// Simulates a session idle for >10 minutes, then verifies the function
/// fetches `/models-v2`, parses the response, and updates `context_window`
/// fetches `/models`, parses the response, and updates `context_window`
/// and `max_completion_tokens` in the sampling config.
#[tokio::test(flavor = "current_thread")]
async fn test_e2e_idle_resume_refreshes_model_metadata() {
@@ -1177,7 +1175,7 @@ async fn test_e2e_idle_resume_refreshes_model_metadata() {
local
.run_until(async {
let app = axum::Router::new().route(
"/v1/models-v2",
"/v1/models",
get(|| async {
axum::Json(serde_json::json!(
{ "data" : [{ "model" : "test-model", "name" : "Test Model",
@@ -1241,7 +1239,6 @@ async fn test_e2e_idle_resume_refreshes_model_metadata() {
api_key: Some("test-key".to_string()),
auth_type: Default::default(),
alpha_test_key: None,
client_version: None,
});
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
let actor = SessionActor {
@@ -1346,7 +1343,6 @@ async fn test_e2e_idle_resume_refreshes_model_metadata() {
client_identifier: None,
origin_client: None,
feedback_manager: Arc::new(FeedbackManager::local_only("test-session")),
sync_loop_cancel: None,
agent: std::cell::RefCell::new(test_agent_default().await),
last_reported_branch: std::sync::Arc::new(parking_lot::Mutex::new(None)),
git_head_enabled: false,
@@ -1448,12 +1444,12 @@ async fn test_e2e_idle_resume_refreshes_model_metadata() {
assert_eq!(
cfg_after.context_window,
std::num::NonZeroU64::new(300_000).unwrap(),
"context_window should be updated to 300K from /models-v2"
"context_window should be updated to 300K from /models"
);
assert_eq!(
cfg_after.max_completion_tokens,
Some(16384),
"max_completion_tokens should be updated to 16384 from /models-v2"
"max_completion_tokens should be updated to 16384 from /models"
);
})
.await;
@@ -211,7 +211,6 @@ async fn create_test_actor_with_memory(
client_identifier: None,
origin_client: None,
feedback_manager: Arc::new(FeedbackManager::local_only("test-memory")),
sync_loop_cancel: None,
agent: std::cell::RefCell::new(test_agent_default().await),
last_reported_branch: std::sync::Arc::new(parking_lot::Mutex::new(None)),
git_head_enabled: false,
@@ -166,7 +166,7 @@ async fn actor_with_proxy(
let cfg = crate::agent::config::Config {
endpoints: crate::agent::config::EndpointsConfig {
cli_chat_proxy_base_url: Some(proxy_base.to_string()),
coding_api_base_url: Some(proxy_base.to_string()),
..Default::default()
},
..Default::default()
@@ -157,7 +157,6 @@ pub(super) async fn make_replay_send_update_fixture() -> ReplaySendUpdateFixture
client_identifier: None,
origin_client: None,
feedback_manager: Arc::new(FeedbackManager::local_only("test-session")),
sync_loop_cancel: None,
agent: std::cell::RefCell::new(test_agent_default().await),
last_reported_branch: std::sync::Arc::new(parking_lot::Mutex::new(None)),
git_head_enabled: false,
@@ -271,7 +271,6 @@ pub(crate) async fn create_test_actor_ex(
client_identifier: None,
origin_client: None,
feedback_manager: Arc::new(FeedbackManager::local_only("test-session")),
sync_loop_cancel: None,
agent: std::cell::RefCell::new(test_agent_default().await),
last_reported_branch: std::sync::Arc::new(parking_lot::Mutex::new(None)),
git_head_enabled: false,
@@ -64,9 +64,6 @@ async fn web_search_uses_model_override_from_config_end_to_end() {
entry,
crate::agent::config::resolve_credentials(entry, None),
None,
None,
None,
None,
);
let web_search_sampling = crate::tools::config::web_search_sampling_config(resolved);