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>
This commit is contained in:
97
scripts/rename_conversations.py
Normal file
97
scripts/rename_conversations.py
Normal file
@@ -0,0 +1,97 @@
|
||||
#!/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))
|
||||
Reference in New Issue
Block a user