implemented basic feedback words without finite points or good prompt
This commit is contained in:
@@ -164,6 +164,11 @@ class JournalPromptGenerator:
|
||||
self.console.print("[yellow]Warning: feedback_words.json is corrupted, starting with empty feedback words[/yellow]")
|
||||
self.feedback_words = []
|
||||
|
||||
def _save_feedback_words(self):
|
||||
"""Save feedback words to JSON file."""
|
||||
with open("feedback_words.json", "w") as f:
|
||||
json.dump(self.feedback_words, f, indent=2)
|
||||
|
||||
def _save_pool_prompts(self):
|
||||
"""Save pool prompts to JSON file."""
|
||||
with open("pool_prompts.json", "w") as f:
|
||||
@@ -528,6 +533,149 @@ class JournalPromptGenerator:
|
||||
self.console.print("[red]Failed to generate prompts[/red]")
|
||||
return 0
|
||||
|
||||
def generate_theme_feedback_words(self) -> List[str]:
|
||||
"""Generate 6 theme feedback words using AI based on historic prompts."""
|
||||
self.console.print("\n[cyan]Generating theme feedback words based on historic prompts...[/cyan]")
|
||||
|
||||
# Load the feedback prompt template
|
||||
try:
|
||||
with open("ds_feedback.txt", "r") as f:
|
||||
feedback_template = f.read()
|
||||
except FileNotFoundError:
|
||||
self.console.print("[red]Error: ds_feedback.txt not found[/red]")
|
||||
return []
|
||||
|
||||
# Prepare the full prompt with historic context
|
||||
if self.historic_prompts:
|
||||
historic_context = json.dumps(self.historic_prompts, indent=2)
|
||||
full_prompt = f"{feedback_template}\n\nPrevious prompts:\n{historic_context}"
|
||||
else:
|
||||
self.console.print("[yellow]Warning: No historic prompts available for feedback analysis[/yellow]")
|
||||
return []
|
||||
|
||||
# Show progress
|
||||
with Progress(
|
||||
SpinnerColumn(),
|
||||
TextColumn("[progress.description]{task.description}"),
|
||||
transient=True,
|
||||
) as progress:
|
||||
task = progress.add_task("Calling AI API for theme analysis...", total=None)
|
||||
|
||||
try:
|
||||
# Call the AI API
|
||||
response = self.client.chat.completions.create(
|
||||
model=self.model,
|
||||
messages=[
|
||||
{"role": "system", "content": "You are a creative writing assistant that analyzes writing prompts. Always respond with valid JSON."},
|
||||
{"role": "user", "content": full_prompt}
|
||||
],
|
||||
temperature=0.7,
|
||||
max_tokens=1000
|
||||
)
|
||||
|
||||
response_content = response.choices[0].message.content
|
||||
|
||||
except Exception as e:
|
||||
self.console.print(f"[red]Error calling AI API: {e}[/red]")
|
||||
self.console.print(f"[yellow]Full prompt sent to API (first 500 chars):[/yellow]")
|
||||
self.console.print(f"[yellow]{full_prompt[:500]}...[/yellow]")
|
||||
return []
|
||||
|
||||
# Parse the response to get 6 theme words
|
||||
theme_words = self._parse_theme_words_response(response_content)
|
||||
|
||||
if not theme_words or len(theme_words) != 6:
|
||||
self.console.print(f"[red]Error: Expected 6 theme words, got {len(theme_words) if theme_words else 0}[/red]")
|
||||
return []
|
||||
|
||||
return theme_words
|
||||
|
||||
def _parse_theme_words_response(self, response_content: str) -> List[str]:
|
||||
"""
|
||||
Parse the AI response to extract 6 theme words.
|
||||
Expected format: JSON list of 6 lowercase words.
|
||||
"""
|
||||
# First, try to clean up the response content
|
||||
cleaned_content = self._clean_ai_response(response_content)
|
||||
|
||||
try:
|
||||
# Try to parse as JSON
|
||||
data = json.loads(cleaned_content)
|
||||
|
||||
# Check if data is a list
|
||||
if isinstance(data, list):
|
||||
# Ensure all items are strings and lowercase them
|
||||
theme_words = []
|
||||
for word in data:
|
||||
if isinstance(word, str):
|
||||
theme_words.append(word.lower().strip())
|
||||
else:
|
||||
theme_words.append(str(word).lower().strip())
|
||||
|
||||
return theme_words
|
||||
else:
|
||||
self.console.print(f"[yellow]Warning: AI returned unexpected data type: {type(data)}[/yellow]")
|
||||
return []
|
||||
|
||||
except json.JSONDecodeError:
|
||||
# If not valid JSON, try to extract words from text
|
||||
self.console.print("[yellow]Warning: AI response is not valid JSON, attempting to extract theme words...[/yellow]")
|
||||
|
||||
# Look for patterns in the text
|
||||
lines = response_content.strip().split('\n')
|
||||
theme_words = []
|
||||
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if line and len(line) < 50: # Theme words should be short
|
||||
# Try to extract words (lowercase, no punctuation)
|
||||
words = [w.lower().strip('.,;:!?()[]{}"\'') for w in line.split()]
|
||||
theme_words.extend(words)
|
||||
|
||||
if len(theme_words) >= 6:
|
||||
break
|
||||
|
||||
return theme_words[:6]
|
||||
|
||||
def collect_feedback_ratings(self, theme_words: List[str]) -> List[Dict[str, Any]]:
|
||||
"""Collect user ratings (0-6) for each theme word and return structured feedback."""
|
||||
self.console.print("\n[bold]Please rate each theme word from 0 to 6:[/bold]")
|
||||
self.console.print("[dim]0 = Not relevant, 6 = Very relevant[/dim]\n")
|
||||
|
||||
feedback_items = []
|
||||
|
||||
for i, word in enumerate(theme_words):
|
||||
while True:
|
||||
try:
|
||||
rating = Prompt.ask(
|
||||
f"[bold]Word {i+1}: {word}[/bold]",
|
||||
choices=[str(x) for x in range(0, 7)], # 0-6 inclusive
|
||||
default="3"
|
||||
)
|
||||
rating_int = int(rating)
|
||||
|
||||
if 0 <= rating_int <= 6:
|
||||
# Create feedback item with key (feedback00, feedback01, etc.)
|
||||
feedback_key = f"feedback{i:02d}"
|
||||
feedback_items.append({
|
||||
feedback_key: word,
|
||||
"weight": rating_int
|
||||
})
|
||||
break
|
||||
else:
|
||||
self.console.print("[yellow]Please enter a number between 0 and 6[/yellow]")
|
||||
except ValueError:
|
||||
self.console.print("[yellow]Please enter a valid number[/yellow]")
|
||||
|
||||
return feedback_items
|
||||
|
||||
def update_feedback_words(self, new_feedback_items: List[Dict[str, Any]]):
|
||||
"""Update feedback words with new ratings."""
|
||||
# Replace existing feedback words with new ones
|
||||
self.feedback_words = new_feedback_items
|
||||
self._save_feedback_words()
|
||||
self.console.print(f"[green]Updated feedback words with {len(new_feedback_items)} items[/green]")
|
||||
|
||||
def display_prompts(self, prompts: List[str]):
|
||||
"""Display generated prompts in a nice format."""
|
||||
self.console.print("\n" + "="*60)
|
||||
@@ -598,9 +746,10 @@ class JournalPromptGenerator:
|
||||
self.console.print("1. Draw prompts from pool (no API call)")
|
||||
self.console.print("2. Fill prompt pool using API")
|
||||
self.console.print("3. View combined statistics")
|
||||
self.console.print("4. Exit")
|
||||
self.console.print("4. Generate and rate theme feedback words")
|
||||
self.console.print("5. Exit")
|
||||
|
||||
choice = Prompt.ask("\nEnter your choice", choices=["1", "2", "3", "4"], default="1")
|
||||
choice = Prompt.ask("\nEnter your choice", choices=["1", "2", "3", "4", "5"], default="1")
|
||||
|
||||
if choice == "1":
|
||||
# Draw prompts from pool
|
||||
@@ -634,6 +783,15 @@ class JournalPromptGenerator:
|
||||
self.show_combined_stats()
|
||||
|
||||
elif choice == "4":
|
||||
# Generate and rate theme feedback words
|
||||
theme_words = self.generate_theme_feedback_words()
|
||||
if theme_words:
|
||||
feedback_items = self.collect_feedback_ratings(theme_words)
|
||||
self.update_feedback_words(feedback_items)
|
||||
else:
|
||||
self.console.print("[yellow]No theme words were generated[/yellow]")
|
||||
|
||||
elif choice == "5":
|
||||
self.console.print("[green]Goodbye! Happy journaling! 📓[/green]")
|
||||
break
|
||||
|
||||
|
||||
Reference in New Issue
Block a user