use std::path::Path;
use super::types::PlanningRule;
use skilllite_evolution::seed;
pub fn load_rules(workspace: Option<&Path>, chat_root: Option<&Path>) -> Vec<PlanningRule> {
let mut rules = if let Some(root) = chat_root {
seed::load_rules(root)
} else {
seed::load_rules(Path::new("/nonexistent"))
};
if let Some(ws) = workspace {
let path = ws.join(".skilllite").join("planning_rules.json");
if path.exists() {
if let Ok(content) = skilllite_fs::read_file(&path) {
if let Ok(ws_rules) = serde_json::from_str::<Vec<PlanningRule>>(&content) {
let ws_count = ws_rules.len();
merge_workspace_rules(&mut rules, ws_rules);
tracing::debug!(
"Merged {} workspace rules from {}",
ws_count,
path.display()
);
}
}
}
}
rules
}
fn merge_workspace_rules(base: &mut Vec<PlanningRule>, workspace: Vec<PlanningRule>) {
for ws_rule in workspace {
if let Some(pos) = base.iter().position(|r| r.id == ws_rule.id) {
if base[pos].mutable {
base[pos] = ws_rule;
}
} else {
base.push(ws_rule);
}
}
}
pub fn load_full_examples(chat_root: Option<&Path>) -> String {
if let Some(root) = chat_root {
return seed::load_examples(root);
}
include_str!("seed/examples.seed.md").to_string()
}
pub fn compact_examples_section(user_message: &str) -> String {
let msg_lower = user_message.to_lowercase();
let mut lines = vec![
"Example 1 - Simple (no tools): \"Write a poem\", \"Translate X\", \"Explain this code\" → []".to_string(),
"Example 2 - Tools: \"Calculate 123*456\" → [{\"id\":1,\"description\":\"Use calculator\",\"tool_hint\":\"calculator\",\"completed\":false}]".to_string(),
];
let is_city_or_place = user_message.contains("城市")
|| user_message.contains("地方")
|| user_message.contains("对比")
|| user_message.contains("优劣势")
|| user_message.contains("全方位")
|| user_message.contains("两地")
|| msg_lower.contains("city")
|| msg_lower.contains("place");
let candidates: Vec<(&str, &str, &str)> = vec![
(
"介绍",
"景点",
"介绍+地点/景点/路线: agent-browser or http-request for fresh info. NOT [].",
),
(
"城市",
"全方位",
"城市/地方/全方位分析: http-request for fresh data. NOT chat_history.",
),
(
"对比",
"优劣势",
"对比/优劣势: http-request for fresh data. NOT chat_history.",
),
(
"分析",
"稳定性",
"分析稳定性/项目: chat_history (ONLY when analyzing chat/project, NOT places)",
),
("历史", "记录", "历史记录: chat_history + analysis."),
(
"输出到",
"保存到",
"输出到output: write_output, file_write.",
),
(
"继续",
"",
"继续: use context to infer task, often http-request.",
),
("天气", "气象", "天气: weather skill."),
("官网", "网站", "官网/网站: file_write + preview, 2 tasks."),
(
"refactor",
"panic",
"编码refactor: file_read定位→file_edit修改→command测试.",
),
("整理", "项目", "模糊请求: file_list探索→analysis总结/确认."),
];
let mut added = 0;
for (k1, k2, text) in candidates {
if added >= 3 {
break;
}
let matches = user_message.contains(k1)
|| msg_lower.contains(&k1.to_lowercase())
|| (!k2.is_empty()
&& (user_message.contains(k2) || msg_lower.contains(&k2.to_lowercase())));
let skip = matches && k1 == "分析" && is_city_or_place;
if matches && !skip {
lines.push(format!("Example - {}: {}", k1, text));
added += 1;
}
}
lines.join("\n")
}