Merge branch 'kennethreitz:main' into main

This commit is contained in:
Siddhesh Agarwal
2024-11-04 10:20:44 +05:30
committed by GitHub
6 changed files with 323 additions and 48 deletions
+46 -13
View File
@@ -1,34 +1,68 @@
from pydantic import BaseModel
import simplemind as sm
from _context import simplemind as sm
from rich.console import Console
from rich.panel import Panel
from rich.text import Text
class InstructionStep(BaseModel):
step_number: int
instruction: str
class RecipeIngredient(BaseModel):
name: str
quantity: float
unit: str
class Recipe(BaseModel):
name: str
ingredients: list[RecipeIngredient]
instructions: list[InstructionStep]
def __str__(self) -> str:
output = f"\n=== {self.name.upper()} ===\n\n"
output += "INGREDIENTS:\n"
console = Console(record=True, file=None)
# Create formatted title with more emphasis
title = Text("" + self.name.upper() + "", style="bold blue")
# Format ingredients with better structure
ingredients_text = Text("\n📝 INGREDIENTS:\n", style="bold green")
for ing in self.ingredients:
output += f"{ing.quantity} {ing.unit} {ing.name}\n"
output += "\nINSTRUCTIONS:\n"
# Format numbers to avoid floating decimals when whole numbers
quantity = int(ing.quantity) if ing.quantity.is_integer() else ing.quantity
ingredients_text.append(f"{quantity} {ing.unit} ", style="bright_white")
ingredients_text.append(f"{ing.name}\n", style="italic bright_white")
# Format instructions with better spacing and styling
instructions_text = Text("\n👩‍🍳 INSTRUCTIONS:\n", style="bold yellow")
for step in self.instructions:
output += f"{step.step_number}. {step.instruction}\n"
return output
instructions_text.append(
f"\n {step.step_number}. ", style="bold bright_white"
)
instructions_text.append(f"{step.instruction}", style="bright_white")
# Combine all text
full_text = Text.assemble(
ingredients_text, instructions_text, "\n"
) # Added extra newline
# Create panel with enhanced styling
panel = Panel(
full_text,
title=title,
border_style="blue",
padding=(1, 2), # Add padding (vertical, horizontal)
expand=False, # Don't expand to full terminal width
title_align="center",
)
# Render the panel to string without printing
with console.capture() as capture:
console.print(panel)
return capture.get()
recipe = sm.generate_data(
"Write a recipe for chocolate chip cookies",
@@ -63,4 +97,3 @@ print(recipe)
# 7. Drop by rounded tablespoon onto ungreased cookie sheets.
# 8. Bake for 9 to 11 minutes, or until edges are golden.
# 9. Let cool on the cookie sheet for a few minutes before transferring to wire racks to cool completely.
+30 -31
View File
@@ -11,14 +11,6 @@ class MultiAIConversation:
"""Orchestrates conversations between multiple AI models."""
MODEL_SESSIONS = {
"Llama3.2": sm.Session(
llm_provider="ollama",
llm_model="llama3.2",
),
"Claude-3.5-Sonnet": sm.Session(
llm_provider="anthropic",
llm_model="claude-3-5-sonnet-20241022",
),
"GPT-4o": sm.Session(
llm_provider="openai",
llm_model="gpt-4o",
@@ -27,6 +19,10 @@ class MultiAIConversation:
llm_provider="xai",
llm_model="grok-beta",
),
"Claude-3.5-Sonnet": sm.Session(
llm_provider="anthropic",
llm_model="claude-3-5-sonnet-20241022",
),
}
def __init__(self, topic: str, turns_per_model: int = 1, max_rounds: int = 5):
@@ -36,13 +32,14 @@ class MultiAIConversation:
self.max_rounds = max_rounds
self.conversation_history: List[Tuple[str, str]] = []
self.console = Console()
self.user_name = "Kenneth Reitz"
def _format_system_prompt(self, ai_name: str) -> str:
"""Creates a system prompt for each AI model."""
return f"""You are {ai_name}. You are participating in a thoughtful discussion with other AI models about {self.topic}.
Rules:
1. Be concise but insightful (keep responses under 100 words)
1. Be concise but insightful (keep responses under 140 words)
2. Build upon previous points made in the conversation
3. Ask questions to deepen the discussion when appropriate
4. Stay on topic while maintaining your unique perspective
@@ -72,32 +69,31 @@ Current discussion topic: {self.topic}"""
# Store in history
self.conversation_history.append((ai_name, response))
def _get_user_input(self) -> str:
"""Gets input from the user for the discussion."""
self.console.print("\n[bold green]Your turn! Share your thoughts:[/bold green]")
user_response = input("> ")
self._print_response(self.user_name, user_response)
return user_response
def run_conversation(self):
"""Runs the multi-AI conversation."""
# Initialize the conversation
initial_prompt = (
f"Let's have a thoughtful discussion about {self.topic}. "
"Please share your initial thoughts in 2-3 sentences."
# Get initial thoughts from the human
self.console.print(
f"\n[bold green]Start the discussion about {self.topic}:[/bold green]"
)
self._get_user_input()
for round_num in range(self.max_rounds):
self.console.print(f"\n[bold green]Round {round_num + 1}[/bold green]")
# Let all AI models respond
for model_name, session in self.MODEL_SESSIONS.items():
for turn in range(self.turns_per_model):
conversation = self._create_conversation(session, model_name)
# Add the prompt
prompt = (
initial_prompt
if round_num == 0 and turn == 0
else (
f"Continue the discussion about {self.topic}, "
"responding to the previous points made."
)
)
# Add the prompt (simplified since human always starts)
prompt = f"Continue the discussion about {self.topic}, responding to the previous points made."
conversation.add_message(role="user", text=prompt)
# Get and print response
@@ -107,17 +103,24 @@ Current discussion topic: {self.topic}"""
# Small delay to prevent rate limiting
time.sleep(1)
# Then get user input at the end of the round
self._get_user_input()
# Optional: Add a separator between rounds
self.console.print("\n" + "-" * 50)
def have_ai_discussion(topic: str, turns_per_model: int = 1, max_rounds: int = 3):
def have_ai_discussion(turns_per_model: int = 1, max_rounds: int = 3):
"""Convenience function to start an AI discussion."""
# Get topic from user
print("\nWhat topic would you like to discuss?")
topic = input("> ")
debate = MultiAIConversation(
topic=topic, turns_per_model=turns_per_model, max_rounds=max_rounds
)
print(f"\nStarting AI discussion on: {topic}")
print(f"\nStarting AI discussion about: {topic}")
print("=" * 50)
debate.run_conversation()
@@ -125,8 +128,4 @@ def have_ai_discussion(topic: str, turns_per_model: int = 1, max_rounds: int = 3
# Example usage
if __name__ == "__main__":
# Example topics
topic = "The future of human-AI collaboration in creative fields",
# Run a discussion on the first topic
have_ai_discussion(topic=topic, turns_per_model=1, max_rounds=3)
have_ai_discussion(turns_per_model=1, max_rounds=5)
+238
View File
@@ -0,0 +1,238 @@
from fastapi import FastAPI, Request, HTTPException
from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles
from pydantic import BaseModel
from typing import List
import simplemind as sm
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
templates = Jinja2Templates(directory="templates")
class CrossReference(BaseModel):
"""Model for cross references."""
verse_reference: str
explanation: str
relevance: str
class BibleVerseAnalysis(BaseModel):
"""Model for a Bible verse and its analysis."""
book: str
chapter: int
verse: int
text: str
historical_context: str
theological_significance: str
practical_application: str
cross_references: List[CrossReference]
# Bible data constants
BIBLE_BOOKS = [
# Old Testament
"Genesis",
"Exodus",
"Leviticus",
"Numbers",
"Deuteronomy",
"Joshua",
"Judges",
"Ruth",
"1 Samuel",
"2 Samuel",
"1 Kings",
"2 Kings",
"1 Chronicles",
"2 Chronicles",
"Ezra",
"Nehemiah",
"Esther",
"Job",
"Psalms",
"Proverbs",
"Ecclesiastes",
"Song of Solomon",
"Isaiah",
"Jeremiah",
"Lamentations",
"Ezekiel",
"Daniel",
"Hosea",
"Joel",
"Amos",
"Obadiah",
"Jonah",
"Micah",
"Nahum",
"Habakkuk",
"Zephaniah",
"Haggai",
"Zechariah",
"Malachi",
# New Testament
"Matthew",
"Mark",
"Luke",
"John",
"Acts",
"Romans",
"1 Corinthians",
"2 Corinthians",
"Galatians",
"Ephesians",
"Philippians",
"Colossians",
"1 Thessalonians",
"2 Thessalonians",
"1 Timothy",
"2 Timothy",
"Titus",
"Philemon",
"Hebrews",
"James",
"1 Peter",
"2 Peter",
"1 John",
"2 John",
"3 John",
"Jude",
"Revelation",
]
BIBLE_BOOK_CHAPTERS = {
# Old Testament
"Genesis": 50,
"Exodus": 40,
"Leviticus": 27,
"Numbers": 36,
"Deuteronomy": 34,
"Joshua": 24,
"Judges": 21,
"Ruth": 4,
"1 Samuel": 31,
"2 Samuel": 24,
"1 Kings": 22,
"2 Kings": 25,
"1 Chronicles": 29,
"2 Chronicles": 36,
"Ezra": 10,
"Nehemiah": 13,
"Esther": 10,
"Job": 42,
"Psalms": 150,
"Proverbs": 31,
"Ecclesiastes": 12,
"Song of Solomon": 8,
"Isaiah": 66,
"Jeremiah": 52,
"Lamentations": 5,
"Ezekiel": 48,
"Daniel": 12,
"Hosea": 14,
"Joel": 3,
"Amos": 9,
"Obadiah": 1,
"Jonah": 4,
"Micah": 7,
"Nahum": 3,
"Habakkuk": 3,
"Zephaniah": 3,
"Haggai": 2,
"Zechariah": 14,
"Malachi": 4,
# New Testament
"Matthew": 28,
"Mark": 16,
"Luke": 24,
"John": 21,
"Acts": 28,
"Romans": 16,
"1 Corinthians": 16,
"2 Corinthians": 13,
"Galatians": 6,
"Ephesians": 6,
"Philippians": 4,
"Colossians": 4,
"1 Thessalonians": 5,
"2 Thessalonians": 3,
"1 Timothy": 6,
"2 Timothy": 4,
"Titus": 3,
"Philemon": 1,
"Hebrews": 13,
"James": 5,
"1 Peter": 5,
"2 Peter": 3,
"1 John": 5,
"2 John": 1,
"3 John": 1,
"Jude": 1,
"Revelation": 22,
}
# Add a new endpoint to get chapter count
@app.get("/chapters/{book}")
async def get_chapter_count(book: str):
if book in BIBLE_BOOK_CHAPTERS:
return {"chapters": BIBLE_BOOK_CHAPTERS[book]}
return {"chapters": 0}
@app.get("/")
async def home(request: Request):
return templates.TemplateResponse(
"index.html",
{
"request": request,
"bible_books": BIBLE_BOOKS,
"current_book": "Genesis",
"current_chapter": 1,
"current_verse": 1,
},
)
@app.get("/verse/{book}/{chapter}/{verse}")
async def get_verse(book: str, chapter: int, verse: int):
# Validate book and chapter
if book not in BIBLE_BOOK_CHAPTERS:
raise HTTPException(status_code=400, detail="Invalid book name")
if chapter < 1 or chapter > BIBLE_BOOK_CHAPTERS[book]:
raise HTTPException(
status_code=400,
detail=f"Invalid chapter. {book} has {BIBLE_BOOK_CHAPTERS[book]} chapters",
)
prompt = f"""
For {book} {chapter}:{verse}, provide:
1. The ESV Bible text
2. Analysis of the verse
Return in this exact format:
{{
"book": "{book}",
"chapter": {chapter},
"verse": {verse},
"text": "The ESV Bible text",
"historical_context": "brief historical background",
"theological_significance": "main theological points",
"practical_application": "how to apply this verse today",
"cross_references": [
{{
"verse_reference": "Book Chapter:Verse",
"explanation": "why this verse is related",
"relevance": "how it connects to the main verse"
}}
]
}}
"""
data = sm.generate_data(prompt, response_model=BibleVerseAnalysis)
return data