Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 18 additions & 16 deletions agent/context_compressor.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,22 +102,24 @@ def _generate_summary(self, turns_to_summarize: List[Dict[str, Any]]) -> Optiona
parts.append(f"[{role.upper()}]: {content}")

content_to_summarize = "\n\n".join(parts)
prompt = f"""Summarize these conversation turns concisely. This summary will replace these turns in the conversation history.

Write from a neutral perspective describing:
1. What actions were taken (tool calls, searches, file operations)
2. Key information or results obtained
3. Important decisions or findings
4. Relevant data, file names, or outputs

Keep factual and informative. Target ~{self.summary_target_tokens} tokens.

---
TURNS TO SUMMARIZE:
{content_to_summarize}
---

Write only the summary, starting with "[CONTEXT SUMMARY]:" prefix."""
prompt = (
"You are performing a CONTEXT CHECKPOINT COMPACTION. Create a handoff "
"summary for the AI assistant that will resume this conversation.\n\n"
"Include:\n"
"- Current progress and key decisions made\n"
"- Important context, constraints, or user preferences discovered\n"
"- What remains to be done (clear next steps)\n"
"- Any critical data: file paths, variable names, URLs, error messages, "
"or code snippets needed to continue\n"
"- Tool calls made and their key results\n\n"
"Be concise, structured, and focused on helping the assistant seamlessly "
"continue the work without re-doing what's already been done.\n\n"
f"Target roughly {self.summary_target_tokens} tokens.\n\n"
"---\n"
f"TURNS TO SUMMARIZE:\n{content_to_summarize}\n"
"---\n\n"
'Write only the summary, starting with "[CONTEXT SUMMARY]:" prefix.'
)

# Use the centralized LLM router — handles provider resolution,
# auth, and fallback internally.
Expand Down
27 changes: 27 additions & 0 deletions tests/agent/test_context_compressor.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,33 @@ def test_none_content_in_system_message_compress(self):
assert len(result) < len(msgs)


class TestSummaryPrompt:
def test_generate_summary_uses_handoff_compaction_prompt(self):
mock_response = MagicMock()
mock_response.choices = [MagicMock()]
mock_response.choices[0].message.content = "[CONTEXT SUMMARY]: compacted"

with patch("agent.context_compressor.get_model_context_length", return_value=100000):
c = ContextCompressor(model="test", quiet_mode=True, summary_target_tokens=1234)

messages = [
{"role": "user", "content": "Investigate the failing test"},
{"role": "assistant", "content": "I'll inspect the traceback."},
]

with patch("agent.context_compressor.call_llm", return_value=mock_response) as mock_call_llm:
c._generate_summary(messages)

prompt = mock_call_llm.call_args.kwargs["messages"][0]["content"]
assert "CONTEXT CHECKPOINT COMPACTION" in prompt
assert "Current progress and key decisions made" in prompt
assert "Important context, constraints, or user preferences discovered" in prompt
assert "What remains to be done (clear next steps)" in prompt
assert "Tool calls made and their key results" in prompt
assert "Target roughly 1234 tokens." in prompt
assert 'Write only the summary, starting with "[CONTEXT SUMMARY]:" prefix.' in prompt


class TestNonStringContent:
"""Regression: content as dict (e.g., llama.cpp tool calls) must not crash."""

Expand Down
Loading