Skip to content

Commit ccf7a26

Browse files
author
codegen-bot
committed
Merge branch 'develop' into tawsif/codebase-from-string-from-files
2 parents 3240904 + 696fb97 commit ccf7a26

File tree

32 files changed

+1570
-219
lines changed

32 files changed

+1570
-219
lines changed

.github/workflows/pre-commit.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
fetch-depth: 0
2121
repository: ${{ github.event.pull_request.head.repo.full_name }}
2222
ref: ${{ github.event.pull_request.head.ref }}
23-
token: ${{ secrets.REPO_SCOPED_TOKEN }}
23+
token: ${{ secrets.REPO_SCOPED_TOKEN || github.token }}
2424

2525
- name: Setup environment
2626
uses: ./.github/actions/setup-environment

.github/workflows/release.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ jobs:
5252
with:
5353
fetch-depth: 0
5454
ref: ${{ inputs.release-tag || github.event.pull_request.head.ref || github.ref }}
55+
repository: ${{ github.event.pull_request.head.repo.full_name || github.event.repository.full_name }}
5556

5657
- name: Install UV
5758
uses: astral-sh/[email protected]
@@ -64,6 +65,7 @@ jobs:
6465
cache-suffix: 3.${{ matrix.python }}
6566

6667
- name: Fetch tags
68+
if: ${{ inputs.release-tag || startsWith(github.ref, 'refs/tags/') }}
6769
run: |
6870
git branch
6971
git fetch --depth=1 origin +refs/tags/*:refs/tags/*

Dockerfile-runner

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ ENV NVM_DIR=/root/.nvm \
1010
PYTHONPATH="/usr/local/lib/python3.13/site-packages" \
1111
IS_SANDBOX=True \
1212
HATCH_BUILD_HOOKS_ENABLE=1
13+
1314
# Update packages lists and install git and curl
1415
RUN apt-get update && apt-get install -y \
1516
git \
@@ -41,17 +42,14 @@ RUN node --version \
4142
&& pnpm --version \
4243
&& python --version
4344

44-
# Install codegen from source instead of PyPI
45+
# Build codegen
4546
WORKDIR /codegen-sdk
4647
COPY . .
47-
48-
# Install dependencies and build codegen with entry points
4948
RUN --mount=type=cache,target=/root/.cache/uv \
5049
uv venv && source .venv/bin/activate \
5150
&& uv sync --frozen --no-dev --all-extras \
5251
&& uv pip install --system -e . --no-deps \
5352
&& uv pip install --system .
54-
5553
RUN codegen --version
5654

5755
# Create a non-root user for local development + debugging
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Codegen App
2+
3+
Simple example of running a codegen app.
4+
5+
## Run Locally
6+
7+
Spin up the server:
8+
9+
```
10+
codegen serve
11+
```
12+
13+
Spin up ngrok
14+
15+
```
16+
ngrok http 8000
17+
```
18+
19+
Go to Slack [app settings](https://api.slack.com/apps/A08CR9HUJ3W/event-subscriptions) and set the URL for event subscriptions
20+
21+
```
22+
{ngrok_url}/slack/events
23+
```
24+
25+
## Deploy to Modal
26+
27+
This will deploy it as a function
28+
29+
```
30+
modal deploy app.py
31+
```
32+
33+
Then you can swap in the modal URL for slack etc.
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import logging
2+
3+
import modal
4+
from codegen import CodeAgent, CodegenApp
5+
from codegen.extensions.github.types.events.pull_request import PullRequestLabeledEvent
6+
from codegen.extensions.linear.types import LinearEvent
7+
from codegen.extensions.slack.types import SlackEvent
8+
from codegen.extensions.tools.github.create_pr_comment import create_pr_comment
9+
10+
# Set up logging
11+
logging.basicConfig(level=logging.INFO)
12+
logger = logging.getLogger(__name__)
13+
14+
########################################################################################################################
15+
# EVENTS
16+
########################################################################################################################
17+
18+
# Create the cg_app
19+
cg = CodegenApp(name="codegen-test", repos=["codegen-sh/Kevin-s-Adventure-Game"])
20+
21+
22+
@cg.slack.event("app_mention")
23+
async def handle_mention(event: SlackEvent):
24+
logger.info("[APP_MENTION] Received cg_app_mention event")
25+
logger.info(event)
26+
27+
# Codebase
28+
logger.info("[CODEBASE] Initializing codebase")
29+
codebase = cg.get_codebase("codegen-sh/Kevin-s-Adventure-Game")
30+
31+
# Code Agent
32+
logger.info("[CODE_AGENT] Initializing code agent")
33+
agent = CodeAgent(codebase=codebase)
34+
35+
logger.info("[CODE_AGENT] Running code agent")
36+
response = agent.run(event.text)
37+
38+
cg.slack.client.chat_postMessage(channel=event.channel, text=response, thread_ts=event.ts)
39+
return {"message": "Mentioned", "received_text": event.text, "response": response}
40+
41+
42+
@cg.github.event("pull_request:labeled")
43+
def handle_pr(event: PullRequestLabeledEvent):
44+
logger.info("PR labeled")
45+
logger.info(f"PR head sha: {event.pull_request.head.sha}")
46+
codebase = cg.get_codebase("codegen-sh/Kevin-s-Adventure-Game")
47+
48+
# =====[ Check out commit ]=====
49+
# Might require fetch?
50+
logger.info("> Checking out commit")
51+
codebase.checkout(commit=event.pull_request.head.sha)
52+
53+
logger.info("> Getting files")
54+
file = codebase.get_file("README.md")
55+
56+
# =====[ Create PR comment ]=====
57+
create_pr_comment(codebase, event.pull_request.number, f"File content:\n```python\n{file.content}\n```")
58+
59+
return {"message": "PR event handled", "num_files": len(codebase.files), "num_functions": len(codebase.functions)}
60+
61+
62+
@cg.linear.event("Issue")
63+
def handle_issue(event: LinearEvent):
64+
logger.info(f"Issue created: {event}")
65+
codebase = cg.get_codebase("codegen-sh/Kevin-s-Adventure-Game")
66+
return {"message": "Linear Issue event", "num_files": len(codebase.files), "num_functions": len(codebase.functions)}
67+
68+
69+
########################################################################################################################
70+
# MODAL DEPLOYMENT
71+
########################################################################################################################
72+
# This deploys the FastAPI app to Modal
73+
# TODO: link this up with memory snapshotting.
74+
75+
# For deploying local package
76+
REPO_URL = "https://github.com/codegen-sh/codegen-sdk.git"
77+
COMMIT_ID = "26dafad2c319968e14b90806d42c6c7aaa627bb0"
78+
79+
# Create the base image with dependencies
80+
base_image = (
81+
modal.Image.debian_slim(python_version="3.13")
82+
.apt_install("git")
83+
.pip_install(
84+
# =====[ Codegen ]=====
85+
# "codegen",
86+
f"git+{REPO_URL}@{COMMIT_ID}",
87+
# =====[ Rest ]=====
88+
"openai>=1.1.0",
89+
"fastapi[standard]",
90+
"slack_sdk",
91+
)
92+
)
93+
94+
app = modal.App("codegen-test")
95+
96+
97+
@app.function(image=base_image, secrets=[modal.Secret.from_dotenv()])
98+
@modal.asgi_app()
99+
def fastapi_app():
100+
return cg.app

docs/tutorials/build-code-agent.mdx

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,18 @@ agent.run("Tell me about this repo")
2222

2323
The agent has access to powerful code viewing and manipulation tools powered by Codegen, including:
2424
- `ViewFileTool`: View contents and metadata of files
25-
- `SemanticSearchTool`: Search over code using natural language queries
2625
- `SemanticEditTool`: Make intelligent edits to files
2726
- `RevealSymbolTool`: Analyze symbol dependencies and usages
2827
- `MoveSymbolTool`: Move symbols between files with import handling
29-
- And many more...
28+
- `ReplacementEditTool`: Make regex-based replacement editing on files
29+
- `ListDirectoryTool`: List directory contents
30+
- `SearchTool`: Search for files and symbols
31+
- `CreateFileTool`: Create new files
32+
- `DeleteFileTool`: Delete files
33+
- `RenameFileTool`: Rename files
34+
- `EditFileTool`: Edit files
35+
36+
3037

3138
<Info>View the full code for the default tools and agent implementation in our [examples repository](https://github.com/codegen-sh/codegen-sdk/tree/develop/src/codegen/extensions/langchain/tools)</Info>
3239

@@ -48,7 +55,7 @@ agent.run("Tell me about this repo")
4855
```
4956

5057

51-
<Note>Your `ANTHROPIC_API_KEY` and/or `OPENAI_API_KEY` must be set in your env.</Note>
58+
<Note>Your `ANTHROPIC_API_KEY` must be set in your env.</Note>
5259

5360
The default implementation uses `anthropic/claude-3-5-sonnet-latest` for the model but this can be changed through the `model_provider` and `model_name` arguments.
5461

@@ -60,22 +67,25 @@ agent = CodeAgent(
6067
)
6168
```
6269

70+
<Note>If using a non-default model provider, make sure to set the appropriate API key (e.g., `OPENAI_API_KEY` for OpenAI models) in your env.</Note>
71+
6372
# Available Tools
6473

6574
The agent comes with a comprehensive set of tools for code analysis and manipulation. Here are some key tools:
6675

6776
```python
6877
from codegen.extensions.langchain.tools import (
69-
ViewFileTool,
70-
SemanticSearchTool,
71-
SemanticEditTool,
72-
RevealSymbolTool,
73-
MoveSymbolTool,
74-
EditFileTool,
7578
CreateFileTool,
7679
DeleteFileTool,
80+
EditFileTool,
7781
ListDirectoryTool,
82+
MoveSymbolTool,
83+
RenameFileTool,
84+
ReplacementEditTool,
85+
RevealSymbolTool,
7886
SearchTool,
87+
SemanticEditTool,
88+
ViewFileTool,
7989
)
8090
```
8191

@@ -170,5 +180,5 @@ class CustomCodeTool(BaseTool):
170180

171181
# Add custom tool to agent
172182
tools.append(CustomCodeTool())
173-
agent = CodebaseAgent(codebase, tools=tools, model_name="gpt-4o")
183+
agent = CodebaseAgent(codebase, tools=tools, model_name="claude-3-5-sonnet-latest")
174184
```

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ dependencies = [
7171
"slack-sdk",
7272
"langchain-anthropic>=0.3.7",
7373
"lox>=0.12.0",
74+
"httpx>=0.28.1",
7475
]
7576

7677
license = { text = "Apache-2.0" }

src/codegen/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
from codegen.agents.code_agent import CodeAgent
22
from codegen.cli.sdk.decorator import function
33
from codegen.cli.sdk.functions import Function
4+
from codegen.extensions.events.codegen_app import CodegenApp
45

56
# from codegen.extensions.index.file_index import FileIndex
67
# from codegen.extensions.langchain.agent import create_agent_with_tools, create_codebase_agent
78
from codegen.sdk.core.codebase import Codebase
89
from codegen.shared.enums.programming_language import ProgrammingLanguage
910

10-
__all__ = ["CodeAgent", "Codebase", "Function", "ProgrammingLanguage", "function"]
11+
__all__ = ["CodeAgent", "Codebase", "CodegenApp", "Function", "ProgrammingLanguage", "function"]

src/codegen/cli/cli.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from codegen.cli.commands.reset.main import reset_command
1717
from codegen.cli.commands.run.main import run_command
1818
from codegen.cli.commands.run_on_pr.main import run_on_pr_command
19+
from codegen.cli.commands.serve.main import serve_command
1920
from codegen.cli.commands.start.main import start_command
2021
from codegen.cli.commands.style_debug.main import style_debug_command
2122
from codegen.cli.commands.update.main import update_command
@@ -48,6 +49,7 @@ def main():
4849
main.add_command(update_command)
4950
main.add_command(config_command)
5051
main.add_command(lsp_command)
52+
main.add_command(serve_command)
5153
main.add_command(start_command)
5254

5355

src/codegen/cli/commands/create/main.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,17 @@ def make_relative(path: Path) -> str:
6868
@click.command(name="create")
6969
@requires_init
7070
@click.argument("name", type=str)
71-
@click.argument("path", type=click.Path(path_type=Path), default=Path.cwd())
71+
@click.argument("path", type=click.Path(path_type=Path), default=None)
7272
@click.option("--description", "-d", default=None, help="Description of what this codemod does.")
7373
@click.option("--overwrite", is_flag=True, help="Overwrites function if it already exists.")
74-
def create_command(session: CodegenSession, name: str, path: Path, description: str | None = None, overwrite: bool = False):
74+
def create_command(session: CodegenSession, name: str, path: Path | None, description: str | None = None, overwrite: bool = False):
7575
"""Create a new codegen function.
7676
7777
NAME is the name/label for the function
7878
PATH is where to create the function (default: current directory)
7979
"""
8080
# Get the target path for the function
81-
codemod_path, prompt_path = get_target_paths(name, path)
81+
codemod_path, prompt_path = get_target_paths(name, path or Path.cwd())
8282

8383
# Check if file exists
8484
if codemod_path.exists() and not overwrite:

0 commit comments

Comments
 (0)