30
30
from codegen .sdk ._proxy import proxy_property
31
31
from codegen .sdk .ai .client import get_openai_client
32
32
from codegen .sdk .codebase .codebase_ai import generate_system_prompt , generate_tools
33
- from codegen .sdk .codebase .codebase_context import GLOBAL_FILE_IGNORE_LIST , CodebaseContext
33
+ from codegen .sdk .codebase .codebase_context import (
34
+ GLOBAL_FILE_IGNORE_LIST ,
35
+ CodebaseContext ,
36
+ )
34
37
from codegen .sdk .codebase .config import ProjectConfig , SessionOptions
35
38
from codegen .sdk .codebase .diff_lite import DiffLite
36
39
from codegen .sdk .codebase .flagging .code_flag import CodeFlag
110
113
111
114
112
115
@apidoc
113
- class Codebase (Generic [TSourceFile , TDirectory , TSymbol , TClass , TFunction , TImport , TGlobalVar , TInterface , TTypeAlias , TParameter , TCodeBlock ]):
116
+ class Codebase (
117
+ Generic [
118
+ TSourceFile ,
119
+ TDirectory ,
120
+ TSymbol ,
121
+ TClass ,
122
+ TFunction ,
123
+ TImport ,
124
+ TGlobalVar ,
125
+ TInterface ,
126
+ TTypeAlias ,
127
+ TParameter ,
128
+ TCodeBlock ,
129
+ ]
130
+ ):
114
131
"""This class provides the main entrypoint for most programs to analyzing and manipulating codebases.
115
132
116
133
Attributes:
@@ -180,7 +197,10 @@ def __init__(
180
197
181
198
# Initialize project with repo_path if projects is None
182
199
if repo_path is not None :
183
- main_project = ProjectConfig .from_path (repo_path , programming_language = ProgrammingLanguage (language .upper ()) if language else None )
200
+ main_project = ProjectConfig .from_path (
201
+ repo_path ,
202
+ programming_language = ProgrammingLanguage (language .upper ()) if language else None ,
203
+ )
184
204
projects = [main_project ]
185
205
else :
186
206
main_project = projects [0 ]
@@ -286,7 +306,10 @@ def files(self, *, extensions: list[str] | Literal["*"] | None = None) -> list[T
286
306
else :
287
307
files = []
288
308
# Get all files with the specified extensions
289
- for filepath , _ in self ._op .iter_files (extensions = None if extensions == "*" else extensions , ignore_list = GLOBAL_FILE_IGNORE_LIST ):
309
+ for filepath , _ in self ._op .iter_files (
310
+ extensions = None if extensions == "*" else extensions ,
311
+ ignore_list = GLOBAL_FILE_IGNORE_LIST ,
312
+ ):
290
313
files .append (self .get_file (filepath , optional = False ))
291
314
# Sort files alphabetically
292
315
return sort_editables (files , alphabetical = True , dedupe = False )
@@ -298,9 +321,12 @@ def codeowners(self) -> list["CodeOwner[TSourceFile]"]:
298
321
Returns:
299
322
list[CodeOwners]: A list of CodeOwners objects in the codebase.
300
323
"""
301
- if self .G .codeowners_parser is None :
324
+ if self .ctx .codeowners_parser is None :
302
325
return []
303
- return CodeOwner .from_parser (self .G .codeowners_parser , lambda * args , ** kwargs : self .files (* args , ** kwargs ))
326
+ return CodeOwner .from_parser (
327
+ self .ctx .codeowners_parser ,
328
+ lambda * args , ** kwargs : self .files (* args , ** kwargs ),
329
+ )
304
330
305
331
@property
306
332
def directories (self ) -> list [TDirectory ]:
@@ -814,7 +840,14 @@ def reset(self, git_reset: bool = False) -> None:
814
840
self .reset_logs ()
815
841
self .ctx .undo_applied_diffs ()
816
842
817
- def checkout (self , * , commit : str | GitCommit | None = None , branch : str | None = None , create_if_missing : bool = False , remote : bool = False ) -> CheckoutResult :
843
+ def checkout (
844
+ self ,
845
+ * ,
846
+ commit : str | GitCommit | None = None ,
847
+ branch : str | None = None ,
848
+ create_if_missing : bool = False ,
849
+ remote : bool = False ,
850
+ ) -> CheckoutResult :
818
851
"""Checks out a git branch or commit and syncs the codebase graph to the new state.
819
852
820
853
This method discards any pending changes, performs a git checkout of the specified branch or commit,
@@ -939,7 +972,12 @@ def create_pr(self, title: str, body: str) -> PullRequest:
939
972
raise ValueError (msg )
940
973
self ._op .stage_and_commit_all_changes (message = title )
941
974
self ._op .push_changes ()
942
- return self ._op .remote_git_repo .create_pull (head_branch_name = self ._op .git_cli .active_branch .name , base_branch_name = self ._op .default_branch , title = title , body = body )
975
+ return self ._op .remote_git_repo .create_pull (
976
+ head_branch_name = self ._op .git_cli .active_branch .name ,
977
+ base_branch_name = self ._op .default_branch ,
978
+ title = title ,
979
+ body = body ,
980
+ )
943
981
944
982
####################################################################################################################
945
983
# GRAPH VISUALIZATION
@@ -1064,15 +1102,27 @@ def get_finalized_logs(self) -> str:
1064
1102
1065
1103
@contextmanager
1066
1104
@noapidoc
1067
- def session (self , sync_graph : bool = True , commit : bool = True , session_options : SessionOptions = SessionOptions ()) -> Generator [None , None , None ]:
1105
+ def session (
1106
+ self ,
1107
+ sync_graph : bool = True ,
1108
+ commit : bool = True ,
1109
+ session_options : SessionOptions = SessionOptions (),
1110
+ ) -> Generator [None , None , None ]:
1068
1111
with self .ctx .session (sync_graph = sync_graph , commit = commit , session_options = session_options ):
1069
1112
yield None
1070
1113
1071
1114
@noapidoc
1072
- def _enable_experimental_language_engine (self , async_start : bool = False , install_deps : bool = False , use_v8 : bool = False ) -> None :
1115
+ def _enable_experimental_language_engine (
1116
+ self ,
1117
+ async_start : bool = False ,
1118
+ install_deps : bool = False ,
1119
+ use_v8 : bool = False ,
1120
+ ) -> None :
1073
1121
"""Debug option to enable experimental language engine for the current codebase."""
1074
1122
if install_deps and not self .ctx .language_engine :
1075
- from codegen .sdk .core .external .dependency_manager import get_dependency_manager
1123
+ from codegen .sdk .core .external .dependency_manager import (
1124
+ get_dependency_manager ,
1125
+ )
1076
1126
1077
1127
logger .info ("Cold installing dependencies..." )
1078
1128
logger .info ("This may take a while for large repos..." )
@@ -1086,7 +1136,12 @@ def _enable_experimental_language_engine(self, async_start: bool = False, instal
1086
1136
1087
1137
logger .info ("Cold starting language engine..." )
1088
1138
logger .info ("This may take a while for large repos..." )
1089
- self .ctx .language_engine = get_language_engine (self .ctx .projects [0 ].programming_language , self .ctx , use_ts = True , use_v8 = use_v8 )
1139
+ self .ctx .language_engine = get_language_engine (
1140
+ self .ctx .projects [0 ].programming_language ,
1141
+ self .ctx ,
1142
+ use_ts = True ,
1143
+ use_v8 = use_v8 ,
1144
+ )
1090
1145
self .ctx .language_engine .start (async_start = async_start )
1091
1146
# Wait for the language engine to be ready
1092
1147
self .ctx .language_engine .wait_until_ready (ignore_error = False )
@@ -1112,7 +1167,13 @@ def ai_client(self) -> OpenAI:
1112
1167
self ._ai_helper = get_openai_client (key = self .ctx .secrets .openai_api_key )
1113
1168
return self ._ai_helper
1114
1169
1115
- def ai (self , prompt : str , target : Editable | None = None , context : Editable | list [Editable ] | dict [str , Editable | list [Editable ]] | None = None , model : str = "gpt-4o" ) -> str :
1170
+ def ai (
1171
+ self ,
1172
+ prompt : str ,
1173
+ target : Editable | None = None ,
1174
+ context : Editable | list [Editable ] | dict [str , Editable | list [Editable ]] | None = None ,
1175
+ model : str = "gpt-4o" ,
1176
+ ) -> str :
1116
1177
"""Generates a response from the AI based on the provided prompt, target, and context.
1117
1178
1118
1179
A method that sends a prompt to the AI client along with optional target and context information to generate a response.
@@ -1139,7 +1200,10 @@ def ai(self, prompt: str, target: Editable | None = None, context: Editable | li
1139
1200
raise MaxAIRequestsError (msg , threshold = self .ctx .session_options .max_ai_requests )
1140
1201
1141
1202
params = {
1142
- "messages" : [{"role" : "system" , "content" : generate_system_prompt (target , context )}, {"role" : "user" , "content" : prompt }],
1203
+ "messages" : [
1204
+ {"role" : "system" , "content" : generate_system_prompt (target , context )},
1205
+ {"role" : "user" , "content" : prompt },
1206
+ ],
1143
1207
"model" : model ,
1144
1208
"functions" : generate_tools (),
1145
1209
"temperature" : 0 ,
@@ -1293,7 +1357,10 @@ def from_repo(
1293
1357
1294
1358
# Initialize and return codebase with proper context
1295
1359
logger .info ("Initializing Codebase..." )
1296
- project = ProjectConfig .from_repo_operator (repo_operator = repo_operator , programming_language = ProgrammingLanguage (language .upper ()) if language else None )
1360
+ project = ProjectConfig .from_repo_operator (
1361
+ repo_operator = repo_operator ,
1362
+ programming_language = ProgrammingLanguage (language .upper ()) if language else None ,
1363
+ )
1297
1364
codebase = Codebase (projects = [project ], config = config , secrets = secrets )
1298
1365
logger .info ("Codebase initialization complete" )
1299
1366
return codebase
@@ -1442,7 +1509,16 @@ def create_pr_comment(self, pr_number: int, body: str) -> None:
1442
1509
"""Create a comment on a pull request"""
1443
1510
return self ._op .create_pr_comment (pr_number , body )
1444
1511
1445
- def create_pr_review_comment (self , pr_number : int , body : str , commit_sha : str , path : str , line : int | None = None , side : str = "RIGHT" , start_line : int | None = None ) -> None :
1512
+ def create_pr_review_comment (
1513
+ self ,
1514
+ pr_number : int ,
1515
+ body : str ,
1516
+ commit_sha : str ,
1517
+ path : str ,
1518
+ line : int | None = None ,
1519
+ side : str = "RIGHT" ,
1520
+ start_line : int | None = None ,
1521
+ ) -> None :
1446
1522
"""Create a review comment on a pull request.
1447
1523
1448
1524
Args:
@@ -1462,6 +1538,42 @@ def create_pr_review_comment(self, pr_number: int, body: str, commit_sha: str, p
1462
1538
1463
1539
# The last 2 lines of code are added to the runner. See codegen-backend/cli/generate/utils.py
1464
1540
# Type Aliases
1465
- CodebaseType = Codebase [SourceFile , Directory , Symbol , Class , Function , Import , Assignment , Interface , TypeAlias , Parameter , CodeBlock ]
1466
- PyCodebaseType = Codebase [PyFile , PyDirectory , PySymbol , PyClass , PyFunction , PyImport , PyAssignment , Interface , TypeAlias , PyParameter , PyCodeBlock ]
1467
- TSCodebaseType = Codebase [TSFile , TSDirectory , TSSymbol , TSClass , TSFunction , TSImport , TSAssignment , TSInterface , TSTypeAlias , TSParameter , TSCodeBlock ]
1541
+ CodebaseType = Codebase [
1542
+ SourceFile ,
1543
+ Directory ,
1544
+ Symbol ,
1545
+ Class ,
1546
+ Function ,
1547
+ Import ,
1548
+ Assignment ,
1549
+ Interface ,
1550
+ TypeAlias ,
1551
+ Parameter ,
1552
+ CodeBlock ,
1553
+ ]
1554
+ PyCodebaseType = Codebase [
1555
+ PyFile ,
1556
+ PyDirectory ,
1557
+ PySymbol ,
1558
+ PyClass ,
1559
+ PyFunction ,
1560
+ PyImport ,
1561
+ PyAssignment ,
1562
+ Interface ,
1563
+ TypeAlias ,
1564
+ PyParameter ,
1565
+ PyCodeBlock ,
1566
+ ]
1567
+ TSCodebaseType = Codebase [
1568
+ TSFile ,
1569
+ TSDirectory ,
1570
+ TSSymbol ,
1571
+ TSClass ,
1572
+ TSFunction ,
1573
+ TSImport ,
1574
+ TSAssignment ,
1575
+ TSInterface ,
1576
+ TSTypeAlias ,
1577
+ TSParameter ,
1578
+ TSCodeBlock ,
1579
+ ]
0 commit comments