OpenHands / OpenHands/software-agent-sdk

feat(profiles): server-side prompt-file composition — `system_prompt_filename` / `system_prompt_kwargs` on `OpenHandsAgentProfile` and `OpenHandsAgentSettings`

Open
#4,943 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

agent-execution enhancement release-note-required sdk
Dominant language
Python
Stars
1.1k
Forks
539
Avg merge
1d 19h
Merged PRs (30d)
137

Description

Problem

Measured at v1.44.1 and re-verified at v1.46.0: Agent supports system_prompt_filename (default "system_prompt.j2") + system_prompt_kwargs with the inline↔filename exclusivity validator, rendered through the Jinja escape hatch (agent/base.py:207-262, render at :346-373 at v1.46.0). But every server-side/profile path to an agent drops this channel:

  • StartConversationRequest.agent is client-composed — the server only appends suffix/tools/plugins; shipping a full Agent object from every client is the only way to get a custom prompt FILE today.
  • OpenHandsAgentSettings.create_agent() (sdk/settings/model.py:1365-1401) passes llm/tools/include_default_tools/agent_context/condenser only — the file contains no system_prompt* occurrence at all.
  • OpenHandsAgentProfile (sdk/profiles/agent_profile.py:122-187) carries system_message_suffix only — suffix, not a prompt template file.

Net effect: a deployment that keeps LLM profiles + agent profiles server-side (never shipping provider config to clients) cannot give conversations a custom system-prompt template + kwargs without falling back to client-side agent assembly — which defeats the purpose of profiles.

Ask

Additive fields on OpenHandsAgentProfile and OpenHandsAgentSettings:

system_prompt_filename: str = "system_prompt.j2"
system_prompt_kwargs: dict[str, object] = {}
# optionally: prompt_dir: Path | None = None

forwarded by create_agent() / resolve_agent_profile() into the composed Agent, honoring the existing inline↔filename exclusivity. Profiles then stay server-side, secret-free, and prompt-capable.

Precedent

  • #3213 (open): server-side ConversationSettings.create_request() injects agent.system_prompt_kwargs via model_copy — same direction of composition.
  • #4029 (closed, completed): added agent_launch_additions overrides on the agent_profile_id path — the path this ask extends.
  • #2826 (merged): accepted inline system_prompt on Agent — the file+kwargs form is its natural pair.

Alignment with the prompt-registry roadmap

#3914 + draft #3947 plan to deprecate the custom-Jinja fallback in favor of a typed prompt registry. If/when that lands, these profile fields can map onto registry entries (create_registry(...)) — we'd welcome that as the long-term home; the additive fields are the bridge that keeps server-side deployments prompt-capable meanwhile.

Environment

openhands-sdk / agent-server / tools / workspace 1.44.1 (pinned), re-verified against v1.46.0 sources (2026-09-10). Custom system_prompt_filename + ~10 system_prompt_kwargs rendered through the existing Jinja path, composed client-side today.

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 with sdk/settings/model.py:1365-1401 and sdk/profiles/agent_profile.py:122-187, then compare Agent field handling and validation in agent/base.py:207-262 and rendering at :346-373. Trace create_agent() and resolve_agent_profile() to see how profile values reach the composed Agent. Done means both profile/settings paths forward the filename and kwargs while preserving inline↔filename exclusivity.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend-api-design
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.