§9 acceptance: grep-zero sweep — every internal x.ai/grok identifier renamed
The PRD's first acceptance gate now holds: grep -RinE '\bx\.ai\b|grok' crates/ --include='*.rs' → 0 matches (exempt: NOTICE and third-party license archives, README provenance, and the required 'Based on Grok Build Open Source' attribution, now sourced from version_attribution.txt). Wire-visible renames (both sides in this repo, changed in lockstep): - Auth method id 'grok.com' → 'kimi-code' (AuthMethodKind::KimiCode). - Every x.ai/* and _x.ai/* ACP ext method and meta key → kigi/* / _kigi/* (~200 names; grokShell → kigiShell). Session-file replay keeps a read-side alias for the legacy '_x.ai/session/update' method so existing updates.jsonl histories load; writes emit only the new name (both directions test-pinned). - Agent types grok-build* → kigi* with a documented legacy-prefix alias at resolution time so persisted sessions keep resolving. - ToolNamespace/BuiltinAgentName GrokBuild* → Kigi* (wire snake_case kigi/kigi_concise/kigi_hashline; schema regenerated); grok_build implementation dirs renamed to kigi*. - x-grok-* headers → x-kigi-*, __GROK_* sentinels → __KIGI_*, themes grokday/groknight → kigiday/kiginight (old persisted values fall back to the default theme), web_fetch allowlist xAI hosts → kimi.com + moonshot platforms, changelog CDN → this repo, grok-build changelog archives deleted. - BYOK default endpoint removed: [endpoints] api_base_url is now truly optional with NO default — consumers fail fast with the flag name when unset (no silent x.ai egress). Mock harnesses inject it explicitly. - System-prompt identity fixed: 'released by xAI' → 'an unofficial community CLI for Kimi' (template + regenerated encrypted form). Also repaired pre-existing grok-era test debt found by the sweep: the stale trace_classify default-model pin, the grok-pager UA label test, pty-harness stale-binary reuse and non-hermetic moonshot routing (a PTY test could previously reach the real api.moonshot.cn), and the outdated oauth fixture scope key. Gates: §9 grep 0; fmt clean; workspace check/clippy 0/0 (-D warnings); FULL cargo test --workspace: 234 suites, 21,961 passed, 0 failed; deny advisories ok.
This commit is contained in:
@@ -250,13 +250,13 @@ mod tests {
|
||||
/// it from the raw JSON to preserve downstream data fidelity.
|
||||
#[test]
|
||||
fn test_assistant_with_reasoning() {
|
||||
let v1 = r#"{"type":"assistant","content":"The answer is 42.","reasoning":{"text":"Let me think..."},"tool_calls":[],"model_id":"grok-3"}"#;
|
||||
let v1 = r#"{"type":"assistant","content":"The answer is 42.","reasoning":{"text":"Let me think..."},"tool_calls":[],"model_id":"kigi-3"}"#;
|
||||
let out = convert_line_for_test(v1);
|
||||
let v = v0_value(&out);
|
||||
assert_eq!(v["role"], "assistant");
|
||||
assert_eq!(v["content"], "The answer is 42.");
|
||||
assert_eq!(v["reasoning_content"], "Let me think...");
|
||||
assert_eq!(v["model_id"], "grok-3");
|
||||
assert_eq!(v["model_id"], "kigi-3");
|
||||
}
|
||||
|
||||
/// Current shape: reasoning is a sibling line
|
||||
@@ -274,7 +274,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(pending.len(), 1);
|
||||
|
||||
let a_line = r#"{"type":"assistant","content":"The answer is 42.","tool_calls":[],"model_id":"grok-3"}"#;
|
||||
let a_line = r#"{"type":"assistant","content":"The answer is 42.","tool_calls":[],"model_id":"kigi-3"}"#;
|
||||
let a = convert_line(a_line, &mut pending)
|
||||
.unwrap()
|
||||
.expect("assistant line produces a v0 message");
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
//! Usage:
|
||||
//! cargo run --bin trace_classify -- \
|
||||
//! --trace /path/to/trace-<id>-all-turns.json \
|
||||
//! --api-base-url <url> \
|
||||
//! [--output out.jsonl] \
|
||||
//! [--model kimi-for-coding] \
|
||||
//! [--api-base-url https://api.x.ai/v1] \
|
||||
//! [--api-key <key> | $XAI_API_KEY | <kigi-home>/auth.json] \
|
||||
//! [--min-confidence 0.7] \
|
||||
//! [--include-reasoning true] \
|
||||
@@ -47,8 +47,9 @@ struct Cli {
|
||||
#[arg(long, default_value = "kimi-for-coding")]
|
||||
model: String,
|
||||
|
||||
/// Sampler base URL.
|
||||
#[arg(long, default_value = "https://api.x.ai/v1")]
|
||||
/// Sampler base URL. REQUIRED: there is no default BYOK endpoint —
|
||||
/// pass the base URL your API key is valid for explicitly.
|
||||
#[arg(long)]
|
||||
api_base_url: String,
|
||||
|
||||
/// API key. Overrides `$XAI_API_KEY` when set; falls back to
|
||||
@@ -109,13 +110,23 @@ mod tests {
|
||||
use super::*;
|
||||
use clap::CommandFactory;
|
||||
|
||||
/// Minimal args for a valid invocation. `--api-base-url` is included
|
||||
/// because it is REQUIRED — there is no default BYOK endpoint.
|
||||
const BASE_ARGS: [&str; 5] = [
|
||||
"trace_classify",
|
||||
"--trace",
|
||||
"foo.json",
|
||||
"--api-base-url",
|
||||
"https://byok.example/v1",
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn cli_parses_minimal_args() {
|
||||
let cli = Cli::try_parse_from(["trace_classify", "--trace", "foo.json", "--model", "bar"])
|
||||
let cli = Cli::try_parse_from(BASE_ARGS.iter().copied().chain(["--model", "bar"]))
|
||||
.expect("parse");
|
||||
assert_eq!(cli.trace, PathBuf::from("foo.json"));
|
||||
assert_eq!(cli.model, "bar");
|
||||
assert_eq!(cli.api_base_url, "https://api.x.ai/v1");
|
||||
assert_eq!(cli.api_base_url, "https://byok.example/v1");
|
||||
assert!(cli.output.is_none());
|
||||
assert!(cli.api_key.is_none());
|
||||
assert!(cli.min_confidence.is_none());
|
||||
@@ -123,45 +134,54 @@ mod tests {
|
||||
assert!(cli.kigi_home.is_none());
|
||||
}
|
||||
|
||||
/// Fail fast: the BYOK path has no default endpoint, so omitting
|
||||
/// `--api-base-url` must be a parse error that names the flag.
|
||||
#[test]
|
||||
fn cli_requires_api_base_url() {
|
||||
let err = Cli::try_parse_from(["trace_classify", "--trace", "foo.json"])
|
||||
.expect_err("missing --api-base-url");
|
||||
let msg = err.to_string();
|
||||
assert!(
|
||||
msg.contains("--api-base-url"),
|
||||
"error mentions --api-base-url: {msg}"
|
||||
);
|
||||
}
|
||||
|
||||
/// Per-model knob (mirrored as a CLI override on the offline tool):
|
||||
/// `--include-reasoning true` and `--include-reasoning false` both
|
||||
/// parse; absent → `None` so the harness default applies.
|
||||
#[test]
|
||||
fn cli_include_reasoning_override_parses() {
|
||||
let cli_true = Cli::try_parse_from([
|
||||
"trace_classify",
|
||||
"--trace",
|
||||
"foo.json",
|
||||
"--include-reasoning",
|
||||
"true",
|
||||
])
|
||||
let cli_true = Cli::try_parse_from(
|
||||
BASE_ARGS
|
||||
.iter()
|
||||
.copied()
|
||||
.chain(["--include-reasoning", "true"]),
|
||||
)
|
||||
.expect("parse true");
|
||||
assert_eq!(cli_true.include_reasoning, Some(true));
|
||||
|
||||
let cli_false = Cli::try_parse_from([
|
||||
"trace_classify",
|
||||
"--trace",
|
||||
"foo.json",
|
||||
"--include-reasoning",
|
||||
"false",
|
||||
])
|
||||
let cli_false = Cli::try_parse_from(
|
||||
BASE_ARGS
|
||||
.iter()
|
||||
.copied()
|
||||
.chain(["--include-reasoning", "false"]),
|
||||
)
|
||||
.expect("parse false");
|
||||
assert_eq!(cli_false.include_reasoning, Some(false));
|
||||
|
||||
let cli_absent =
|
||||
Cli::try_parse_from(["trace_classify", "--trace", "foo.json"]).expect("parse absent");
|
||||
let cli_absent = Cli::try_parse_from(BASE_ARGS).expect("parse absent");
|
||||
assert!(cli_absent.include_reasoning.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cli_kigi_home_override_parses() {
|
||||
let cli = Cli::try_parse_from([
|
||||
"trace_classify",
|
||||
"--trace",
|
||||
"foo.json",
|
||||
"--kigi-home",
|
||||
"/tmp/scratch-kigi",
|
||||
])
|
||||
let cli = Cli::try_parse_from(
|
||||
BASE_ARGS
|
||||
.iter()
|
||||
.copied()
|
||||
.chain(["--kigi-home", "/tmp/scratch-kigi"]),
|
||||
)
|
||||
.expect("parse");
|
||||
assert_eq!(cli.kigi_home, Some(PathBuf::from("/tmp/scratch-kigi")));
|
||||
}
|
||||
@@ -186,8 +206,8 @@ mod tests {
|
||||
.map(|v| v.to_string_lossy().into_owned())
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
assert_eq!(by_id("model"), vec!["grok-4.5"]);
|
||||
assert_eq!(by_id("api_base_url"), vec!["https://api.x.ai/v1"]);
|
||||
assert_eq!(by_id("model"), vec!["kimi-for-coding"]);
|
||||
assert!(by_id("api_base_url").is_empty(), "no default BYOK endpoint");
|
||||
assert!(by_id("min_confidence").is_empty(), "no default");
|
||||
assert!(by_id("include_reasoning").is_empty(), "no default");
|
||||
}
|
||||
@@ -195,13 +215,12 @@ mod tests {
|
||||
/// F6 — `--min-confidence 0.5` parses and lands in `RunArgs`.
|
||||
#[test]
|
||||
fn cli_min_confidence_override_parses() {
|
||||
let cli = Cli::try_parse_from([
|
||||
"trace_classify",
|
||||
"--trace",
|
||||
"foo.json",
|
||||
"--min-confidence",
|
||||
"0.42",
|
||||
])
|
||||
let cli = Cli::try_parse_from(
|
||||
BASE_ARGS
|
||||
.iter()
|
||||
.copied()
|
||||
.chain(["--min-confidence", "0.42"]),
|
||||
)
|
||||
.expect("parse");
|
||||
assert_eq!(cli.min_confidence, Some(0.42));
|
||||
}
|
||||
@@ -214,7 +233,7 @@ mod tests {
|
||||
fn cli_min_confidence_rejects_bad_values() {
|
||||
for bad in ["1.5", "-0.1", "nan", "inf", "not-a-float"] {
|
||||
let arg = format!("--min-confidence={bad}");
|
||||
let err = Cli::try_parse_from(["trace_classify", "--trace", "foo.json", arg.as_str()])
|
||||
let err = Cli::try_parse_from(BASE_ARGS.iter().copied().chain([arg.as_str()]))
|
||||
.expect_err(bad);
|
||||
// Parsing failed — that's all we need. Exact error text
|
||||
// is clap-version-dependent.
|
||||
|
||||
Reference in New Issue
Block a user