Skip to content

Commit f7057fc

Browse files
author
dori
committed
feat: improve memory cleanup when plan approve
1 parent 7a636d9 commit f7057fc

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

src/mcp_as_a_judge/db/interface.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,19 @@ async def get_recent_sessions(self, limit: int = 10) -> list[tuple[str, int]]:
7878
List of tuples: (session_id, last_activity_timestamp), ordered by most recent first
7979
"""
8080
pass
81+
82+
@abstractmethod
83+
async def delete_previous_plan(self, session_id: str) -> int:
84+
"""
85+
Delete all previous judge_coding_plan records except the most recent one.
86+
87+
This method removes all but the last conversation record with source='judge_coding_plan'
88+
for the given session to avoid keeping multiple failed plan attempts.
89+
90+
Args:
91+
session_id: Session identifier
92+
93+
Returns:
94+
Number of records deleted
95+
"""
96+
pass

src/mcp_as_a_judge/db/providers/sqlite_provider.py

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import time
99
import uuid
1010

11-
from sqlalchemy import create_engine, func
11+
from sqlalchemy import create_engine, delete, func
1212
from sqlmodel import Session, SQLModel, asc, desc, select
1313

1414
from mcp_as_a_judge.core.constants import MAX_CONTEXT_TOKENS
@@ -303,3 +303,46 @@ async def get_recent_sessions(self, limit: int = 10) -> list[tuple[str, int]]:
303303
results = session.exec(stmt).all()
304304
# results are tuples (session_id, last_activity)
305305
return [(row[0], int(row[1])) for row in results]
306+
307+
async def delete_previous_plan(self, session_id: str) -> int:
308+
"""
309+
Delete all previous judge_coding_plan records except the most recent one.
310+
311+
Uses SQL ORM to find all judge_coding_plan records for the session,
312+
keeps only the most recent one, and deletes the rest.
313+
"""
314+
with Session(self.engine) as session:
315+
# Find all judge_coding_plan records for this session, ordered by timestamp DESC
316+
stmt = (
317+
select(ConversationRecord)
318+
.where(ConversationRecord.session_id == session_id)
319+
.where(ConversationRecord.source == "judge_coding_plan")
320+
.order_by(
321+
desc(ConversationRecord.timestamp),
322+
desc(ConversationRecord.id),
323+
)
324+
)
325+
plan_records = list(session.exec(stmt).all())
326+
327+
if len(plan_records) <= 1:
328+
# No previous plans to delete
329+
logger.info(f"No previous judge_coding_plan records to delete for session {session_id}")
330+
return 0
331+
332+
# Keep the first record (most recent), delete the rest
333+
records_to_delete = plan_records[1:] # Skip the first (most recent)
334+
record_ids_to_delete = [record.id for record in records_to_delete]
335+
336+
logger.info(f"Deleting {len(records_to_delete)} previous judge_coding_plan records for session {session_id}")
337+
338+
# Delete records using SQL IN clause
339+
delete_stmt = delete(ConversationRecord).where(
340+
ConversationRecord.id.in_(record_ids_to_delete)
341+
)
342+
result = session.exec(delete_stmt)
343+
session.commit()
344+
345+
deleted_count = result.rowcount if hasattr(result, 'rowcount') else len(records_to_delete)
346+
logger.info(f"Successfully deleted {deleted_count} previous judge_coding_plan records")
347+
348+
return deleted_count

src/mcp_as_a_judge/server.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1686,6 +1686,11 @@ async def judge_coding_plan(
16861686
# Mark plan as approved for completion validation and update state
16871687
updated_task_metadata.mark_plan_approved()
16881688
updated_task_metadata.update_state(TaskState.PLAN_APPROVED)
1689+
1690+
# Delete previous failed plan attempts, keeping only the most recent approved one
1691+
deleted_count = await conversation_service.db.delete_previous_plan(updated_task_metadata.task_id)
1692+
logger.info(f"Plan approved - deleted {deleted_count} previous plan attempts")
1693+
16891694
# Force next step to code review implementation gate
16901695
workflow_guidance.next_tool = "judge_code_change"
16911696
if not workflow_guidance.reasoning:

0 commit comments

Comments
 (0)