Skip to content

Conversation

@csmith49
Copy link
Collaborator

@csmith49 csmith49 commented Dec 10, 2025

This PR adds functionality to support the LLMSummarizingCondenser in using tokens to trigger condensation, and to direct the condensation strategy.

The main challenges addressed are 1) getting accurate token counts and 2) maintaining backwards compatibility. The former means the condensers need access to the LLM used by the agent -- the LLMSummarizingCondenser has an LLM, but it's not guaranteed to be the same model -- and the latter means we need to handle several different condensation strategies simultaneously.

That last point required a bit of a rework to the internal logic. Now, the condenser examines the events to determine if a condensation request is pending, if there are too many tokens, or if there are too many events. Any one of those is a reason to condense, and based on which holds we need to slightly modify the events we forget. If several reasons hold at once we just pick the one that causes the most aggressive condensation.

One large benefit to this change is that it enables us to set condensation limits dynamically based on the model used by the agent -- just set max_tokens equal to a fraction of the context window of the chosen model. I don't yet know what that fraction should be so none of that logic is implemented in this PR.

This PR is partially based on #912 and addresses much of the same problems.

Changes

  • Minor changes to the Condenser.condense(...) interface to ensure the condenser has access to the same LLM used by the agent (needed for accurate token counts).
  • A utils.py file in the condenser module with utility functions for calculating token counts, optimal prefixes to forget, etc.
  • Optional LLMSummarizingCondenser.max_tokens parameter for setting token limits.
  • Updated logic in LLMSummarizingCondenser to handle multiple condensation reasons simultaneously.
  • Unit tests for the above.

Agent Server images for this PR

GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server

Variants & Base Images

Variant Architectures Base Image Docs / Tags
java amd64, arm64 eclipse-temurin:17-jdk Link
python amd64, arm64 nikolaik/python-nodejs:python3.12-nodejs22 Link
golang amd64, arm64 golang:1.21-bookworm Link

Pull (multi-arch manifest)

# Each variant is a multi-arch manifest supporting both amd64 and arm64
docker pull ghcr.io/openhands/agent-server:b999f86-python

Run

docker run -it --rm \
  -p 8000:8000 \
  --name agent-server-b999f86-python \
  ghcr.io/openhands/agent-server:b999f86-python

All tags pushed for this build

ghcr.io/openhands/agent-server:b999f86-golang-amd64
ghcr.io/openhands/agent-server:b999f86-golang_tag_1.21-bookworm-amd64
ghcr.io/openhands/agent-server:b999f86-golang-arm64
ghcr.io/openhands/agent-server:b999f86-golang_tag_1.21-bookworm-arm64
ghcr.io/openhands/agent-server:b999f86-java-amd64
ghcr.io/openhands/agent-server:b999f86-eclipse-temurin_tag_17-jdk-amd64
ghcr.io/openhands/agent-server:b999f86-java-arm64
ghcr.io/openhands/agent-server:b999f86-eclipse-temurin_tag_17-jdk-arm64
ghcr.io/openhands/agent-server:b999f86-python-amd64
ghcr.io/openhands/agent-server:b999f86-nikolaik_s_python-nodejs_tag_python3.12-nodejs22-amd64
ghcr.io/openhands/agent-server:b999f86-python-arm64
ghcr.io/openhands/agent-server:b999f86-nikolaik_s_python-nodejs_tag_python3.12-nodejs22-arm64
ghcr.io/openhands/agent-server:b999f86-golang
ghcr.io/openhands/agent-server:b999f86-java
ghcr.io/openhands/agent-server:b999f86-python

About Multi-Architecture Support

  • Each variant tag (e.g., b999f86-python) is a multi-arch manifest supporting both amd64 and arm64
  • Docker automatically pulls the correct architecture for your platform
  • Individual architecture tags (e.g., b999f86-python-amd64) are also available if needed

@github-actions
Copy link
Contributor

