From 3d790c4531e9f42fe75da2ac757fe36e6e824af6 Mon Sep 17 00:00:00 2001 From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com> Date: Mon, 24 Aug 2026 05:09:27 +0000 Subject: [PATCH 1/7] fix(adhoc-sweep-fixes): 9 review findings across 7 files --- test_clustering_validation.py | 125 +++++++++++++++++----------------- 1 file changed, 64 insertions(+), 61 deletions(-) diff --git a/test_clustering_validation.py b/test_clustering_validation.py index 47daade6..2bc3a7dd 100644 --- a/test_clustering_validation.py +++ b/test_clustering_validation.py @@ -6,14 +6,61 @@ import json import logging +import sys +import os # Setup logging logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s') logger = logging.getLogger(__name__) +sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "codewiki", "src", "be")) + +from cluster_modules import validate_cluster_response + + +class TestResults: + """Accumulates test results and prints a summary.""" + + def __init__(self): + self.passed = 0 + self.failed = 0 + self.failures = [] + + def add_test(self, name: str, passed: bool, details: str = ""): + if passed: + self.passed += 1 + logger.info(f"āœ… TEST PASSED: {name}") + else: + self.failed += 1 + self.failures.append((name, details)) + logger.error(f"āŒ TEST FAILED: {name} {details}") + + def print_summary(self): + total = self.passed + self.failed + print("\n" + "="*70) + print("TEST SUMMARY") + print("="*70) + print(f"Total tests: {total}") + print(f"āœ… Passed: {self.passed}") + print(f"āŒ Failed: {self.failed}") + if total: + print(f"Success rate: {self.passed/total*100:.1f}%") + + if self.failed == 0: + print("\nšŸŽ‰ ALL TESTS PASSED! Validation logic is working correctly.") + else: + print(f"\nāš ļø {self.failed} test(s) failed. Please review the validation logic.") + for name, details in self.failures: + print(f" - {name}: {details}") + + @property + def success(self): + return self.failed == 0 + + def simulate_validation(response_content: str, max_id: int): """ - Simulates the validation logic from cluster_modules.py (lines 338-369) + Exercises the real validation logic from cluster_modules.py. Args: response_content: JSON string with component IDs @@ -26,44 +73,14 @@ def simulate_validation(response_content: str, max_id: int): logger.info(f"Testing response with max_id={max_id}") logger.info(f"Response: {response_content[:200]}") - # Parse JSON safely (no code execution) - try: - module_tree = json.loads(response_content) - logger.info(f"āœ… JSON parsing succeeded") - except json.JSONDecodeError as e: - logger.error(f"āŒ Invalid JSON in LLM response: {e}") - logger.error(f"Response excerpt: {response_content[:500]}...") - return (False, None) - - if not isinstance(module_tree, dict): - logger.error(f"āŒ Invalid module tree format - expected dict, got {type(module_tree)}") - return (False, None) - - # CRITICAL: Validate all component IDs are integers - for module_name, module_info in module_tree.items(): - if "components" not in module_info: - continue - - component_ids = module_info["components"] - invalid_ids = [] - - for comp_id in component_ids: - # Check if ID is an integer - if not isinstance(comp_id, int): - invalid_ids.append(f"{comp_id} (type: {type(comp_id).__name__})") - # Check if ID is in valid range - elif comp_id < 0 or comp_id > max_id: - invalid_ids.append(f"{comp_id} (out of range 0-{max_id})") - - if invalid_ids: - logger.error(f"āŒ Module '{module_name}' contains invalid component IDs:") - logger.error(f" Invalid IDs: {invalid_ids}") - logger.error(f" Expected: Integers in range 0-{max_id}") - logger.error(f" LLM ignored instructions and returned non-integer IDs!") - return (False, None) - - logger.info(f"āœ… LLM response validation passed: All IDs are integers in valid range") - return (True, module_tree) + success, module_tree = validate_cluster_response(response_content, max_id) + + if success: + logger.info(f"āœ… LLM response validation passed: All IDs are integers in valid range") + else: + logger.error(f"āŒ LLM response validation failed") + + return (success, module_tree) # Test cases @@ -136,8 +153,7 @@ def run_tests(): print("CODEWIKI CLUSTERING VALIDATION TEST SUITE") print("="*70) - passed = 0 - failed = 0 + results = TestResults() for i, test_case in enumerate(test_cases, 1): print(f"\n{'='*70}") @@ -149,28 +165,15 @@ def run_tests(): test_case['max_id'] ) - if success == test_case['should_pass']: - logger.info(f"āœ… TEST PASSED: Got expected result (success={success})") - passed += 1 - else: - logger.error(f"āŒ TEST FAILED: Expected {test_case['should_pass']}, got {success}") - failed += 1 - - # Summary - print("\n" + "="*70) - print("TEST SUMMARY") - print("="*70) - print(f"Total tests: {len(test_cases)}") - print(f"āœ… Passed: {passed}") - print(f"āŒ Failed: {failed}") - print(f"Success rate: {passed/len(test_cases)*100:.1f}%") + results.add_test( + test_case['name'], + success == test_case['should_pass'], + f"(expected {test_case['should_pass']}, got {success})" + ) - if failed == 0: - print("\nšŸŽ‰ ALL TESTS PASSED! Validation logic is working correctly.") - else: - print(f"\nāš ļø {failed} test(s) failed. Please review the validation logic.") + results.print_summary() - return failed == 0 + return results.success if __name__ == "__main__": success = run_tests() From 9e8ff0aa4b507ae18e0a7b129bc26f070961ac0b Mon Sep 17 00:00:00 2001 From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com> Date: Mon, 24 Aug 2026 05:09:29 +0000 Subject: [PATCH 2/7] fix(adhoc-sweep-fixes): 9 review findings across 7 files --- FQDN_NORMALIZATION_FIX.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/FQDN_NORMALIZATION_FIX.py b/FQDN_NORMALIZATION_FIX.py index 196d6e2e..7c5fc3f4 100644 --- a/FQDN_NORMALIZATION_FIX.py +++ b/FQDN_NORMALIZATION_FIX.py @@ -1,6 +1,11 @@ """ FQDN Normalization Fix - Enhanced Component ID Resolution +NOTE: This file is a standalone reference/patch proposal for +codewiki/src/be/cluster_modules.py. It is kept at the repository root +temporarily for review purposes; its logic should be integrated into +codewiki/src/be/cluster_modules.py (or this file removed) once merged. + This file contains the proposed fix for cluster_modules.py to handle: 1. LLM-added "deps." prefixes 2. Fuzzy substring matching for nested paths @@ -133,6 +138,7 @@ def normalize_component_ids_enhanced( if '.' in comp_id: # Try matching last 2-4 segments segments = comp_id.split('.') + suffix_matches = [] for n in range(2, min(5, len(segments) + 1)): suffix = '.'.join(segments[-n:]) suffix_matches = [ @@ -314,3 +320,4 @@ def build_short_id_to_fqdn_map_enhanced(components: Dict) -> Dict[str, str]: logger.warning(f" āš ļø Failed to normalize {total_failed} component IDs") logger.info("") """ + From a78af4969dc276a0081f9e5a676719b62ee15093 Mon Sep 17 00:00:00 2001 From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com> Date: Mon, 24 Aug 2026 05:09:31 +0000 Subject: [PATCH 3/7] fix(adhoc-sweep-fixes): 9 review findings across 7 files --- codewiki/src/be/llm_services.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/codewiki/src/be/llm_services.py b/codewiki/src/be/llm_services.py index 27a69bf2..3fd52513 100644 --- a/codewiki/src/be/llm_services.py +++ b/codewiki/src/be/llm_services.py @@ -136,7 +136,7 @@ def create_main_model(config: Config) -> OpenAIModel: provider=OpenAIProvider( base_url=base_url, api_key=api_key, - # default_headers removed - use http_client if needed + default_headers=default_headers if default_headers else None, ), settings=OpenAIModelSettings(**settings_dict) ) @@ -186,7 +186,7 @@ def create_fallback_model(config: Config) -> OpenAIModel: provider=OpenAIProvider( base_url=base_url, api_key=api_key, - # default_headers removed - use http_client if needed + default_headers=default_headers if default_headers else None, ), settings=OpenAIModelSettings(**settings_dict) ) @@ -250,7 +250,7 @@ def create_cluster_model(config: Config) -> OpenAIModel: provider=OpenAIProvider( base_url=base_url, api_key=api_key, - # default_headers removed - use http_client if needed + default_headers=default_headers if default_headers else None, ), settings=OpenAIModelSettings(**settings_dict) ) @@ -336,7 +336,7 @@ def create_openai_client(config: Config, model: str = None) -> OpenAI: return OpenAI( base_url=base_url, api_key=api_key, - # default_headers removed - use http_client if needed + default_headers=default_headers if default_headers else None, ) @@ -457,4 +457,4 @@ def call_llm( raise RuntimeError( f"Unexpected error calling {model_stage_name} model '{model}': " f"{type(e).__name__}: {str(e)}" - ) from e \ No newline at end of file + ) from e From fdafc1ad2d88608af46dadc64b2e6dc70555e65f Mon Sep 17 00:00:00 2001 From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com> Date: Mon, 24 Aug 2026 05:09:34 +0000 Subject: [PATCH 4/7] fix(adhoc-sweep-fixes): 9 review findings across 7 files --- test_normalization_simple.py | 41 +----------------------------------- 1 file changed, 1 insertion(+), 40 deletions(-) diff --git a/test_normalization_simple.py b/test_normalization_simple.py index afb44c15..610cdb72 100644 --- a/test_normalization_simple.py +++ b/test_normalization_simple.py @@ -5,46 +5,7 @@ This tests the core normalization algorithm without requiring full imports. """ -from collections import defaultdict - - -def build_short_id_to_fqdn_map(components): - """ - Build mapping from short component IDs to FQDNs. - Simplified version without logging for testing. - """ - mapping = {} - collisions = defaultdict(list) - - for fqdn, node_data in components.items(): - # Extract short ID from node or derive from FQDN - short_id = node_data.get('short_id') - - if not short_id: - # Fallback: extract from FQDN - if '::' in fqdn: - short_id = fqdn.split('::')[-1] - else: - short_id = fqdn.split('.')[-1] - - # Track collisions for debugging - if short_id in mapping: - collisions[short_id].append(fqdn) - if mapping[short_id] not in collisions[short_id]: - collisions[short_id].insert(0, mapping[short_id]) - else: - mapping[short_id] = fqdn - - # Report collisions - if collisions: - print("šŸ”€ Short ID collisions detected:") - for short_id, fqdns in collisions.items(): - print(f" ā”œā”€ '{short_id}' maps to {len(fqdns)} components:") - for fqdn in fqdns: - print(f" │ └─ {fqdn}") - print(f" └─ Using first match for each collision\n") - - return mapping +from codewiki.src.be.cluster_modules import build_short_id_to_fqdn_map def test_normalization(): From d99470c47afa7bb851a59732363f8396c9f0c4c1 Mon Sep 17 00:00:00 2001 From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com> Date: Mon, 24 Aug 2026 05:09:36 +0000 Subject: [PATCH 5/7] fix(adhoc-sweep-fixes): 9 review findings across 7 files --- .../analysis/call_graph_analyzer.py | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/codewiki/src/be/dependency_analyzer/analysis/call_graph_analyzer.py b/codewiki/src/be/dependency_analyzer/analysis/call_graph_analyzer.py index 7175cd9b..db524edf 100644 --- a/codewiki/src/be/dependency_analyzer/analysis/call_graph_analyzer.py +++ b/codewiki/src/be/dependency_analyzer/analysis/call_graph_analyzer.py @@ -231,13 +231,16 @@ def _analyze_c_file(self, file_path: str, content: str, repo_dir: str): """ from codewiki.src.be.dependency_analyzer.analyzers.c import analyze_c_file - functions, relationships = analyze_c_file(file_path, content, repo_path=repo_dir) + try: + functions, relationships = analyze_c_file(file_path, content, repo_path=repo_dir) - for func in functions: - func_id = func.id if func.id else f"{file_path}:{func.name}" - self.functions[func_id] = func + for func in functions: + func_id = func.id if func.id else f"{file_path}:{func.name}" + self.functions[func_id] = func - self.call_relationships.extend(relationships) + self.call_relationships.extend(relationships) + except Exception as e: + logger.error(f"Failed to analyze C file {file_path}: {e}", exc_info=True) def _analyze_cpp_file(self, file_path: str, content: str, repo_dir: str): """ @@ -249,15 +252,18 @@ def _analyze_cpp_file(self, file_path: str, content: str, repo_dir: str): """ from codewiki.src.be.dependency_analyzer.analyzers.cpp import analyze_cpp_file - functions, relationships = analyze_cpp_file( - file_path, content, repo_path=repo_dir - ) + try: + functions, relationships = analyze_cpp_file( + file_path, content, repo_path=repo_dir + ) - for func in functions: - func_id = func.id if func.id else f"{file_path}:{func.name}" - self.functions[func_id] = func + for func in functions: + func_id = func.id if func.id else f"{file_path}:{func.name}" + self.functions[func_id] = func - self.call_relationships.extend(relationships) + self.call_relationships.extend(relationships) + except Exception as e: + logger.error(f"Failed to analyze C++ file {file_path}: {e}", exc_info=True) def _analyze_java_file(self, file_path: str, content: str, repo_dir: str): """ From 5ec8dff80a6f5010d3a118974f114bac46c861a0 Mon Sep 17 00:00:00 2001 From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com> Date: Mon, 24 Aug 2026 05:09:39 +0000 Subject: [PATCH 6/7] fix(adhoc-sweep-fixes): 9 review findings across 7 files --- codewiki/src/fe/visualise_docs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/codewiki/src/fe/visualise_docs.py b/codewiki/src/fe/visualise_docs.py index 2c8648dc..f33b42b5 100644 --- a/codewiki/src/fe/visualise_docs.py +++ b/codewiki/src/fe/visualise_docs.py @@ -154,7 +154,7 @@ async def serve_doc(filename: str): try: file_path = file_path.resolve() docs_folder_resolved = Path(DOCS_FOLDER).resolve() - if not str(file_path).startswith(str(docs_folder_resolved)): + if not file_path.is_relative_to(docs_folder_resolved): raise HTTPException(status_code=403, detail="Access denied") except Exception: raise HTTPException(status_code=403, detail="Invalid file path") @@ -265,4 +265,4 @@ def main(): if __name__ == "__main__": - main() \ No newline at end of file + main() From e6edbc99fc70cbd28b1409b0617a30241901020a Mon Sep 17 00:00:00 2001 From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com> Date: Mon, 24 Aug 2026 05:09:42 +0000 Subject: [PATCH 7/7] fix(adhoc-sweep-fixes): 9 review findings across 7 files --- codewiki/src/fe/config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/codewiki/src/fe/config.py b/codewiki/src/fe/config.py index c77d3d4a..8637aac9 100644 --- a/codewiki/src/fe/config.py +++ b/codewiki/src/fe/config.py @@ -22,7 +22,7 @@ class WebAppConfig: CACHE_EXPIRY_DAYS = 365 # Job cleanup settings - JOB_CLEANUP_HOURS = 24000 + JOB_CLEANUP_HOURS = 24 RETRY_COOLDOWN_MINUTES = 3 # Server settings @@ -48,4 +48,4 @@ def ensure_directories(cls): @classmethod def get_absolute_path(cls, path: str) -> str: """Get absolute path for a given relative path.""" - return os.path.abspath(path) \ No newline at end of file + return os.path.abspath(path)