refactor(rust-core): Constructor-Pattern splits in kei-router + kei-auth

- kei-router: extract kw_tables.rs from keywords.rs (keep <200 LOC)
- kei-auth: extract new_payload + encode_token helpers
This commit is contained in:
Parfii-bot 2026-04-22 12:57:12 +08:00
parent 319295860f
commit a3769ebbb6
4 changed files with 224 additions and 205 deletions

View file

@ -43,27 +43,41 @@ pub fn issue(
) -> Result<String> {
let now = Utc::now().timestamp();
let expires_at = now + ttl_secs;
let payload = new_payload(user_id, project, scope, expires_at);
let token = encode_token(&payload, key)?;
persist_token(conn, &token, user_id, project, scope, expires_at, now)?;
Ok(token)
}
fn new_payload(user_id: &str, project: &str, scope: Scope, expires_at: i64) -> Payload {
let mut raw = [0u8; 16];
rand::thread_rng().fill_bytes(&mut raw);
let tid = base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(raw);
let payload = Payload {
tid: tid.clone(),
Payload {
tid,
user_id: user_id.into(),
project: project.into(),
scope: scope.to_string(),
expires_at,
};
let body = serde_json::to_vec(&payload)?;
}
}
fn encode_token(payload: &Payload, key: &[u8]) -> Result<String> {
let body = serde_json::to_vec(payload)?;
let body_b64 = base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(&body);
let sig = sign(key, body_b64.as_bytes());
let token = format!("{}.{}", body_b64, sig);
Ok(format!("{}.{}", body_b64, sig))
}
fn persist_token(conn: &Connection, token: &str, user_id: &str, project: &str,
scope: Scope, expires_at: i64, now: i64) -> Result<()> {
let hash = sha256_hex(token.as_bytes());
conn.execute(
"INSERT INTO auth_tokens (token_hash, user_id, project, scope, expires_at, created_at)
VALUES (?1,?2,?3,?4,?5,?6)",
params![hash, user_id, project, scope.as_str(), expires_at, now],
)?;
Ok(token)
Ok(())
}
/// Verify a token: signature valid, not revoked, not expired, returns identity + scope.

View file

