Skip to content

Commit c408c6a

Browse files
committed
Merge branch 'develop' into tawsif/fix-imports
2 parents 974ccd5 + 3e2e6e1 commit c408c6a

File tree

23 files changed

+1778
-324
lines changed

23 files changed

+1778
-324
lines changed

.codegen/.gitignore

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,8 @@ jupyter/
88
codegen-system-prompt.txt
99

1010
# Python cache files
11-
__pycache__/
11+
**/__pycache__/
1212
*.py[cod]
1313
*$py.class
1414
*.txt
1515
*.pyc
16-
17-
# Keep codemods
18-
!codemods/
19-
!codemods/**

.codegen/codemods/no_link_backticks/no_link_backticks.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from codegen import Codebase
33

44

5-
@codegen.function("no-link-backticks")
5+
@codegen.function(name="no-link-backticks", subdirectories=["test/unit"])
66
def run(codebase: Codebase):
77
import re
88

@@ -12,6 +12,7 @@ def run(codebase: Codebase):
1212
# Iterate over all .mdx files in the codebase
1313
for file in codebase.files(extensions=["mdx"]):
1414
if file.extension == ".mdx":
15+
print(f"Processing {file.path}")
1516
new_content = file.content
1617

1718
# Find all markdown links with backticks in link text

.github/workflows/generate-docs.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,14 @@ jobs:
2424
- name: Generate API reference
2525
run: uv run python src/codegen/gscli/cli.py generate docs
2626

27+
- name: Generate System Prompt
28+
run: uv run python src/codegen/gscli/cli.py generate system-prompt
29+
2730
- name: Commit changes
2831
run: |
2932
git config --local user.email ${{ secrets.DOCS_USER_EMAIL }}
3033
git config --local user.name ${{ secrets.DOCS_USER_NAME }}
31-
git add docs/
34+
git add docs/ src/codegen/sdk/system-prompt.txt
3235
git diff --staged --quiet || git commit -m "docs: updated API reference"
3336
3437
- name: Push changes

.github/workflows/test.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ jobs:
2323
unit-tests:
2424
needs: access-check
2525
runs-on: ubuntu-latest-8
26-
environment: testing
2726
steps:
2827
- uses: actions/checkout@v4
2928
with:
@@ -48,7 +47,6 @@ jobs:
4847
# TODO: re-enable when this check is a develop required check
4948
if: false
5049
runs-on: ubuntu-latest-32
51-
environment: testing
5250
strategy:
5351
matrix:
5452
sync_graph: [ true, false ]
@@ -90,7 +88,6 @@ jobs:
9088
needs: access-check
9189
if: contains(github.event.pull_request.labels.*.name, 'parse-tests') || github.event_name == 'push' || github.event_name == 'workflow_dispatch'
9290
runs-on: ubuntu-latest-32
93-
environment: testing
9491
steps:
9592
- uses: actions/checkout@v4
9693
with:
@@ -161,7 +158,6 @@ jobs:
161158
integration-tests:
162159
needs: access-check
163160
runs-on: ubuntu-latest-16
164-
environment: testing
165161
steps:
166162
- uses: actions/checkout@v4
167163
with:

codegen-examples/examples/swebench_agent_run/.env.template

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ OPENAI_API_KEY= # Your OpenAI API key
22
ANTHROPIC_API_KEY= # Your Anthropic API key
33
LANGSMITH_API_KEY= # Your Langsmith API key
44
LANGCHAIN_TRACING_V2= # `true` for tracing, `false` for no tracing
5+
LANGCHAIN_PROJECT= # Your Langchain project
6+
RELACE_API= # Your Relace API key

codegen-examples/examples/swebench_agent_run/entry_point.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
from codegen.extensions.swebench.utils import SweBenchExample
22
from codegen.extensions.swebench.harness import run_agent_on_entry
33
import modal
4+
import sys
5+
from codegen.sdk.core.codebase import Codebase
46

57
image = (
68
modal.Image.debian_slim(python_version="3.13")
7-
.apt_install("git")
9+
.apt_install(["git", "ripgrep"])
810
.pip_install("fastapi[standard]")
911
.copy_local_dir("../../../", "/root/codegen", ignore=[".venv", "**/.venv", "tests", "**/tests"])
1012
.run_commands("pip install -e /root/codegen")
@@ -17,3 +19,22 @@
1719
async def run_agent_modal(entry: SweBenchExample):
1820
"""Modal function to process a single example from the SWE-bench dataset."""
1921
return run_agent_on_entry(entry)
22+
23+
24+
@app.cls(image=image, secrets=[modal.Secret.from_dotenv()], enable_memory_snapshot=True)
25+
class SwebenchAgentRun:
26+
repo_full_name: str = modal.parameter()
27+
commit: str = modal.parameter()
28+
codebase: Codebase | None = None
29+
30+
@modal.enter(snap=True)
31+
def load(self):
32+
self.codebase = Codebase.from_repo(repo_full_name=self.repo_full_name, commit=self.commit, language="python")
33+
34+
@modal.exit()
35+
def exit(self):
36+
sys.exit(0)
37+
38+
@modal.method()
39+
async def run(self, entry: SweBenchExample):
40+
return run_agent_on_entry(entry, codebase=self.codebase)

