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:
85
src/skill/mod.rs
Normal file
85
src/skill/mod.rs
Normal file
@@ -0,0 +1,85 @@
|
||||
pub mod router;
|
||||
pub mod zhihu;
|
||||
pub mod zhihu_hotlist;
|
||||
pub mod zhihu_hotlist_store;
|
||||
pub mod zhihu_navigation;
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::pipe::{BrowserPipeTool, PipeError, Transport};
|
||||
|
||||
fn relative_skill_resource_path(resource_name: &str) -> PathBuf {
|
||||
PathBuf::from("resources")
|
||||
.join("skills")
|
||||
.join(resource_name)
|
||||
}
|
||||
|
||||
pub(crate) fn skill_resource_path_from_executable(
|
||||
executable_path: PathBuf,
|
||||
resource_name: &str,
|
||||
) -> PathBuf {
|
||||
executable_path
|
||||
.parent()
|
||||
.map(|dir| dir.join("resources").join("skills").join(resource_name))
|
||||
.unwrap_or_else(|| relative_skill_resource_path(resource_name))
|
||||
}
|
||||
|
||||
pub(crate) fn default_skill_resource_path(resource_name: &str) -> PathBuf {
|
||||
std::env::current_exe()
|
||||
.ok()
|
||||
.map(|path| skill_resource_path_from_executable(path, resource_name))
|
||||
.filter(|path| path.exists())
|
||||
.unwrap_or_else(|| relative_skill_resource_path(resource_name))
|
||||
}
|
||||
|
||||
pub fn try_execute_skill<T: Transport>(
|
||||
transport: &T,
|
||||
browser_tool: &BrowserPipeTool<T>,
|
||||
instruction: &str,
|
||||
) -> Result<Option<String>, PipeError> {
|
||||
match router::route_instruction(instruction)
|
||||
.map_err(|err| PipeError::Protocol(err.to_string()))?
|
||||
{
|
||||
Some(router::RoutedSkill::ZhihuWrite(req)) => {
|
||||
let result = zhihu::execute(transport, browser_tool, req)
|
||||
.map_err(|err| PipeError::Protocol(err.to_string()))?;
|
||||
Ok(Some(result.summary))
|
||||
}
|
||||
Some(router::RoutedSkill::ZhihuHotlistCollect(req)) => {
|
||||
let result = zhihu_hotlist::execute_collect(transport, browser_tool, req)
|
||||
.map_err(|err| PipeError::Protocol(err.to_string()))?;
|
||||
Ok(Some(result.summary))
|
||||
}
|
||||
Some(router::RoutedSkill::ZhihuHotlistReport(req)) => {
|
||||
let result = zhihu_hotlist::execute_report(req)
|
||||
.map_err(|err| PipeError::Protocol(err.to_string()))?;
|
||||
Ok(Some(result.summary))
|
||||
}
|
||||
Some(router::RoutedSkill::ZhihuNavigate(req)) => {
|
||||
let result = zhihu_navigation::execute(transport, browser_tool, req)
|
||||
.map_err(|err| PipeError::Protocol(err.to_string()))?;
|
||||
Ok(Some(result.summary))
|
||||
}
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::PathBuf;
|
||||
|
||||
use super::skill_resource_path_from_executable;
|
||||
|
||||
#[test]
|
||||
fn skill_resource_path_uses_executable_directory_instead_of_cwd() {
|
||||
let executable_path = PathBuf::from("/tmp/out/KylinRelease/sgclaw");
|
||||
|
||||
let resolved =
|
||||
skill_resource_path_from_executable(executable_path, "zhihu_navigation_pages.json");
|
||||
|
||||
assert_eq!(
|
||||
resolved,
|
||||
PathBuf::from("/tmp/out/KylinRelease/resources/skills/zhihu_navigation_pages.json")
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user