feat(gateway): GET /api/skills
This commit is contained in:
parent
119df57b49
commit
5e2771c538
@ -844,6 +844,23 @@ pub async fn get_tools(State(state): State<Arc<GatewayState>>) -> Result<Json<Va
|
|||||||
Ok(Json(json!({ "tools": tools })))
|
Ok(Json(json!({ "tools": tools })))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_skills(State(state): State<Arc<GatewayState>>) -> Result<Json<Value>, ApiError> {
|
||||||
|
let loader = state.session_manager.skills_loader();
|
||||||
|
let skills: Vec<Value> = loader
|
||||||
|
.get_loaded_skills()
|
||||||
|
.iter()
|
||||||
|
.map(|s| {
|
||||||
|
json!({
|
||||||
|
"name": s.name,
|
||||||
|
"description": s.description,
|
||||||
|
"always": s.always,
|
||||||
|
"source": loader.source_of(s.path.as_deref()),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
Ok(Json(json!({ "skills": skills })))
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn get_tasks(
|
pub async fn get_tasks(
|
||||||
State(state): State<Arc<GatewayState>>,
|
State(state): State<Arc<GatewayState>>,
|
||||||
Query(query): Query<LimitQuery>,
|
Query(query): Query<LimitQuery>,
|
||||||
|
|||||||
@ -595,6 +595,7 @@ fn build_router(state: Arc<GatewayState>) -> Router {
|
|||||||
.route("/api/tasks", routing::get(http::get_tasks))
|
.route("/api/tasks", routing::get(http::get_tasks))
|
||||||
.route("/api/status", routing::get(http::get_status))
|
.route("/api/status", routing::get(http::get_status))
|
||||||
.route("/api/tools", routing::get(http::get_tools))
|
.route("/api/tools", routing::get(http::get_tools))
|
||||||
|
.route("/api/skills", routing::get(http::get_skills))
|
||||||
.route("/api/jobs", routing::get(http::get_jobs))
|
.route("/api/jobs", routing::get(http::get_jobs))
|
||||||
.route("/api/jobs/{id}/runs", routing::get(http::get_job_runs))
|
.route("/api/jobs/{id}/runs", routing::get(http::get_job_runs))
|
||||||
.route("/api/memories", routing::get(http::get_memories))
|
.route("/api/memories", routing::get(http::get_memories))
|
||||||
|
|||||||
@ -1708,6 +1708,10 @@ impl SessionManager {
|
|||||||
self.tools.clone()
|
self.tools.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn skills_loader(&self) -> Arc<SkillsLoader> {
|
||||||
|
self.skills_loader.clone()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn work_manager(&self) -> Arc<crate::work::WorkManager> {
|
pub fn work_manager(&self) -> Arc<crate::work::WorkManager> {
|
||||||
self.work_manager.clone()
|
self.work_manager.clone()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -248,6 +248,24 @@ impl SkillsLoader {
|
|||||||
max_mtime
|
max_mtime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn source_of(&self, path: Option<&Path>) -> &'static str {
|
||||||
|
let Some(path) = path else {
|
||||||
|
return "unknown";
|
||||||
|
};
|
||||||
|
if let Some(ws) = &self.workspace_skills_dir
|
||||||
|
&& path.starts_with(ws)
|
||||||
|
{
|
||||||
|
return "workspace";
|
||||||
|
}
|
||||||
|
if path.starts_with(&self.picobot_skills_dir) {
|
||||||
|
return "picobot";
|
||||||
|
}
|
||||||
|
if path.starts_with(&self.agent_skills_dir) {
|
||||||
|
return "agent";
|
||||||
|
}
|
||||||
|
"other"
|
||||||
|
}
|
||||||
|
|
||||||
/// Get a copy of loaded skills (checks for changes first)
|
/// Get a copy of loaded skills (checks for changes first)
|
||||||
pub fn get_loaded_skills(&self) -> Vec<Skill> {
|
pub fn get_loaded_skills(&self) -> Vec<Skill> {
|
||||||
self.reload_if_changed();
|
self.reload_if_changed();
|
||||||
@ -586,4 +604,31 @@ This is the content.
|
|||||||
let beta_pos = prompt.find("**beta**").unwrap();
|
let beta_pos = prompt.find("**beta**").unwrap();
|
||||||
assert!(alpha_pos < beta_pos);
|
assert!(alpha_pos < beta_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_source_of() {
|
||||||
|
let mut loader = SkillsLoader::new_for_testing(
|
||||||
|
PathBuf::from("/home/user/.picobot/skills"),
|
||||||
|
PathBuf::from("/home/user/.agents/skills"),
|
||||||
|
);
|
||||||
|
loader.set_workspace_skills_dir(PathBuf::from("/workspace"));
|
||||||
|
|
||||||
|
assert_eq!(loader.source_of(None), "unknown");
|
||||||
|
assert_eq!(
|
||||||
|
loader.source_of(Some(Path::new("/workspace/skills/my-skill"))),
|
||||||
|
"workspace"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
loader.source_of(Some(Path::new("/home/user/.picobot/skills/foo"))),
|
||||||
|
"picobot"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
loader.source_of(Some(Path::new("/home/user/.agents/skills/bar"))),
|
||||||
|
"agent"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
loader.source_of(Some(Path::new("/opt/other/skill"))),
|
||||||
|
"other"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user