feat(skills): capacités agent découvrables via idea_list_agents
Ajoute SkillKind (Workflow/Reference) sur Skill, extrait le use case ResolveAgentCapabilities à partir des SkillRef assignés, et enrichit idea_list_agents d'un champ additif capabilities (name, description, kind) — remplace l'exposition de SkillRef opaques par un inventaire de capacités interrogeable, source commune avec le bloc « Skills disponibles » injecté au lancement (#119). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -2628,7 +2628,7 @@ pub async fn create_agent_from_template(
|
||||
.create_agent_from_template
|
||||
.execute(input)
|
||||
.await
|
||||
.map(|out| AgentDto(out.agent))
|
||||
.map(|out| AgentDto::from_agent(out.agent))
|
||||
.map_err(ErrorDto::from)
|
||||
}
|
||||
|
||||
|
||||
@ -9,14 +9,15 @@ use app_tauri_lib::dto::{
|
||||
};
|
||||
use application::AppError;
|
||||
use application::{
|
||||
AgentTicketState, AgentWorkState, CreateAgentOutput, InspectConversationOutput,
|
||||
LaunchAgentOutput, ListAgentsOutput, LiveSessionKind, LiveSessionSnapshot, LiveWorkSession,
|
||||
ProjectWorkState, TicketWorkSource, TicketWorkStatus,
|
||||
AgentCapability, AgentTicketState, AgentWorkState, CreateAgentOutput,
|
||||
InspectConversationOutput, LaunchAgentOutput, ListAgentsOutput, ListedAgentCapabilities,
|
||||
LiveSessionKind, LiveSessionSnapshot, LiveWorkSession, ProjectWorkState, TicketWorkSource,
|
||||
TicketWorkStatus,
|
||||
};
|
||||
use domain::ids::{AgentId, NodeId, ProfileId, SessionId};
|
||||
use domain::ports::ConversationDetails;
|
||||
use domain::terminal::{PtySize, SessionKind, SessionStatus, TerminalSession};
|
||||
use domain::{Agent, AgentOrigin, ProjectPath};
|
||||
use domain::{Agent, AgentOrigin, ProjectPath, SkillKind};
|
||||
use serde_json::json;
|
||||
use uuid::Uuid;
|
||||
|
||||
@ -40,7 +41,7 @@ fn make_agent(agent_uuid: u128, profile_uuid: u128) -> Agent {
|
||||
#[test]
|
||||
fn agent_dto_serialises_camelcase() {
|
||||
let agent = make_agent(1, 2);
|
||||
let dto = AgentDto(agent.clone());
|
||||
let dto = AgentDto::from_agent(agent.clone());
|
||||
let v = serde_json::to_value(&dto).unwrap();
|
||||
|
||||
assert_eq!(v["id"], agent.id.to_string());
|
||||
@ -53,6 +54,7 @@ fn agent_dto_serialises_camelcase() {
|
||||
assert_eq!(v["synchronized"], false);
|
||||
// origin: tagged `{ "type": "scratch" }`
|
||||
assert_eq!(v["origin"]["type"], "scratch");
|
||||
assert_eq!(v["capabilities"], json!([]));
|
||||
// no snake_case leak
|
||||
assert!(v.get("context_path").is_none());
|
||||
assert!(v.get("profile_id").is_none());
|
||||
@ -60,14 +62,27 @@ fn agent_dto_serialises_camelcase() {
|
||||
|
||||
#[test]
|
||||
fn agent_list_dto_is_transparent_array() {
|
||||
let first = make_agent(1, 2);
|
||||
let out = ListAgentsOutput {
|
||||
agents: vec![make_agent(1, 2), make_agent(3, 4)],
|
||||
agents: vec![first.clone(), make_agent(3, 4)],
|
||||
capabilities: vec![ListedAgentCapabilities {
|
||||
agent_id: first.id,
|
||||
capabilities: vec![AgentCapability {
|
||||
name: "review".to_owned(),
|
||||
description: "Reviews changes".to_owned(),
|
||||
kind: SkillKind::Reference,
|
||||
}],
|
||||
}],
|
||||
};
|
||||
let dto = AgentListDto::from(out);
|
||||
let v = serde_json::to_value(&dto).unwrap();
|
||||
let arr = v.as_array().expect("transparent array");
|
||||
assert_eq!(arr.len(), 2);
|
||||
assert_eq!(arr[0]["name"], "My Agent");
|
||||
assert_eq!(arr[0]["capabilities"][0]["name"], "review");
|
||||
assert_eq!(arr[0]["capabilities"][0]["description"], "Reviews changes");
|
||||
assert_eq!(arr[0]["capabilities"][0]["kind"], "reference");
|
||||
assert_eq!(arr[1]["capabilities"], json!([]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -77,7 +92,8 @@ fn create_agent_output_maps_to_agent_dto() {
|
||||
agent: agent.clone(),
|
||||
};
|
||||
let dto = AgentDto::from(out);
|
||||
assert_eq!(dto.0.id, agent.id);
|
||||
assert_eq!(dto.agent.id, agent.id);
|
||||
assert!(dto.capabilities.is_empty());
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@ -94,7 +94,7 @@ fn output_maps_agent_and_omits_session_when_no_relaunch() {
|
||||
relaunched: None,
|
||||
};
|
||||
let dto = ChangeAgentProfileDto::from(out);
|
||||
assert_eq!(dto.agent.0.id, agent.id);
|
||||
assert_eq!(dto.agent.agent.id, agent.id);
|
||||
assert!(dto.relaunched_session.is_none());
|
||||
|
||||
let v = serde_json::to_value(&dto).unwrap();
|
||||
|
||||
Reference in New Issue
Block a user