DarwinAnim8or commited on
Commit
7d0d9e5
Β·
verified Β·
1 Parent(s): de33e80

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +355 -225
app.py CHANGED
@@ -1,259 +1,389 @@
 
 
 
 
 
 
1
  import gradio as gr
2
- from transformers import AutoTokenizer, AutoModelForCausalLM
3
  import torch
 
 
 
 
 
4
 
5
- # Load your model
6
- MODEL_NAME = "DarwinAnim8or/TinyRP"
7
-
8
- # Initialize model and tokenizer globally to avoid reloading
9
- try:
10
- tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
11
- model = AutoModelForCausalLM.from_pretrained(
12
- MODEL_NAME,
13
- torch_dtype=torch.float16,
14
- device_map="auto",
15
- trust_remote_code=True
16
- )
17
- print(f"Model loaded successfully: {MODEL_NAME}")
18
- except Exception as e:
19
- print(f"Error loading model: {e}")
20
- tokenizer = None
21
- model = None
22
-
23
- # Sample character presets
24
  SAMPLE_CHARACTERS = {
25
- "Custom Character": "",
26
- "Adventurous Knight": "You are Sir Gareth, a brave and noble knight on a quest to save the kingdom. You speak with honor and courage, always ready to help those in need. You carry an enchanted sword and have a loyal horse named Thunder.",
27
- "Mysterious Wizard": "You are Eldara, an ancient and wise wizard who speaks in riddles and knows secrets of the mystical arts. You live in a tower filled with magical books and potions. You are helpful but often cryptic in your responses.",
28
- "Friendly Tavern Keeper": "You are Bram, a cheerful tavern keeper who loves telling stories and meeting new travelers. Your tavern 'The Dancing Dragon' is a warm, welcoming place. You know all the local gossip and always have a tale to share.",
29
- "Curious Scientist": "You are Dr. Maya Chen, a brilliant scientist who is fascinated by discovery and invention. You're enthusiastic about explaining complex concepts in simple ways and always looking for new experiments to try.",
30
- "Space Explorer": "You are Captain Nova, a fearless space explorer who has traveled to distant galaxies. You pilot the starship 'Wanderer' and have encountered many alien species. You're brave, curious, and always ready for the next adventure."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  }
32
 
33
- def generate_response(message, history, character_description, max_tokens, temperature, top_p, repetition_penalty, use_chatml_format):
34
- """Generate a response from the model"""
35
-
36
- if model is None or tokenizer is None:
37
- return "Error: Model not loaded properly"
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
- if not message.strip():
40
- return "Please enter a message"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
- try:
43
- # Build conversation context
44
- if use_chatml_format and character_description.strip():
45
- # Use ChatML format
46
- conversation = f"<|im_start|>system\n{character_description}<|im_end|>\n"
47
-
48
- # Add history
49
- for user_msg, assistant_msg in history:
50
- if user_msg:
51
- conversation += f"<|im_start|>user\n{user_msg}<|im_end|>\n"
52
- if assistant_msg:
53
- conversation += f"<|im_start|>assistant\n{assistant_msg}<|im_end|>\n"
54
-
55
- # Add current message
56
- conversation += f"<|im_start|>user\n{message}<|im_end|>\n<|im_start|>assistant\n"
57
- else:
58
- # Simple format
59
- if character_description.strip():
60
- conversation = f"{character_description}\n\n"
61
- else:
62
- conversation = ""
63
-
64
- # Add history
65
- for user_msg, assistant_msg in history:
66
- if user_msg:
67
- conversation += f"Human: {user_msg}\n"
68
- if assistant_msg:
69
- conversation += f"Assistant: {assistant_msg}\n"
70
-
71
- conversation += f"Human: {message}\nAssistant:"
72
 
73
- # Tokenize with proper truncation
74
- inputs = tokenizer.encode(
75
- conversation,
76
- return_tensors="pt",
77
- truncation=True,
78
- max_length=1024-max_tokens
79
- )
80
 
81
- # Move to same device as model
82
- if hasattr(model, 'device'):
83
- inputs = inputs.to(model.device)
 
 
 
 
 
 
 
 
84
 
85
  # Generate
86
  with torch.no_grad():
