|
26 | 26 | from trpc_agent_sdk.skills._repository import ( |
27 | 27 | BASE_DIR_PLACEHOLDER, |
28 | 28 | BaseSkillRepository, |
| 29 | + CachedFsSkillRepository, |
29 | 30 | FsSkillRepository, |
30 | 31 | create_default_skill_repository, |
31 | 32 | ) |
@@ -203,6 +204,65 @@ def test_summaries(self, tmp_path): |
203 | 204 | assert "a-skill" in names |
204 | 205 | assert "b-skill" in names |
205 | 206 |
|
| 207 | + def test_base_repository_reads_body_for_summaries(self, tmp_path): |
| 208 | + _create_skill_dir(tmp_path, "summary-baseline", "Summary", body="# Large Body\n") |
| 209 | + repo = FsSkillRepository(str(tmp_path)) |
| 210 | + original_read_text = Path.read_text |
| 211 | + |
| 212 | + with patch.object(Path, "read_text", autospec=True, side_effect=original_read_text) as mock_read_text: |
| 213 | + summaries = repo.summaries() |
| 214 | + |
| 215 | + assert [summary.name for summary in summaries] == ["summary-baseline"] |
| 216 | + assert mock_read_text.call_count == 1 |
| 217 | + |
| 218 | + def test_cached_repository_summaries_do_not_read_skill_body(self, tmp_path): |
| 219 | + _create_skill_dir(tmp_path, "summary-only", "Summary", body="# Large Body\n") |
| 220 | + |
| 221 | + with patch.object(Path, "read_text", side_effect=AssertionError("body should not be read")): |
| 222 | + repo = CachedFsSkillRepository(str(tmp_path)) |
| 223 | + summaries = repo.summaries() |
| 224 | + |
| 225 | + assert [summary.name for summary in summaries] == ["summary-only"] |
| 226 | + assert summaries[0].description == "Summary" |
| 227 | + |
| 228 | + def test_base_repository_does_not_reuse_skill_body(self, tmp_path): |
| 229 | + _create_skill_dir(tmp_path, "uncached-skill", "Uncached", body="# Uncached Body\n") |
| 230 | + repo = FsSkillRepository(str(tmp_path)) |
| 231 | + original_read_text = Path.read_text |
| 232 | + |
| 233 | + with patch.object(Path, "read_text", autospec=True, side_effect=original_read_text) as mock_read_text: |
| 234 | + repo.get("uncached-skill") |
| 235 | + repo.get("uncached-skill") |
| 236 | + |
| 237 | + assert mock_read_text.call_count == 2 |
| 238 | + |
| 239 | + def test_cached_repository_get_reuses_cached_skill_body(self, tmp_path): |
| 240 | + _create_skill_dir(tmp_path, "cached-skill", "Cached", body="# Cached Body\n") |
| 241 | + repo = CachedFsSkillRepository(str(tmp_path)) |
| 242 | + original_read_text = Path.read_text |
| 243 | + |
| 244 | + with patch.object(Path, "read_text", autospec=True, side_effect=original_read_text) as mock_read_text: |
| 245 | + first = repo.get("cached-skill") |
| 246 | + second = repo.get("cached-skill") |
| 247 | + |
| 248 | + assert first.body == second.body |
| 249 | + assert mock_read_text.call_count == 1 |
| 250 | + |
| 251 | + def test_cached_repository_get_refreshes_cached_body_when_skill_file_changes(self, tmp_path): |
| 252 | + skill_dir = _create_skill_dir(tmp_path, "mutable-skill", "Before", body="# Before\n") |
| 253 | + skill_file = skill_dir / "SKILL.md" |
| 254 | + repo = CachedFsSkillRepository(str(tmp_path)) |
| 255 | + first = repo.get("mutable-skill") |
| 256 | + |
| 257 | + skill_file.write_text("---\nname: mutable-skill\ndescription: After\n---\n# After changed body\n", |
| 258 | + encoding="utf-8") |
| 259 | + |
| 260 | + second = repo.get("mutable-skill") |
| 261 | + |
| 262 | + assert "Before" in first.body |
| 263 | + assert "After changed body" in second.body |
| 264 | + assert second.summary.description == "After" |
| 265 | + |
206 | 266 | def test_refresh(self, tmp_path): |
207 | 267 | repo = FsSkillRepository(str(tmp_path)) |
208 | 268 | assert repo.skill_list() == [] |
@@ -311,6 +371,7 @@ class TestCreateDefaultSkillRepository: |
311 | 371 | def test_creates_repository(self, tmp_path): |
312 | 372 | _create_skill_dir(tmp_path, "test") |
313 | 373 | repo = create_default_skill_repository(str(tmp_path)) |
| 374 | + assert isinstance(repo, CachedFsSkillRepository) |
314 | 375 | assert isinstance(repo, FsSkillRepository) |
315 | 376 | assert "test" in repo.skill_list() |
316 | 377 |
|
|
0 commit comments