Spaces:
Build error
Build error
File size: 5,177 Bytes
51ff9e5 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
"""Utility functions for generating conversation summaries."""
from typing import Optional
from openhands.core.config import LLMConfig
from openhands.core.logger import openhands_logger as logger
from openhands.events.action.message import MessageAction
from openhands.events.event import EventSource
from openhands.events.stream import EventStream
from openhands.llm.llm import LLM
from openhands.storage.data_models.settings import Settings
from openhands.storage.files import FileStore
async def generate_conversation_title(
message: str, llm_config: LLMConfig, max_length: int = 50
) -> Optional[str]:
"""Generate a concise title for a conversation based on the first user message.
Args:
message: The first user message in the conversation.
llm_config: The LLM configuration to use for generating the title.
max_length: The maximum length of the generated title.
Returns:
A concise title for the conversation, or None if generation fails.
"""
if not message or message.strip() == '':
return None
# Truncate very long messages to avoid excessive token usage
if len(message) > 1000:
truncated_message = message[:1000] + '...(truncated)'
else:
truncated_message = message
try:
llm = LLM(llm_config)
# Create a simple prompt for the LLM to generate a title
messages = [
{
'role': 'system',
'content': 'You are a helpful assistant that generates concise, descriptive titles for conversations with OpenHands. OpenHands is a helpful AI agent that can interact with a computer to solve tasks using bash terminal, file editor, and browser. Given a user message (which may be truncated), generate a concise, descriptive title for the conversation. Return only the title, with no additional text, quotes, or explanations.',
},
{
'role': 'user',
'content': f'Generate a title (maximum {max_length} characters) for a conversation that starts with this message:\n\n{truncated_message}',
},
]
response = llm.completion(messages=messages)
title = response.choices[0].message.content.strip()
# Ensure the title isn't too long
if len(title) > max_length:
title = title[: max_length - 3] + '...'
return title
except Exception as e:
logger.error(f'Error generating conversation title: {e}')
return None
def get_default_conversation_title(conversation_id: str) -> str:
"""
Generate a default title for a conversation based on its ID.
Args:
conversation_id: The ID of the conversation
Returns:
A default title string
"""
return f'Conversation {conversation_id[:5]}'
async def auto_generate_title(
conversation_id: str, user_id: str | None, file_store: FileStore, settings: Settings
) -> str:
"""
Auto-generate a title for a conversation based on the first user message.
Uses LLM-based title generation if available, otherwise falls back to a simple truncation.
Args:
conversation_id: The ID of the conversation
user_id: The ID of the user
Returns:
A generated title string
"""
try:
# Create an event stream for the conversation
event_stream = EventStream(conversation_id, file_store, user_id)
# Find the first user message
first_user_message = None
for event in event_stream.get_events():
if (
event.source == EventSource.USER
and isinstance(event, MessageAction)
and event.content
and event.content.strip()
):
first_user_message = event.content
break
if first_user_message:
# Get LLM config from user settings
try:
if settings and settings.llm_model:
# Create LLM config from settings
llm_config = LLMConfig(
model=settings.llm_model,
api_key=settings.llm_api_key,
base_url=settings.llm_base_url,
)
# Try to generate title using LLM
llm_title = await generate_conversation_title(
first_user_message, llm_config
)
if llm_title:
logger.info(f'Generated title using LLM: {llm_title}')
return llm_title
except Exception as e:
logger.error(f'Error using LLM for title generation: {e}')
# Fall back to simple truncation if LLM generation fails or is unavailable
first_user_message = first_user_message.strip()
title = first_user_message[:30]
if len(first_user_message) > 30:
title += '...'
logger.info(f'Generated title using truncation: {title}')
return title
except Exception as e:
logger.error(f'Error generating title: {str(e)}')
return ''
|