Skip to content

Commit 16de51e

Browse files
author
dori
committed
refactor: add history records as separate input
1 parent 70b3d22 commit 16de51e

16 files changed

+647
-85
lines changed

src/mcp_as_a_judge/constants.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,5 @@
1313

1414
# Database Configuration
1515
DATABASE_URL = "sqlite://:memory:"
16-
MAX_CONTEXT_RECORDS = 20
17-
CONTEXT_ENRICHMENT_COUNT = 10
16+
MAX_SESSION_RECORDS = 20 # Maximum records to keep per session (FIFO)
1817
RECORD_RETENTION_DAYS = 1

src/mcp_as_a_judge/db/conversation_history_service.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ async def load_context_for_enrichment(
5252
# Load recent conversations for this session
5353
recent_records = await self.db.get_session_conversations(
5454
session_id=session_id,
55-
limit=self.config.database.context_enrichment_count, # load last X records
55+
limit=self.config.database.max_session_records, # load last X records (same as save limit)
5656
)
5757

5858
logger.info(f"📚 Retrieved {len(recent_records)} conversation records from DB")
@@ -109,33 +109,35 @@ async def get_conversation_history(
109109

110110
return context_records
111111

112-
def format_conversation_history_as_context(
112+
def format_conversation_history_as_json_array(
113113
self, conversation_history: list[ConversationRecord]
114-
) -> str:
114+
) -> list[dict]:
115115
"""
116-
Convert conversation history list to formatted string for context field.
116+
Convert conversation history list to JSON array for prompt injection.
117117
118118
Args:
119119
conversation_history: List of conversation records
120120
121121
Returns:
122-
Formatted string representation of conversation history
122+
List of dictionaries with conversation history data including timestamps
123123
"""
124124
if not conversation_history:
125-
return ""
125+
return []
126126

127127
logger.info(
128-
f"📝 Formatting {len(conversation_history)} conversation records as context string"
128+
f"📝 Formatting {len(conversation_history)} conversation records as JSON array"
129129
)
130130

131-
context_parts = []
131+
json_array = []
132132
for record in conversation_history:
133-
context_parts.append(f"Tool: {record.source}")
134-
context_parts.append(f"Input: {record.input}")
135-
context_parts.append(f"Output: {record.output}")
136-
context_parts.append("") # Empty line between records
137-
138-
formatted_context = "\n".join(context_parts).strip()
139-
logger.info(f"📝 Generated context string: {len(formatted_context)} characters")
140-
141-
return formatted_context
133+
json_array.append(
134+
{
135+
"source": record.source,
136+
"input": record.input,
137+
"output": record.output,
138+
"timestamp": record.timestamp.isoformat()
139+
}
140+
)
141+
142+
logger.info(f"📝 Generated JSON array with {len(json_array)} records")
143+
return json_array

src/mcp_as_a_judge/db/db_config.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@
66
"""
77

88
from mcp_as_a_judge.constants import (
9-
CONTEXT_ENRICHMENT_COUNT,
109
DATABASE_URL,
11-
MAX_CONTEXT_RECORDS,
10+
MAX_SESSION_RECORDS,
1211
RECORD_RETENTION_DAYS,
1312
)
1413

@@ -61,8 +60,7 @@ class DatabaseConfig:
6160

6261
def __init__(self) -> None:
6362
self.url = DATABASE_URL
64-
self.max_context_records = MAX_CONTEXT_RECORDS
65-
self.context_enrichment_count = CONTEXT_ENRICHMENT_COUNT
63+
self.max_session_records = MAX_SESSION_RECORDS
6664
self.record_retention_days = RECORD_RETENTION_DAYS
6765

6866

src/mcp_as_a_judge/db/factory.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,14 @@ def create_provider(cls, config: Config) -> ConversationHistoryDB:
5454
if provider_name in ["in_memory", "sqlite"]:
5555
# SQLite-based providers (both SQLModel and legacy)
5656
return provider_class(
57-
max_context_records=config.database.max_context_records,
57+
max_session_records=config.database.max_session_records,
5858
url=config.database.url,
5959
)
6060
else:
6161
# For future network database providers (PostgreSQL, MySQL, etc.)
6262
return provider_class(
6363
url=config.database.url,
64-
max_context_records=config.database.max_context_records,
64+
max_session_records=config.database.max_session_records,
6565
)
6666

6767
@classmethod

src/mcp_as_a_judge/db/interface.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,6 @@ class ConversationRecord(SQLModel, table=True):
2929
class ConversationHistoryDB(ABC):
3030
"""Abstract interface for conversation history database operations."""
3131

32-
@abstractmethod
33-
def __init__(
34-
self, max_context_records: int = 20, retention_days: int = 1, url: str = ""
35-
) -> None:
36-
"""
37-
Initialize the database provider.
38-
39-
Args:
40-
max_context_records: Maximum number of conversation records to keep per session
41-
retention_days: Number of days to keep conversation records before deletion
42-
url: Database connection URL
43-
"""
44-
pass
45-
4632
@abstractmethod
4733
async def save_conversation(
4834
self, session_id: str, source: str, input_data: str, output: str

src/mcp_as_a_judge/db/providers/sqlite_provider.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class SQLiteProvider(ConversationHistoryDB):
3434
- Session-based conversation retrieval
3535
"""
3636

37-
def __init__(self, max_context_records: int = 20, url: str = "") -> None:
37+
def __init__(self, max_session_records: int = 20, url: str = "") -> None:
3838
"""Initialize the SQLModel SQLite database with LRU and time-based cleanup."""
3939
# Parse URL to get SQLite connection string
4040
connection_string = self._parse_sqlite_url(url)
@@ -48,7 +48,7 @@ def __init__(self, max_context_records: int = 20, url: str = "") -> None:
4848
else {},
4949
)
5050

51-
self._max_context_records = max_context_records
51+
self._max_session_records = max_session_records
5252

5353
# Initialize cleanup service for time-based cleanup
5454
self._cleanup_service = ConversationCleanupService(engine=self.engine)
@@ -58,7 +58,7 @@ def __init__(self, max_context_records: int = 20, url: str = "") -> None:
5858

5959
logger.info(
6060
f"🗄️ SQLModel SQLite provider initialized: {connection_string}, "
61-
f"max_records={max_context_records}, retention_days={self._cleanup_service.retention_days}"
61+
f"max_records={max_session_records}, retention_days={self._cleanup_service.retention_days}"
6262
)
6363

6464
def _parse_sqlite_url(self, url: str) -> str:
@@ -88,8 +88,8 @@ def _cleanup_old_records(self) -> int:
8888

8989
def _cleanup_old_messages(self, session_id: str) -> int:
9090
"""
91-
Remove old messages from a session using LRU (Least Recently Used) strategy.
92-
Keeps only the most recent max_context_records messages per session.
91+
Remove old messages from a session using FIFO strategy.
92+
Keeps only the most recent max_session_records messages per session.
9393
"""
9494
with Session(self.engine) as session:
9595
# Count current messages in session
@@ -100,16 +100,16 @@ def _cleanup_old_messages(self, session_id: str) -> int:
100100
current_count = len(current_records)
101101

102102
logger.info(
103-
f"🧹 LRU cleanup check for session {session_id}: {current_count} records "
104-
f"(max: {self._max_context_records})"
103+
f"🧹 FIFO cleanup check for session {session_id}: {current_count} records "
104+
f"(max: {self._max_session_records})"
105105
)
106106

107-
if current_count <= self._max_context_records:
107+
if current_count <= self._max_session_records:
108108
logger.info(" No cleanup needed - within limits")
109109
return 0
110110

111-
# Get oldest records to remove
112-
records_to_remove = current_count - self._max_context_records
111+
# Get oldest records to remove (FIFO)
112+
records_to_remove = current_count - self._max_session_records
113113
oldest_stmt = (
114114
select(ConversationRecord)
115115
.where(ConversationRecord.session_id == session_id)

src/mcp_as_a_judge/logging_config.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,7 @@ def log_startup_message(config: Any) -> None:
131131
"🚀 MCP Judge server starting with conversation history logging enabled"
132132
)
133133
logger.info(
134-
f"📊 Configuration: max_context_records={config.database.max_context_records}, "
135-
f"context_enrichment_count={config.database.context_enrichment_count}"
134+
f"📊 Configuration: max_session_records={config.database.max_session_records}"
136135
)
137136

138137

src/mcp_as_a_judge/models.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,18 @@ class JudgeCodingPlanUserVars(BaseModel):
118118
user_requirements: str = Field(
119119
description="The user's requirements for the coding task"
120120
)
121-
context: str = Field(description="Context including conversation history")
121+
context: str = Field(description="Additional context about the task")
122122
plan: str = Field(description="The coding plan to be evaluated")
123123
design: str = Field(description="The design documentation")
124124
research: str = Field(description="Research findings and analysis")
125125
research_urls: list[str] = Field(
126126
default_factory=list,
127127
description="URLs from MANDATORY online research - minimum 3 URLs required",
128128
)
129+
conversation_history: list = Field(
130+
default_factory=list,
131+
description="Previous conversation history as JSON array with timestamps",
132+
)
129133

130134

131135
class JudgeCodeChangeSystemVars(BaseModel):
@@ -145,7 +149,11 @@ class JudgeCodeChangeUserVars(BaseModel):
145149
file_path: str = Field(description="Path to the file being changed")
146150
change_description: str = Field(description="Description of what the change does")
147151
code_change: str = Field(description="The actual code content being reviewed")
148-
context: str = Field(description="Context including conversation history")
152+
context: str = Field(description="Additional context about the code change")
153+
conversation_history: list = Field(
154+
default_factory=list,
155+
description="Previous conversation history as JSON array with timestamps",
156+
)
149157

150158

151159
class ResearchValidationSystemVars(BaseModel):
@@ -167,7 +175,11 @@ class ResearchValidationUserVars(BaseModel):
167175
default_factory=list,
168176
description="URLs from MANDATORY online research - minimum 3 URLs required",
169177
)
170-
context: str = Field(description="Context including conversation history")
178+
context: str = Field(description="Additional context about the research validation")
179+
conversation_history: list = Field(
180+
default_factory=list,
181+
description="Previous conversation history as JSON array with timestamps",
182+
)
171183

172184

173185
class WorkflowGuidanceSystemVars(BaseModel):
@@ -182,7 +194,11 @@ class WorkflowGuidanceUserVars(BaseModel):
182194
"""Variables for build_workflow user prompt."""
183195

184196
task_description: str = Field(description="Description of the development task")
185-
context: str = Field(description="Context including conversation history")
197+
context: str = Field(description="Additional context about the task")
198+
conversation_history: list = Field(
199+
default_factory=list,
200+
description="Previous conversation history as JSON array with timestamps",
201+
)
186202

187203

188204
class ValidationErrorSystemVars(BaseModel):

src/mcp_as_a_judge/prompts/user/build_workflow.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,7 @@ Please analyze this development task and provide workflow guidance:
66
## Context
77
{{ context }}
88

9+
## Previous Conversation History as JSON array
10+
{{ conversation_history }}
11+
912
Determine which MCP as a Judge tools should be used next and provide clear guidance.

src/mcp_as_a_judge/prompts/user/judge_code_change.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ Please review the following code:
1414

1515
## Code Content
1616

17+
## Previous Conversation History as JSON array
18+
{{ conversation_history }}
19+
1720
```
1821
{{ code_change }}
1922
```

0 commit comments

Comments
 (0)