Files
simbarag/scripts/rename_conversations.py
Ryan Chen ffbe992f64 Add management command to rename conversations
Conversations with >10 messages get an LLM-generated summary title.
Conversations with <=10 messages get the first user message truncated
to 100 chars. Supports --dry-run for previewing changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 13:26:47 -04:00

98 lines
2.9 KiB
Python

#!/usr/bin/env python3
"""
Management command to rename all conversations.
- Conversations with >10 messages: renamed to an LLM-generated summary
- Conversations with <=10 messages: renamed to a truncation of the first user message
"""
import argparse
import asyncio
import os
from tortoise import Tortoise
from blueprints.conversation.models import Conversation, Speaker
from llm import LLMClient
async def rename_conversations(dry_run: bool = False):
"""Rename all conversations based on message count."""
database_url = os.getenv("DATABASE_URL", "sqlite://raggr.db")
await Tortoise.init(
db_url=database_url,
modules={
"models": [
"blueprints.users.models",
"blueprints.conversation.models",
]
},
)
try:
llm = LLMClient()
conversations = await Conversation.all().prefetch_related("messages")
renamed = 0
skipped = 0
for conversation in conversations:
messages = sorted(conversation.messages, key=lambda m: m.created_at)
user_messages = [m for m in messages if m.speaker == Speaker.USER]
if not user_messages:
skipped += 1
continue
if len(messages) > 10:
# Summarize via LLM
message_text = "\n".join(
f"{m.speaker.value}: {m.text}" for m in messages[:30]
)
new_name = llm.chat(
prompt=message_text,
system_prompt=(
"You are naming a conversation. Given the messages below, "
"produce a short, descriptive title (max 8 words). "
"Reply with ONLY the title, nothing else."
),
)
new_name = new_name.strip().strip('"').strip("'")[:100]
else:
# Truncate first user message
new_name = user_messages[0].text[:100]
old_name = conversation.name
if old_name == new_name:
skipped += 1
continue
if dry_run:
print(f" [dry-run] '{old_name}' -> '{new_name}'")
else:
conversation.name = new_name
await conversation.save()
print(f" '{old_name}' -> '{new_name}'")
renamed += 1
print(f"\nRenamed: {renamed} Skipped: {skipped}")
if dry_run:
print("(dry run — no changes were saved)")
finally:
await Tortoise.close_connections()
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Rename conversations based on message count"
)
parser.add_argument(
"--dry-run",
action="store_true",
help="Preview renames without saving",
)
args = parser.parse_args()
asyncio.run(rename_conversations(dry_run=args.dry_run))