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
@@ -128,7 +128,16 @@ pub fn stream_chat_completions<'a>(
first_chunk_seen = true;
}
if let Some(u) = chunk.usage.clone() {
// Kimi/Moonshot deviation: usage may ride inside a choice instead
// of (or in addition to) the chunk's top-level `usage`. Same
// fallback as kimi-cli's `extract_usage_from_chunk`
// (packages/kosong/src/kosong/chat_provider/kimi.py:522-533):
// top-level wins, else the first choice carrying one.
let chunk_usage = chunk
.usage
.clone()
.or_else(|| chunk.choices.iter().find_map(|c| c.usage.clone()));
if let Some(u) = chunk_usage {
// Wire cost is cumulative for the response, so last-write-wins.
// Never clobber a known cost with missing/unreported.
let chunk_cost = kigi_sampling_types::reported_cost_ticks(u.cost_in_usd_ticks);
@@ -247,10 +256,27 @@ pub fn stream_chat_completions<'a>(
// ── Build the final response ─────────────────────────────────
let tool_calls: Vec<ToolCall> = tool_call_acc
.into_values()
.map(|(id, name, arguments)| ToolCall {
id: std::sync::Arc::<str>::from(id),
name,
arguments: std::sync::Arc::<str>::from(arguments),
.map(|(id, name, arguments)| {
// Kimi/Moonshot deviation: tool-call deltas may omit `id`.
// Synthesize one so the tool-result round-trip stays keyed,
// exactly like kimi-cli (`id=tool_call.id or str(uuid.uuid4())`,
// packages/kosong/src/kosong/chat_provider/kimi.py:505).
let id = if id.is_empty() {
let synthesized = uuid::Uuid::new_v4().to_string();
tracing::debug!(
tool_name = %name,
synthesized_id = %synthesized,
"tool-call delta carried no id; synthesized one"
);
synthesized
} else {
id
};
ToolCall {
id: std::sync::Arc::<str>::from(id),
name,
arguments: std::sync::Arc::<str>::from(arguments),
}
})
.collect();
@@ -329,6 +355,7 @@ mod tests {
index: i as u32,
delta,
finish_reason: None,
usage: None,
})
.collect(),
usage: None,
@@ -664,6 +691,7 @@ mod tests {
prompt_tokens: 100,
completion_tokens: 50,
total_tokens: 150,
cached_tokens: None,
prompt_tokens_details: None,
completion_tokens_details: None,
cost_in_usd_ticks: None,
@@ -704,6 +732,7 @@ mod tests {
prompt_tokens: 10,
completion_tokens: 5,
total_tokens: 15,
cached_tokens: None,
prompt_tokens_details: None,
completion_tokens_details: None,
cost_in_usd_ticks: wire,
@@ -737,6 +766,7 @@ mod tests {
prompt_tokens: 10,
completion_tokens: 5,
total_tokens: 15,
cached_tokens: None,
prompt_tokens_details: None,
completion_tokens_details: None,
cost_in_usd_ticks: Some(99),
@@ -746,6 +776,7 @@ mod tests {
prompt_tokens: 12,
completion_tokens: 6,
total_tokens: 18,
cached_tokens: None,
prompt_tokens_details: None,
completion_tokens_details: None,
cost_in_usd_ticks: Some(0),