diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index f51121ef7..84f13fe54 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -72,7 +72,7 @@ repos:
- id: deptry
pass_filenames: false
always_run: true
- entry: bash -c "uv run --frozen --all-extras --dev deptry src --ignore DEP001"
+ entry: bash -c "uv run --frozen --all-extras --dev deptry src --ignore DEP001 --extend-exclude 'codegen-examples/.*'"
- repo: https://github.com/renovatebot/pre-commit-hooks
rev: 39.164.1
diff --git a/codegen-examples/examples/langchain_agent/README.md b/codegen-examples/examples/langchain_agent/README.md
new file mode 100644
index 000000000..ad2645f7a
--- /dev/null
+++ b/codegen-examples/examples/langchain_agent/README.md
@@ -0,0 +1,82 @@
+# Codegen LangChain Agent Example
+
+
+
+
+
+
+
+
+ Build an intelligent code agent with LangChain and Codegen
+
+
+
+
+[](https://docs.codegen.com/tutorials/build-code-agent)
+[](https://github.com/codegen-sh/codegen-sdk/tree/develop?tab=Apache-2.0-1-ov-file)
+
+
+
+This example demonstrates how to build an intelligent code agent using Codegen's LangChain integration. The agent can analyze and manipulate codebases using natural language commands.
+
+## Quick Start
+
+```python
+from codegen import Codebase
+from codegen.extensions.langchain import create_codebase_agent
+
+# Initialize codebase
+codebase = Codebase.from_repo("fastapi/fastapi")
+
+# Create the agent
+agent = create_codebase_agent(codebase=codebase, model_name="gpt-4", verbose=True)
+
+# Ask the agent to analyze code
+result = agent.invoke({"input": "What are the dependencies of the FastAPI class?", "config": {"configurable": {"session_id": "demo"}}})
+print(result["output"])
+```
+
+## Installation
+
+```bash
+# Install dependencies
+pip install modal-client codegen langchain langchain-openai
+
+# Run the example
+python run.py
+```
+
+## Available Tools
+
+The agent comes with several built-in tools for code operations:
+
+- `ViewFileTool`: View file contents and metadata
+- `ListDirectoryTool`: List directory contents
+- `SearchTool`: Search code using regex
+- `EditFileTool`: Edit file contents
+- `CreateFileTool`: Create new files
+- `DeleteFileTool`: Delete files
+- `RenameFileTool`: Rename files and update imports
+- `MoveSymbolTool`: Move functions/classes between files
+- `RevealSymbolTool`: Analyze symbol dependencies
+- `SemanticEditTool`: Make semantic code edits
+- `CommitTool`: Commit changes to disk
+
+## Example Operations
+
+The agent can perform various code analysis and manipulation tasks:
+
+```python
+# Analyze dependencies
+agent.invoke({"input": "What are the dependencies of the reveal_symbol function?", "config": {"configurable": {"session_id": "demo"}}})
+
+# Find usage patterns
+agent.invoke({"input": "Show me examples of dependency injection in the codebase", "config": {"configurable": {"session_id": "demo"}}})
+
+# Move code
+agent.invoke({"input": "Move the validate_email function to validation_utils.py", "config": {"configurable": {"session_id": "demo"}}})
+```
+
+## Learn More
+
+- [Full Tutorial](https://docs.codegen.com/tutorials/build-code-agent)
diff --git a/codegen-examples/examples/langchain_agent/run.py b/codegen-examples/examples/langchain_agent/run.py
new file mode 100644
index 000000000..cff0d15f1
--- /dev/null
+++ b/codegen-examples/examples/langchain_agent/run.py
@@ -0,0 +1,107 @@
+"""Demo implementation of an agent with Codegen tools."""
+
+from codegen import Codebase
+from codegen.extensions.langchain.tools import (
+ CommitTool,
+ CreateFileTool,
+ DeleteFileTool,
+ EditFileTool,
+ ListDirectoryTool,
+ MoveSymbolTool,
+ RenameFileTool,
+ RevealSymbolTool,
+ SearchTool,
+ SemanticEditTool,
+ ViewFileTool,
+)
+from codegen.sdk.enums import ProgrammingLanguage
+from langchain import hub
+from langchain.agents import AgentExecutor
+from langchain.agents.openai_functions_agent.base import OpenAIFunctionsAgent
+from langchain_core.chat_history import ChatMessageHistory
+from langchain_core.runnables.history import RunnableWithMessageHistory
+from langchain_openai import ChatOpenAI
+
+
+def create_codebase_agent(
+ codebase: Codebase,
+ model_name: str = "gpt-4o",
+ temperature: float = 0,
+ verbose: bool = True,
+) -> RunnableWithMessageHistory:
+ """Create an agent with all codebase tools.
+
+ Args:
+ codebase: The codebase to operate on
+ model_name: Name of the model to use (default: gpt-4)
+ temperature: Model temperature (default: 0)
+ verbose: Whether to print agent's thought process (default: True)
+
+ Returns:
+ Initialized agent with message history
+ """
+ # Initialize language model
+ llm = ChatOpenAI(
+ model_name=model_name,
+ temperature=temperature,
+ )
+
+ # Get all codebase tools
+ tools = [
+ ViewFileTool(codebase),
+ ListDirectoryTool(codebase),
+ SearchTool(codebase),
+ EditFileTool(codebase),
+ CreateFileTool(codebase),
+ DeleteFileTool(codebase),
+ RenameFileTool(codebase),
+ MoveSymbolTool(codebase),
+ RevealSymbolTool(codebase),
+ SemanticEditTool(codebase),
+ CommitTool(codebase),
+ ]
+
+ # Get the prompt to use
+ prompt = hub.pull("hwchase17/openai-functions-agent")
+
+ # Create the agent
+ agent = OpenAIFunctionsAgent(
+ llm=llm,
+ tools=tools,
+ prompt=prompt,
+ )
+
+ # Create the agent executor
+ agent_executor = AgentExecutor(
+ agent=agent,
+ tools=tools,
+ verbose=verbose,
+ )
+
+ # Create message history handler
+ message_history = ChatMessageHistory()
+
+ # Wrap with message history
+ return RunnableWithMessageHistory(
+ agent_executor,
+ lambda session_id: message_history,
+ input_messages_key="input",
+ history_messages_key="chat_history",
+ )
+
+
+if __name__ == "__main__":
+ # Initialize codebase
+ print("Initializing codebase...")
+ codebase = Codebase.from_repo("fastapi/fastapi", programming_language=ProgrammingLanguage.PYTHON)
+
+ # Create agent with history
+ print("Creating agent...")
+ agent = create_codebase_agent(codebase)
+
+ print("\nAsking agent to analyze symbol relationships...")
+ result = agent.invoke(
+ {"input": "What are the dependencies of the reveal_symbol function?"},
+ config={"configurable": {"session_id": "demo"}},
+ )
+ print("Messages:", result["messages"])
diff --git a/pyproject.toml b/pyproject.toml
index 4c6649552..2717a487d 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -151,6 +151,7 @@ dev-dependencies = [
"loguru>=0.7.3",
"httpx<0.28.2,>=0.28.1",
"jupyterlab>=4.3.5",
+ "modal>=0.73.25",
]
diff --git a/src/codegen/extensions/langchain/agent.py b/src/codegen/extensions/langchain/agent.py
index 514658ce5..458903c24 100644
--- a/src/codegen/extensions/langchain/agent.py
+++ b/src/codegen/extensions/langchain/agent.py
@@ -8,7 +8,6 @@
from langchain_openai import ChatOpenAI
from codegen import Codebase
-from codegen.sdk.enums import ProgrammingLanguage
from .tools import (
CommitTool,
@@ -27,7 +26,7 @@
def create_codebase_agent(
codebase: Codebase,
- model_name: str = "gpt-4",
+ model_name: str = "gpt-4o",
temperature: float = 0,
verbose: bool = True,
) -> RunnableWithMessageHistory:
@@ -90,20 +89,3 @@ def create_codebase_agent(
input_messages_key="input",
history_messages_key="chat_history",
)
-
-
-if __name__ == "__main__":
- # Initialize codebase
- print("Initializing codebase...")
- codebase = Codebase.from_repo("fastapi/fastapi", programming_language=ProgrammingLanguage.PYTHON)
-
- # Create agent with history
- print("Creating agent...")
- agent = create_codebase_agent(codebase)
-
- print("\nAsking agent to analyze symbol relationships...")
- result = agent.invoke(
- {"input": "What are the dependencies of the reveal_symbol function?"},
- config={"configurable": {"session_id": "demo"}},
- )
- print("Messages:", result["messages"])
diff --git a/src/codegen/extensions/modal/README.md b/src/codegen/extensions/modal/README.md
deleted file mode 100644
index 108df5e42..000000000
--- a/src/codegen/extensions/modal/README.md
+++ /dev/null
@@ -1,68 +0,0 @@
-# Repository Analyzer API
-
-A simple Modal API endpoint that analyzes GitHub repositories using Codegen. The API returns basic metrics about any public GitHub repository including:
-
-- Total number of files
-- Number of functions
-- Number of classes
-
-## Running Locally
-
-1. Install dependencies:
-
-```bash
-uv add modal
-```
-
-2. Start the API server:
-
-```bash
-modal serve src/codegen/extensions/modal/api.py
-```
-
-3. Test with curl:
-
-```bash
-# Replace with your local Modal endpoint URL
-curl "{URL}?repo_name=fastapi/fastapi"
-```
-
-## Response Format
-
-The API returns JSON in this format:
-
-```json
-{
- "status": "success",
- "error": "",
- "num_files": 123,
- "num_functions": 456,
- "num_classes": 78
-}
-```
-
-If there's an error, you'll get:
-
-```json
-{
- "status": "error",
- "error": "Error message here",
- "num_files": 0,
- "num_functions": 0,
- "num_classes": 0
-}
-```
-
-## Development
-
-The API is built using:
-
-- Modal for serverless deployment
-- FastAPI for the web endpoint
-- Codegen for repository analysis
-
-To deploy changes:
-
-```bash
-modal deploy src/codegen/extensions/modal/api.py
-```
diff --git a/src/codegen/extensions/modal/api.py b/src/codegen/extensions/modal/api.py
deleted file mode 100644
index 13d33ff4f..000000000
--- a/src/codegen/extensions/modal/api.py
+++ /dev/null
@@ -1,56 +0,0 @@
-"""Modal API endpoint for repository analysis."""
-
-import modal
-from pydantic import BaseModel
-
-from codegen import Codebase
-
-# Create image with dependencies
-image = modal.Image.debian_slim(python_version="3.13").apt_install("git").pip_install("fastapi[standard]", "codegen>=0.5.30")
-
-# Create Modal app
-app = modal.App("codegen-repo-analyzer")
-
-
-class RepoMetrics(BaseModel):
- """Response model for repository metrics."""
-
- num_files: int = 0
- num_functions: int = 0
- num_classes: int = 0
- status: str = "success"
- error: str = ""
-
-
-@app.function(image=image)
-@modal.web_endpoint(method="GET")
-def analyze_repo(repo_name: str) -> RepoMetrics:
- """Analyze a GitHub repository and return metrics.
-
- Args:
- repo_name: Repository name in format 'owner/repo'
-
- Returns:
- RepoMetrics object containing repository metrics or error information
- """
- try:
- # Validate input
- if "/" not in repo_name:
- return RepoMetrics(status="error", error="Repository name must be in format 'owner/repo'")
-
- # Initialize codebase
- codebase = Codebase.from_repo(repo_name)
-
- # Calculate metrics
- num_files = len(codebase.files(extensions="*")) # Get all files
- num_functions = len(codebase.functions)
- num_classes = len(codebase.classes)
-
- return RepoMetrics(
- num_files=num_files,
- num_functions=num_functions,
- num_classes=num_classes,
- )
-
- except Exception as e:
- return RepoMetrics(status="error", error=str(e))
diff --git a/src/codegen/extensions/modal/pyproject.toml b/src/codegen/extensions/modal/pyproject.toml
deleted file mode 100644
index 899030322..000000000
--- a/src/codegen/extensions/modal/pyproject.toml
+++ /dev/null
@@ -1,6 +0,0 @@
-[project]
-name = "codegen-repo-analyzer"
-version = "0.1.0"
-description = "Modal API endpoint for analyzing GitHub repositories using Codegen"
-requires-python = ">=3.13"
-dependencies = ["modal>=0.73.25", "fastapi[standard]", "codegen>=0.5.30"]