OpenHands / OpenHands/software-agent-sdk
[Roadmap] System-prompt section registry + variant strategies
@VascoSch92 is already working on this.
Since Jun 9, 2026.
- Dominant language
- Python
- Stars
- 1.1k
- Forks
- 539
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 137
Description
Overview
Implementation roadmap for OpenHands/software-agent-sdk#2827 : refactor system-prompt construction into a typed section registry with declared cache tiers, replacing the monolithic system_prompt.j2 + post-render refine() approach.
Target architecture (Layers 2 + 3 of OpenHands/software-agent-sdk#2827**):**
PromptSection— typed, pure, synchronous unit (guard(ctx)+render(ctx)+cache_tier).PromptContext— frozen snapshot of everything that shapes the prompt (model family, platform, interaction mode, tools, cwd, now, skills, secrets, …); all I/O resolved before assembly.PromptRegistry— assembles registered sections into the(static, dynamic)pair that maps 1:1 ontoSystemPromptEvent's two content blocks.
Why: make the static/dynamic cache split declared and test-enforceable instead of "whichever function produced the block"; enable per-section unit tests and A/B swaps; and unblock the two feature goals (shell-aware prompt, interactive-vs-non-interactive behavior).
Grounding (verified against current main)
refine()is live today (context/prompts/prompt.py:114, also a Jinja filter at:73): Windows-onlyterminal→execute_powershell/bash→powershell. Deleting it is a real behavior change the shell section must absorb.current_datetimeis already timezone-aware (agent_context.py:133) and sits in the dynamic block, so it does not threaten cache today; minute-rounding is purely defensive.- The static/dynamic split is implemented by
static_system_message/dynamic_context(agent/base.py:426,469) →SystemPromptEvent(event/llm_convertible/system.py:72) →LLM._apply_prompt_caching(llm.py:2085). This contract is preserved by the refactor. - Only
system_prompt_planning.j2is wired (planning preset).system_prompt_{interactive,long_horizon,tech_philosophy}.j2are orphaned (zero references).cli_modeis not consumed bysystem_prompt.j2— the interactive-mode goal is genuinely unmet. - #85 and OpenHands/software-agent-sdk#1317 are closed as
NOT_PLANNED; this roadmap revives their goals in Phase 4. - Existing safety net to keep green:
tests/sdk/llm/test_prompt_caching_cross_conversation.py+tests/sdk/context/test_agent_context.py.
Phases
- Phase 0 — Foundations & de-risking OpenHands/software-agent-sdk#3607 (no deps)
- Phase 1 — Typed core OpenHands/software-agent-sdk#3608 (no deps; parallel with Phase 0)
- Phase 2 — Port sections behind the snapshot OpenHands/software-agent-sdk#3610 (depends on OpenHands/software-agent-sdk#3607*,* OpenHands/software-agent-sdk#3608*)*
- Phase 3 — Cutover OpenHands/software-agent-sdk#3611 (depends on OpenHands/software-agent-sdk#3610*)*
- Phase 4 — Feature payoffs (#85, OpenHands/software-agent-sdk#1317**)** OpenHands/software-agent-sdk#3612 (depends on OpenHands/software-agent-sdk#3611*)*
- Phase 5 — Retire templates & extend OpenHands/software-agent-sdk#3613 (depends on OpenHands/software-agent-sdk#3611*,* OpenHands/software-agent-sdk#3612*)*
Dependency graph
Phase 0 ─┐
├─► Phase 2 ─► Phase 3 ─┬─► Phase 4 ─┐
Phase 1 ─┘ │ ├─► Phase 5
└────────────┘
Phases 0 and 1 are independent and can run in parallel. Phase 2 needs both. Phase 4 and the Phase 5 retire work both depend on the Phase 3 cutover; Phase 5 also depends on Phase 4 (salvage interactive wording before deleting the orphaned variants).
Out of scope (follow-ups enabled by this refactor)
- Layer 1 (priority resolver), Layer 4 (AGENTS.md preamble injection as a user-role reminder), Layer 5 (auto-memory).
- Model-specific tweaks driven by index data (per @juanmichelini on OpenHands/software-agent-sdk#2827) — becomes a
ModelSpecificSectionenhancement once the registry exists.
Parent proposal: OpenHands/software-agent-sdk#2827
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.