OpenHands / OpenHands/software-agent-sdk

condenser hard context reset: preserve the leading system prompt instead of summarizing it at offset 0

Open
#5,149 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

invariants
Dominant language
Python
Stars
1.1k
Forks
539
Avg merge
1d 19h
Merged PRs (30d)
137

Description

Problem

LLMSummarizingCondenser.hard_context_reset() in openhands-sdk/openhands/sdk/context/condenser/llm_summarizing_condenser.py summarizes all events in the view:

return self._generate_condensation(
    forgotten_events=view.events,   # ALL events, including the system prompt
    summary_offset=0,
    max_event_str_length=max_event_str_length,
)

with summary_offset=0. The resulting CondensationSummaryEvent (a user message, see the related edge-case issue) is inserted at index 0 — before (or replacing) the SystemPromptEvent. Combined with keep_first semantics, this means the system prompt can be entirely forgotten and the re-injected conversation opens with a user-role summary with no system message.

This violates the repo convention that every LLM request starts with a system message (see parent tracking issue #5144). It is an edge case triggered by LLM-error/hard-reset recovery, but the resulting view violates the invariant that init_state otherwise guarantees.

Proposed change

In hard_context_reset, exclude the leading SystemPromptEvent from the forgotten events (or always preserve it in the retained prefix):

  1. Keep the SystemPromptEvent (and any essential prefix events) out of forgotten_events, e.g. pass view.events[max(0, first_non_system_index):] and compute a summary_offset that places the summary after the preserved system prompt.
  2. Ensure both the sync hard_context_reset and async ahard_context_reset paths do the same.

Add a regression test: trigger a hard context reset and assert the resulting view/messages still begin with a system message.

Note this issue and the keep_first edge-case issue are related but distinct: this one concerns the hard-reset path that summarizes the entire view including the system prompt with summary_offset=0.

Parent issue: #5144


This issue was created by an AI agent (OpenHands) on behalf of juanmichelini.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in openhands-sdk/openhands/sdk/context/condenser/llm_summarizing_condenser.py and inspect the sync hard_context_reset and async ahard_context_reset entry points. Add a regression test that triggers a hard context reset and verifies the resulting view and messages still begin with a system message. Confirm both reset paths preserve the leading SystemPromptEvent while summarizing the remaining events.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
ai-infra-agents
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.