87
- outputs = model.generate(
88
- inputs,
89
- max_new_tokens=int(max_tokens),
90
- temperature=float(temperature),
91
- top_p=float(top_p),
92
- repetition_penalty=float(repetition_penalty),
93
- do_sample=True,
94
- pad_token_id=tokenizer.eos_token_id,
95
- eos_token_id=tokenizer.eos_token_id,
96
- use_cache=True
97
- )
98
 
99
- # Decode response
100
- full_response = tokenizer.decode(outputs[0], skip_special_tokens=True)
101
 
102
- # Extract just the new response
103
- if use_chatml_format and "<|im_start|>assistant" in full_response:
104
- response = full_response.split("<|im_start|>assistant\n")[-1]
105
- response = response.replace("<|im_end|>", "").strip()
106
- elif "Assistant:" in full_response:
107
- response = full_response.split("Assistant:")[-1].strip()
108
- else:
109
- # Fallback - just take everything after the input
110
- input_text = tokenizer.decode(inputs[0], skip_special_tokens=True)
111
- response = full_response[len(input_text):].strip()
112
 
113
- return response
 
 
114
 
115
- except Exception as e:
116
- return f"Error generating response: {str(e)}"
117
 
118
- def load_character_preset(character_name):
119
- """Load a character preset description"""
120
- return SAMPLE_CHARACTERS.get(character_name, "")
 
 
 
 
121
 
122
- def chat_function(message, history, character_description, max_tokens, temperature, top_p, repetition_penalty, use_chatml_format):
123
- """Main chat function that handles the conversation flow"""
124
 
125
- if not message.strip():
126
- return history, ""
127
 
128
- # Generate response
129
- response = generate_response(
130
- message,
131
- history,
132
- character_description,
133
- max_tokens,
134
- temperature,
135
- top_p,
136
- repetition_penalty,
137
- use_chatml_format
138
- )
139
 
140
- # Add to history
141
- history.append([message, response])
 
 
 
 
 
142
 
143
- return history, ""
144
-
145
- # Create the interface
146
- with gr.Blocks(title="TinyRP Character Chat") as demo:
147
- gr.Markdown("# 🎭 TinyRP Character Chat")
148
- gr.Markdown("Chat with AI characters powered by a custom-trained language model!")
 
149
 
