Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -26,10 +26,8 @@ from PIL import Image
|
|
| 26 |
from transformers import AutoModelForCausalLM, AutoTokenizer, AutoModel
|
| 27 |
from typing import Optional
|
| 28 |
|
| 29 |
-
# OpenAI client initialization
|
| 30 |
client = OpenAI(api_key=os.getenv('OPENAI_API_KEY'), organization=os.getenv('OPENAI_ORG_ID'))
|
| 31 |
|
| 32 |
-
# Logging setup
|
| 33 |
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
|
| 34 |
logger = logging.getLogger(__name__)
|
| 35 |
log_records = []
|
|
@@ -38,7 +36,6 @@ class LogCaptureHandler(logging.Handler):
|
|
| 38 |
log_records.append(record)
|
| 39 |
logger.addHandler(LogCaptureHandler())
|
| 40 |
|
| 41 |
-
# Streamlit configuration
|
| 42 |
st.set_page_config(
|
| 43 |
page_title="AI Vision & SFT Titans 🚀",
|
| 44 |
page_icon="🤖",
|
|
@@ -51,7 +48,6 @@ st.set_page_config(
|
|
| 51 |
}
|
| 52 |
)
|
| 53 |
|
| 54 |
-
# Session state initialization
|
| 55 |
st.session_state.setdefault('history', [])
|
| 56 |
st.session_state.setdefault('builder', None)
|
| 57 |
st.session_state.setdefault('model_loaded', False)
|
|
@@ -64,6 +60,7 @@ st.session_state.setdefault('selected_model', "None")
|
|
| 64 |
st.session_state.setdefault('cam0_file', None)
|
| 65 |
st.session_state.setdefault('cam1_file', None)
|
| 66 |
st.session_state.setdefault('characters', [])
|
|
|
|
| 67 |
if 'asset_gallery_container' not in st.session_state:
|
| 68 |
st.session_state['asset_gallery_container'] = st.sidebar.empty()
|
| 69 |
|
|
@@ -275,9 +272,7 @@ def process_text_with_prompt(text, prompt, model="gpt-4o-mini"):
|
|
| 275 |
except Exception as e:
|
| 276 |
return f"Error processing text with GPT: {str(e)}"
|
| 277 |
|
| 278 |
-
# Character Editor Functions
|
| 279 |
def randomize_character_content():
|
| 280 |
-
# Templates for randomizing Intro and Greeting
|
| 281 |
intro_templates = [
|
| 282 |
"{char} is a valiant knight who is silent and reserved, he looks handsome but aloof.",
|
| 283 |
"{char} is a mischievous thief with a heart of gold, always sneaking around but helping those in need.",
|
|
@@ -297,7 +292,6 @@ def randomize_character_content():
|
|
| 297 |
return intro, greeting
|
| 298 |
|
| 299 |
def save_character(character_data):
|
| 300 |
-
# Save character to a JSON file
|
| 301 |
characters = st.session_state.get('characters', [])
|
| 302 |
characters.append(character_data)
|
| 303 |
st.session_state['characters'] = characters
|
|
@@ -312,12 +306,10 @@ def load_characters():
|
|
| 312 |
except FileNotFoundError:
|
| 313 |
st.session_state['characters'] = []
|
| 314 |
|
| 315 |
-
# Sidebar: Gallery Settings
|
| 316 |
st.sidebar.subheader("Gallery Settings")
|
| 317 |
st.session_state.setdefault('gallery_size', 2)
|
| 318 |
st.session_state['gallery_size'] = st.sidebar.slider("Gallery Size", 1, 10, st.session_state['gallery_size'], key="gallery_size_slider")
|
| 319 |
|
| 320 |
-
# Tabs setup
|
| 321 |
tabs = st.tabs([
|
| 322 |
"Camera Snap 📷", "Download PDFs 📥", "Test OCR 🔍", "Build Titan 🌱",
|
| 323 |
"Test Image Gen 🎨", "PDF Process 📄", "Image Process 🖼️", "MD Gallery 📚",
|
|
@@ -669,56 +661,65 @@ with tab_md_gallery:
|
|
| 669 |
with tab_character_editor:
|
| 670 |
st.header("Character Editor 🧑🎨")
|
| 671 |
st.subheader("Create Your Character")
|
| 672 |
-
|
| 673 |
-
|
| 674 |
-
|
| 675 |
-
|
| 676 |
-
|
| 677 |
-
|
| 678 |
-
|
| 679 |
-
|
| 680 |
-
st.session_state['char_intro'] = intro.format(char=name)
|
| 681 |
-
st.session_state['char_greeting'] = greeting.format(char=name)
|
| 682 |
-
|
| 683 |
-
name = st.text_input("Name (3-25 characters, letters, numbers, underscore, hyphen, space only)",
|
| 684 |
-
value=st.session_state.get('char_name', 'Character_3857'),
|
| 685 |
-
max_chars=25,
|
| 686 |
-
key="char_name")
|
| 687 |
-
gender = st.radio("Gender", ["Male", "Female", "Non-binary"],
|
| 688 |
-
index=["Male", "Female", "Non-binary"].index(st.session_state.get('char_gender', "Male")),
|
| 689 |
-
key="char_gender")
|
| 690 |
-
intro = st.text_area("Intro (Publicly seen)",
|
| 691 |
-
value=st.session_state.get('char_intro', 'Character_3857 is a gentle healer who speaks softly, always carrying herbs and a warm smile.'),
|
| 692 |
-
max_chars=300,
|
| 693 |
-
key="char_intro")
|
| 694 |
-
greeting = st.text_area("Greeting",
|
| 695 |
-
value=st.session_state.get('char_greeting', "A soft hand touches your shoulder. 'I’m Character_3857, here to heal your wounds—don’t worry, I’ve got you.'"),
|
| 696 |
-
max_chars=300,
|
| 697 |
-
key="char_greeting")
|
| 698 |
-
|
| 699 |
-
if st.button("Create Character", key="create_character"):
|
| 700 |
-
if not name or len(name) < 3:
|
| 701 |
-
st.error("Name must be 3-25 characters long.")
|
| 702 |
-
elif not re.match(r'^[a-zA-Z0-9 _-]+$', name): # Fixed regex to avoid bad character range
|
| 703 |
-
st.error("Name can only contain letters, numbers, underscores, hyphens, and spaces.")
|
| 704 |
-
elif not intro or not greeting:
|
| 705 |
-
st.error("Intro and Greeting cannot be empty.")
|
| 706 |
else:
|
| 707 |
-
|
| 708 |
-
|
| 709 |
-
|
| 710 |
-
|
| 711 |
-
|
| 712 |
-
|
| 713 |
-
|
| 714 |
-
|
| 715 |
-
|
| 716 |
-
|
| 717 |
-
|
| 718 |
-
|
| 719 |
-
|
| 720 |
-
|
| 721 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 722 |
|
| 723 |
with tab_character_gallery:
|
| 724 |
st.header("Character Gallery 🖼️")
|
|
|
|
| 26 |
from transformers import AutoModelForCausalLM, AutoTokenizer, AutoModel
|
| 27 |
from typing import Optional
|
| 28 |
|
|
|
|
| 29 |
client = OpenAI(api_key=os.getenv('OPENAI_API_KEY'), organization=os.getenv('OPENAI_ORG_ID'))
|
| 30 |
|
|
|
|
| 31 |
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
|
| 32 |
logger = logging.getLogger(__name__)
|
| 33 |
log_records = []
|
|
|
|
| 36 |
log_records.append(record)
|
| 37 |
logger.addHandler(LogCaptureHandler())
|
| 38 |
|
|
|
|
| 39 |
st.set_page_config(
|
| 40 |
page_title="AI Vision & SFT Titans 🚀",
|
| 41 |
page_icon="🤖",
|
|
|
|
| 48 |
}
|
| 49 |
)
|
| 50 |
|
|
|
|
| 51 |
st.session_state.setdefault('history', [])
|
| 52 |
st.session_state.setdefault('builder', None)
|
| 53 |
st.session_state.setdefault('model_loaded', False)
|
|
|
|
| 60 |
st.session_state.setdefault('cam0_file', None)
|
| 61 |
st.session_state.setdefault('cam1_file', None)
|
| 62 |
st.session_state.setdefault('characters', [])
|
| 63 |
+
st.session_state.setdefault('char_form_reset', False)
|
| 64 |
if 'asset_gallery_container' not in st.session_state:
|
| 65 |
st.session_state['asset_gallery_container'] = st.sidebar.empty()
|
| 66 |
|
|
|
|
| 272 |
except Exception as e:
|
| 273 |
return f"Error processing text with GPT: {str(e)}"
|
| 274 |
|
|
|
|
| 275 |
def randomize_character_content():
|
|
|
|
| 276 |
intro_templates = [
|
| 277 |
"{char} is a valiant knight who is silent and reserved, he looks handsome but aloof.",
|
| 278 |
"{char} is a mischievous thief with a heart of gold, always sneaking around but helping those in need.",
|
|
|
|
| 292 |
return intro, greeting
|
| 293 |
|
| 294 |
def save_character(character_data):
|
|
|
|
| 295 |
characters = st.session_state.get('characters', [])
|
| 296 |
characters.append(character_data)
|
| 297 |
st.session_state['characters'] = characters
|
|
|
|
| 306 |
except FileNotFoundError:
|
| 307 |
st.session_state['characters'] = []
|
| 308 |
|
|
|
|
| 309 |
st.sidebar.subheader("Gallery Settings")
|
| 310 |
st.session_state.setdefault('gallery_size', 2)
|
| 311 |
st.session_state['gallery_size'] = st.sidebar.slider("Gallery Size", 1, 10, st.session_state['gallery_size'], key="gallery_size_slider")
|
| 312 |
|
|
|
|
| 313 |
tabs = st.tabs([
|
| 314 |
"Camera Snap 📷", "Download PDFs 📥", "Test OCR 🔍", "Build Titan 🌱",
|
| 315 |
"Test Image Gen 🎨", "PDF Process 📄", "Image Process 🖼️", "MD Gallery 📚",
|
|
|
|
| 661 |
with tab_character_editor:
|
| 662 |
st.header("Character Editor 🧑🎨")
|
| 663 |
st.subheader("Create Your Character")
|
| 664 |
+
|
| 665 |
+
with st.form(key="character_form"):
|
| 666 |
+
if st.session_state.get('char_form_reset', False):
|
| 667 |
+
default_name = ''
|
| 668 |
+
default_gender = "Male"
|
| 669 |
+
default_intro = ''
|
| 670 |
+
default_greeting = ''
|
| 671 |
+
st.session_state['char_form_reset'] = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 672 |
else:
|
| 673 |
+
default_name = 'Character_3857'
|
| 674 |
+
default_gender = "Male"
|
| 675 |
+
default_intro = 'Character_3857 is a gentle healer who speaks softly, always carrying herbs and a warm smile.'
|
| 676 |
+
default_greeting = "A soft hand touches your shoulder. 'I’m Character_3857, here to heal your wounds—don’t worry, I’ve got you.'"
|
| 677 |
+
|
| 678 |
+
if st.form_submit_button("Randomize Content 🎲"):
|
| 679 |
+
name = f"Character_{random.randint(1000, 9999)}"
|
| 680 |
+
gender = random.choice(["Male", "Female", "Non-binary"])
|
| 681 |
+
intro, greeting = randomize_character_content()
|
| 682 |
+
default_name = name
|
| 683 |
+
default_gender = gender
|
| 684 |
+
default_intro = intro.format(char=name)
|
| 685 |
+
default_greeting = greeting.format(char=name)
|
| 686 |
+
|
| 687 |
+
name = st.text_input("Name (3-25 characters, letters, numbers, underscore, hyphen, space only)",
|
| 688 |
+
value=default_name,
|
| 689 |
+
max_chars=25,
|
| 690 |
+
key="char_name")
|
| 691 |
+
gender = st.radio("Gender", ["Male", "Female", "Non-binary"],
|
| 692 |
+
index=["Male", "Female", "Non-binary"].index(default_gender),
|
| 693 |
+
key="char_gender")
|
| 694 |
+
intro = st.text_area("Intro (Publicly seen)",
|
| 695 |
+
value=default_intro,
|
| 696 |
+
max_chars=300,
|
| 697 |
+
key="char_intro")
|
| 698 |
+
greeting = st.text_area("Greeting",
|
| 699 |
+
value=default_greeting,
|
| 700 |
+
max_chars=300,
|
| 701 |
+
key="char_greeting")
|
| 702 |
+
|
| 703 |
+
if st.form_submit_button("Create Character"):
|
| 704 |
+
if not name or len(name) < 3:
|
| 705 |
+
st.error("Name must be 3-25 characters long.")
|
| 706 |
+
elif not re.match(r'^[a-zA-Z0-9 _-]+$', name):
|
| 707 |
+
st.error("Name can only contain letters, numbers, underscores, hyphens, and spaces.")
|
| 708 |
+
elif not intro or not greeting:
|
| 709 |
+
st.error("Intro and Greeting cannot be empty.")
|
| 710 |
+
else:
|
| 711 |
+
character_data = {
|
| 712 |
+
"name": name,
|
| 713 |
+
"gender": gender,
|
| 714 |
+
"intro": intro,
|
| 715 |
+
"greeting": greeting,
|
| 716 |
+
"created_at": datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
|
| 717 |
+
"tags": ["OC"]
|
| 718 |
+
}
|
| 719 |
+
save_character(character_data)
|
| 720 |
+
st.success(f"Character '{name}' created successfully!")
|
| 721 |
+
st.session_state['char_form_reset'] = True
|
| 722 |
+
st.rerun()
|
| 723 |
|
| 724 |
with tab_character_gallery:
|
| 725 |
st.header("Character Gallery 🖼️")
|