Skip to content

Commit 3017bf3

Browse files
committed
Code comments
1 parent c73e2eb commit 3017bf3

4 files changed

Lines changed: 104 additions & 11 deletions

File tree

backend/agent/coding_agent.py

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
# import os
2+
"""
3+
This Python module defines the classes and functions used by the coding agent in the backend of an application. The coding agent is responsible for interacting with various components such as the database, memory management system, and external APIs to facilitate code generation, manipulation, and management tasks. It utilizes models for code generation, applies AST (Abstract Syntax Tree) operations to modify code, and manages the working context and system prompts for the user. Additionally, it handles the execution of generated code operations and integrates with external services like OpenAI and AWS for enhanced functionality.
4+
"""
5+
26
import re
37
import json
48
import boto3
@@ -37,6 +41,7 @@ class NestedNamespace(SimpleNamespace):
3741
"""
3842
A class to convert a dictionary into a nested namespace.
3943
"""
44+
4045
def __init__(self, dictionary, **kwargs):
4146
if not isinstance(dictionary, dict):
4247
raise ValueError("Input must be a dictionary")
@@ -85,7 +90,7 @@ def __init__(
8590

8691
self.memory_manager = memory_manager
8792
self.function_map = function_map
88-
self.GPT_MODEL = 'gpt-4-0125-preview'
93+
self.GPT_MODEL = "gpt-4-0125-preview"
8994
self.codebase = codebase
9095
self.max_tokens = 4000
9196
self.temperature = 0.75
@@ -200,6 +205,20 @@ def query(self, input: str, command: Optional[str] = None) -> List[str]:
200205
yield chunk.choices[0].delta.content
201206

202207
def execute_ops(self, ops: List[dict]):
208+
"""
209+
Executes the operations stored in the `ops_to_execute` list.
210+
211+
This method iterates over each operation in `ops_to_execute`, applying the necessary changes to the
212+
corresponding file. It handles file path normalization, reads the original code, applies the AST changes,
213+
computes the diff between the original and transformed code, and finally writes the transformed code back to the file.
214+
It accumulates and returns a list of diffs for each operation.
215+
216+
Args:
217+
ops (List[dict]): A list of operations to be executed.
218+
219+
Returns:
220+
List[str]: A list of unified diff strings representing the changes made to each file.
221+
"""
203222
diffs = [] # List to store the diffs for each operation
204223

205224
for op in self.ops_to_execute:
@@ -279,6 +298,17 @@ def process_json(self, args: str) -> str:
279298
return json.loads(response_str)
280299

281300
def call_model_streaming(self, command: Optional[str] | None = None, **kwargs):
301+
if command:
302+
kwargs["prompt"] = command
303+
else:
304+
kwargs["prompt"] = "Please generate code based on the provided context."
305+
306+
kwargs["stream"] = True
307+
kwargs["max_tokens"] = kwargs.get("max_tokens", 256)
308+
kwargs["temperature"] = kwargs.get("temperature", 0.5)
309+
310+
if "model" not in kwargs:
311+
raise ValueError("Model not specified in kwargs")
282312
print("Calling model streaming")
283313
print(kwargs["model"])
284314
if self.GPT_MODEL.startswith("gpt"):
@@ -296,7 +326,6 @@ def call_model_streaming(self, command: Optional[str] | None = None, **kwargs):
296326
modelId="anthropic.claude-3-sonnet-20240229-v1:0",
297327
body=json.dumps(
298328
{
299-
300329
"messages": kwargs["messages"][1:],
301330
"system": self.generate_anthropic_prompt(sys_only=True),
302331
"max_tokens": max(kwargs["max_tokens"], 2000),
@@ -345,7 +374,9 @@ def call_model_streaming(self, command: Optional[str] | None = None, **kwargs):
345374
print("UnboundLocalError")
346375
break
347376

348-
def generate_anthropic_prompt(self, include_messages: Optional[bool]=True, sys_only: Optional[bool]=None) -> str:
377+
def generate_anthropic_prompt(
378+
self, include_messages: Optional[bool] = True, sys_only: Optional[bool] = None
379+
) -> str:
349380
"""
350381
Generates a prompt for the Gaive model.
351382
@@ -409,7 +440,7 @@ def generate_anthropic_prompt(self, include_messages: Optional[bool]=True, sys_o
409440

410441
if sys_only:
411442
return sys_prompt
412-
443+
413444
return (
414445
"\n\nHuman: The folllowing is your system prompt: "
415446
+ sys_prompt
@@ -421,6 +452,15 @@ def generate_anthropic_prompt(self, include_messages: Optional[bool]=True, sys_o
421452

422453
@staticmethod
423454
def normalize_path(input_path):
455+
"""
456+
Normalizes a path to be relative to the current working directory.
457+
458+
Args:
459+
input_path (str): The path to normalize.
460+
461+
Returns:
462+
str: The normalized path.
463+
"""
424464
# Get the current working directory as a Path object
425465
working_directory = Path.cwd()
426466

backend/database/my_codebase.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
"""
2+
This module defines the MyCodebase class, which is responsible for managing the database operations related to codebase management. It includes functionalities such as initializing the database connection, setting up the directory to scan for code, creating necessary database tables, updating files and embeddings, and removing old files from the database. The class utilizes an external encoder (tiktoken) for encoding model specifics and interacts with the database to store and manage the codebase information efficiently.
3+
"""
4+
15
import os
26
import datetime
37
import tiktoken
@@ -97,6 +101,9 @@ def update_file(self, file_path: str) -> None:
97101
self.conn.commit()
98102

99103
def create_tables(self) -> None:
104+
"""
105+
Creates the necessary tables in the database if they don't exist.
106+
"""
100107
try:
101108
self.cur.execute(
102109
"""
@@ -127,6 +134,18 @@ def create_tables(self) -> None:
127134
print(f"Failed to create tables: {e}")
128135

129136
def tree(self) -> str:
137+
"""
138+
Generates a visual representation of the project's directory structure.
139+
140+
This method fetches the file paths and summaries from the database, constructs a tree
141+
structure representing the directory hierarchy, and then generates a string representation
142+
of this tree. Each node in the tree represents a directory or file, with directories containing
143+
nested dictionaries of their contents.
144+
145+
Returns:
146+
str: A string representation of the directory tree, with each node prefixed by "+--" and
147+
indented to represent its depth in the hierarchy.
148+
"""
130149
tree = {}
131150
start_from = os.path.basename(self.directory)
132151
print("Start from: ", start_from)

backend/memory/memory_manager.py

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
"""
2+
This module contains the implementation of the memory management system for the backend. It includes the `WorkingContext` class, which is responsible for managing the working context of the user, including the database connection, project directory, and interaction with the OpenAI API client. The module also handles the creation of necessary database tables and provides methods for managing the working context data within the database. Additionally, it integrates with other components such as the system prompt handler and the OpenAI API client to facilitate the generation and management of system prompts and responses.
3+
"""
4+
15
import tiktoken
26
from typing import Optional, List
37
from datetime import datetime
@@ -119,10 +123,6 @@ def execute(self, working_context: WorkingContext) -> None:
119123

120124

121125
class MemoryManager:
122-
# MemoryManager class manages interactions with the memory database
123-
# including initializing connections, creating tables, and
124-
# delegating to other classes that interact with the database.
125-
126126
def __init__(
127127
self,
128128
model: str = "gpt-3.5-turbo-16k",
@@ -163,6 +163,17 @@ def __init__(
163163
self.background_tasks = None
164164

165165
def get_messages(self, chat_box: Optional[bool] = None) -> List[dict]:
166+
"""
167+
Fetches messages from the system prompt table.
168+
169+
This method queries the system prompt table for messages, filtering based on the chat_box flag. If chat_box is True, it fetches messages with a higher token limit to accommodate more verbose interactions typical in a chat interface. Otherwise, it uses the default max_tokens limit defined for the system.
170+
171+
Args:
172+
chat_box (Optional[bool]): A flag indicating whether the messages are being fetched for a chat box interface. Defaults to None.
173+
174+
Returns:
175+
List[dict]: A list of dictionaries, each containing the role and content of a message.
176+
"""
166177
self.cur.execute(
167178
f"""
168179
SELECT role, content
@@ -218,7 +229,7 @@ def get_messages(self, chat_box: Optional[bool] = None) -> List[dict]:
218229
),
219230
)
220231
results = self.cur.fetchall()
221-
prev_role = 'assistant'
232+
prev_role = "assistant"
222233
for result in results[::-1]:
223234
if prev_role == result[0]:
224235
continue
@@ -235,6 +246,20 @@ def add_message(
235246
command: Optional[str] = None,
236247
function_response: Optional[str] = None,
237248
) -> None:
249+
"""
250+
Adds a message to the memory database.
251+
252+
This method inserts a new message into the memory database with the provided role, content, and optional command and function response. It also calculates the timestamp, the total number of tokens in the message, and optionally summarizes the message if the number of tokens exceeds a certain threshold.
253+
254+
Args:
255+
role (str): The role of the message sender (e.g., "user" or "assistant").
256+
content (str): The content of the message.
257+
command (Optional[str]): An optional command associated with the message.
258+
function_response (Optional[str]): An optional function response associated with the message.
259+
260+
Returns:
261+
None
262+
"""
238263
timestamp = datetime.now().isoformat()
239264
message_tokens = self.get_total_tokens_in_message(content)
240265
summary, summary_tokens = (
@@ -266,7 +291,15 @@ def add_message(
266291
return
267292

268293
def get_total_tokens_in_message(self, message: str) -> int:
269-
"""Returns the number of tokens in a message."""
294+
"""
295+
Calculates the total number of tokens in a given message using the tiktoken library.
296+
297+
Args:
298+
message (str): The message for which to calculate the total number of tokens.
299+
300+
Returns:
301+
int: The total number of tokens in the message.
302+
"""
270303
encoding = tiktoken.encoding_for_model("gpt-3.5-turbo")
271304
num_tokens = len(encoding.encode(message))
272305
return num_tokens

backend/memory/system_prompt_handler.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""
2-
Methods and CRUD operations for managing system prompts.
2+
This module contains classes and methods for handling system prompts and logging relevant information within the backend memory system. It includes a `RelevantLogHandler` class for managing logs relevant to the system's operation, focusing on error logs, and a `SystemPromptHandler` class for managing system prompts, including CRUD operations on system prompts stored in a database. These components are essential for maintaining a responsive and informed system environment, aiding in debugging and user interaction management.
33
"""
4+
45
from typing import Optional, Dict
56
import os
67
import logging

0 commit comments

Comments
 (0)