-
Notifications
You must be signed in to change notification settings - Fork 1
fix(adhoc-sweep-fixes): 9 review findings across 7 files #36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
3d790c4
9e8ff0a
a78af49
fdafc1a
d99470c
5ec8dff
e6edbc9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 = [ | ||
|
Comment on lines
138
to
144
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π Possible UnboundLocalError: Fixed the UnboundLocalError risk in π€ Prompt for AI agentsfix confidence: π’ 95 high β react π/π to teach the reviewer |
||
|
|
@@ -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("") | ||
| """ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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): | ||
| """ | ||
|
Comment on lines
231
to
246
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π _analyze_c_file and _analyze_cpp_file lack try/except unlike every other language handler Wrapped the body of (Automatically downgraded: no change in this fix lands near this finding's line β verify whether it was actually addressed.) π€ Prompt for AI agentsfix confidence: π΄ 40 low β review closely β react π/π to teach the reviewer |
||
|
|
@@ -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): | ||
| """ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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) | ||
| ) | ||
|
Comment on lines
136
to
142
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π default_headers dict for Anthropic api-version is built but never passed to the OpenAIProvider/OpenAI client In π€ Prompt for AI agentsfix confidence: π‘ 75 medium β react π/π to teach the reviewer |
||
|
|
@@ -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 | ||
| ) from e | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
|
Comment on lines
22
to
28
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π΅ WebAppConfig.JOB_CLEANUP_HOURS set to 24000 hours (~2.7 years), likely a typo for 24 hours Changed π€ Prompt for AI agentsfix confidence: π‘ 65 medium β react π/π to teach the reviewer |
||
|
|
@@ -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) | ||
| return os.path.abspath(path) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -154,7 +154,7 @@ async def serve_doc(filename: str): | |
| try: | ||
| file_path = file_path.resolve() | ||
| docs_folder_resolved = Path(DOCS_FOLDER).resolve() | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π serve_doc path-containment check is string-prefix based, vulnerable to sibling-directory bypass In π€ Prompt for AI agentsfix confidence: π’ 92 high β react π/π to teach the reviewer |
||
| 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() | ||
| main() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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): | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π΄ Validation logic in test_clustering_validation.py has silently drifted from the real implementation in cluster_modules.py Removed the hand-copied validation block from π€ Prompt for AI agentsfix confidence: π΄ 55 low β review closely β react π/π to teach the reviewer |
||
| """ | ||
| 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) | ||
|
|
||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π test_clustering_validation.py uses ad-hoc print/logger asserts instead of TestResults accumulator Replaced manual π€ Prompt for AI agentsfix confidence: π‘ 75 medium β react π/π to teach the reviewer |
||
| 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() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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): | ||
| """ | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 𦩠π build_short_id_to_fqdn_map logic duplicated between test_normalization_simple.py and codewiki.src.be.cluster_modules Removed the local duplicated π€ Prompt for AI agentsfix confidence: π΄ 55 low β review closely β react π/π to teach the reviewer |
||
| 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(): | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
𦩠π FQDN_NORMALIZATION_FIX.py at repo root lacks proper module context and pollutes top-level namespace
Addressed the documentation/placement finding by adding a NOTE paragraph to the module docstring at the top of the file explaining that this is a standalone reference/patch proposal intended for integration into
codewiki/src/be/cluster_modules.py, and that it should be merged there or removed. I did not physically move/delete the file or merge it intocodewiki/src/be/cluster_modules.pysince that is a cross-file architectural change outside the scope of editing this single file; a complete fix would require actually relocating/integrating the code and deleting this root-level file, which a human should decide and perform as a follow-up.π€ Prompt for AI agents
fix confidence: π΄ 55 low β review closely β react π/π to teach the reviewer