File size: 6,051 Bytes
f6f5153 ef0cac9 1a60357 75adfc3 1a60357 c589e1a 1a60357 c589e1a 5508f2d c589e1a 4d2513f 834791f 0177524 5508f2d 776a762 3b45c3d 5508f2d c589e1a 3b45c3d c589e1a fdbb2f6 0177524 ef0cac9 1524bab c589e1a 776a762 70bcdad 776a762 70bcdad 776a762 1524bab 776a762 af51472 776a762 834791f ee24018 776a762 ef0cac9 70bcdad 2fced36 74df5aa 2fced36 6c86f43 ac4492f 3003c6a 3c46432 3671edc e7a8f0c 3671edc e7a8f0c d2e51f8 e7a8f0c 3671edc d4db6df 0177524 1a60357 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
import gradio as gr
from huggingface_hub import InferenceClient
from sentence_transformers import SentenceTransformer
import torch
# Load knowledge
with open("knowledge.txt", "r", encoding="utf-8") as file:
knowledge = file.read()
cleaned_chunks = [chunk.strip() for chunk in knowledge.strip().split("\n") if chunk.strip()]
model = SentenceTransformer('all-MiniLM-L6-v2')
chunk_embeddings = model.encode(cleaned_chunks, convert_to_tensor=True)
def get_top_chunks(query):
query_embedding = model.encode(query, convert_to_tensor=True)
query_embedding_normalized = query_embedding / query_embedding.norm()
similarities = torch.matmul(chunk_embeddings, query_embedding_normalized)
top_indices = torch.topk(similarities, k=20).indices.tolist()
return [cleaned_chunks[i] for i in top_indices]
client = InferenceClient("mistralai/Mistral-7B-Instruct-v0.2")
def respond(message, history, name, char_class, char_alignment, char_race, campaign, party):
response = ""
print(message)
top_chunks = get_top_chunks(f"{char_class}, {char_alignment}, {char_race}, {campaign},{party},{message}")
context = "\n".join(top_chunks)
print(context)
messages = [
{
"role": "system",
"content": (
"You are Gorf, a 25 year old female druid who knows Wild Shape, but only ever learned how to become a Frog. You mention that sometimes. Your life passion is to help people find the perfect person to join their party, by helping the user create the perfect character to help their party. You are very kind and helpful."
f"The user might provide the following information, please use the context of their inputs in your response: \n Character name: {name}, Character Class: {char_class}, Character Race: {char_race}, Character Alignment: {char_alignment}, a description of the other characters in their party: {party} and the plot of their campaign with their current situation: {campaign}. If they don't include all the information, try to fill in these details with traits that best fit the needs of the party."
f"Use the following knowledge to inform your answers:\n\n{context}\n\n"
"Reply with 2 or 3 sentences about how the character is introduced to the rest of the party, then catagory:paragraph \n catagory: paragraph format for each section: Character Backstory, Personality Traits, Ideals, Flaws, Features and Traits, Other Proficiencies and Languages, Treasure. Keep the paragraphs 3 sentences or below"
)
}
]
if history:
messages.extend(history)
messages.append({"role": "user", "content": message})
stream = client.chat_completion(
messages,
max_tokens=500,
temperature=1.2,
stream=True,
)
for message in stream:
token = message.choices[0].delta.content
if token is not None:
response += token
yield response
# === GUI ===
google_font_link = """
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&family=Marcellus&family=Noto+Sans+Mono:wght@100..900&family=Tangerine:wght@400;700&display=swap" rel="stylesheet">
<style>
body, h1, h2, h3, h4, h5, h6, p, .gorf-font {
font-family: 'Tangerine';
font-size: 50px;
}
</style>
"""
theme = gr.themes.Base(
primary_hue="yellow",
neutral_hue="amber"
)
with gr.Blocks(theme=theme) as chatbot:
# gr.HTML(google_font_link)
with gr.Row():
gr.Image(
value="logo.png",
show_label=False,
show_share_button=False,
show_download_button=False
)
with gr.Row():
with gr.Column(scale=1):
with gr.Tab("Character Preferences"):
character_name = gr.Textbox(label = "Character Name", placeholder="Type your name here…", info ="optional")
character_class = gr.Dropdown(['Barbarian', 'Bard', 'Cleric', 'Druid', 'Fighter', 'Monk', 'Paladin', 'Ranger', 'Rogue', 'Sorcerer', 'Warlock', 'Wizard'], label="Character Class", info="Choose one or more", multiselect=True)
character_race = gr.Dropdown([
"Aarakocra", "Aasimar", "Bugbear", "Centaur", "Changeling", "Dragonborn", "Dwarf", "Elf",
"Fairy", "Firbolg", "Genasi", "Githyanki", "Githzerai", "Gnome", "Goblin", "Goliath",
"Half-Elf", "Half-Orc", "Halfling", "Hobgoblin", "Human", "Kenku", "Kobold", "Leonin",
"Lizardfolk", "Minotaur", "Orc", "Owlin", "Satyr", "Shadar-kai", "Shifter", "Tabaxi",
"Tiefling", "Tortle", "Triton", "Warforged", "Yuan-ti"
], multiselect=True, label="Character Race", info="You can choose multiple")
character_alignment = gr.Dropdown(["Lawful Good", "Neutral Good", "Chaotic Good", "Lawful Neutral", "True Neutral", "Chaotic Neutral", "Lawful Evil", "Neutral Evil", "Chaotic Evil"], label="Character Alignment", elem_classes="alignment_radio")
with gr.Tab("Campaign Details"):
campaign_description = gr.Textbox(label="Describe the campaign and the current situation", lines=5)
party_description = gr.Textbox(label="Describe the current members of your party", lines=5)
with gr.Column(scale=2):
with gr.Column(scale=2):
gr.ChatInterface(
fn=respond,
type="messages",
additional_inputs=[character_name, character_class, character_race, character_alignment, campaign_description, party_description]) # Pass name into function!
chatbot.launch() |