OpenHands / OpenHands/software-agent-sdk

Feature: Allow custom title generation prompt via ConversationConfig

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

Nobody has claimed this yet.

enhancement release-note-required sdk
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 categories list, and max_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_prompt is None (the default), behavior must be identical to today. No existing conversations should be affected.

Downstream Dependencies

  • OpenHands/typescript-client needs to expose title_generation_prompt on 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

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

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.