150
- with gr.Row():
151
- with gr.Column(scale=3):
152
- # Main chat interface
153
- chatbot = gr.Chatbot(
154
- label="Conversation",
155
- height=500
156
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
 
158
- with gr.Row():
159
- msg_input = gr.Textbox(
160
- label="Your message",
161
- placeholder="Type your message here...",
162
- lines=2,
163
- scale=4
 
 
 
 
164
  )
165
- send_button = gr.Button("Send", variant="primary", scale=1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
 
167
- with gr.Column(scale=2):
168
- # Character setup
169
- gr.Markdown("### Character Setup")
170
-
171
- character_dropdown = gr.Dropdown(
172
- choices=list(SAMPLE_CHARACTERS.keys()),
173
- value="Custom Character",
174
- label="Choose a character preset"
175
- )
176
-
177
- character_input = gr.Textbox(
178
- label="Character description",
179
- placeholder="Describe your character...",
180
- lines=4,
181
- value=""
182
- )
183
-
184
- load_button = gr.Button("Load Selected Character")
185
-
186
- # Generation settings
187
- gr.Markdown("### Generation Settings")
188
-
189
- use_chatml = gr.Checkbox(
190
- label="Use ChatML format",
191
- value=True
192
- )
193
-
194
- max_tokens = gr.Slider(
195
- minimum=16,
196
- maximum=256,
197
- value=100,
198
- step=16,
199
- label="Max response length"
200
- )
201
-
202
- temperature = gr.Slider(
203
- minimum=0.1,
204
- maximum=2.0,
205
- value=0.9,
206
- step=0.1,
207
- label="Temperature"
208
- )
209
 
210
- top_p = gr.Slider(
211
- minimum=0.1,
212
- maximum=1.0,
213
- value=0.85,
214
- step=0.05,
215
- label="Top-p"
216
- )
217
 
218
- repetition_penalty = gr.Slider(
219
- minimum=1.0,
220
- maximum=1.5,
221
- value=1.1,
222
- step=0.05,
223
- label="Repetition penalty"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
  )
225
-
226
- clear_button = gr.Button("Clear conversation")
227
-
228
- # Show sample characters
229
- gr.Markdown("### Sample Characters")
230
- with gr.Row():
231
- for char_name in ["Adventurous Knight", "Mysterious Wizard", "Friendly Tavern Keeper"]:
232
- gr.Markdown(f"**{char_name}**: {SAMPLE_CHARACTERS[char_name][:100]}...")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
 
234
- # Event handlers
235
- send_button.click(
236
- chat_function,
237
- inputs=[msg_input, chatbot, character_input, max_tokens, temperature, top_p, repetition_penalty, use_chatml],
238
- outputs=[chatbot, msg_input]
239
- )
240
 
241
- msg_input.submit(
242
- chat_function,
243
- inputs=[msg_input, chatbot, character_input, max_tokens, temperature, top_p, repetition_penalty, use_chatml],
244
- outputs=[chatbot, msg_input]
245
- )
246
 
247
- load_button.click(
248
- load_character_preset,
249
- inputs=[character_dropdown],
250
- outputs=[character_input]
251
- )
252
 
253
- clear_button.click(
254
- lambda: ([], ""),
255
- outputs=[chatbot, msg_input]
256
- )
257
-
258
- if __name__ == "__main__":
259
- demo.launch()
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Gradio Demo App for TinyRP Mistral Model
4
+ Supports ChatML formatting, character creation, and custom generation parameters
5
+ """
6
+
7
  import gradio as gr
 
8
  import torch
9
+ from transformers import AutoTokenizer, AutoModelForCausalLM, GenerationConfig
10
+ import json
11
+ import random
12
+ from typing import Dict, List, Tuple
13
+ import re
14
 
15
+ # Sample characters for demo
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  SAMPLE_CHARACTERS = {
17
+ "Luna the Mage": {
18
+ "description": "A mysterious elven mage with silver hair and glowing blue eyes. She specializes in ice magic and ancient knowledge.",
19
+ "personality": "Wise, mysterious, slightly aloof but caring. Speaks in an eloquent manner.",
20
+ "background": "Born in the Frostwood Academy, Luna has spent centuries studying arcane arts."
21
+ },
22
+ "Rex the Warrior": {
23
+ "description": "A brave human knight with a strong sense of justice. Wears gleaming armor and carries an enchanted sword.",
24
+ "personality": "Noble, brave, protective of others. Direct in speech but kind-hearted.",
25
+ "background": "Grew up as a farm boy, became a knight after saving his village from bandits."
26
+ },
27
+ "Zara the Rogue": {
28
+ "description": "A cunning halfling thief with quick wit and nimble fingers. Has curly red hair and green eyes.",
29
+ "personality": "Sarcastic, clever, independent. Uses humor to deflect serious situations.",
30
+ "background": "Former street orphan who learned to survive through wit and stealth."
31
+ },
32
+ "Dr. Elena Cross": {
33
+ "description": "A brilliant scientist working on advanced AI research in a near-future setting.",
34
+ "personality": "Analytical, passionate about her work, caring but sometimes absent-minded.",
35
+ "background": "PhD in Computer Science, leads a small research team at a tech corporation."
36
+ }
37
  }
38
 
39
+ class TinyRPModel:
40
+ def __init__(self, model_name: str):
41
+ """Initialize the model and tokenizer"""
42
+ print(f"Loading model: {model_name}")
43
+ self.tokenizer = AutoTokenizer.from_pretrained(model_name)
44
+ self.model = AutoModelForCausalLM.from_pretrained(
45
+ model_name,
46
+ torch_dtype=torch.float32, # Use float32 for CPU
47
+ device_map="cpu",
48
+ low_cpu_mem_usage=True
49
+ )
50
+ self.model.eval()
51
+
52
+ # Ensure pad token is set
53
+ if self.tokenizer.pad_token is None:
54
+ self.tokenizer.pad_token = self.tokenizer.eos_token
55
+
56
+ print("Model loaded successfully!")
57
 
58
+ def format_chatml(self, character_info: str, conversation_history: List[Tuple[str, str]], user_input: str) -> str:
59
+ """Format conversation using ChatML format"""
60
+ formatted = ""
61
+
62
+ # System message with character info
63
+ if character_info.strip():
64
+ formatted += f"<|im_start|>system\n{character_info.strip()}<|im_end|>\n"
65
+
66
+ # Add conversation history
67
+ for user_msg, assistant_msg in conversation_history:
68
+ if user_msg:
69
+ formatted += f"<|im_start|>user\n{user_msg}<|im_end|>\n"
70
+ if assistant_msg:
71
+ formatted += f"<|im_start|>assistant\n{assistant_msg}<|im_end|>\n"
72
+
73
+ # Add current user input
74
+ if user_input.strip():
75
+ formatted += f"<|im_start|>user\n{user_input.strip()}<|im_end|>\n"
76
+
77
+ # Start assistant response
78
+ formatted += "<|im_start|>assistant\n"
79
+
80
+ return formatted
81
 
82
+ def generate_response(self,
83
+ character_info: str,
84
+ conversation_history: List[Tuple[str, str]],
85
+ user_input: str,
86
+ max_length: int = 150,
87
+ temperature: float = 0.8,
88
+ top_p: float = 0.9,
89
+ top_k: int = 50,
90
+ repetition_penalty: float = 1.1) -> str:
91
+ """Generate character response"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
+ # Format input using ChatML
94
+ formatted_input = self.format_chatml(character_info, conversation_history, user_input)
95
+
96
+ # Tokenize
97
+ inputs = self.tokenizer.encode(formatted_input, return_tensors="pt", truncation=True, max_length=1024)
 
 
98
 
99
+ # Generation config
100
+ gen_config = GenerationConfig(
101
+ max_new_tokens=max_length,
102
+ temperature=temperature,
103
+ top_p=top_p,
104
+ top_k=top_k,
105
+ repetition_penalty=repetition_penalty,
106
+ do_sample=True,
107
+ pad_token_id=self.tokenizer.pad_token_id,
108
+ eos_token_id=self.tokenizer.eos_token_id,
109
+ )
110
 
111
  # Generate
112
  with torch.no_grad():
113
+ outputs = self.model.generate(inputs, generation_config=gen_config)
 
 
 
 
 
 
 
 
 
 
114
 
115
+ # Decode and extract response
116
+ generated_text = self.tokenizer.decode(outputs[0], skip_special_tokens=False)
117
 
118
+ # Extract assistant response (between <|im_start|>assistant and <|im_end|>)
119
+ assistant_start = generated_text.rfind("<|im_start|>assistant\n") + len("<|im_start|>assistant\n")
120
+ assistant_text = generated_text[assistant_start:]
 
 
 
 
 
 
 
121
 
122
+ # Remove end tokens
123
+ if "<|im_end|>" in assistant_text:
124
+ assistant_text = assistant_text.split("<|im_end|>")[0]
125
 
126
+ return assistant_text.strip()
 
127
 
128
+ def load_sample_character(character_name: str) -> Tuple[str, str, str]:
129
+ """Load a sample character's information"""
130
+ if character_name in SAMPLE_CHARACTERS:
131
+ char = SAMPLE_CHARACTERS[character_name]
132
+ system_prompt = f"You are {character_name}. {char['description']} {char['background']} Personality: {char['personality']}"
133
+ return system_prompt, char['description'], char['background']
134
+ return "", "", ""
135
 
136
+ def create_gradio_interface(model_name: str = "DarwinAnim8or/TinyRP"):
137
+ """Create the Gradio interface"""
138
 
139
+ # Initialize model
140
+ rp_model = TinyRPModel(model_name)
141
 
142
+ # Custom CSS for better styling
143
+ custom_css = """
144
+ .gradio-container {
145
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif !important;
146
+ }
 
 
 
 
 
 
147
 
148
+ .character-card {
149
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
150
+ padding: 20px;
151
+ border-radius: 15px;
152
+ color: white;
153
+ margin: 10px 0;
154
+ }
155
 
156
+ .chat-bubble-user {
157
+ background: #e3f2fd;
158
+ padding: 10px 15px;
159
+ border-radius: 18px;
160
+ margin: 5px 0;
161
+ border-left: 4px solid #2196f3;
162
+ }
163
 
164
+ .chat-bubble-assistant {
165
+ background: #f3e5f5;
166
+ padding: 10px 15px;
167
+ border-radius: 18px;
168
+ margin: 5px 0;
169
+ border-left: 4px solid #9c27b0;
170
+ }
171
+
172
+ .parameter-box {
173
+ background: #f8f9fa;
174
+ padding: 15px;
175
+ border-radius: 10px;
176
+ border: 1px solid #dee2e6;
177
+ }
178
+ """
179
+
180
+ with gr.Blocks(css=custom_css, theme=gr.themes.Soft(), title="TinyRP Mistral Demo") as interface:
181
+ gr.HTML("""
182
+ <div style="text-align: center; padding: 20px;">
183
+ <h1 style="background: linear-gradient(45deg, #667eea, #764ba2); -webkit-background-clip: text; -webkit-text-fill-color: transparent; font-size: 3em; margin: 0;">
184
+ 🎭 TinyRP Mistral Demo
185
+ </h1>
186
+ <p style="font-size: 1.2em; color: #666; margin-top: 10px;">
187
+ Interactive roleplay with your custom-trained language model
188
+ </p>
189
+ </div>
190
+ """)
191
+
192
+ with gr.Row():
193
+ with gr.Column(scale=1):
194
+ gr.HTML('<div class="character-card"><h3>πŸŽͺ Character Setup</h3></div>')
195
+
196
+ # Sample character dropdown
197
+ sample_char_dropdown = gr.Dropdown(
198
+ choices=[""] + list(SAMPLE_CHARACTERS.keys()),
199
+ label="πŸ“š Load Sample Character",
200
+ value="",
201
+ interactive=True
202
+ )
203
+
204
+ # Character information inputs
205
+ character_name = gr.Textbox(
206
+ label="πŸ‘€ Character Name",
207
+ placeholder="Enter character name...",
208
+ lines=1
209
+ )
210
+
211
+ character_desc = gr.Textbox(
212
+ label="🎨 Character Description",
213
+ placeholder="Describe your character's appearance, role, etc...",
214
+ lines=3
215
+ )
216
+
217
+ character_background = gr.Textbox(
218
+ label="πŸ“– Background & Personality",
219
+ placeholder="Character's history, personality traits, speaking style...",
220
+ lines=4
221
+ )
222
+
223
+ # Generation parameters
224
+ gr.HTML('<div class="parameter-box"><h4>βš™οΈ Generation Settings</h4></div>')
225
+
226
+ max_length = gr.Slider(
227
+ minimum=50, maximum=300, value=150, step=10,
228
+ label="πŸ“ Max Response Length"
229
+ )
230
+
231
+ temperature = gr.Slider(
232
+ minimum=0.1, maximum=2.0, value=0.8, step=0.1,
233
+ label="🌑️ Temperature (creativity)"
234
+ )
235
+
236
+ top_p = gr.Slider(
237
+ minimum=0.1, maximum=1.0, value=0.9, step=0.05,
238
+ label="🎯 Top-p (focus)"
239
+ )
240
+
241
+ top_k = gr.Slider(
242
+ minimum=1, maximum=100, value=50, step=5,
243
+ label="πŸ” Top-k"
244
+ )
245
+
246
+ repetition_penalty = gr.Slider(
247
+ minimum=1.0, maximum=1.5, value=1.1, step=0.05,
248
+ label="πŸ”„ Repetition Penalty"
249
+ )
250
+
251
+ clear_btn = gr.Button("πŸ—‘οΈ Clear Conversation", variant="secondary")
252
 
253
+ with gr.Column(scale=2):
254
+ gr.HTML('<div class="character-card"><h3>πŸ’¬ Roleplay Chat</h3></div>')
255
+
256
+ # Chat interface
257
+ chatbot = gr.Chatbot(
258
+ label="Conversation",
259
+ height=400,
260
+ show_label=False,
261
+ container=True,
262
+ bubble_full_width=False
263
  )
264
+
265
+ with gr.Row():
266
+ msg = gr.Textbox(
267
+ label="Your message",
268
+ placeholder="Type your message here...",
269
+ lines=2,
270
+ scale=4,
271
+ show_label=False
272
+ )
273
+ send_btn = gr.Button("Send πŸ“€", variant="primary", scale=1)
274
+
275
+ # System prompt preview
276
+ with gr.Accordion("πŸ” System Prompt Preview", open=False):
277
+ system_prompt_preview = gr.Textbox(
278
+ label="Generated System Prompt",
279
+ lines=3,
280
+ interactive=False
281
+ )
282
 
283
+ # Event handlers
284
+ def update_character_info(selected_char):
285
+ if selected_char:
286
+ return load_sample_character(selected_char)
287
+ return "", "", ""
288
+
289
+ def update_system_prompt(name, desc, bg):
290
+ if name.strip():
291
+ prompt = f"You are {name.strip()}."
292
+ if desc.strip():
293
+ prompt += f" {desc.strip()}"
294
+ if bg.strip():
295
+ prompt += f" {bg.strip()}"
296
+ return prompt
297
+ return ""
298
+
299
+ def respond(message, history, char_name, char_desc, char_bg, max_len, temp, top_p_val, top_k_val, rep_pen):
300
+ if not message.strip():
301
+ return history, ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
 
303
+ # Create system prompt
304
+ system_prompt = update_system_prompt(char_name, char_desc, char_bg)
 
 
 
 
 
305
 
306
+ # Generate response
307
+ try:
308
+ response = rp_model.generate_response(
309
+ character_info=system_prompt,
310
+ conversation_history=history,
311
+ user_input=message,
312
+ max_length=max_len,
313
+ temperature=temp,
314
+ top_p=top_p_val,
315
+ top_k=top_k_val,
316
+ repetition_penalty=rep_pen
317
+ )
318
+
319
+ # Update history
320
+ history.append((message, response))
321
+ return history, ""
322
+
323
+ except Exception as e:
324
+ error_msg = f"Error generating response: {str(e)}"
325
+ history.append((message, error_msg))
326
+ return history, ""
327
+
328
+ def clear_conversation():
329
+ return [], ""
330
+
331
+ # Wire up events
332
+ sample_char_dropdown.change(
333
+ update_character_info,
334
+ inputs=[sample_char_dropdown],
335
+ outputs=[character_name, character_desc, character_background]
336
+ )
337
+
338
+ for input_component in [character_name, character_desc, character_background]:
339
+ input_component.change(
340
+ update_system_prompt,
341
+ inputs=[character_name, character_desc, character_background],
342
+ outputs=[system_prompt_preview]
343
  )
344
+
345
+ msg.submit(
346
+ respond,
347
+ inputs=[msg, chatbot, character_name, character_desc, character_background,
348
+ max_length, temperature, top_p, top_k, repetition_penalty],
349
+ outputs=[chatbot, msg]
350
+ )
351
+
352
+ send_btn.click(
353
+ respond,
354
+ inputs=[msg, chatbot, character_name, character_desc, character_background,
355
+ max_length, temperature, top_p, top_k, repetition_penalty],
356
+ outputs=[chatbot, msg]
357
+ )
358
+
359
+ clear_btn.click(
360
+ clear_conversation,
361
+ outputs=[chatbot, msg]
362
+ )
363
+
364
+ # Load initial character
365
+ interface.load(
366
+ lambda: load_sample_character("Luna the Mage"),
367
+ outputs=[character_name, character_desc, character_background]
368
+ )
369
 
370
+ return interface
371
+
372
+ if __name__ == "__main__":
373
+ import argparse
 
 
374
 
375
+ parser = argparse.ArgumentParser(description="TinyRP Mistral Gradio Demo")
376
+ parser.add_argument("--model", type=str, default="DarwinAnim8or/TinyRP",
377
+ help="Hugging Face model name or local path")
378
+ parser.add_argument("--share", action="store_true", help="Create public share link")
379
+ parser.add_argument("--port", type=int, default=7860, help="Port to run on")
380
 
381
+ args = parser.parse_args()
 
 
 
 
382
 
383
+ # Create and launch interface
384
+ demo = create_gradio_interface(args.model)
385
+ demo.launch(
386
+ share=args.share,
387
+ server_port=args.port,
388
+ server_name="0.0.0.0" if args.share else "127.0.0.1"
389
+ )