codegen-examples/examples/swebench_agent_run/run_eval.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@
66
import modal
77
import click
88
from datetime import datetime
9-
from codegen.extensions.swebench.utils import SWEBenchDataset, get_swe_bench_example, get_swe_bench_examples
9+
from codegen.extensions.swebench.utils import SWEBenchDataset, SweBenchExample, get_swe_bench_example, get_swe_bench_examples
1010
from codegen.extensions.swebench.report import generate_report
1111

1212
PREDS_DNAME = Path(__file__).parent / "predictions"
1313
LOG_DIR = Path(__file__).parent / "logs"
1414

15-
run_agent_modal = modal.Function.lookup("swebench-agent-run", "run_agent_modal")
15+
SwebenchAgentRun = modal.Cls.from_name(app_name="swebench-agent-run", name="SwebenchAgentRun")
1616

1717

18-
async def process_batch(examples, batch_size=10):
18+
async def process_batch(examples: list[SweBenchExample], batch_size=10):
1919
"""Process a batch of examples concurrently.
2020
2121
Args:
@@ -31,7 +31,7 @@ async def process_batch(examples, batch_size=10):
3131
batch = examples[i : i + batch_size]
3232

3333
# Create tasks for this batch
34-
batch_tasks = [run_agent_modal.remote.aio(example) for example in batch]
34+
batch_tasks = [SwebenchAgentRun(repo_full_name=example.repo, commit=example.base_commit).run.remote.aio(example) for example in batch]
3535

3636
# Wait for all tasks in this batch to complete
3737
print(f"Processing batch {i // batch_size + 1}/{len(examples) // batch_size + 1} (examples {i + 1}-{min(i + batch_size, len(examples))})")
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from codegen import Codebase
2+
import modal
3+
4+
image = modal.Image.debian_slim(python_version="3.13").apt_install("git").pip_install("fastapi[standard]").run_commands("pip install codegen")
5+
6+
app = modal.App(name="codegen-examples", image=image, secrets=[modal.Secret.from_dotenv()])
7+
8+
9+
@app.function()
10+
def run_agent(AgentClass):
11+
codebase = Codebase.from_repo(repo_full_name="pallets/flask")
12+
agent = AgentClass(codebase)
13+
agent.run(prompt="Tell me about the codebase and the files in it.")
14+
return True

docs/changelog/changelog.mdx

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,74 @@ icon: "clock"
44
iconType: "solid"
55
---
66

7+
<Update label="v0.40.0" description="February 26, 2025">
8+
### [Adds Chat Agent and subdirectory support in codegen.](https://github.com/codegen-sh/codegen-sdk/releases/tag/v0.40.0)
9+
- Add functionality to specify subdirectories in `codegen.function`
10+
- Introduce a new Chat Agent
11+
</Update>
12+
13+
<Update label="v0.39.1" description="February 26, 2025">
14+
### [Custom codebase path setting for code generation.](https://github.com/codegen-sh/codegen-sdk/releases/tag/v0.39.1)
15+
- Allow setting custom codebase path in code generation
16+
</Update>
17+
18+
<Update label="v0.39.0" description="February 26, 2025">
19+
### [Lazy Graph Compute Mode and new agent run snapshots.](https://github.com/codegen-sh/codegen-sdk/releases/tag/v0.39.0)
20+
- Implement Lazy Graph Compute Mode
21+
- Add agent run snapshots feature
22+
- Update API reference documentation
23+
</Update>
24+
25+
<Update label="v0.38.0" description="February 26, 2025">
26+
### [Adds ripgrep search tool and updates API docs.](https://github.com/codegen-sh/codegen-sdk/releases/tag/v0.38.0)
27+
- Integrate ripgrep in search tool
28+
- Update API reference documentation
29+
</Update>
30+
31+
32+
<Update label="v0.37.1" description="February 26, 2025">
33+
### [Fixes linting issues.](https://github.com/codegen-sh/codegen-sdk/releases/tag/v0.37.1)
34+
- Fix linting issues
35+
</Update>
36+
37+
38+
<Update label="v0.37.0" description="February 26, 2025">
39+
### [Custom package resolving and error handling improvements.](https://github.com/codegen-sh/codegen-sdk/releases/tag/v0.37.0)
40+
- Allow custom overrides for package resolving
41+
- Add optional sys.path support
42+
- Improve error handling with linear tools
43+
- Fix wildcard resolution issues
44+
</Update>
45+
46+
47+
<Update label="v0.36.0" description="February 25, 2025">
48+
### [File Parse Mode disabled by default](https://github.com/codegen-sh/codegen-sdk/releases/tag/v0.36.0)
49+
- Disable File Parse Mode feature implemented
50+
</Update>
51+
52+
53+
<Update label="v0.35.0" description="February 25, 2025">
54+
### [Replaces edit tool and enhances test configurations.](https://github.com/codegen-sh/codegen-sdk/releases/tag/v0.35.0)
55+
- Replace edit tool with a new version
56+
- Enhance test configurations and execution
57+
</Update>
58+
59+
60+
<Update label="v0.34.0" description="February 24, 2025">
61+
### [Introduces Docker client and major refactor.](https://github.com/codegen-sh/codegen-sdk/releases/tag/v0.34.0)
62+
- Introduce Docker client feature
63+
- Refactor codebase directory structure
64+
- Implement heuristics-based minified file detection
65+
</Update>
66+
67+
68+
<Update label="v0.33.1" description="February 24, 2025">
69+
### [Improves GitHub Actions handling and fixes Docker issues.](https://github.com/codegen-sh/codegen-sdk/releases/tag/v0.33.1)
70+
- Improve GitHub Actions token and repo handling
71+
- Fix codegen Docker runner issues
72+
- Update agent documentation
73+
</Update>
74+
775
<Update label="v0.33.0" description="February 24, 2025">
876
### [Introduces CodegenApp and enhances codegen capabilities.](https://github.com/codegen-sh/codegen-sdk/releases/tag/v0.33.0)
977
- Introduce CodegenApp feature

src/codegen/agents/chat_agent.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
from typing import TYPE_CHECKING, Optional
2+
from uuid import uuid4
3+
4+
from langchain.tools import BaseTool
5+
from langchain_core.messages import AIMessage
6+
7+
from codegen.extensions.langchain.agent import create_chat_agent
8+
9+
if TYPE_CHECKING:
10+
from codegen import Codebase
11+
12+
13+
class ChatAgent:
14+
"""Agent for interacting with a codebase."""
15+
16+
def __init__(self, codebase: "Codebase", model_provider: str = "anthropic", model_name: str = "claude-3-5-sonnet-latest", memory: bool = True, tools: Optional[list[BaseTool]] = None, **kwargs):
17+
"""Initialize a CodeAgent.
18+
19+
Args:
20+
codebase: The codebase to operate on
21+
model_provider: The model provider to use ("anthropic" or "openai")
22+
model_name: Name of the model to use
23+
memory: Whether to let LLM keep track of the conversation history
24+
tools: Additional tools to use
25+
**kwargs: Additional LLM configuration options. Supported options:
26+
- temperature: Temperature parameter (0-1)
27+
- top_p: Top-p sampling parameter (0-1)
28+
- top_k: Top-k sampling parameter (>= 1)
29+
- max_tokens: Maximum number of tokens to generate
30+
"""
31+
self.codebase = codebase
32+
self.agent = create_chat_agent(self.codebase, model_provider=model_provider, model_name=model_name, memory=memory, additional_tools=tools, **kwargs)
33+
34+
def run(self, prompt: str, thread_id: Optional[str] = None) -> str:
35+
"""Run the agent with a prompt.
36+
37+
Args:
38+
prompt: The prompt to run
39+
thread_id: Optional thread ID for message history. If None, a new thread is created.
40+
41+
Returns:
42+
The agent's response
43+
"""
44+
if thread_id is None:
45+
thread_id = str(uuid4())
46+
47+
input = {"messages": [("user", prompt)]}
48+
stream = self.agent.stream(input, config={"configurable": {"thread_id": thread_id}}, stream_mode="values")
49+
50+
for s in stream:
51+
message = s["messages"][-1]
52+
if isinstance(message, tuple):
53+
print(message)
54+
else:
55+
if isinstance(message, AIMessage) and isinstance(message.content, list) and "text" in message.content[0]:
56+
AIMessage(message.content[0]["text"]).pretty_print()
57+
else:
58+
message.pretty_print()
59+
60+
return s["messages"][-1].content
61+
62+
def chat(self, prompt: str, thread_id: Optional[str] = None) -> tuple[str, str]:
63+
"""Chat with the agent, maintaining conversation history.
64+
65+
Args:
66+
prompt: The user message
67+
thread_id: Optional thread ID for message history. If None, a new thread is created.
68+
69+
Returns:
70+
A tuple of (response_content, thread_id) to allow continued conversation
71+
"""
72+
if thread_id is None:
73+
thread_id = str(uuid4())
74+
print(f"Starting new chat thread: {thread_id}")
75+
else:
76+
print(f"Continuing chat thread: {thread_id}")
77+
78+
response = self.run(prompt, thread_id=thread_id)
79+
return response, thread_id
80+
81+
def get_chat_history(self, thread_id: str) -> list:
82+
"""Retrieve the chat history for a specific thread.
83+
84+
Args:
85+
thread_id: The thread ID to retrieve history for
86+
87+
Returns:
88+
List of messages in the conversation history
89+
"""
90+
# Access the agent's memory to get conversation history
91+
if hasattr(self.agent, "get_state"):
92+
state = self.agent.get_state({"configurable": {"thread_id": thread_id}})
93+
if state and "messages" in state:
94+
return state["messages"]
95+
return []

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,16 @@ def list_command():
1717
table.add_column("Name", style="cyan")
1818
table.add_column("Type", style="magenta")
1919
table.add_column("Path", style="dim")
20+
table.add_column("Subdirectories", style="dim")
2021

2122
for func in functions:
2223
func_type = "Webhook" if func.lint_mode else "Function"
23-
table.add_row(func.name, func_type, str(func.filepath.relative_to(Path.cwd())) if func.filepath else "<unknown>")
24+
table.add_row(
25+
func.name,
26+
func_type,
27+
str(func.filepath.relative_to(Path.cwd())) if func.filepath else "<unknown>",
28+
", ".join(func.subdirectories) if func.subdirectories else "",
29+
)
2430

2531
rich.print(table)
2632
rich.print("\nRun a function with:")

0 commit comments

Comments
 (0)