feat: restore zhihu browser skills

Reconnect the recovered Zhihu skill flows to the live browser runtime and resolve their resources relative to the executable so they work outside the repo root.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
木炎
2026-03-27 14:29:38 +08:00
parent b87968632a
commit 6aad2ce48e
32 changed files with 7607 additions and 146 deletions

441
tests/skill_router_test.rs Normal file
View File

@@ -0,0 +1,441 @@
use sgclaw::skill::router::{route_instruction, RoutedSkill, RouterError};
#[test]
fn route_instruction_parses_explicit_zhihu_skill() {
let routed = route_instruction(
r#"skill:zhihu_write {"title":"自动发文能力测试","body":"第一段\n\n第二段","publish":false}"#,
)
.unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuWrite(req))
if req.title == "自动发文能力测试"
&& req.body == "第一段\n\n第二段"
&& !req.publish
));
}
#[test]
fn route_instruction_parses_explicit_zhihu_hotlist_collect_skill() {
let routed = route_instruction(
r#"skill:zhihu_hotlist_collect {"top_n":5,"comments_per_item":8,"store_dir":"data/zhihu_hotlist"}"#,
)
.unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuHotlistCollect(req))
if req.top_n == 5
&& req.comments_per_item == 8
&& req.store_dir.as_deref() == Some("data/zhihu_hotlist")
));
}
#[test]
fn route_instruction_parses_explicit_zhihu_hotlist_report_skill() {
let routed =
route_instruction(r#"skill:zhihu_hotlist_report {"snapshot_id":"snap-1","top_n":3}"#)
.unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuHotlistReport(req))
if req.snapshot_id.as_deref() == Some("snap-1")
&& req.top_n == 3
));
}
#[test]
fn route_instruction_parses_explicit_zhihu_navigation_skill() {
let routed = route_instruction(
r#"skill:zhihu_navigate {"page":"content_analysis","ensure_loaded":true}"#,
)
.unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "content_analysis" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_content_analysis_natural_language() {
let routed = route_instruction("帮我打开知乎中的内容分析页面").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "content_analysis" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_short_zhihu_content_analysis_phrase() {
let routed = route_instruction("打开知乎内容分析").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "content_analysis" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_income_analysis_natural_language() {
let routed = route_instruction("打开知乎收益分析页面").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "income_analysis" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_home_natural_language() {
let routed = route_instruction("打开知乎首页").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "home" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_hot_list_natural_language() {
let routed = route_instruction("打开知乎热榜页面").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "hot_list" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_column_home_natural_language() {
let routed = route_instruction("打开知乎专栏页").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "column_home" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_question_page_natural_language() {
let routed = route_instruction("打开知乎问题页").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "question_page" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_messages_page_natural_language() {
let routed = route_instruction("打开知乎消息分栏").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "messages_page" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_messages_all_tab_natural_language() {
let routed = route_instruction("打开知乎消息分栏全部私信").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "messages_all_tab" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_messages_unread_tab_natural_language() {
let routed = route_instruction("打开知乎消息分栏未读消息").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "messages_unread_tab" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_messages_strangers_tab_natural_language() {
let routed = route_instruction("打开知乎消息分栏陌生人消息").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "messages_strangers_tab" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_messages_settings_menu_natural_language() {
let routed = route_instruction("打开知乎消息设置菜单").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "messages_settings_menu" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_notifications_page_natural_language() {
let routed = route_instruction("打开知乎通知分栏").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "notifications_page" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_notifications_replies_tab_natural_language() {
let routed = route_instruction("打开知乎通知分栏回复我的").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "notifications_replies_tab" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_notifications_votes_favorites_tab_natural_language() {
let routed = route_instruction("打开知乎通知分栏赞同与收藏").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "notifications_votes_favorites_tab" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_notifications_follows_tab_natural_language() {
let routed = route_instruction("打开知乎通知分栏关注我的").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "notifications_follows_tab" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_notifications_system_tab_natural_language() {
let routed = route_instruction("打开知乎通知分栏系统通知").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "notifications_system_tab" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_notifications_settings_menu_natural_language() {
let routed = route_instruction("打开知乎通知设置菜单").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "notifications_settings_menu" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_profile_page_natural_language() {
let routed = route_instruction("打开知乎个人主页").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "profile_page" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_profile_answers_tab_natural_language() {
let routed = route_instruction("打开知乎个人主页回答分栏").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "profile_answers_tab" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_profile_followers_tab_natural_language() {
let routed = route_instruction("打开知乎个人主页粉丝分栏").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "profile_followers_tab" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_account_settings_natural_language() {
let routed = route_instruction("打开知乎账号设置菜单").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "settings_account_menu" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_privacy_settings_natural_language() {
let routed = route_instruction("打开知乎隐私设置菜单").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "settings_privacy_menu" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_security_settings_natural_language() {
let routed = route_instruction("打开知乎安全设置菜单").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "settings_security_menu" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_search_filter_menu_natural_language() {
let routed = route_instruction("打开知乎搜索筛选菜单").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "search_filter_menu" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_context_more_menu_natural_language() {
let routed = route_instruction("打开知乎更多菜单").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "context_more_menu" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_notifications_menu_natural_language() {
let routed = route_instruction("打开知乎通知菜单").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "notifications_menu" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_notifications_entry_natural_language() {
let routed = route_instruction("打开知乎通知按钮").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "notifications_entry" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_zhihu_search_box_natural_language() {
let routed = route_instruction("打开知乎搜索框").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "search_box" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_creator_write_button_natural_language() {
let routed = route_instruction("打开知乎创作中心写文章按钮").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "creator_write_button" && req.ensure_loaded
));
}
#[test]
fn route_instruction_routes_open_hot_from_home_flow_natural_language() {
let routed = route_instruction("从知乎首页进入热榜").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "open_hot_from_home" && req.ensure_loaded
));
}
#[test]
fn route_instruction_returns_none_for_non_skill_text() {
let routed = route_instruction("打开百度搜索天气").unwrap();
assert!(routed.is_none());
}
#[test]
fn route_instruction_returns_none_for_vague_zhihu_navigation_text() {
let routed = route_instruction("打开知乎").unwrap();
assert!(routed.is_none());
}
#[test]
fn route_instruction_returns_none_for_ambiguous_zhihu_notification_phrase() {
let routed = route_instruction("打开知乎通知").unwrap();
assert!(routed.is_none());
}
#[test]
fn route_instruction_routes_zhihu_hot_button_phrase_to_hot_tab() {
let routed = route_instruction("打开知乎热榜按钮").unwrap();
assert!(matches!(
routed,
Some(RoutedSkill::ZhihuNavigate(req))
if req.page == "hot_tab" && req.ensure_loaded
));
}
#[test]
fn route_instruction_rejects_unknown_skill_name() {
let err = route_instruction(r#"skill:unknown {"x":1}"#).unwrap_err();
assert!(matches!(err, RouterError::UnknownSkill(name) if name == "unknown"));
}