@ -1,9 +1,13 @@
//! Default keyword tables. Each function returns a static slice of rules.
//! Default keyword tables — aggregated from per-domain cubes.
//!
//! Ordering matters — more-specific multi-word keywords must come before
//! single-word matches on the same tool family.
use crate::rules::*;
use crate::kw_tables::{
CHAT_RULES, CODE_RULES, CONTENT_RULES, CROSS_RULES, CURATOR_RULES,
SAGE_RULES, SEARCH_RULES, SOCIAL_RULES, TASK_RULES,
};
use crate::rules::KeywordRule;
pub fn default_rules() -> Vec<KeywordRule> {
let mut rules = Vec::with_capacity(128);
@ -18,200 +22,3 @@ pub fn default_rules() -> Vec<KeywordRule> {
rules.extend_from_slice(&SEARCH_RULES);
rules
}
// --- sage -----------------------------------------------------------------
const SAGE_RULES: [KeywordRule; 13] = [
KeywordRule { tool: "find_related_knowledge",
keywords: &["related_knowledge", "related knowledge", "vault related"], require: always },
KeywordRule { tool: "search_knowledge",
keywords: &["search_knowledge", "search knowledge", "vault search", "find in vault", "knowledge search"], require: always },
KeywordRule { tool: "get_unit",
keywords: &["get_unit", "get unit", "show unit", "read unit"], require: always },
KeywordRule { tool: "get_unit", keywords: &["unit"], require: has_id },
KeywordRule { tool: "list_units",
keywords: &["list_units", "list units", "show units", "all units"], require: always },
KeywordRule { tool: "get_unit_graph",
keywords: &["unit_graph", "unit graph", "knowledge graph", "vault graph"], require: always },
KeywordRule { tool: "knowledge_stats",
keywords: &["knowledge_stats", "knowledge stats", "vault stats"], require: always },
KeywordRule { tool: "add_note",
keywords: &["add_note", "add note", "create note", "new note"], require: always },
KeywordRule { tool: "update_note",
keywords: &["update_note", "update note", "edit note"], require: has_id },
KeywordRule { tool: "grade_evidence",
keywords: &["grade_evidence", "grade evidence", "set grade", "evidence grade"], require: has_id },
KeywordRule { tool: "link_units",
keywords: &["link_units", "link units", "connect units", "create edge"], require: always },
KeywordRule { tool: "import_vault",
keywords: &["import_vault", "import vault", "import obsidian"], require: has_path },
KeywordRule { tool: "sync_vault",
keywords: &["sync_vault", "sync vault", "sync obsidian"], require: always },
];
// --- code -----------------------------------------------------------------
const CODE_RULES: [KeywordRule; 17] = [
KeywordRule { tool: "get_architecture",
keywords: &["architecture", "arch", "overview", "project overview", "get_architecture"], require: has_path },
KeywordRule { tool: "find_importers",
keywords: &["importer", "importers", "who imports", "depends on", "reverse dep", "find_importers"], require: has_path },
KeywordRule { tool: "find_tests",
keywords: &["test file", "find_tests", "find tests", "test for"], require: has_path },
KeywordRule { tool: "get_change_impact",
keywords: &["impact", "change_impact", "change impact", "refactor impact", "get_change_impact"], require: has_path },
KeywordRule { tool: "get_file_info",
keywords: &["file_info", "file info", "get_file_info"], require: has_path },
KeywordRule { tool: "find_similar",
keywords: &["similar", "find_similar", "like this file"], require: has_path },
KeywordRule { tool: "get_related_files",
keywords: &["related", "get_related", "get_related_files"], require: has_path },
KeywordRule { tool: "get_edges",
keywords: &["edges", "get_edges", "dependencies of"], require: has_path },
KeywordRule { tool: "batch_edges",
keywords: &["batch", "batch_edges"], require: has_paths },
KeywordRule { tool: "check_patterns",
keywords: &["lint", "check_pattern", "check_patterns", "constructor pattern", "loc check"], require: has_path },
KeywordRule { tool: "suggest_files",
keywords: &["suggest", "suggest_files", "next file", "what to open"], require: has_path },
KeywordRule { tool: "hot_files",
keywords: &["hot file", "hottest", "hot_files", "most connected"], require: always },
KeywordRule { tool: "ranked_files",
keywords: &["ranked", "pagerank", "ranked_files", "important files", "central files"], require: always },
KeywordRule { tool: "graph_stats",
keywords: &["graph_stats", "graph stats", "edge count", "code stats"], require: always },
KeywordRule { tool: "add_root",
keywords: &["add_root", "add root", "add scan root"], require: has_path },
KeywordRule { tool: "list_roots",
keywords: &["list_roots", "list roots", "scan roots", "show roots"], require: always },
KeywordRule { tool: "search_code",
keywords: &["search_code", "search code", "find code", "grep", "fts"], require: always },
];
// --- task -----------------------------------------------------------------
const TASK_RULES: [KeywordRule; 9] = [
KeywordRule { tool: "search_tasks",
keywords: &["search_tasks", "search task", "find task", "task search"], require: always },
KeywordRule { tool: "get_task",
keywords: &["get_task", "get task", "task detail"], require: has_id },
KeywordRule { tool: "task_graph",
keywords: &["task_graph", "task graph", "task deps"], require: always },
KeywordRule { tool: "task_stats",
keywords: &["task_stats", "task stats", "task statistics"], require: always },
KeywordRule { tool: "dependency_chain",
keywords: &["dependency_chain", "dep chain", "critical path"], require: always },
KeywordRule { tool: "create_task",
keywords: &["create_task", "create task", "new task", "add task"], require: always },
KeywordRule { tool: "update_task",
keywords: &["update_task", "update task"], require: has_id },
KeywordRule { tool: "add_dependency",
keywords: &["add_dependency", "add dep", "task depends"], require: always },
KeywordRule { tool: "create_milestone",
keywords: &["create_milestone", "create milestone", "new milestone"], require: always },
];
// --- chat -----------------------------------------------------------------
const CHAT_RULES: [KeywordRule; 9] = [
KeywordRule { tool: "search_chat",
keywords: &["search_chat", "search chat", "find in chat", "chat search"], require: always },
KeywordRule { tool: "get_session",
keywords: &["get_session", "chat session", "get session"], require: has_any_id_or_query },
KeywordRule { tool: "list_sessions",
keywords: &["list_sessions", "list sessions", "list chats", "chat history", "my chats"], require: always },
KeywordRule { tool: "chat_stats",
keywords: &["chat_stats", "chat stats", "chat analytics"], require: always },
KeywordRule { tool: "chat_model_usage",
keywords: &["chat_model_usage", "model usage", "token usage"], require: always },
KeywordRule { tool: "start_chat",
keywords: &["start_chat", "new chat", "start chat", "create session"], require: always },
KeywordRule { tool: "save_message",
keywords: &["save_message", "save message", "log message"], require: always },
KeywordRule { tool: "archive_chat",
keywords: &["archive_chat", "archive chat", "close chat"], require: has_any_id_or_query },
KeywordRule { tool: "link_chat",
keywords: &["link_chat", "link chat", "connect chat"], require: always },
];
// --- content, social, cross, curator, search -------------------------------
const CONTENT_RULES: [KeywordRule; 8] = [
KeywordRule { tool: "search_content",
keywords: &["search_content", "search content", "find content", "content search"], require: always },
KeywordRule { tool: "get_asset",
keywords: &["get_asset", "get asset", "asset detail"], require: has_id },
KeywordRule { tool: "content_lineage",
keywords: &["content_lineage", "content lineage", "asset lineage"], require: always },
KeywordRule { tool: "content_stats",
keywords: &["content_stats", "content stats", "content statistics"], require: always },
KeywordRule { tool: "prompt_history",
keywords: &["prompt_history", "prompt history", "prompt log"], require: always },
KeywordRule { tool: "register_asset",
keywords: &["register_asset", "register asset", "new asset", "add asset"], require: always },
KeywordRule { tool: "register_prompt",
keywords: &["register_prompt", "register prompt", "new prompt", "add prompt"], require: always },
KeywordRule { tool: "create_campaign",
keywords: &["create_campaign", "create campaign", "new campaign", "add campaign"], require: always },
];
const SOCIAL_RULES: [KeywordRule; 8] = [
KeywordRule { tool: "search_people",
keywords: &["search_people", "search people", "find people", "people search"], require: always },
KeywordRule { tool: "get_person",
keywords: &["get_person", "get person", "person detail"], require: has_id },
KeywordRule { tool: "relationship_graph",
keywords: &["relationship_graph", "relationship graph", "social graph"], require: always },
KeywordRule { tool: "social_stats",
keywords: &["social_stats", "social stats", "social statistics"], require: always },
KeywordRule { tool: "add_person",
keywords: &["add_person", "add person", "new person"], require: always },
KeywordRule { tool: "add_org",
keywords: &["add_org", "add org", "new org", "add organization"], require: always },
KeywordRule { tool: "log_interaction",
keywords: &["log_interaction", "log interaction", "record interaction"], require: always },
KeywordRule { tool: "link_people",
keywords: &["link_people", "link people", "connect people"], require: always },
];
const CROSS_RULES: [KeywordRule; 8] = [
KeywordRule { tool: "cross_search",
keywords: &["cross_search", "cross search", "search cross", "cross-domain search"], require: always },
KeywordRule { tool: "cross_graph",
keywords: &["cross_graph", "cross graph", "cross-domain graph", "connected across"], require: always },
KeywordRule { tool: "cross_edges",
keywords: &["cross_edges", "cross edges", "inter-domain edges"], require: always },
KeywordRule { tool: "cross_stats",
keywords: &["cross_stats", "cross stats", "cross-domain stats"], require: always },
KeywordRule { tool: "domain_cooccurrence",
keywords: &["domain_cooccurrence", "cooccurrence", "domain cooccurrence"], require: always },
KeywordRule { tool: "cross_link",
keywords: &["cross_link", "link domain", "cross link"], require: always },
KeywordRule { tool: "cross_unlink",
keywords: &["cross_unlink", "unlink domain", "cross unlink"], require: always },
KeywordRule { tool: "cross_auto_link",
keywords: &["cross_auto_link", "auto link", "discover links"], require: always },
];
const CURATOR_RULES: [KeywordRule; 3] = [
KeywordRule { tool: "curator_status",
keywords: &["curator_status", "curator status", "curation status", "curation"], require: always },
KeywordRule { tool: "curator_check",
keywords: &["curator_check", "curator check", "curator dry-run", "curator preview"], require: always },
KeywordRule { tool: "curator_run",
keywords: &["curator_run", "curator run", "run curator"], require: always },
];
const SEARCH_RULES: [KeywordRule; 8] = [
KeywordRule { tool: "search_research",
keywords: &["search_research", "search research", "find research", "past research"], require: always },
KeywordRule { tool: "get_research",
keywords: &["get_research", "get research", "research detail", "show research"], require: has_id },
KeywordRule { tool: "research_sources",
keywords: &["research_sources", "research sources", "sources for research"], require: has_id },
KeywordRule { tool: "research_claims",
keywords: &["research_claims", "research claims", "validated claims", "claims for"], require: has_id },
KeywordRule { tool: "search_stats",
keywords: &["search_stats", "search stats", "research statistics", "research stats"], require: always },
KeywordRule { tool: "run_research",
keywords: &["run_research", "deep research", "research:", "investigate:", "research this"], require: always },
KeywordRule { tool: "stop_research",
keywords: &["stop_research", "stop research", "cancel research"], require: has_id },
KeywordRule { tool: "research_export",
keywords: &["research_export", "export research", "research markdown", "download research"], require: has_id },
];

View file

@ -0,0 +1,197 @@
//! Per-domain keyword rule tables. Split from `keywords.rs` for Constructor
//! Pattern <200 LOC compliance. Each table is a `const` slice so the whole
//! router is built at compile time — zero allocation hot-path.
use crate::rules::{always, has_any_id_or_query, has_id, has_path, has_paths, KeywordRule};
pub const SAGE_RULES: [KeywordRule; 13] = [
KeywordRule { tool: "find_related_knowledge",
keywords: &["related_knowledge", "related knowledge", "vault related"], require: always },
KeywordRule { tool: "search_knowledge",
keywords: &["search_knowledge", "search knowledge", "vault search", "find in vault", "knowledge search"], require: always },
KeywordRule { tool: "get_unit",
keywords: &["get_unit", "get unit", "show unit", "read unit"], require: always },
KeywordRule { tool: "get_unit", keywords: &["unit"], require: has_id },
KeywordRule { tool: "list_units",
keywords: &["list_units", "list units", "show units", "all units"], require: always },
KeywordRule { tool: "get_unit_graph",
keywords: &["unit_graph", "unit graph", "knowledge graph", "vault graph"], require: always },
KeywordRule { tool: "knowledge_stats",
keywords: &["knowledge_stats", "knowledge stats", "vault stats"], require: always },
KeywordRule { tool: "add_note",
keywords: &["add_note", "add note", "create note", "new note"], require: always },
KeywordRule { tool: "update_note",
keywords: &["update_note", "update note", "edit note"], require: has_id },
KeywordRule { tool: "grade_evidence",
keywords: &["grade_evidence", "grade evidence", "set grade", "evidence grade"], require: has_id },
KeywordRule { tool: "link_units",
keywords: &["link_units", "link units", "connect units", "create edge"], require: always },
KeywordRule { tool: "import_vault",
keywords: &["import_vault", "import vault", "import obsidian"], require: has_path },
KeywordRule { tool: "sync_vault",
keywords: &["sync_vault", "sync vault", "sync obsidian"], require: always },
];
pub const CODE_RULES: [KeywordRule; 17] = [
KeywordRule { tool: "get_architecture",
keywords: &["architecture", "arch", "overview", "project overview", "get_architecture"], require: has_path },
KeywordRule { tool: "find_importers",
keywords: &["importer", "importers", "who imports", "depends on", "reverse dep", "find_importers"], require: has_path },
KeywordRule { tool: "find_tests",
keywords: &["test file", "find_tests", "find tests", "test for"], require: has_path },
KeywordRule { tool: "get_change_impact",
keywords: &["impact", "change_impact", "change impact", "refactor impact", "get_change_impact"], require: has_path },
KeywordRule { tool: "get_file_info",
keywords: &["file_info", "file info", "get_file_info"], require: has_path },
KeywordRule { tool: "find_similar",
keywords: &["similar", "find_similar", "like this file"], require: has_path },
KeywordRule { tool: "get_related_files",
keywords: &["related", "get_related", "get_related_files"], require: has_path },
KeywordRule { tool: "get_edges",
keywords: &["edges", "get_edges", "dependencies of"], require: has_path },
KeywordRule { tool: "batch_edges",
keywords: &["batch", "batch_edges"], require: has_paths },
KeywordRule { tool: "check_patterns",
keywords: &["lint", "check_pattern", "check_patterns", "constructor pattern", "loc check"], require: has_path },
KeywordRule { tool: "suggest_files",
keywords: &["suggest", "suggest_files", "next file", "what to open"], require: has_path },
KeywordRule { tool: "hot_files",
keywords: &["hot file", "hottest", "hot_files", "most connected"], require: always },
KeywordRule { tool: "ranked_files",
keywords: &["ranked", "pagerank", "ranked_files", "important files", "central files"], require: always },
KeywordRule { tool: "graph_stats",
keywords: &["graph_stats", "graph stats", "edge count", "code stats"], require: always },
KeywordRule { tool: "add_root",
keywords: &["add_root", "add root", "add scan root"], require: has_path },
KeywordRule { tool: "list_roots",
keywords: &["list_roots", "list roots", "scan roots", "show roots"], require: always },
KeywordRule { tool: "search_code",
keywords: &["search_code", "search code", "find code", "grep", "fts"], require: always },
];
pub const TASK_RULES: [KeywordRule; 9] = [
KeywordRule { tool: "search_tasks",
keywords: &["search_tasks", "search task", "find task", "task search"], require: always },
KeywordRule { tool: "get_task",
keywords: &["get_task", "get task", "task detail"], require: has_id },
KeywordRule { tool: "task_graph",
keywords: &["task_graph", "task graph", "task deps"], require: always },
KeywordRule { tool: "task_stats",
keywords: &["task_stats", "task stats", "task statistics"], require: always },
KeywordRule { tool: "dependency_chain",
keywords: &["dependency_chain", "dep chain", "critical path"], require: always },
KeywordRule { tool: "create_task",
keywords: &["create_task", "create task", "new task", "add task"], require: always },
KeywordRule { tool: "update_task",
keywords: &["update_task", "update task"], require: has_id },
KeywordRule { tool: "add_dependency",
keywords: &["add_dependency", "add dep", "task depends"], require: always },
KeywordRule { tool: "create_milestone",
keywords: &["create_milestone", "create milestone", "new milestone"], require: always },
];
pub const CHAT_RULES: [KeywordRule; 9] = [
KeywordRule { tool: "search_chat",
keywords: &["search_chat", "search chat", "find in chat", "chat search"], require: always },
KeywordRule { tool: "get_session",
keywords: &["get_session", "chat session", "get session"], require: has_any_id_or_query },
KeywordRule { tool: "list_sessions",
keywords: &["list_sessions", "list sessions", "list chats", "chat history", "my chats"], require: always },
KeywordRule { tool: "chat_stats",
keywords: &["chat_stats", "chat stats", "chat analytics"], require: always },
KeywordRule { tool: "chat_model_usage",
keywords: &["chat_model_usage", "model usage", "token usage"], require: always },
KeywordRule { tool: "start_chat",
keywords: &["start_chat", "new chat", "start chat", "create session"], require: always },
KeywordRule { tool: "save_message",
keywords: &["save_message", "save message", "log message"], require: always },
KeywordRule { tool: "archive_chat",
keywords: &["archive_chat", "archive chat", "close chat"], require: has_any_id_or_query },
KeywordRule { tool: "link_chat",
keywords: &["link_chat", "link chat", "connect chat"], require: always },
];
pub const CONTENT_RULES: [KeywordRule; 8] = [
KeywordRule { tool: "search_content",
keywords: &["search_content", "search content", "find content", "content search"], require: always },
KeywordRule { tool: "get_asset",
keywords: &["get_asset", "get asset", "asset detail"], require: has_id },
KeywordRule { tool: "content_lineage",
keywords: &["content_lineage", "content lineage", "asset lineage"], require: always },
KeywordRule { tool: "content_stats",
keywords: &["content_stats", "content stats", "content statistics"], require: always },
KeywordRule { tool: "prompt_history",
keywords: &["prompt_history", "prompt history", "prompt log"], require: always },
KeywordRule { tool: "register_asset",
keywords: &["register_asset", "register asset", "new asset", "add asset"], require: always },
KeywordRule { tool: "register_prompt",
keywords: &["register_prompt", "register prompt", "new prompt", "add prompt"], require: always },
KeywordRule { tool: "create_campaign",
keywords: &["create_campaign", "create campaign", "new campaign", "add campaign"], require: always },
];
pub const SOCIAL_RULES: [KeywordRule; 8] = [
KeywordRule { tool: "search_people",
keywords: &["search_people", "search people", "find people", "people search"], require: always },
KeywordRule { tool: "get_person",
keywords: &["get_person", "get person", "person detail"], require: has_id },
KeywordRule { tool: "relationship_graph",
keywords: &["relationship_graph", "relationship graph", "social graph"], require: always },
KeywordRule { tool: "social_stats",
keywords: &["social_stats", "social stats", "social statistics"], require: always },
KeywordRule { tool: "add_person",
keywords: &["add_person", "add person", "new person"], require: always },
KeywordRule { tool: "add_org",
keywords: &["add_org", "add org", "new org", "add organization"], require: always },
KeywordRule { tool: "log_interaction",
keywords: &["log_interaction", "log interaction", "record interaction"], require: always },
KeywordRule { tool: "link_people",
keywords: &["link_people", "link people", "connect people"], require: always },
];
pub const CROSS_RULES: [KeywordRule; 8] = [
KeywordRule { tool: "cross_search",
keywords: &["cross_search", "cross search", "search cross", "cross-domain search"], require: always },
KeywordRule { tool: "cross_graph",
keywords: &["cross_graph", "cross graph", "cross-domain graph", "connected across"], require: always },
KeywordRule { tool: "cross_edges",
keywords: &["cross_edges", "cross edges", "inter-domain edges"], require: always },
KeywordRule { tool: "cross_stats",
keywords: &["cross_stats", "cross stats", "cross-domain stats"], require: always },
KeywordRule { tool: "domain_cooccurrence",
keywords: &["domain_cooccurrence", "cooccurrence", "domain cooccurrence"], require: always },
KeywordRule { tool: "cross_link",
keywords: &["cross_link", "link domain", "cross link"], require: always },
KeywordRule { tool: "cross_unlink",
keywords: &["cross_unlink", "unlink domain", "cross unlink"], require: always },
KeywordRule { tool: "cross_auto_link",
keywords: &["cross_auto_link", "auto link", "discover links"], require: always },
];
pub const CURATOR_RULES: [KeywordRule; 3] = [
KeywordRule { tool: "curator_status",
keywords: &["curator_status", "curator status", "curation status", "curation"], require: always },
KeywordRule { tool: "curator_check",
keywords: &["curator_check", "curator check", "curator dry-run", "curator preview"], require: always },
KeywordRule { tool: "curator_run",
keywords: &["curator_run", "curator run", "run curator"], require: always },
];
pub const SEARCH_RULES: [KeywordRule; 8] = [
KeywordRule { tool: "search_research",
keywords: &["search_research", "search research", "find research", "past research"], require: always },
KeywordRule { tool: "get_research",
keywords: &["get_research", "get research", "research detail", "show research"], require: has_id },
KeywordRule { tool: "research_sources",
keywords: &["research_sources", "research sources", "sources for research"], require: has_id },
KeywordRule { tool: "research_claims",
keywords: &["research_claims", "research claims", "validated claims", "claims for"], require: has_id },
KeywordRule { tool: "search_stats",
keywords: &["search_stats", "search stats", "research statistics", "research stats"], require: always },
KeywordRule { tool: "run_research",
keywords: &["run_research", "deep research", "research:", "investigate:", "research this"], require: always },
KeywordRule { tool: "stop_research",
keywords: &["stop_research", "stop research", "cancel research"], require: has_id },
KeywordRule { tool: "research_export",
keywords: &["research_export", "export research", "research markdown", "download research"], require: has_id },
];

View file

@ -12,6 +12,7 @@
pub mod extract;
pub mod keywords;
pub mod kw_tables;
pub mod router;
pub mod rules;