Skip to content
Open
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
10 changes: 8 additions & 2 deletions src/claude_agent_sdk/_internal/transport/subprocess_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,10 +241,16 @@ def _build_command(self) -> list[str]:
if self._options.tools is not None:
tools = self._options.tools
if isinstance(tools, list):
if len(tools) == 0:
# When skills are enabled, ensure "Skill" is in the tools list
# so the skill tool is available for the agent to invoke
tools_list = list(tools) # Copy to avoid mutating the original
if self._options.skills is not None and "Skill" not in tools_list:
tools_list.append("Skill")

if len(tools_list) == 0:
cmd.extend(["--tools", ""])
else:
cmd.extend(["--tools", ",".join(tools)])
cmd.extend(["--tools", ",".join(tools_list)])
else:
# Preset object - 'claude_code' preset maps to 'default'
cmd.extend(["--tools", "default"])
Expand Down
51 changes: 51 additions & 0 deletions tests/test_transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,57 @@ def test_build_command_skills_does_not_duplicate_entries(self):
cmd = transport._build_command()
assert cmd[cmd.index("--allowedTools") + 1] == "Skill(pdf)"

def test_build_command_skills_all_with_explicit_tools_adds_skill(self):
"""When skills='all' is set with explicit tools list, 'Skill' is added to tools."""
transport = SubprocessCLITransport(
prompt="test",
options=make_options(
tools=["WebSearch", "WebFetch", "Read"],
skills="all",
),
)
cmd = transport._build_command()
# Skill should be added to the tools list
assert "--tools" in cmd
tools_idx = cmd.index("--tools")
assert cmd[tools_idx + 1] == "WebSearch,WebFetch,Read,Skill"
# Skill should also be in allowed_tools
assert "--allowedTools" in cmd
assert cmd[cmd.index("--allowedTools") + 1] == "Skill"

def test_build_command_skills_list_with_explicit_tools_adds_skill(self):
"""When skills list is set with explicit tools list, 'Skill' is added to tools."""
transport = SubprocessCLITransport(
prompt="test",
options=make_options(
tools=["WebSearch", "WebFetch", "Read"],
skills=["pdf", "docx"],
),
)
cmd = transport._build_command()
# Skill should be added to the tools list
assert "--tools" in cmd
tools_idx = cmd.index("--tools")
assert cmd[tools_idx + 1] == "WebSearch,WebFetch,Read,Skill"
# Skill patterns should be in allowed_tools
assert "--allowedTools" in cmd
assert cmd[cmd.index("--allowedTools") + 1] == "Skill(pdf),Skill(docx)"

def test_build_command_skills_with_explicit_tools_already_has_skill(self):
"""When skills='all' is set and 'Skill' already in tools list, it's not duplicated."""
transport = SubprocessCLITransport(
prompt="test",
options=make_options(
tools=["WebSearch", "Skill", "Read"],
skills="all",
),
)
cmd = transport._build_command()
# Skill should not be duplicated
assert "--tools" in cmd
tools_idx = cmd.index("--tools")
assert cmd[tools_idx + 1] == "WebSearch,Skill,Read"

@pytest.mark.parametrize(
("skills", "extra", "want_tools", "want_sources", "want_init_skills"),
[
Expand Down