-
Notifications
You must be signed in to change notification settings - Fork 1
fix(DUP-001): CU-86akn96pk 10 review findings across 7 files #113
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
110785f
b948195
a745b86
ee304b3
36a3098
301eb34
978e6cf
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 |
|---|---|---|
|
|
@@ -373,6 +373,14 @@ def _class_has_method(self, class_node, method_name): | |
| return False | ||
|
|
||
| def analyze_cpp_file(file_path: str, content: str, repo_path: str = None) -> Tuple[List[Node], List[CallRelationship]]: | ||
|
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. 𦩠π codewiki/src/be/dependency_analyzer/analyzers/cpp#analyze_cpp_file duplicates an existing definition In π€ Prompt for AI agentsfix confidence: π΄ 35 low β review closely β react π/π to teach the reviewer |
||
| """Analyze a C++ source file and extract nodes and call relationships. | ||
|
|
||
| Note: structurally similar to analyze_c_file (c.py) and other language | ||
| analyzers in this package, since each wraps a language-specific | ||
| TreeSitter*Analyzer with the same construct-and-collect pattern. Kept | ||
| separate because the underlying analyzer classes are not identical | ||
| (different tree-sitter grammars and node handling). | ||
| """ | ||
| analyzer = TreeSitterCppAnalyzer(file_path, content, repo_path) | ||
| return analyzer.nodes, analyzer.call_relationships | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -698,7 +698,16 @@ def _extract_assignment_name(self, node) -> Optional[str]: | |
| def analyze_javascript_file_treesitter( | ||
|
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. 𦩠π codewiki/src/be/dependency_analyzer/analyzers/javascript#analyze_javascript_file_treesitter duplicates a near-identical definition In π€ Prompt for AI agentsfix confidence: π΄ 30 low β review closely β react π/π to teach the reviewer |
||
| file_path: str, content: str, repo_path: str = None | ||
| ) -> Tuple[List[Node], List[CallRelationship]]: | ||
| """Analyze a JavaScript file using tree-sitter.""" | ||
| """Analyze a JavaScript file using tree-sitter. | ||
|
|
||
| Thin wrapper around `TreeSitterJSAnalyzer`, structurally identical to | ||
| `analyze_typescript_file_treesitter` in the sibling `typescript` module | ||
| (both build an analyzer, run `.analyze()`, and return its nodes and | ||
| relationships). Kept file-local because the analyzer classes themselves | ||
| (`TreeSitterJSAnalyzer` vs. the TypeScript analyzer) differ and are not | ||
| currently unified behind a shared interface; extracting a shared wrapper | ||
| would require introducing that shared interface first. | ||
| """ | ||
| try: | ||
| logger.debug(f"Tree-sitter JS analysis for {file_path}") | ||
| analyzer = TreeSitterJSAnalyzer(file_path, content, repo_path) | ||
|
|
@@ -710,7 +719,3 @@ def analyze_javascript_file_treesitter( | |
| except Exception as e: | ||
| logger.error(f"Error in tree-sitter JS analysis for {file_path}: {e}", exc_info=True) | ||
| return [], [] | ||
|
|
||
|
|
||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,6 +22,7 @@ | |
| import tree_sitter_typescript | ||
|
|
||
| from codewiki.src.be.dependency_analyzer.models.core import Node, CallRelationship | ||
| from codewiki.src.be.dependency_analyzer.analyzers.javascript import analyze_javascript_file_treesitter | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
||
|
|
@@ -992,3 +993,4 @@ def analyze_typescript_file_treesitter( | |
| except Exception as e: | ||
| logger.error(f"Error in tree-sitter TS analysis for {file_path}: {e}", exc_info=True) | ||
| return [], [] | ||
|
|
||
|
Comment on lines
993
to
+996
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. 𦩠π codewiki/src/be/dependency_analyzer/analyzers/typescript#analyze_typescript_file_treesitter duplicates a near-identical definition I reused the existing π€ Prompt for AI agentsfix confidence: π΄ 55 low β review closely β react π/π to teach the reviewer |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,37 +23,56 @@ | |
| VALIDATION_RULES_ENV_VAR = "VALIDATION_RULES_PATH" | ||
|
|
||
|
|
||
| def load_flamingo_guidelines() -> str: | ||
|
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. 𦩠π codewiki/src/be/flamingo_guidelines#load_flamingo_guidelines duplicates an existing definition Extracted the shared file-loading logic from π€ Prompt for AI agentsfix confidence: π’ 95 high β react π/π to teach the reviewer |
||
| def _load_markdown_file_from_env(env_var: str, missing_log_suffix: str, content_description: str) -> str: | ||
| """ | ||
| Load Flamingo markdown guidelines from file path specified in env var. | ||
| Load markdown content from a file path specified in an environment variable. | ||
|
|
||
| Environment Variable: | ||
| FLAMINGO_MARKDOWN_GUIDELINES_PATH: Path to the guidelines markdown file | ||
| (downloaded during GitHub Actions workflow) | ||
| Args: | ||
| env_var: Name of the environment variable holding the file path. | ||
| missing_log_suffix: Text appended to the log message when the env var is not set. | ||
| content_description: Human-readable description of the content, used in log messages. | ||
|
|
||
| Returns: | ||
| Guidelines content string, or empty string if not available. | ||
| File content string, or empty string if not available. | ||
| """ | ||
| guidelines_path = os.environ.get(GUIDELINES_ENV_VAR) | ||
| file_path = os.environ.get(env_var) | ||
|
|
||
| if not guidelines_path: | ||
| logger.info(f"[CodeWiki] {GUIDELINES_ENV_VAR} not set - continuing without Flamingo guidelines") | ||
| if not file_path: | ||
| logger.info(f"[CodeWiki] {env_var} not set - continuing without {missing_log_suffix}") | ||
| return "" | ||
|
|
||
| try: | ||
| path = Path(guidelines_path) | ||
| path = Path(file_path) | ||
| if not path.exists(): | ||
| logger.warning(f"[CodeWiki] Guidelines file not found: {guidelines_path}") | ||
| logger.warning(f"[CodeWiki] {content_description} file not found: {file_path}") | ||
| return "" | ||
|
|
||
| content = path.read_text(encoding='utf-8') | ||
| logger.info(f"[CodeWiki] Loaded Flamingo markdown guidelines ({len(content)} chars)") | ||
| logger.info(f"[CodeWiki] Loaded {content_description} ({len(content)} chars)") | ||
| return content | ||
| except Exception as e: | ||
| logger.warning(f"[CodeWiki] Failed to load guidelines: {e}") | ||
| logger.warning(f"[CodeWiki] Failed to load {content_description}: {e}") | ||
| return "" | ||
|
|
||
|
|
||
| def load_flamingo_guidelines() -> str: | ||
| """ | ||
| Load Flamingo markdown guidelines from file path specified in env var. | ||
|
|
||
| Environment Variable: | ||
| FLAMINGO_MARKDOWN_GUIDELINES_PATH: Path to the guidelines markdown file | ||
| (downloaded during GitHub Actions workflow) | ||
|
|
||
| Returns: | ||
| Guidelines content string, or empty string if not available. | ||
| """ | ||
| return _load_markdown_file_from_env( | ||
| GUIDELINES_ENV_VAR, | ||
| "Flamingo guidelines", | ||
| "Flamingo markdown guidelines", | ||
| ) | ||
|
|
||
|
|
||
| # Load guidelines at module import time | ||
| FLAMINGO_MARKDOWN_GUIDELINES = load_flamingo_guidelines() | ||
|
|
||
|
|
@@ -291,24 +310,11 @@ def load_validation_rules() -> str: | |
| Returns: | ||
| Validation rules content string, or empty string if not available. | ||
| """ | ||
| rules_path = os.environ.get(VALIDATION_RULES_ENV_VAR) | ||
|
|
||
| if not rules_path: | ||
| logger.info(f"[CodeWiki] {VALIDATION_RULES_ENV_VAR} not set - continuing without validation rules injection") | ||
| return "" | ||
|
|
||
| try: | ||
| path = Path(rules_path) | ||
| if not path.exists(): | ||
| logger.warning(f"[CodeWiki] Validation rules file not found: {rules_path}") | ||
| return "" | ||
|
|
||
| content = path.read_text(encoding='utf-8') | ||
| logger.info(f"[CodeWiki] Loaded markdown validation rules ({len(content)} chars)") | ||
| return content | ||
| except Exception as e: | ||
| logger.warning(f"[CodeWiki] Failed to load validation rules: {e}") | ||
| return "" | ||
| return _load_markdown_file_from_env( | ||
| VALIDATION_RULES_ENV_VAR, | ||
| "validation rules injection", | ||
| "markdown validation rules", | ||
| ) | ||
|
|
||
|
|
||
| # Load validation rules at module import time | ||
|
Comment on lines
310
to
320
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. 𦩠π codewiki/src/be/flamingo_guidelines#load_validation_rules duplicates an existing definition
π€ Prompt for AI agentsfix confidence: π’ 95 high β react π/π to teach the reviewer |
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -85,54 +85,56 @@ def get_model_max_token_field(stage: str = 'generation') -> str: | |
| return os.environ.get(env_var, 'max_tokens') | ||
|
|
||
|
|
||
| def create_main_model(config: Config) -> OpenAIModel: | ||
|
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. 𦩠π codewiki/src/be/llm_services#create_main_model duplicates an existing definition Extracted the shared body of π€ Prompt for AI agentsfix confidence: π’ 95 high β react π/π to teach the reviewer |
||
| def _create_provider_model(config: Config, prefix: str) -> OpenAIModel: | ||
| """ | ||
| Create the main LLM model from configuration. | ||
| Create an LLM model for the given per-provider config prefix (e.g. 'main' or 'fallback'). | ||
|
|
||
| NOTE: Pydantic AI currently hardcodes the 'max_tokens' parameter name in OpenAIModelSettings. | ||
| For reasoning models (o3, o3-mini) that require 'max_completion_tokens', the direct API call | ||
| in call_llm() uses the correct parameter name. If Pydantic AI models fail with "Unrecognized | ||
| request argument supplied: max_tokens", the system will fall back to the direct API call. | ||
| """ | ||
| model_name = getattr(config, f'{prefix}_model') | ||
|
|
||
| # Use per-provider max_tokens | ||
| max_tokens = getattr(config, 'main_max_tokens', None) or get_max_output_tokens() | ||
| max_tokens = getattr(config, f'{prefix}_max_tokens', None) or get_max_output_tokens() | ||
| # Check if model supports custom temperature (use per-provider field) | ||
| temperature = getattr(config, 'main_temperature', 0.0) | ||
| temperature_supported = getattr(config, 'main_temperature_supported', True) | ||
| temperature = getattr(config, f'{prefix}_temperature', 0.0) | ||
| temperature_supported = getattr(config, f'{prefix}_temperature_supported', True) | ||
|
|
||
| # Build settings dict - only include temperature if model supports it | ||
| settings_dict = {'max_tokens': max_tokens} | ||
| if temperature_supported: | ||
| settings_dict['temperature'] = temperature | ||
|
|
||
| # Build provider with per-provider base_url and optional api_version header | ||
| base_url = getattr(config, 'main_base_url', None) | ||
| base_url = getattr(config, f'{prefix}_base_url', None) | ||
| if not base_url: | ||
| raise ValueError( | ||
| "main_base_url is required in configuration for main/generation model.\n" | ||
| f"Model: {config.main_model}\n" | ||
| "Please set via CLI: --main-base-url <url>\n" | ||
| "Or in config file: main_base_url = '<url>'" | ||
| f"{prefix}_base_url is required in configuration for {prefix} model.\n" | ||
| f"Model: {model_name}\n" | ||
| f"Please set via CLI: --{prefix}-base-url <url>\n" | ||
| f"Or in config file: {prefix}_base_url = '<url>'" | ||
| ) | ||
|
|
||
| # Prepare default headers for API version (Anthropic models) | ||
| default_headers = {} | ||
| api_version = getattr(config, 'main_api_version', None) | ||
| api_version = getattr(config, f'{prefix}_api_version', None) | ||
| if api_version: | ||
| default_headers['anthropic-version'] = api_version | ||
|
|
||
| # Get per-provider API key | ||
| api_key = getattr(config, 'main_api_key', None) | ||
| api_key = getattr(config, f'{prefix}_api_key', None) | ||
| if not api_key: | ||
| raise ValueError( | ||
| "main_api_key is required in configuration for main/generation model.\n" | ||
| f"Model: {config.main_model}\n" | ||
| "Please set via CLI: --main-api-key <key>\n" | ||
| f"{prefix}_api_key is required in configuration for {prefix} model.\n" | ||
| f"Model: {model_name}\n" | ||
| f"Please set via CLI: --{prefix}-api-key <key>\n" | ||
| "Different AI providers require different API keys." | ||
| ) | ||
|
|
||
| return OpenAIModel( | ||
| model_name=config.main_model, | ||
| model_name=model_name, | ||
| provider=OpenAIProvider( | ||
| base_url=base_url, | ||
| api_key=api_key, | ||
|
|
@@ -147,59 +149,21 @@ def create_main_model(config: Config) -> OpenAIModel: | |
| ) | ||
|
|
||
|
|
||
| def create_fallback_model(config: Config) -> OpenAIModel: | ||
|
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. 𦩠π codewiki/src/be/llm_services#create_fallback_model duplicates an existing definition
π€ Prompt for AI agentsfix confidence: π’ 95 high β react π/π to teach the reviewer |
||
| """Create the fallback LLM model from configuration.""" | ||
| # Use per-provider max_tokens | ||
| max_tokens = getattr(config, 'fallback_max_tokens', None) or get_max_output_tokens() | ||
| # Check if model supports custom temperature (use per-provider field) | ||
| temperature = getattr(config, 'fallback_temperature', 0.0) | ||
| temperature_supported = getattr(config, 'fallback_temperature_supported', True) | ||
|
|
||
| # Build settings dict - only include temperature if model supports it | ||
| settings_dict = {'max_tokens': max_tokens} | ||
| if temperature_supported: | ||
| settings_dict['temperature'] = temperature | ||
|
|
||
| # Build provider with per-provider base_url and optional api_version header | ||
| base_url = getattr(config, 'fallback_base_url', None) | ||
| if not base_url: | ||
| raise ValueError( | ||
| "fallback_base_url is required in configuration for fallback model.\n" | ||
| f"Model: {config.fallback_model}\n" | ||
| "Please set via CLI: --fallback-base-url <url>\n" | ||
| "Or in config file: fallback_base_url = '<url>'" | ||
| ) | ||
| def create_main_model(config: Config) -> OpenAIModel: | ||
| """ | ||
| Create the main LLM model from configuration. | ||
|
|
||
| # Prepare default headers for API version (Anthropic models) | ||
| default_headers = {} | ||
| api_version = getattr(config, 'fallback_api_version', None) | ||
| if api_version: | ||
| default_headers['anthropic-version'] = api_version | ||
| NOTE: Pydantic AI currently hardcodes the 'max_tokens' parameter name in OpenAIModelSettings. | ||
| For reasoning models (o3, o3-mini) that require 'max_completion_tokens', the direct API call | ||
| in call_llm() uses the correct parameter name. If Pydantic AI models fail with "Unrecognized | ||
| request argument supplied: max_tokens", the system will fall back to the direct API call. | ||
| """ | ||
| return _create_provider_model(config, 'main') | ||
|
|
||
| # Get per-provider API key | ||
| api_key = getattr(config, 'fallback_api_key', None) | ||
| if not api_key: | ||
| raise ValueError( | ||
| "fallback_api_key is required in configuration for fallback model.\n" | ||
| f"Model: {config.fallback_model}\n" | ||
| "Please set via CLI: --fallback-api-key <key>\n" | ||
| "Different AI providers require different API keys." | ||
| ) | ||
|
|
||
| return OpenAIModel( | ||
| model_name=config.fallback_model, | ||
| provider=OpenAIProvider( | ||
| base_url=base_url, | ||
| api_key=api_key, | ||
| # NOTE: pydantic-ai's OpenAIProvider takes only base_url, api_key, | ||
| # openai_client and http_client - there is no default_headers | ||
| # parameter (verified against pydantic-ai 2.40.0), so passing one | ||
| # raises TypeError. To send anthropic-version here, build an | ||
| # AsyncOpenAI client with default_headers and pass it as | ||
| # openai_client=. | ||
| ), | ||
| settings=OpenAIModelSettings(**settings_dict) | ||
| ) | ||
| def create_fallback_model(config: Config) -> OpenAIModel: | ||
| """Create the fallback LLM model from configuration.""" | ||
| return _create_provider_model(config, 'fallback') | ||
|
|
||
|
|
||
|
|
||
|
|
@@ -473,3 +437,4 @@ def call_llm( | |
| f"Unexpected error calling {model_stage_name} model '{model}': " | ||
| f"{type(e).__name__}: {str(e)}" | ||
| ) from e | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,7 +5,7 @@ | |
|
|
||
| from datetime import datetime | ||
| from typing import Optional | ||
| from dataclasses import dataclass | ||
| from dataclasses import dataclass, asdict | ||
| from pydantic import BaseModel, HttpUrl | ||
|
|
||
|
|
||
|
|
@@ -14,11 +14,12 @@ class RepositorySubmission(BaseModel): | |
| repo_url: HttpUrl | ||
|
|
||
|
|
||
| class JobStatusResponse(BaseModel): | ||
|
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. 𦩠π codewiki/src/fe/models#JobStatusResponse duplicates a near-identical definition In π€ Prompt for AI agentsfix confidence: π‘ 75 medium β react π/π to teach the reviewer |
||
| """Pydantic model for job status API response.""" | ||
| @dataclass | ||
| class JobStatus: | ||
| """Tracks the status of a documentation generation job.""" | ||
| job_id: str | ||
| repo_url: str | ||
| status: str | ||
| status: str # 'queued', 'processing', 'completed', 'failed' | ||
| created_at: datetime | ||
| started_at: Optional[datetime] = None | ||
| completed_at: Optional[datetime] = None | ||
|
|
@@ -29,12 +30,11 @@ class JobStatusResponse(BaseModel): | |
| commit_id: Optional[str] = None | ||
|
|
||
|
|
||
| @dataclass | ||
|
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. 𦩠π codewiki/src/fe/models#JobStatus duplicates a near-identical definition In π€ Prompt for AI agentsfix confidence: π‘ 75 medium β react π/π to teach the reviewer |
||
| class JobStatus: | ||
| """Tracks the status of a documentation generation job.""" | ||
| class JobStatusResponse(BaseModel): | ||
| """Pydantic model for job status API response.""" | ||
| job_id: str | ||
| repo_url: str | ||
| status: str # 'queued', 'processing', 'completed', 'failed' | ||
| status: str | ||
| created_at: datetime | ||
| started_at: Optional[datetime] = None | ||
| completed_at: Optional[datetime] = None | ||
|
|
@@ -44,6 +44,11 @@ class JobStatus: | |
| main_model: Optional[str] = None | ||
| commit_id: Optional[str] = None | ||
|
|
||
| @classmethod | ||
| def from_job_status(cls, job_status: JobStatus) -> "JobStatusResponse": | ||
| """Build a JobStatusResponse from a JobStatus instance.""" | ||
| return cls(**asdict(job_status)) | ||
|
|
||
|
|
||
| @dataclass | ||
| class CacheEntry: | ||
|
|
@@ -52,4 +57,4 @@ class CacheEntry: | |
| repo_url_hash: str | ||
| docs_path: str | ||
| created_at: datetime | ||
| last_accessed: datetime | ||
| last_accessed: datetime | ||
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.
𦩠π codewiki/cli/commands/generate#parse_patterns duplicates an existing definition
Removed the duplicate
parse_patternsfunction definition fromcodewiki/cli/commands/generate.pyand replaced it withfrom codewiki.cli.commands.config import parse_patterns, reusing the existing implementation atcodewiki/cli/commands/config.py:27. All call sites ingenerate_command(include/exclude/focus parsing, additional_paths parsing) continue to referenceparse_patternsunchanged, now bound to the imported function. This assumescodewiki/cli/commands/config.pyhas no heavy side effects or circular-import risk when imported fromgenerate.py; ifconfig.pyimports fromgenerate.pythis could create a circular import, which should be verified by the reviewer.π€ Prompt for AI agents
fix confidence: π’ 92 high β react π/π to teach the reviewer