Skip to content

Commit e6efa7c

Browse files
feat(pipeline): implement LangGraph StateGraph engine & reflective critic repair loops
1 parent fc79ecc commit e6efa7c

7 files changed

Lines changed: 2368 additions & 41 deletions

File tree

‎codeslim/context/pruner.py‎

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ def leave_ImportFrom(
7171

7272

7373
class DocstringAndDeadCodeTransformer(cst.CSTTransformer):
74+
METADATA_DEPENDENCIES = (PositionProvider,)
7475

7576
def __init__(self, dead_code_lines: set[int], strip_docstrings: bool = True) -> None:
7677
super().__init__()
@@ -145,3 +146,84 @@ def leave_FunctionDef(
145146
return updated_node
146147

147148

149+
def prune_source_code(
150+
code: str,
151+
dead_code_lines: set[int] | None = None,
152+
strip_docstrings: bool = True,
153+
) -> str:
154+
"""
155+
Prune docstrings and dead code lines from Python source code using LibCST.
156+
157+
Args:
158+
code: Source code string to prune.
159+
dead_code_lines: Set of 1-indexed line numbers flagged as dead.
160+
strip_docstrings: If True, strip docstring statements.
161+
162+
Returns:
163+
Pruned source code string.
164+
"""
165+
if not code.strip():
166+
return code
167+
if dead_code_lines is None:
168+
dead_code_lines = set()
169+
try:
170+
wrapper = MetadataWrapper(cst.parse_module(code))
171+
transformer = DocstringAndDeadCodeTransformer(
172+
dead_code_lines=dead_code_lines,
173+
strip_docstrings=strip_docstrings,
174+
)
175+
modified_module = wrapper.visit(transformer)
176+
return modified_module.code
177+
except Exception as exc:
178+
err_msg = str(exc).encode("ascii", errors="replace").decode("ascii")
179+
log.warning("cst_pruning_failed", error=err_msg)
180+
return code
181+
182+
183+
def remove_dead_functions(code: str, dead_function_names: set[str]) -> str:
184+
"""
185+
Remove top-level unused function definitions from source code using LibCST.
186+
187+
Args:
188+
code: Target Python source code string.
189+
dead_function_names: Set of top-level function names to remove.
190+
191+
Returns:
192+
Source code with unused functions removed.
193+
"""
194+
if not code.strip() or not dead_function_names:
195+
return code
196+
try:
197+
module = cst.parse_module(code)
198+
transformer = RemoveDeadFunctionsTransformer(dead_function_names=dead_function_names)
199+
return module.visit(transformer).code
200+
except Exception as exc:
201+
err_msg = str(exc).encode("ascii", errors="replace").decode("ascii")
202+
log.warning("dead_function_removal_failed", error=err_msg)
203+
return code
204+
205+
206+
def remove_unused_imports(code: str, unused_names: set[str]) -> str:
207+
"""
208+
Remove unused import statements from Python source code using LibCST.
209+
210+
Args:
211+
code: Target Python source code string.
212+
unused_names: Set of symbol names flagged as unused.
213+
214+
Returns:
215+
Cleaned source code string.
216+
"""
217+
if not code.strip() or not unused_names:
218+
return code
219+
try:
220+
module = cst.parse_module(code)
221+
transformer = RemoveUnusedImportsTransformer(unused_names=unused_names)
222+
return module.visit(transformer).code
223+
except Exception as exc:
224+
err_msg = str(exc).encode("ascii", errors="replace").decode("ascii")
225+
log.warning("import_removal_failed", error=err_msg)
226+
return code
227+
228+
229+

‎codeslim/pipeline/critic.py‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""
2+
Reflective Critic Repair Node for CodeSlim StateGraph.
3+
4+
Intercepts ASTInvariantGate safety failures, constructs targeted feedback prompts with exact
5+
AST error tracebacks, and increments retry counter up to max ceiling (max_retries = 2).
6+
"""
7+
8+
from __future__ import annotations
9+
10+
from typing import TYPE_CHECKING, Any
11+
12+
if TYPE_CHECKING:
13+
from codeslim.pipeline.graph import PipelineState
14+
15+
from codeslim.utils.logger import get_logger
16+
17+
logger = get_logger(__name__)
18+
19+
20+
async def reflective_critic_node(state: PipelineState) -> dict[str, Any]:
21+
"""Intercepts AST validation failures, records feedback trace, and increments retry counter."""
22+
retry_count = state.get("retry_count", 0) + 1
23+
ast_errors = state.get("ast_errors", [])
24+
latest_error = ast_errors[-1] if ast_errors else "Unknown AST invariant violation."
25+
26+
logger.info(
27+
"reflective_critic_retry_triggered",
28+
attempt=retry_count,
29+
error=latest_error,
30+
)
31+
32+
return {
33+
"retry_count": retry_count,
34+
"stages_completed": ["critic_node"],
35+
}

0 commit comments

Comments
 (0)