KeiSeiKit-1.0/_primitives/_rust/kei-router/tests/integration.rs
Parfii-bot adc007b7b0 feat(primitives): 10 Rust crates extracted from LBM (Genesis-scrubbed)
- kei-router — keyword-dispatch meta-tool (CfC ML fallback removed)
- kei-sage — Obsidian-style knowledge graph, FTS5 + BFS + PageRank
- kei-task — task DAG with deps, milestones, dependency-chain queries
- kei-chat-store — Claude conversation session persistence + FTS search
- kei-crossdomain — typed-edge store + BFS cross-domain glue
- kei-search-core — 3-wave deep research with microcent budget cap
- kei-content-store — asset + prompt + campaign registry
- kei-social-store — people + interactions CRM (lite)
- kei-curator — edge-decay graph hygiene utility
- kei-auth — multi-tenant session tokens (replaces single-bearer)

Genesis-scan pre-import pass: skipped pkg/mxl1/*, pkg/inference/*, pkg/trainer/*,
pkg/nc01/*, internal/ml/* (all Genesis/CfC adjacent, sensitive IP).
Security: skipped tools_threat/radio/protocol/med/mlreg (offensive/banned).
Domain verticals skipped: hr/legal/infra/ops/api/osint/edu/geo/hw/finance.

New 'mcp' profile in MANIFEST.toml bundles all 10 for MCP server deployment.

Workspace now 24 crates, cargo check --workspace clean, 94 workspace tests pass.
2026-04-22 12:48:56 +08:00

76 lines
2.1 KiB
Rust

//! kei-router integration tests — mirror LBM router_test.go semantics.
use kei_router::{DynRule, Method, Router};
#[test]
fn exact_match_search_knowledge() {
let r = Router::new();
let out = r.route("search knowledge base for rust async");
assert_eq!(out.tool, "search_knowledge");
assert_eq!(out.method, Method::Keyword);
assert!(out.confidence > 0.7);
}
#[test]
fn fuzzy_match_find_importers_with_path() {
let r = Router::new();
let out = r.route("who imports /src/router.rs");
assert_eq!(out.tool, "find_importers");
assert_eq!(
out.params.get("path").and_then(|v| v.as_str()),
Some("/src/router.rs")
);
}
#[test]
fn no_match_fallback_knowledge() {
let r = Router::new();
let out = r.route("hello this is not a routed query");
assert_eq!(out.tool, "search_knowledge");
assert_eq!(out.method, Method::Fallback);
assert!(out.confidence < 0.3);
}
#[test]
fn no_match_fallback_code_with_path() {
let r = Router::new();
let out = r.route("what happened in /tmp/mystery.rs");
assert_eq!(out.tool, "search_code");
assert_eq!(out.method, Method::Fallback);
}
#[test]
fn confidence_ranking_keyword_above_fallback() {
let r = Router::new();
let kw = r.route("knowledge stats please");
let fb = r.route("asdf zxcv qwer");
assert!(kw.confidence > fb.confidence);
}
#[test]
fn dynamic_rule_addition() {
let mut r = Router::new();
r.add_dynamic(vec![DynRule {
tool: "custom_tool".into(),
keywords: vec!["magic-keyword".into()],
}]);
let out = r.route("please run magic-keyword now");
assert_eq!(out.tool, "custom_tool");
assert_eq!(out.method, Method::Keyword);
}
#[test]
fn remote_mcp_forward_hint() {
let r = Router::new();
let out = r.route_with_hint("completely novel utterance xyz");
assert_eq!(out.method, Method::Fallback);
assert_eq!(out.params.get("_forward"), Some(&serde_json::json!(true)));
}
#[test]
fn id_extraction_for_get_task() {
let r = Router::new();
let out = r.route("get task id=42");
assert_eq!(out.tool, "get_task");
assert_eq!(out.params.get("id").and_then(|v| v.as_i64()), Some(42));
}