Compare commits
4 Commits
feat/conve
...
feat/renam
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ffbe992f64 | ||
|
|
9ed4ca126a | ||
|
|
f3ae76ce68 | ||
|
|
7ee3bdef84 |
@@ -120,20 +120,6 @@ export const ChatScreen = ({ setAuthenticated }: ChatScreenProps) => {
|
|||||||
scrollToBottom();
|
scrollToBottom();
|
||||||
}, [messages]);
|
}, [messages]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const load = async () => {
|
|
||||||
if (!selectedConversation) return;
|
|
||||||
try {
|
|
||||||
const conv = await conversationService.getConversation(selectedConversation.id);
|
|
||||||
setSelectedConversation({ id: conv.id, title: conv.name });
|
|
||||||
setMessages(conv.messages.map((m) => ({ text: m.text, speaker: m.speaker, image_key: m.image_key })));
|
|
||||||
} catch (err) {
|
|
||||||
console.error("Failed to load messages:", err);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
load();
|
|
||||||
}, [selectedConversation?.id]);
|
|
||||||
|
|
||||||
const handleQuestionSubmit = useCallback(async () => {
|
const handleQuestionSubmit = useCallback(async () => {
|
||||||
if ((!query.trim() && !pendingImage) || isLoading) return;
|
if ((!query.trim() && !pendingImage) || isLoading) return;
|
||||||
|
|
||||||
@@ -215,7 +201,10 @@ export const ChatScreen = ({ setAuthenticated }: ChatScreenProps) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
if (isMountedRef.current) setIsLoading(false);
|
if (isMountedRef.current) {
|
||||||
|
setIsLoading(false);
|
||||||
|
loadConversations();
|
||||||
|
}
|
||||||
abortControllerRef.current = null;
|
abortControllerRef.current = null;
|
||||||
}
|
}
|
||||||
}, [query, pendingImage, isLoading, selectedConversation, simbaMode, messages, setAuthenticated]);
|
}, [query, pendingImage, isLoading, selectedConversation, simbaMode, messages, setAuthenticated]);
|
||||||
|
|||||||
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