/ archive / python / kamaji / agents / documentation.py
documentation.py
  1  """
  2  Documentation specialized agent.
  3  """
  4  
  5  from langchain.agents import AgentExecutor, create_react_agent
  6  from langchain_core.tools import Tool
  7  from langchain_core.prompts import PromptTemplate
  8  from langchain_core.language_models import BaseLLM
  9  
 10  from kamaji.tools import read_file, write_file_smart, list_directory, execute_shell_command
 11  
 12  
 13  def extract_docstrings(file_path: str) -> str:
 14      """Extract all docstrings from a Python file."""
 15      try:
 16          with open(file_path, 'r') as f:
 17              content = f.read()
 18  
 19          import ast
 20          tree = ast.parse(content)
 21  
 22          docstrings = []
 23          for node in ast.walk(tree):
 24              if isinstance(node, (ast.FunctionDef, ast.ClassDef, ast.Module)):
 25                  docstring = ast.get_docstring(node)
 26                  if docstring:
 27                      name = getattr(node, 'name', 'Module')
 28                      docstrings.append(f"{name}: {docstring[:100]}...")
 29  
 30          if docstrings:
 31              return "\n".join(docstrings)
 32          else:
 33              return f"No docstrings found in {file_path}"
 34  
 35      except Exception as e:
 36          return f"Error extracting docstrings: {str(e)}"
 37  
 38  
 39  def check_missing_docs(file_path: str) -> str:
 40      """Find functions/classes without docstrings."""
 41      try:
 42          with open(file_path, 'r') as f:
 43              content = f.read()
 44  
 45          import ast
 46          tree = ast.parse(content)
 47  
 48          missing = []
 49          for node in ast.walk(tree):
 50              if isinstance(node, (ast.FunctionDef, ast.ClassDef)):
 51                  if not ast.get_docstring(node):
 52                      missing.append(f"Line {node.lineno}: {node.name}")
 53  
 54          if missing:
 55              return f"Missing documentation:\n" + "\n".join(missing)
 56          else:
 57              return f"✅ All functions/classes in {file_path} have docstrings"
 58  
 59      except Exception as e:
 60          return f"Error checking documentation: {str(e)}"
 61  
 62  
 63  def create_documentation_agent(llm: BaseLLM, verbose: bool = False) -> AgentExecutor:
 64      """
 65      Create a documentation specialized agent.
 66  
 67      This agent is optimized for writing, reviewing, and improving documentation.
 68  
 69      Args:
 70          llm: The language model to use
 71          verbose: Show detailed reasoning
 72  
 73      Returns:
 74          AgentExecutor configured for documentation tasks
 75      """
 76      tools = [
 77          Tool(
 78              name="read_file",
 79              func=read_file,
 80              description="Read a source file to document. Input should be the file path."
 81          ),
 82          Tool(
 83              name="write_file",
 84              func=write_file_smart,
 85              description="Write documentation to a file. Format: 'filepath|||content'"
 86          ),
 87          Tool(
 88              name="extract_docstrings",
 89              func=extract_docstrings,
 90              description="Extract existing docstrings from a Python file. Input: file path."
 91          ),
 92          Tool(
 93              name="check_missing_docs",
 94              func=check_missing_docs,
 95              description="Find functions/classes without docstrings. Input: file path."
 96          ),
 97          Tool(
 98              name="list_directory",
 99              func=list_directory,
100              description="List files in a directory. Input: directory path."
101          ),
102          Tool(
103              name="run_command",
104              func=execute_shell_command,
105              description="Run documentation tools like sphinx or mkdocs. Input: shell command."
106          ),
107      ]
108  
109      prompt = PromptTemplate.from_template("""
110  You are a technical writer specialized in software documentation.
111  
112  Your responsibilities:
113  - Write clear, comprehensive documentation
114  - Create README files, API docs, and guides
115  - Add/improve docstrings in code
116  - Ensure documentation completeness
117  
118  Documentation standards:
119  📝 Clear and concise language
120  📝 Code examples where helpful
121  📝 Proper formatting (Markdown, reStructuredText)
122  📝 Complete function/class documentation
123  📝 Usage examples and best practices
124  
125  Available tools: {tools}
126  
127  Use the following format:
128  
129  Question: {input}
130  Thought: I should understand what needs to be documented
131  Action: [one of: {tool_names}]
132  Action Input: [input for the tool]
133  Observation: [tool result]
134  ... (repeat Thought/Action/Observation as needed)
135  Thought: I have created/improved the documentation
136  Final Answer: [summary of documentation changes made]
137  
138  Begin!
139  
140  Question: {input}
141  Thought:{agent_scratchpad}
142  """)
143  
144      agent = create_react_agent(llm, tools, prompt)
145  
146      return AgentExecutor(
147          agent=agent,
148          tools=tools,
149          verbose=verbose,
150          handle_parsing_errors=True,
151          max_iterations=30,  # Increased for complex documentation tasks
152          early_stopping_method="generate"  # Generate answer even if not complete
153      )