Skip to content
Merged
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
15 changes: 11 additions & 4 deletions codewiki/src/be/agent_orchestrator.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
"""Agent orchestration for documentation generation.

This module defines AgentOrchestrator, the component responsible for
creating and running pydantic_ai agents that generate documentation for
modules discovered in a repository. It selects agent configurations based
on module complexity, wires up the required tools and dependencies, and
drives the per-module documentation generation pipeline (loading/saving the
module tree, invoking the agent, and persisting generated docs).
"""

from pydantic_ai import Agent
from pydantic_ai.usage import UsageLimits
# import logfire
Expand Down Expand Up @@ -61,9 +71,6 @@ class AgentOrchestrator:
"""Orchestrates the AI agents for documentation generation."""

def __init__(self, config: Config):
import logging
logger = logging.getLogger(__name__)

self.config = config
self.fallback_models = create_fallback_models(config)
self.custom_instructions = config.get_prompt_addition() if config else None
Expand Down Expand Up @@ -207,4 +214,4 @@ async def process_module(self, module_name: str, components: Dict[str, Node],
except Exception as e:
logger.error(f"❌ Error processing module {module_name}: {str(e)}")
logger.error(f" └─ Traceback: {traceback.format_exc()}")
raise
raise
3 changes: 2 additions & 1 deletion codewiki/src/be/agent_tools/deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
pipeline.
"""
from dataclasses import dataclass
from typing import Any
from codewiki.src.be.dependency_analyzer.models.core import Node
from codewiki.src.config import Config

Expand All @@ -17,7 +18,7 @@ class CodeWikiDeps:
components: dict[str, Node]
path_to_current_module: list[str]
current_module_name: str
module_tree: dict[str, any]
module_tree: dict[str, Any]
max_depth: int
current_depth: int
config: Config # LLM configuration
Expand Down
36 changes: 24 additions & 12 deletions codewiki/src/be/agent_tools/generate_sub_module_documentations.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
"""Sub-module documentation generation pipeline step.

This module implements the recursive agent-dispatch tool used by CodeWiki to
split a module into smaller sub-modules and generate documentation for each
one. It is responsible for:

- Normalizing the component identifiers returned by the LLM (which may be
either FQDN strings or integer IDs from the ID-based clustering system)
into canonical FQDNs that exist in ``deps.components``.
- Updating the in-memory module tree with the newly created sub-modules.
- Spawning nested ``pydantic_ai`` agents (leaf or non-leaf, depending on
module complexity and depth) to recursively generate documentation for
each sub-module.

It is exposed to the top-level documentation agent as
``generate_sub_module_documentation_tool``.
"""

from pydantic_ai import RunContext, Tool, Agent
from pydantic_ai.usage import UsageLimits

Expand Down Expand Up @@ -147,28 +165,22 @@ async def generate_sub_module_documentation(
description="""Generate detailed documentation for sub-modules by grouping related components.

CRITICAL FORMAT REQUIREMENTS:
- Use the EXACT component identifiers as shown in the <CORE_COMPONENT_CODES> section
- Use the EXACT integer component IDs as shown in the <CORE_COMPONENT_CODES> section
- DO NOT extract just class names (e.g., "AuthService", "ApiApplicationConfig")
- Use the COMPLETE identifiers like: "main-repo.src/services/auth.py::AuthService"
- DO NOT invent full FQDN strings; use the integer IDs assigned to each component

Example CORRECT format:
{
"Authentication": [
"main-repo.src/services/auth.py::AuthService",
"main-repo.src/services/auth.py::LoginController"
],
"Configuration": [
"main-repo.src/config/api.py::ApiApplicationConfig",
"main-repo.src/config/security.py::SecurityConfig"
]
"Authentication": [0, 1],
"Configuration": [2, 3]
}

Example WRONG format (DO NOT USE):
{
"Authentication": ["AuthService", "LoginController"], # ❌ Class names only
"Configuration": ["ApiApplicationConfig"] # ❌ Missing full path
"Configuration": ["main-repo.src/config/api.py::ApiApplicationConfig"] # ❌ Full FQDN string instead of integer ID
}

The component identifiers must match exactly what appears in <CORE_COMPONENT_CODES>.""",
The integer IDs must match exactly what appears in <CORE_COMPONENT_CODES>.""",
takes_ctx=True
)
10 changes: 10 additions & 0 deletions codewiki/src/be/dependency_analyzer/analysis/cloning.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
"""Repository cloning and cleanup utilities.

This module implements the repository acquisition step of the dependency
analysis pipeline: given a GitHub URL, it sanitizes and validates the URL,
clones the repository into a temporary directory for analysis, and safely
cleans up that directory afterwards (including handling Windows-specific
read-only file permission issues). Downstream analysis stages in the
dependency_analyzer package operate on the local clone produced here.
"""