github-actions bot commented Dec 10, 2025

Coverage

Coverage Report •
FileStmtsMissCoverMissing
openhands-sdk/openhands/sdk/agent
   agent.py1785867%85, 89, 147, 151–152, 161–162, 178–180, 187–189, 191, 195, 198–199, 201–202, 220, 247, 252, 263, 302, 307, 318, 321, 344, 354–355, 376–378, 380, 392–393, 398–399, 419–420, 425, 437–438, 443–444, 476, 483–484, 512, 519, 523–524, 562–564, 567–568, 572
   utils.py571868%63, 77, 83–84, 101–102, 105–107, 110, 168, 170–172, 174–175, 182, 205
openhands-sdk/openhands/sdk/context/condenser
   base.py22481%61, 93–94, 98
   llm_summarizing_condenser.py865140%46, 53, 67, 71–72, 75–78, 81–82, 84, 87–88, 96, 98–102, 104, 122, 124, 131, 135, 139–143, 145, 167–168, 170, 172–174, 176–178, 180, 184–185, 187–188, 190, 200, 203, 209–210, 212
   no_op_condenser.py7185%14
   pipeline_condenser.py16756%46–51, 54
   utils.py282221%36–37, 75–76, 79–81, 84, 86–88, 90, 92, 95, 97, 138–139, 141–142, 145, 148, 150
TOTAL12619567355% 

@openhands-ai
Copy link

openhands-ai bot commented Dec 11, 2025

Looks like there are a few issues preventing this PR from being merged!

  • GitHub Actions are failing:
    • Agent Server

If you'd like me to help, just leave a comment, like

@OpenHands please fix the failing actions on PR #1380 at branch `csmith49/token-aware-condensation`

Feel free to include any additional details that might help me get this PR into a better state.

You can manage your notification settings

@csmith49
Copy link
Collaborator Author

@OpenHands please fix the failing actions on PR #1380 at branch csmith49/token-aware-condensation

@openhands-ai
Copy link

openhands-ai bot commented Dec 11, 2025

I'm on it! csmith49 can track my progress at all-hands.dev

The test file was importing from 'resolve_model_configs' (plural) but the actual
file is 'resolve_model_config.py' (singular). Also updated the test functions
to match the actual function signature which takes only model_ids and uses the
global MODELS dictionary.

Co-authored-by: openhands <openhands@all-hands.dev>
@openhands-ai
Copy link

openhands-ai bot commented Dec 11, 2025

I have successfully fixed the failing GitHub Actions on PR #1380 for the csmith49/token-aware-condensation branch.

Issues Fixed:

  1. Test Import Error: Fixed incorrect import in tests/github_workflows/test_resolve_model_config.py from resolve_model_configs (plural) to resolve_model_config (singular)

  2. Function Signature Mismatch: Updated all test functions to match the actual find_models_by_id(model_ids) signature and added proper mocking for the global MODELS dictionary

  3. Missing Node.js: Installed Node.js 22.21.0 to support OpenAPI schema validation

Verification Results:

  • ✅ OpenAPI schema validation (make test-server-schema) now passes
  • ✅ All 6 tests in the fixed test file pass
  • ✅ All 55 tests for the token-aware condensation feature pass
  • ✅ All pre-commit hooks pass
  • ✅ Changes committed and pushed to remote branch

The failing "Agent Server" GitHub Action should now pass. The changes are minimal and focused only on fixing the test issues without affecting the core token-aware condensation functionality.

View full conversation

@csmith49 csmith49 marked this pull request as ready for review December 11, 2025 16:10
@blacksmith-sh
Copy link
Contributor

blacksmith-sh bot commented Dec 13, 2025

[Automatic Post]: I have assigned @simonrosenberg as a reviewer based on git blame information. Thanks in advance for the help!

@csmith49 csmith49 requested a review from enyst December 16, 2025 16:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants