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
35 changes: 35 additions & 0 deletions src/skillspector/llm_analyzer_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,38 @@
CHARS_PER_TOKEN = 4
CHUNK_OVERLAP_LINES = 50

_MEDIA_FILE_EXTENSIONS = (
".png",
".jpg",
".jpeg",
".gif",
".bmp",
".ico",
".webp",
".avif",
".heic",
".heif",
".tif",
".tiff",
".mp3",
".aac",
".flac",
".m4a",
".ogg",
".opus",
".wav",
".mp4",
".m4v",
".avi",
".mov",
".webm",
".mkv",
".mpeg",
".mpg",
".ogv",
".3gp",
)


# ---------------------------------------------------------------------------
# Default structured-output schemas (discovery mode)
Expand Down Expand Up @@ -303,6 +335,9 @@ def get_batches(

batches: list[Batch] = []
for path in file_paths:
if path.lower().endswith(_MEDIA_FILE_EXTENSIONS):
Comment thread
Makia9879 marked this conversation as resolved.
logger.info("Skipping media file from LLM analysis: %s", path)
continue
content = file_cache.get(path) or "No content available for this file."
file_findings = findings_by_file.get(path, [])

Expand Down
38 changes: 38 additions & 0 deletions tests/nodes/test_llm_analyzer_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,44 @@ def test_zero_padding(self) -> None:
assert "L11: line10" in result


# ---------------------------------------------------------------------------
# LLMAnalyzerBase.get_batches
# ---------------------------------------------------------------------------


class TestLLMAnalyzerBaseGetBatches:
MODEL = "nvidia/openai/gpt-oss-120b"

@pytest.mark.parametrize(
"path",
[
"assets/demo.gif",
"assets/screenshot.PNG",
"assets/tutorial.mp4",
"assets/voice.mp3",
"assets/photo.webp",
"assets/movie.mkv",
],
)
@patch(MOCK_PATCH_TARGET, _mock_get_chat_model)
def test_media_files_are_skipped(self, path: str) -> None:
analyzer = LLMAnalyzerBase(base_prompt="test", model=self.MODEL)

assert analyzer.get_batches([path], {path: "decoded media data"}) == []

@patch(MOCK_PATCH_TARGET, _mock_get_chat_model)
def test_text_files_and_svg_are_preserved(self) -> None:
analyzer = LLMAnalyzerBase(base_prompt="test", model=self.MODEL)
file_cache = {
"src/main.py": "print('hello')\n",
"assets/icon.svg": '<svg><script>alert("x")</script></svg>',
}

batches = analyzer.get_batches(list(file_cache), file_cache)

assert {batch.file_path for batch in batches} == set(file_cache)


# ---------------------------------------------------------------------------
# LLMAnalyzerBase.build_prompt (default implementation)
# ---------------------------------------------------------------------------
Expand Down