import os
import shutil
import tempfile
Expand Down
8 changes: 8 additions & 0 deletions codewiki/src/be/dependency_analyzer/analyzers/c.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
"""Tree-sitter based analyzer for C source files.

This module parses C source code using tree-sitter to extract call-graph
nodes (functions, structs, and global variables) and the call/usage
relationships between them. It is part of the multi-language dependency
analysis pipeline, producing `Node` and `CallRelationship` objects that
feed into the broader dependency graph and clustering system.
"""
import logging
from typing import List, Optional, Tuple
from pathlib import Path
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ def _get_parent_context(self, node) -> str:
if node.parent.parent and node.parent.parent.type in ["module", "ambient_declaration"]:
return "module_block"
return "statement_block"
return "unknown"
def _extract_function_entity(self, node, func_type: str, depth: int) -> dict:
name_node = self._find_child_by_type(node, "identifier")
if not name_node:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
"""Dependency graph construction for repository analysis.

This module defines the DependencyGraphBuilder class, which orchestrates
parsing a repository's source files, building a dependency graph from the
extracted components, validating graph completeness, and filtering leaf
nodes to those relevant for downstream processing.
"""
from typing import Dict, List, Any
import os
from codewiki.src.config import Config
Expand Down Expand Up @@ -154,4 +161,4 @@ def build_dependency_graph(self) -> tuple[Dict[str, Any], List[str]]:
logger.info(f" β”œβ”€ Skipped (wrong type): {skipped_type}")
logger.info(f" └─ Skipped (not found): {skipped_not_found}")

return components, keep_leaf_nodes
return components, keep_leaf_nodes
6 changes: 6 additions & 0 deletions codewiki/src/be/dependency_analyzer/models/core.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
"""Core pydantic data models for the dependency analyzer.

Defines the Node, CallRelationship, and Repository models that form the
core data contract used throughout the dependency analysis pipeline.
"""
from pydantic import BaseModel
from typing import List, Optional, Dict, Any, Set
from datetime import datetime
Expand Down Expand Up @@ -66,3 +71,4 @@ class Repository(BaseModel):
clone_path: str

analysis_id: str

9 changes: 9 additions & 0 deletions codewiki/src/be/dependency_analyzer/utils/security.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
"""Security utilities for safe file access within a repository root.

This module implements path-traversal and symlink protections used when
reading files from a repository. It ensures that file access is confined to
a given base directory and that symlinks are not followed, mitigating
directory-traversal and symlink-escape attacks during dependency analysis.
"""

from pathlib import Path
import os

Expand Down Expand Up @@ -31,3 +39,4 @@ def safe_open_text(base_dir: Path, target: Path, encoding="utf-8"):
os.close(fd)
except OSError:
pass

16 changes: 16 additions & 0 deletions codewiki/src/config.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
"""Configuration module for CodeWiki.

This module defines the central `Config` dataclass used throughout the
CodeWiki documentation-generation pipeline. It encapsulates repository
paths, output directories, LLM provider settings (models, API keys, base
URLs, temperatures, and token limits), and agent instruction customization
(include/exclude patterns, focus modules, doc type, custom instructions).

It also provides constructors for building a `Config` instance from CLI
arguments (`from_args`), for a web-app job (`from_web_job`), from explicit
CLI parameters (`from_cli`), and from a `ConfigManager`
(`from_config_manager`), along with helpers for
multi-path source validation and prompt-addition generation used by the
downstream documentation generation stages.
"""

from dataclasses import dataclass, field, fields, asdict
from typing import Optional, List, Dict, Any
import argparse
Expand Down
3 changes: 3 additions & 0 deletions codewiki/src/utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"""File I/O utility helpers used across the CodeWiki backend and web app."""

import os
import json
from typing import Any, Optional, Dict
Expand Down Expand Up @@ -45,3 +47,4 @@ def load_text(filepath: str) -> str:
return f.read()

file_manager = FileManager()