Update app.py
Browse files
app.py
CHANGED
@@ -164,15 +164,14 @@ def encode_image_to_base64(image_path):
|
|
164 |
elif file_extension == "webp":
|
165 |
mime_type = "image/webp"
|
166 |
return f"data:{mime_type};base64,{encoded_string}"
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
return None
|
176 |
except Exception as e:
|
177 |
logger.error(f"Error encoding image: {str(e)}")
|
178 |
return None
|
@@ -258,40 +257,13 @@ def prepare_message_with_media(text, images=None, documents=None):
|
|
258 |
|
259 |
return content
|
260 |
|
261 |
-
def
|
262 |
-
"""
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
if filtered_models:
|
269 |
-
return gr.Dropdown.update(choices=filtered_models, value=filtered_models[0])
|
270 |
-
else:
|
271 |
-
return gr.Dropdown.update(choices=[model[0] for model in ALL_MODELS], value=ALL_MODELS[0][0])
|
272 |
-
|
273 |
-
def get_model_info(model_name):
|
274 |
-
"""Get model information by name"""
|
275 |
-
for model in ALL_MODELS:
|
276 |
-
if model[0] == model_name:
|
277 |
-
return model
|
278 |
-
return None
|
279 |
-
|
280 |
-
def update_context_display(model_name):
|
281 |
-
"""Update the context size display based on the selected model"""
|
282 |
-
model_info = get_model_info(model_name)
|
283 |
-
if model_info:
|
284 |
-
name, model_id, context_size = model_info
|
285 |
-
context_formatted = f"{context_size:,}"
|
286 |
-
return f"{context_formatted} tokens"
|
287 |
-
return "Unknown"
|
288 |
-
|
289 |
-
def update_category_models(category):
|
290 |
-
"""Update models list when category changes"""
|
291 |
-
for cat in MODELS:
|
292 |
-
if cat["category"] == category:
|
293 |
-
return gr.Radio.update(choices=[model[0] for model in cat["models"]], value=cat["models"][0][0])
|
294 |
-
return gr.Radio.update(choices=[], value=None)
|
295 |
|
296 |
def ask_ai(message, chatbot, model_choice, temperature, max_tokens, top_p,
|
297 |
frequency_penalty, presence_penalty, repetition_penalty, top_k,
|
@@ -428,10 +400,6 @@ def ask_ai(message, chatbot, model_choice, temperature, max_tokens, top_p,
|
|
428 |
|
429 |
return chatbot, ""
|
430 |
|
431 |
-
def process_uploaded_images(files):
|
432 |
-
"""Process uploaded image files"""
|
433 |
-
return [file.name for file in files]
|
434 |
-
|
435 |
def clear_chat():
|
436 |
"""Reset all inputs"""
|
437 |
return [], "", [], [], 0.7, 1000, 0.8, 0.0, 0.0, 1.0, 40, 0.1, 0, 0.0, False, "default", "none", "", []
|
@@ -465,7 +433,7 @@ def create_app():
|
|
465 |
}
|
466 |
""") as demo:
|
467 |
gr.Markdown("""
|
468 |
-
#
|
469 |
|
470 |
Chat with various AI models from OpenRouter with support for images and documents.
|
471 |
""")
|
@@ -545,15 +513,16 @@ def create_app():
|
|
545 |
|
546 |
# Model category selection
|
547 |
with gr.Accordion("Browse by Category", open=False):
|
548 |
-
model_categories = gr.
|
549 |
[category["category"] for category in MODELS],
|
550 |
label="Categories",
|
551 |
value=MODELS[0]["category"]
|
552 |
)
|
553 |
|
554 |
-
category_models = gr.
|
555 |
[model[0] for model in MODELS[0]["models"]],
|
556 |
-
label="Models in Category"
|
|
|
557 |
)
|
558 |
|
559 |
with gr.Accordion("Generation Parameters", open=False):
|
@@ -719,60 +688,90 @@ def create_app():
|
|
719 |
Built with ❤️ using Gradio and OpenRouter API | Context sizes shown next to model names
|
720 |
""")
|
721 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
722 |
# Connect model search to dropdown filter
|
723 |
model_search.change(
|
724 |
fn=filter_models,
|
725 |
-
inputs=
|
726 |
-
outputs=[model_choice]
|
727 |
)
|
728 |
|
729 |
# Update context display when model changes
|
730 |
model_choice.change(
|
731 |
fn=update_context_display,
|
732 |
-
inputs=
|
733 |
-
outputs=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
734 |
)
|
735 |
|
736 |
# Update model list when category changes
|
737 |
model_categories.change(
|
738 |
fn=update_category_models,
|
739 |
-
inputs=
|
740 |
-
outputs=[category_models]
|
741 |
)
|
742 |
|
743 |
# Update main model choice when category model is selected
|
744 |
category_models.change(
|
745 |
fn=lambda x: x,
|
746 |
-
inputs=
|
747 |
-
outputs=
|
748 |
)
|
749 |
|
750 |
# Process uploaded images
|
751 |
image_upload_btn.upload(
|
752 |
fn=process_uploaded_images,
|
753 |
-
inputs=
|
754 |
-
outputs=
|
755 |
-
)
|
756 |
-
|
757 |
-
# Update model info when model changes
|
758 |
-
def update_model_info(model_name):
|
759 |
-
model_info = get_model_info(model_name)
|
760 |
-
if model_info:
|
761 |
-
name, model_id, context_size = model_info
|
762 |
-
return f"""
|
763 |
-
<div class="model-info">
|
764 |
-
<h3>{name}</h3>
|
765 |
-
<p><strong>Model ID:</strong> {model_id}</p>
|
766 |
-
<p><strong>Context Size:</strong> {context_size:,} tokens</p>
|
767 |
-
<p><strong>Provider:</strong> {model_id.split('/')[0]}</p>
|
768 |
-
</div>
|
769 |
-
"""
|
770 |
-
return "<p>Model information not available</p>"
|
771 |
-
|
772 |
-
model_choice.change(
|
773 |
-
fn=update_model_info,
|
774 |
-
inputs=[model_choice],
|
775 |
-
outputs=[model_info_display]
|
776 |
)
|
777 |
|
778 |
# Set up events for the submit button
|
|
|
164 |
elif file_extension == "webp":
|
165 |
mime_type = "image/webp"
|
166 |
return f"data:{mime_type};base64,{encoded_string}"
|
167 |
+
elif Image is not None and hasattr(image_path, 'save'): # Pillow Image
|
168 |
+
buffered = io.BytesIO()
|
169 |
+
image_path.save(buffered, format="PNG")
|
170 |
+
encoded_string = base64.b64encode(buffered.getvalue()).decode('utf-8')
|
171 |
+
return f"data:image/png;base64,{encoded_string}"
|
172 |
+
else: # Handle file object or other types
|
173 |
+
logger.error(f"Unsupported image type: {type(image_path)}")
|
174 |
+
return None
|
|
|
175 |
except Exception as e:
|
176 |
logger.error(f"Error encoding image: {str(e)}")
|
177 |
return None
|
|
|
257 |
|
258 |
return content
|
259 |
|
260 |
+
def process_uploaded_images(files):
|
261 |
+
"""Process uploaded image files - fixed for Gradio 4.44.1"""
|
262 |
+
file_paths = []
|
263 |
+
for file in files:
|
264 |
+
if hasattr(file, 'name'):
|
265 |
+
file_paths.append(file.name)
|
266 |
+
return file_paths
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
267 |
|
268 |
def ask_ai(message, chatbot, model_choice, temperature, max_tokens, top_p,
|
269 |
frequency_penalty, presence_penalty, repetition_penalty, top_k,
|
|
|
400 |
|
401 |
return chatbot, ""
|
402 |
|
|
|
|
|
|
|
|
|
403 |
def clear_chat():
|
404 |
"""Reset all inputs"""
|
405 |
return [], "", [], [], 0.7, 1000, 0.8, 0.0, 0.0, 1.0, 40, 0.1, 0, 0.0, False, "default", "none", "", []
|
|
|
433 |
}
|
434 |
""") as demo:
|
435 |
gr.Markdown("""
|
436 |
+
# Enhanced AI Chat
|
437 |
|
438 |
Chat with various AI models from OpenRouter with support for images and documents.
|
439 |
""")
|
|
|
513 |
|
514 |
# Model category selection
|
515 |
with gr.Accordion("Browse by Category", open=False):
|
516 |
+
model_categories = gr.Dropdown(
|
517 |
[category["category"] for category in MODELS],
|
518 |
label="Categories",
|
519 |
value=MODELS[0]["category"]
|
520 |
)
|
521 |
|
522 |
+
category_models = gr.Dropdown(
|
523 |
[model[0] for model in MODELS[0]["models"]],
|
524 |
+
label="Models in Category",
|
525 |
+
value=MODELS[0]["models"][0][0]
|
526 |
)
|
527 |
|
528 |
with gr.Accordion("Generation Parameters", open=False):
|
|
|
688 |
Built with ❤️ using Gradio and OpenRouter API | Context sizes shown next to model names
|
689 |
""")
|
690 |
|
691 |
+
# Helper function to filter models
|
692 |
+
def filter_models(search_term):
|
693 |
+
if not search_term:
|
694 |
+
return [model[0] for model in ALL_MODELS], ALL_MODELS[0][0]
|
695 |
+
|
696 |
+
filtered_models = [model[0] for model in ALL_MODELS if search_term.lower() in model[0].lower()]
|
697 |
+
|
698 |
+
if filtered_models:
|
699 |
+
return filtered_models, filtered_models[0]
|
700 |
+
else:
|
701 |
+
return [model[0] for model in ALL_MODELS], ALL_MODELS[0][0]
|
702 |
+
|
703 |
+
# Helper function for context display
|
704 |
+
def update_context_display(model_name):
|
705 |
+
for model in ALL_MODELS:
|
706 |
+
if model[0] == model_name:
|
707 |
+
_, _, context_size = model
|
708 |
+
context_formatted = f"{context_size:,}"
|
709 |
+
return f"{context_formatted} tokens"
|
710 |
+
return "Unknown"
|
711 |
+
|
712 |
+
# Helper function for model info display
|
713 |
+
def update_model_info(model_name):
|
714 |
+
for model in ALL_MODELS:
|
715 |
+
if model[0] == model_name:
|
716 |
+
name, model_id, context_size = model
|
717 |
+
return f"""
|
718 |
+
<div class="model-info">
|
719 |
+
<h3>{name}</h3>
|
720 |
+
<p><strong>Model ID:</strong> {model_id}</p>
|
721 |
+
<p><strong>Context Size:</strong> {context_size:,} tokens</p>
|
722 |
+
<p><strong>Provider:</strong> {model_id.split('/')[0]}</p>
|
723 |
+
</div>
|
724 |
+
"""
|
725 |
+
return "<p>Model information not available</p>"
|
726 |
+
|
727 |
+
# Helper function to update category models
|
728 |
+
def update_category_models(category):
|
729 |
+
for cat in MODELS:
|
730 |
+
if cat["category"] == category:
|
731 |
+
model_names = [model[0] for model in cat["models"]]
|
732 |
+
return model_names, model_names[0]
|
733 |
+
return [], ""
|
734 |
+
|
735 |
# Connect model search to dropdown filter
|
736 |
model_search.change(
|
737 |
fn=filter_models,
|
738 |
+
inputs=model_search,
|
739 |
+
outputs=[model_choice, model_choice]
|
740 |
)
|
741 |
|
742 |
# Update context display when model changes
|
743 |
model_choice.change(
|
744 |
fn=update_context_display,
|
745 |
+
inputs=model_choice,
|
746 |
+
outputs=context_display
|
747 |
+
)
|
748 |
+
|
749 |
+
# Update model info when model changes
|
750 |
+
model_choice.change(
|
751 |
+
fn=update_model_info,
|
752 |
+
inputs=model_choice,
|
753 |
+
outputs=model_info_display
|
754 |
)
|
755 |
|
756 |
# Update model list when category changes
|
757 |
model_categories.change(
|
758 |
fn=update_category_models,
|
759 |
+
inputs=model_categories,
|
760 |
+
outputs=[category_models, category_models]
|
761 |
)
|
762 |
|
763 |
# Update main model choice when category model is selected
|
764 |
category_models.change(
|
765 |
fn=lambda x: x,
|
766 |
+
inputs=category_models,
|
767 |
+
outputs=model_choice
|
768 |
)
|
769 |
|
770 |
# Process uploaded images
|
771 |
image_upload_btn.upload(
|
772 |
fn=process_uploaded_images,
|
773 |
+
inputs=image_upload_btn,
|
774 |
+
outputs=images
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
775 |
)
|
776 |
|
777 |
# Set up events for the submit button
|