diff --git a/src/claude_agent_sdk/_internal/sessions.py b/src/claude_agent_sdk/_internal/sessions.py index 2634a0f37..21a72bb63 100644 --- a/src/claude_agent_sdk/_internal/sessions.py +++ b/src/claude_agent_sdk/_internal/sessions.py @@ -1299,9 +1299,9 @@ def list_subagents( searches all project directories under ``~/.claude/projects/``. Returns: - List of subagent ID strings. Returns an empty list if the session - is not found, the session_id is not a valid UUID, or the session - has no subagents. + List of unique subagent ID strings in discovery order. Returns an + empty list if the session is not found, the session_id is not a valid + UUID, or the session has no subagents. See Also: :func:`list_subagents_from_store` for the :class:`SessionStore`-backed @@ -1322,7 +1322,9 @@ def list_subagents( if subagents_dir is None: return [] - return [agent_id for agent_id, _ in _collect_agent_files(subagents_dir)] + return list( + dict.fromkeys(agent_id for agent_id, _ in _collect_agent_files(subagents_dir)) + ) def get_subagent_messages( diff --git a/tests/test_sessions.py b/tests/test_sessions.py index 3e2ffd9a4..987610fe2 100644 --- a/tests/test_sessions.py +++ b/tests/test_sessions.py @@ -1715,6 +1715,22 @@ def test_recurses_into_subdirectories( result = list_subagents(sid, directory=project_path) assert sorted(result) == ["nested", "top"] + def test_dedupes_agent_id_across_subdirectories( + self, claude_config_dir: Path, tmp_path: Path + ): + """Duplicate IDs are returned once in their first-seen order.""" + project_path = str(tmp_path / "proj") + Path(project_path).mkdir(parents=True) + sid, subagents_dir = _make_session_with_subagents( + claude_config_dir, project_path, agent_ids=["top"] + ) + nested = subagents_dir / "workflows" / "run-1" + nested.mkdir(parents=True) + (nested / "agent-nested.jsonl").write_text("{}\n") + (nested / "agent-top.jsonl").write_text("{}\n") + + assert list_subagents(sid, directory=project_path) == ["top", "nested"] + def test_searches_all_projects_without_directory(self, claude_config_dir: Path): """When directory is omitted, all project directories are searched.""" project_dir = _make_project_dir(claude_config_dir, "/some/project")