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:
ZacharyZhang-NY committed 2026-07-17 16:05:51 -04:00
1 parent fe1f885bb3
commit ea0ce9d15f
231 files changed
+4730 -26358

No files matched your search

@@ -1,5 +1,5 @@
use super::*;
use crate::remote::DEFAULT_CONTEXT_WINDOW;
use crate::agent::models_fetch::DEFAULT_CONTEXT_WINDOW;
use kigi_chat_state::conversation_util::replace_or_insert_system_head;
impl SessionActor {
pub(super) async fn handle_set_session_model(
@@ -72,7 +72,6 @@ impl SessionActor {
existing.auth_type,
),
alpha_test_key: existing.alpha_test_key,
client_version: sampling_config.client_version.clone(),
});
self.model_auth_facts.replace(None);
self.signals_handle()
@@ -691,7 +691,6 @@ impl SessionActor {
crate::agent::config::finalize_image_describe_sampler_config(
resolved_describe,
&active_session_config,
self.client_identifier.clone(),
Some(self.max_retries),
);
let client = kigi_sampler::SamplingClient::new(sampler_config).map_err(|e| {
@@ -3,7 +3,7 @@
use super::*;
use crate::remote::DEFAULT_CONTEXT_WINDOW;
use crate::agent::models_fetch::DEFAULT_CONTEXT_WINDOW;
impl SessionActor {
/// Handle a /btw side question — single-turn model call using the
@@ -134,7 +134,7 @@ pub(super) fn build_todo_gate_reminder(pending: &[&str], unbacked_in_progress: &
/// (which is disabled). Extracted from `spawn_session_actor` so the
/// precedence rules are unit-testable. Named `resolve_*` to match the
/// sibling precedence helpers in `crate::util::config`
/// (`resolve_zdr_access_enabled`, `resolve_restore_code`, …).
/// (`resolve_restore_code`, …).
pub(crate) fn resolve_reminder_policy(
remote: Option<&crate::util::config::RemoteSettings>,
todo_gate: bool,
@@ -205,8 +205,7 @@ pub(super) async fn run_session(
.emit_buffered(notification). await; }
if let Some(tx) = respond_to { let _ =
tx.send(()); } } } } } maybe_completion = completion_rx.recv() => { let
Some((prompt_id, result)) = maybe_completion else { if let Some(cancel) = &
session.sync_loop_cancel { cancel.cancel(); } cleanup_session_scratch(&
Some((prompt_id, result)) = maybe_completion else { cleanup_session_scratch(&
session); return; }; if let Some(notification) = replay_buffer.flush() {
session.emit_buffered(notification). await; } let (turn_succeeded,
infra_pause_message) = SessionActor::post_turn_goal_degradation_plan(&
@@ -265,8 +264,7 @@ pub(super) async fn run_session(
{ let
model_id = session.current_model_id(). await; if let Some(signals) = session
.signals_handle().snapshot(). await {
} } if let
Some(cancel) = & session.sync_loop_cancel { cancel.cancel(); } session
} } session
.feedback_manager.shutdown(). await; if ! session
.startup_hints.is_subagent { session.persist_background_task_manifest().
await; } cleanup_session_scratch(& session); return; }; match cmd {
@@ -327,8 +325,7 @@ pub(super) async fn run_session(
::agent::config::try_resolve_model_credentials(model_name.as_str(), existing
.api_key.as_deref()) { session.chat_state_handle
.update_credentials(kigi_chat_state::Credentials { api_key : r.api_key,
auth_type : r.auth_type, alpha_test_key : existing.alpha_test_key,
client_version : existing.client_version, }); } session.model_auth_facts
auth_type : r.auth_type, alpha_test_key : existing.alpha_test_key, }); } session.model_auth_facts
.replace(None); } } SessionCommand::GetCurrentModel { responds_to } => { let
model = session.chat_state_handle.get_sampling_config(). await .map(| c | c
.model).unwrap_or_default(); let _ = responds_to.send(model); }
@@ -697,7 +694,7 @@ pub(super) async fn run_session(
await; session.send_hook_execution("session_start", None, None, & results).
await; } } SessionCommand::GetFeedbackContext { turn_number, responds_to } =>
{ let s = session.clone(); tokio::task::spawn_local(async move { use
prod_mc_cli_chat_proxy_types::feedback_types::FeedbackToolOutcome; let
crate::session::feedback_types::FeedbackToolOutcome; let
turn_idx = turn_number.and_then(| n | usize::try_from(n).ok()); let
(last_user_message, last_assistant_message) = match turn_idx { Some(n) => {
let conv = s.chat_state_handle.get_conversation(). await;
@@ -809,8 +806,7 @@ pub(super) async fn run_session(
"MEMORY_SUBAGENT_SKIP: skipping on_session_end for subagent session"); }
session.maybe_run_dream(). await; let telem = session.memory
.telemetry_snapshot(); session.emit_memory_session_summary(& telem,
total_chunks_at_end, session_end_result); if let Some(cancel) = & session
.sync_loop_cancel { cancel.cancel(); } session.feedback_manager
total_chunks_at_end, session_end_result); session.feedback_manager
.shutdown(). await; if ! session.startup_hints
.is_subagent { session.persist_background_task_manifest(). await; }
cleanup_session_scratch(& session); return; } } }
@@ -49,7 +49,7 @@ impl SessionTokenAuthGate {
is_session_based: auth_method_id
.is_some_and(crate::agent::auth_method::is_session_based_method),
model_byok,
endpoint_is_first_party: crate::util::is_first_party_xai_url(base_url),
endpoint_is_first_party: crate::util::is_first_party_url(base_url),
}
}
fn active(self) -> bool {
@@ -314,22 +314,11 @@ impl SessionActor {
auth_scheme,
extra_headers,
context_window: cfg.context_window.get(),
client_version: creds.client_version,
reasoning_effort: cfg.reasoning_effort,
force_http1: false,
max_retries: Some(self.max_retries),
stream_tool_calls: cfg.stream_tool_calls.unwrap_or(false),
idle_timeout_secs: None,
client_identifier: self.client_identifier.clone(),
deployment_id: crate::managed_config::resolve_deployment_id(
crate::managed_config::resolve_deployment_key().as_deref(),
),
user_id: self
.auth_manager
.as_ref()
.and_then(|am| am.current_or_expired())
.filter(|a| a.is_session_auth())
.map(|a| a.user_id),
origin_client: self.origin_client.clone(),
attribution_callback: self.attribution_callback.clone(),
bearer_resolver: if use_bearer_resolver {
@@ -482,7 +471,6 @@ impl SessionActor {
&endpoints,
session_key.as_deref(),
creds.alpha_test_key.clone(),
creds.client_version.clone(),
)
}
/// Resolve a dedicated sampler for the Auto-mode classifier model `slug`,
@@ -499,7 +487,6 @@ impl SessionActor {
crate::agent::config::stamp_session_local_sampler_fields(
&mut cfg,
&active_session_config,
self.client_identifier.clone(),
Some(self.max_retries),
);
let model = cfg.model.clone();
@@ -323,10 +323,10 @@ impl SessionActor {
/// Check if the session has been idle and proactively refresh model metadata.
///
/// Called at the start of each turn. If idle > `IDLE_REFRESH_THRESHOLD_SECS`,
/// fetches `/models-v2` from cli-chat-proxy and updates the cached
/// fetches `/models` from cli-chat-proxy and updates the cached
/// context_window / max_completion_tokens if remote settings changed them.
///
/// Skipped for BYOK users (no remote settings, no `/models-v2`).
/// Skipped for BYOK users (no remote settings, no `/models`).
pub(super) async fn maybe_refresh_model_metadata_on_resume(&self) {
if !self.is_session_based_auth() {
return;
@@ -353,7 +353,7 @@ impl SessionActor {
tracing::info!(
idle_secs,
threshold_secs = Self::IDLE_REFRESH_THRESHOLD_SECS,
"Session resumed after idle — refreshing model metadata from cli-chat-proxy"
"Session resumed after idle — refreshing model metadata"
);
let creds = self.chat_state_handle.get_credentials().await;
let Some(ref am) = self.auth_manager else {
@@ -370,27 +370,21 @@ impl SessionActor {
);
let middleware_client =
crate::http::with_auth_retry(crate::http::shared_client(), provider);
let url = format!("{}/models-v2", base_url);
let url = format!("{}/models", base_url);
let parse_models_response =
|json: serde_json::Value| -> Option<(std::num::NonZeroU64, Option<u32>)> {
let data = json.get("data")?.as_array()?;
for entry in data {
let parsed = crate::remote::client::parse_remote_model_value(entry, base_url)?;
let parsed =
crate::agent::models_fetch::parse_remote_model_value(entry, base_url)?;
if parsed.model == *current_model {
return Some((parsed.context_window, parsed.max_completion_tokens));
}
}
None
};
#[allow(unused_mut)]
let mut request = middleware_client
let request = middleware_client
.get(&url)
.header("X-XAI-Token-Auth", "xai-grok-cli")
.header("x-grok-client-version", kigi_version::VERSION)
.header(
crate::http::CLIENT_MODE_HEADER,
crate::http::process_client_mode(),
)
.timeout(std::time::Duration::from_secs(5));
let response = match request.send().await {
Ok(r) => r,
@@ -828,7 +828,7 @@ impl SessionActor {
);
let model_id = sampling_config.map(|c| c.model);
let resolved_model_id = model_metadata.resolved_model_id;
let client_version = credentials.client_version;
let client_version = Some(kigi_version::VERSION.to_string());
use crate::session::feedback_manager::{SessionFeedbackData, SubmitOutcome};
let outcome = self
@@ -3,7 +3,7 @@
//! the MCP auto-restart wiring (`SessionRestartActions`).
#![allow(clippy::items_after_test_module)]
use super::*;
use crate::remote::DEFAULT_CONTEXT_WINDOW;
use crate::agent::models_fetch::DEFAULT_CONTEXT_WINDOW;
/// Partition CLI `--allow` rules under the pin: blanket catch-all allows
/// (`Allow(Any)` `*` / `**`, plus bare/match-all Bash/MCP/WebFetch grants — see
/// `resolution::is_catchall_allow`) substitute for the blocked `--yolo`, so drop them when
@@ -123,10 +123,7 @@ pub(crate) async fn spawn_session_actor(
codebase_indexes: std::sync::Arc<parking_lot::Mutex<CodebaseIndexManager>>,
code_nav_enabled: bool,
fs_watch_caps: fs_watch::FsWatchCapabilities,
feedback_proxy_url: Option<String>,
feedback_user_token: Option<String>,
feedback_alpha_test_key: Option<String>,
deployment_key: Option<String>,
feedback_base_url: Option<String>,
client_terminal_capable: bool,
client_fs_capable: bool,
gateway_enabled: std::sync::Arc<std::sync::atomic::AtomicBool>,
@@ -141,7 +138,6 @@ pub(crate) async fn spawn_session_actor(
persisted_goal_mode: Option<crate::session::goal_tracker::GoalOrchestration>,
persisted_announcement_state: Option<crate::session::announcement_state::AnnouncementState>,
memory_config: Option<crate::config::MemoryConfig>,
loc_tracking_enabled: bool,
feedback_flags: crate::session::feedback_manager::FeedbackFlags,
managed_mcp_handle: crate::session::managed_mcp::ManagedMcpStateHandle,
managed_mcp_expires_at: Option<chrono::DateTime<chrono::Utc>>,
@@ -879,36 +875,30 @@ pub(crate) async fn spawn_session_actor(
}
persist_chat_history_jsonl_sync(&session_info, &conversation);
chat_state_handle.replace_conversation(conversation);
let feedback_client = feedback_proxy_url.map(|base_url| {
let mut client =
crate::agent::feedback_client::FeedbackClient::new(base_url, feedback_user_token)
.with_alpha_test_key(feedback_alpha_test_key)
.with_deployment_key(deployment_key);
if let Some(am) = auth_manager.as_ref() {
client = client.with_auth_manager(am.clone());
}
client
});
let feedback_client = match (feedback_base_url, auth_manager.as_ref()) {
(Some(base_url), Some(am)) => Some(
crate::agent::feedback_client::FeedbackClient::new(base_url, am.clone())
.with_session_id(session_info.id.0.to_string()),
),
_ => None,
};
let has_feedback_client = feedback_client.is_some();
tracing::info!(
session_id = % session_info.id.0, has_feedback_client = has_feedback_client,
"Creating feedback manager"
);
let feedback_client_type = match client_type {
ClientType::GrokTUI => prod_mc_cli_chat_proxy_types::feedback_types::ClientType::Tui,
ClientType::GrokWeb => prod_mc_cli_chat_proxy_types::feedback_types::ClientType::Web,
ClientType::Nebula => prod_mc_cli_chat_proxy_types::feedback_types::ClientType::Nebula,
ClientType::Extension => {
prod_mc_cli_chat_proxy_types::feedback_types::ClientType::Extension
}
ClientType::Generic => prod_mc_cli_chat_proxy_types::feedback_types::ClientType::Agent,
ClientType::Desktop => prod_mc_cli_chat_proxy_types::feedback_types::ClientType::Desktop,
ClientType::GrokPager => prod_mc_cli_chat_proxy_types::feedback_types::ClientType::Tui,
ClientType::GrokTUI => crate::session::feedback_types::ClientType::Tui,
ClientType::GrokWeb => crate::session::feedback_types::ClientType::Web,
ClientType::Nebula => crate::session::feedback_types::ClientType::Nebula,
ClientType::Extension => crate::session::feedback_types::ClientType::Extension,
ClientType::Generic => crate::session::feedback_types::ClientType::Agent,
ClientType::Desktop => crate::session::feedback_types::ClientType::Desktop,
ClientType::GrokPager => crate::session::feedback_types::ClientType::Tui,
};
let feedback_config = FeedbackManagerConfig {
feedback_enabled: feedback_flags.enabled,
client_type: feedback_client_type,
loc_tracking_enabled,
..Default::default()
};
let feedback_manager = Arc::new(FeedbackManager::new(
@@ -930,11 +920,6 @@ pub(crate) async fn spawn_session_actor(
}
signals_handle.set_primary_model(&primary_model_id);
signals_handle.set_tracing_config(inference_idle_timeout_secs);
let sync_loop_cancel = if has_feedback_client {
Some(tokio_util::sync::CancellationToken::new())
} else {
None
};
let force_compact = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false));
let resolved_workspace_root = kigi_workspace::session::git::find_git_root_from_path(
std::path::Path::new(&session_info.cwd),
@@ -1141,7 +1126,6 @@ pub(crate) async fn spawn_session_actor(
client_identifier: session_client_identifier.clone(),
origin_client: origin_client.clone(),
feedback_manager: feedback_manager.clone(),
sync_loop_cancel: sync_loop_cancel.clone(),
agent: std::cell::RefCell::new(agent),
last_reported_branch: Arc::new(Mutex::new(None)),
git_head_enabled: fs_watch_caps.git_head,
@@ -1375,18 +1359,6 @@ pub(crate) async fn spawn_session_actor(
}
});
}
if let Some(cancel) = sync_loop_cancel {
tracing::info!(session_id = % session_info.id.0, "Spawning feedback sync loop");
let fm = feedback_manager.clone();
tokio::spawn(async move {
fm.run_sync_loop(cancel).await;
});
} else {
tracing::debug!(
session_id = % session_info.id.0,
"No feedback client available, skipping sync loop"
);
}
{
use agent_client_protocol::Client as _;
use kigi_tools::implementations::grok_build::ask_user_question::{
@@ -1600,10 +1572,7 @@ pub(crate) async fn spawn_session_on_thread(
codebase_indexes: std::sync::Arc<parking_lot::Mutex<CodebaseIndexManager>>,
code_nav_enabled: bool,
fs_watch_caps: fs_watch::FsWatchCapabilities,
feedback_proxy_url: Option<String>,
feedback_user_token: Option<String>,
feedback_alpha_test_key: Option<String>,
deployment_key: Option<String>,
feedback_base_url: Option<String>,
client_terminal_capable: bool,
client_fs_capable: bool,
gateway_enabled: std::sync::Arc<std::sync::atomic::AtomicBool>,
@@ -1618,7 +1587,6 @@ pub(crate) async fn spawn_session_on_thread(
persisted_goal_mode: Option<crate::session::goal_tracker::GoalOrchestration>,
persisted_announcement_state: Option<crate::session::announcement_state::AnnouncementState>,
memory_config: Option<crate::config::MemoryConfig>,
loc_tracking_enabled: bool,
feedback_flags: crate::session::feedback_manager::FeedbackFlags,
managed_mcp_handle: crate::session::managed_mcp::ManagedMcpStateHandle,
managed_mcp_expires_at: Option<chrono::DateTime<chrono::Utc>>,
@@ -1751,10 +1719,7 @@ pub(crate) async fn spawn_session_on_thread(
codebase_indexes,
code_nav_enabled,
fs_watch_caps,
feedback_proxy_url,
feedback_user_token,
feedback_alpha_test_key,
deployment_key,
feedback_base_url,
client_terminal_capable,
client_fs_capable,
gateway_enabled,
@@ -1769,7 +1734,6 @@ pub(crate) async fn spawn_session_on_thread(
persisted_goal_mode,
persisted_announcement_state,
memory_config,
loc_tracking_enabled,
feedback_flags,
managed_mcp_handle,
managed_mcp_expires_at,