OpenHands / OpenHands/software-agent-sdk
Feature: Allow custom title generation prompt via ConversationConfig
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 1.1k
- Forks
- 539
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 137
Description
Feature Request
As a user, I want to configure the prompt used for LLM-based conversation title generation, so I can replace the default hardcoded prompt with my own.
Today, the title generation prompt is hardcoded in generate_title_with_llm() in openhands-sdk/openhands/sdk/conversation/title_utils.py. The system message, user message template (including a 14-entry emoji categories list), and max_length (default 50) are all inlined string literals with no configuration mechanism. The only title-related fields on ConversationConfig are autotitle: bool and title_llm_profile: str | None.
Proposed Change
1. Add title_generation_prompt to ConversationConfig
In openhands-sdk/openhands/sdk/conversation/request.py, add a new field:
title_generation_prompt: str | None = None
This field should be persisted in StoredConversation (which extends ConversationConfig in openhands-agent-server/openhands/agent_server/models.py) so it survives across server restarts, mirroring how autotitle and title_llm_profile are already persisted into meta.json.
2. Use the custom prompt in generate_title_with_llm()
In openhands-sdk/openhands/sdk/conversation/title_utils.py, modify generate_title_with_llm() to accept an optional title_generation_prompt parameter. When provided (non-None, non-empty), use it as the user message (or system message -- see design note below) instead of the hardcoded template. When not provided, fall back to the existing hardcoded prompt (no behavior change).
3. Wire it through the title generation pipeline
In openhands-agent-server/openhands/agent_server/conversation_service.py, the AutoTitleSubscriber (registered in _start_event_service when stored.autotitle and stored.title is None) currently fires on the first user message and calls generate_title_with_llm(). It should pass stored.title_generation_prompt through to that call.
Design Considerations
-
Template variables: The current hardcoded user message interpolates the conversation content, an emoji
categorieslist, andmax_length. A custom prompt would need access to similar context. Consider whether the custom prompt is a free-form string that receives the conversation content as a separate parameter, or a template with documented placeholders (e.g.{conversation_content},{max_length}). The emoji categories list is arguably a concern of the default prompt only -- a custom prompt likely does not need it. -
System vs. user message: The current code sends both a system message and a user message. Decide whether the custom prompt replaces the user message, the system message, or both. Replacing the user message (which contains the conversation content and formatting instructions) is the most intuitive for users.
-
Validation: Consider a max length limit (e.g. 2000 characters) and basic sanitization to prevent excessively long or malformed prompts.
-
Backward compatibility: When
title_generation_promptisNone(the default), behavior must be identical to today. No existing conversations should be affected.
Downstream Dependencies
OpenHands/typescript-clientneeds to exposetitle_generation_prompton the conversation start request type.OpenHands/OpenHands(agent-canvas frontend) needs to add the setting UI, settings plumbing, and payload wiring to send the field at conversation start.
Both of those have their own tracking issues.
Existing Reference
The title_llm_profile field follows the exact same pattern (field on ConversationConfig, persisted in StoredConversation, resolved at conversation start, sent in the payload). This new field should mirror that pattern.
Acceptance Criteria
-
title_generation_prompt, or similar, is storable in meta.json and used to allow a user defined prompt for title generation
This issue was created by an AI agent (OpenHands) on behalf of Devin.
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.
Research direction
Read ConversationConfig in openhands-sdk/openhands/sdk/conversation/request.py and StoredConversation in openhands-agent-server/openhands/agent_server/models.py, then trace title_llm_profile through conversation_service.py and title_utils.py. Done means the prompt is persisted, forwarded to title generation, and the existing hardcoded behavior remains unchanged when it is unset; resolve the custom prompt context and system/user message behavior described in the design notes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- api, backend
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100