Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,7 @@ mod tests {
.expect("runtime context should build");

assert!(skill_listing.contains("# Skill Listing"));
assert!(skill_listing.contains("A skill is a set of instructions provided through a `SKILL.md` source."));
assert!(skill_listing.contains("<available_skills>"));
assert!(!skill_listing.contains("# Agent Listing"));
assert!(agent_listing.contains("# Agent Listing"));
Expand Down
5 changes: 3 additions & 2 deletions src/crates/execution/agent-runtime/src/prompt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
use serde::{Deserialize, Serialize};

const SKILL_LISTING_TITLE: &str = "# Skill Listing";
const SKILL_LISTING_GUIDANCE: &str =
"The following skills are available for use with the Skill tool:";
const SKILL_LISTING_GUIDANCE: &str = r#"A skill is a set of instructions provided through a `SKILL.md` source.
If the user names a skill (with `[$SkillName]` or plain text) OR the task clearly matches a skill's description shown below, you must use that skill for that turn. Multiple mentions mean use them all. Do not carry skills across turns unless re-mentioned.
Below is the list of skills that can be used with the Skill tool. Each entry includes a name and description"#;
const AGENT_LISTING_TITLE: &str = "# Agent Listing";
const AGENT_LISTING_GUIDANCE: &str = "Available subagent types for the Task tool:";
const COLLAPSED_TOOL_LISTING_TITLE: &str = "# Collapsed Tool Listing";
Expand Down
47 changes: 25 additions & 22 deletions src/crates/execution/agent-runtime/src/skill_agent_snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,7 @@ pub struct SkillSnapshotEntry {

impl SkillSnapshotEntry {
fn to_xml_desc(&self) -> String {
format!(
r#"<skill>
<name>
{}
</name>
<description>
{}
</description>
<location>
{}
</location>
</skill>"#,
self.name, self.description, self.location
)
format!(r#"<skill name="{}">{}</skill>"#, self.name, self.description)
}
}

Expand Down Expand Up @@ -385,12 +372,12 @@ mod tests {
SkillSnapshotEntry {
name: "skill-a".to_string(),
description: "desc-a".to_string(),
location: "/a".to_string(),
location: "C:/skills/skill-a".to_string(),
},
SkillSnapshotEntry {
name: "skill-b".to_string(),
description: "desc-b".to_string(),
location: "/b".to_string(),
location: "C:/skills/skill-b".to_string(),
},
],
subagents: vec![AgentSnapshotEntry {
Expand All @@ -404,12 +391,12 @@ mod tests {
SkillSnapshotEntry {
name: "skill-a".to_string(),
description: "desc-a2".to_string(),
location: "/a".to_string(),
location: "C:/skills/skill-a".to_string(),
},
SkillSnapshotEntry {
name: "skill-c".to_string(),
description: "desc-c".to_string(),
location: "/c".to_string(),
location: "C:/skills/skill-c".to_string(),
},
],
subagents: vec![AgentSnapshotEntry {
Expand All @@ -430,13 +417,29 @@ mod tests {
assert!(skill_update.contains("## Changed Skills"));
assert!(skill_update.contains("## Added Skills"));
assert!(skill_update.contains("## Removed Skills"));
assert!(skill_update.contains("skill-a"));
assert!(skill_update.contains("skill-c"));
assert!(skill_update.contains(r#"<skill name="skill-a">desc-a2</skill>"#));
assert!(skill_update.contains(r#"<skill name="skill-c">desc-c</skill>"#));
assert!(!skill_update.contains("C:/skills/skill-a"));
assert!(!skill_update.contains("C:/skills/skill-c"));
assert!(skill_update.contains("- skill-b"));
assert!(agent_update.contains("## Changed Agents"));
assert!(agent_update.contains("Grep"));
}

#[test]
fn full_skill_listing_renders_inline_name_and_description_without_location() {
let listing = super::render_full_skill_listing_body(&[SkillSnapshotEntry {
name: "skill-a".to_string(),
description: "desc-a".to_string(),
location: "C:/skills/skill-a".to_string(),
}]);

assert!(listing.contains("<available_skills>"));
assert!(listing.contains(r#"<skill name="skill-a">desc-a</skill>"#));
assert!(!listing.contains("<location>"));
assert!(!listing.contains("C:/skills/skill-a"));
}

#[test]
fn skill_agent_diff_ignores_default_tool_reordering_for_agents() {
let previous = TurnSkillAgentSnapshot {
Expand Down Expand Up @@ -473,7 +476,7 @@ mod tests {
skills: vec![SkillSnapshotEntry {
name: "skill-a".to_string(),
description: "desc-a".to_string(),
location: "/a".to_string(),
location: "C:/skills/skill-a".to_string(),
}],
..Default::default()
},
Expand All @@ -485,7 +488,7 @@ mod tests {
skills: vec![SkillSnapshotEntry {
name: "skill-b".to_string(),
description: "desc-b".to_string(),
location: "/b".to_string(),
location: "C:/skills/skill-b".to_string(),
}],
..Default::default()
},
Expand Down
16 changes: 1 addition & 15 deletions src/crates/execution/agent-runtime/src/skills/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,7 @@ pub struct SkillInfo {

impl SkillInfo {
pub fn to_xml_desc(&self) -> String {
format!(
r#"<skill>
<name>
{}
</name>
<description>
{}
</description>
<location>
{}
</location>
</skill>
"#,
self.name, self.description, self.path
)
format!(r#"<skill name="{}">{}</skill>"#, self.name, self.description)
}
}

Expand Down
30 changes: 30 additions & 0 deletions src/web-ui/src/flow_chat/components/ChatInput.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1278,6 +1278,29 @@
}
}
}

&__slash-command-section {
display: flex;
align-items: center;
gap: 8px;
padding: 8px var(--flowchat-card-expanded-pad-x) 4px;
}

&__slash-command-section-line {
flex: 1;
min-width: 16px;
height: 1px;
background: var(--border-subtle);
}

&__slash-command-section-title {
flex: 0 0 auto;
font-size: var(--flowchat-font-size-xxs);
font-weight: 600;
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--color-text-muted);
}

&__slash-command-item {
display: flex;
Expand Down Expand Up @@ -1325,6 +1348,13 @@
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;

&--single-line {
display: block;
white-space: nowrap;
text-overflow: ellipsis;
-webkit-line-clamp: unset;
}
}

&__slash-command-current {
Expand Down
Loading
Loading