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:
@ -1967,20 +1967,58 @@ pub fn parse_profile_id(raw: &str) -> Result<ProfileId, ErrorDto> {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
use application::{
|
||||
ChangeAgentProfileOutput, CreateAgentOutput, InspectConversationOutput, LaunchAgentOutput,
|
||||
ListAgentsOutput, ReadAgentContextOutput, ReadMcpToolPermissionsOutput,
|
||||
AgentCapability, ChangeAgentProfileOutput, CreateAgentOutput, InspectConversationOutput,
|
||||
LaunchAgentOutput, ListAgentsOutput, ReadAgentContextOutput, ReadMcpToolPermissionsOutput,
|
||||
};
|
||||
use domain::{
|
||||
Agent, AgentMcpToolPolicyOverride, EffectivePermissions, McpToolPolicy, PermissionSet,
|
||||
ProjectPermissions, TerminalSession,
|
||||
ProjectPermissions, SkillKind, TerminalSession,
|
||||
};
|
||||
|
||||
/// An agent crossing the wire. [`Agent`] already serialises camelCase
|
||||
/// (`id`, `name`, `contextPath`, `profileId`, `origin` tagged, `synchronized`),
|
||||
/// so we embed it directly — the TS mirror matches this shape.
|
||||
/// One discoverable capability carried by an agent.
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
#[serde(transparent)]
|
||||
pub struct AgentDto(pub Agent);
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AgentCapabilityDto {
|
||||
/// Capability display name.
|
||||
pub name: String,
|
||||
/// One-line affordance description.
|
||||
pub description: String,
|
||||
/// Capability nature.
|
||||
pub kind: SkillKind,
|
||||
}
|
||||
|
||||
impl From<AgentCapability> for AgentCapabilityDto {
|
||||
fn from(value: AgentCapability) -> Self {
|
||||
Self {
|
||||
name: value.name,
|
||||
description: value.description,
|
||||
kind: value.kind,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An agent crossing the wire. The raw [`Agent`] shape is flattened so existing
|
||||
/// fields, including `skills`, remain compatible; `capabilities` is additive.
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AgentDto {
|
||||
/// Raw agent manifest shape.
|
||||
#[serde(flatten)]
|
||||
pub agent: Agent,
|
||||
/// Resolved discoverable capabilities.
|
||||
pub capabilities: Vec<AgentCapabilityDto>,
|
||||
}
|
||||
|
||||
impl AgentDto {
|
||||
/// Builds a DTO without resolved capabilities.
|
||||
#[must_use]
|
||||
pub fn from_agent(agent: Agent) -> Self {
|
||||
Self {
|
||||
agent,
|
||||
capabilities: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A list of agents (camelCase array on the wire).
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
@ -1989,13 +2027,25 @@ pub struct AgentListDto(pub Vec<AgentDto>);
|
||||
|
||||
impl From<ListAgentsOutput> for AgentListDto {
|
||||
fn from(out: ListAgentsOutput) -> Self {
|
||||
Self(out.agents.into_iter().map(AgentDto).collect())
|
||||
Self(
|
||||
out.discovery_entries()
|
||||
.into_iter()
|
||||
.map(|entry| AgentDto {
|
||||
agent: entry.agent,
|
||||
capabilities: entry
|
||||
.capabilities
|
||||
.into_iter()
|
||||
.map(AgentCapabilityDto::from)
|
||||
.collect(),
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CreateAgentOutput> for AgentDto {
|
||||
fn from(out: CreateAgentOutput) -> Self {
|
||||
Self(out.agent)
|
||||
Self::from_agent(out.agent)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2326,7 +2376,7 @@ pub struct ChangeAgentProfileDto {
|
||||
impl From<ChangeAgentProfileOutput> for ChangeAgentProfileDto {
|
||||
fn from(out: ChangeAgentProfileOutput) -> Self {
|
||||
Self {
|
||||
agent: AgentDto(out.agent),
|
||||
agent: AgentDto::from_agent(out.agent),
|
||||
relaunched_session: out.relaunched.map(TerminalSessionDto::from),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user