Spaces:
Build error
Build error
| import modal | |
| import gradio as gr | |
| import os | |
| import requests | |
| import json | |
| from fastapi import Request | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| # Create Modal app | |
| app = modal.App("llm-conversation-transfer") | |
| # Define image with dependencies | |
| image = modal.Image.debian_slim().pip_install([ | |
| "gradio==4.44.1", | |
| "requests", | |
| "fastapi" | |
| ]) | |
| # Function to check API keys | |
| def check_api_keys(): | |
| status = { | |
| 'Anthropic': 'β ' if os.getenv('ANTHROPIC_API_KEY') else 'β', | |
| 'Mistral': 'β ' if os.getenv('MISTRAL_API_KEY') else 'β', | |
| 'Hyperbolic': 'β ' if os.getenv('HYPERBOLIC_API_KEY') else 'β' | |
| } | |
| return json.dumps(status) | |
| # Function to handle conversation transfer | |
| def transfer_conversation_backend(conversation_text: str, source_provider: str, target_provider: str, source_model: str, target_model: str): | |
| try: | |
| if not conversation_text.strip(): | |
| return "β Error: Please provide conversation text", "" | |
| messages = parse_conversation_text(conversation_text) | |
| response = get_ai_response(messages, target_provider, target_model) | |
| return "β Transfer successful!", response | |
| except Exception as e: | |
| return f"β Error: {str(e)}", "" | |
| def parse_conversation_text(text: str) -> list: | |
| lines = text.strip().split('\n') | |
| messages = [] | |
| current_message = {"role": "", "content": ""} | |
| for line in lines: | |
| line = line.strip() | |
| if not line: | |
| continue | |
| if line.startswith(('Human:', 'User:')): | |
| if current_message["content"]: | |
| messages.append(current_message.copy()) | |
| current_message = {"role": "user", "content": line.split(':', 1)[1].strip()} | |
| elif line.startswith(('Assistant:', 'AI:')): | |
| if current_message["content"]: | |
| messages.append(current_message.copy()) | |
| current_message = {"role": "assistant", "content": line.split(':', 1)[1].strip()} | |
| else: | |
| current_message["content"] += " " + line | |
| if current_message["content"]: | |
| messages.append(current_message) | |
| return messages | |
| def get_ai_response(messages: list, provider: str, model: str) -> str: | |
| try: | |
| if provider == "Mistral": | |
| headers = { | |
| "Content-Type": "application/json", | |
| "Authorization": f"Bearer {os.getenv('MISTRAL_API_KEY')}" | |
| } | |
| data = { | |
| "model": model, | |
| "messages": messages, | |
| "max_tokens": 1000 | |
| } | |
| response = requests.post("https://api.mistral.ai/v1/chat/completions", headers=headers, json=data) | |
| response.raise_for_status() | |
| return response.json()["choices"][0]["message"]["content"] | |
| elif provider == "Hyperbolic": | |
| headers = { | |
| "Content-Type": "application/json", | |
| "Authorization": f"Bearer {os.getenv('HYPERBOLIC_API_KEY')}" | |
| } | |
| data = { | |
| "model": model, | |
| "messages": messages, | |
| "max_tokens": 1000 | |
| } | |
| response = requests.post("https://api.hyperbolic.xyz/v1/chat/completions", headers=headers, json=data) | |
| response.raise_for_status() | |
| return response.json()["choices"][0]["message"]["content"] | |
| elif provider == "Anthropic": | |
| return "Simulated Claude response." | |
| else: | |
| return f"Unsupported provider: {provider}" | |
| except Exception as e: | |
| raise Exception(f"Failed to get response from {provider}: {str(e)}") | |
| # Create the Gradio interface | |
| def create_interface(): | |
| with gr.Blocks() as demo: | |
| gr.Markdown("# π LLM Conversation Transfer Tool") | |
| with gr.Row(): | |
| api_status_display = gr.Textbox(label="π API Keys Status", interactive=False) | |
| check_status_btn = gr.Button("π Check Status") | |
| with gr.Row(): | |
| source_provider = gr.Dropdown(choices=["Anthropic", "Mistral", "Hyperbolic"], value="Anthropic", label="Source Provider") | |
| source_model = gr.Textbox(value="claude-3-sonnet-20240229", label="Source Model") | |
| target_provider = gr.Dropdown(choices=["Anthropic", "Mistral", "Hyperbolic"], value="Mistral", label="Target Provider") | |
| target_model = gr.Textbox(value="mistral-large-latest", label="Target Model") | |
| conversation_input = gr.Textbox(lines=12, label="Conversation Text") | |
| transfer_btn = gr.Button("π Transfer Conversation") | |
| status_output = gr.Textbox(label="π Transfer Status", interactive=False) | |
| response_output = gr.Textbox(label="π€ AI Response", interactive=False) | |
| async def check_keys(): | |
| result = await check_api_keys.remote.aio() | |
| return result | |
| async def transfer_convo(conv_text, src_prov, tgt_prov, src_model, tgt_model): | |
| status, response = await transfer_conversation_backend.remote.aio(conv_text, src_prov, tgt_prov, src_model, tgt_model) | |
| return status, response | |
| check_status_btn.click(fn=check_keys, outputs=api_status_display) | |
| transfer_btn.click(fn=transfer_convo, | |
| inputs=[conversation_input, source_provider, target_provider, source_model, target_model], | |
| outputs=[status_output, response_output]) | |
| demo.load(fn=check_keys, outputs=api_status_display) | |
| return demo | |
| # ASGI app implementation | |
| def fastapi_app(): | |
| from fastapi import FastAPI | |
| app = FastAPI() | |
| gradio_app = create_interface() | |
| app = gr.mount_gradio_app(app, gradio_app, path="/") | |
| return app |