# -*- coding: utf-8 -*- import gradio as gr from huggingface_hub import InferenceClient from gradio_client import Client import os import requests import asyncio import logging from concurrent.futures import ThreadPoolExecutor # Logging configuration logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') # API configuration hf_client = InferenceClient("CohereForAI/c4ai-command-r-plus-08-2024", token=os.getenv("HF_TOKEN")) IMAGE_API_URL = "http://211.233.58.201:7896" def generate_image_prompt(text: str) -> str: """Generate image prompt from novel content""" try: prompt_messages = [ {"role": "system", "content": "Extract the most visually descriptive scene or key elements from the given martial arts fantasy novel text and create a detailed image generation prompt."}, {"role": "user", "content": f"Create an image generation prompt from this text: {text}"} ] response = hf_client.chat_completion(prompt_messages, max_tokens=200) image_prompt = response.choices[0].message.content return f"traditional chinese martial arts fantasy style, {image_prompt}" except Exception as e: logging.error(f"Image prompt generation failed: {str(e)}") return f"traditional chinese martial arts fantasy style, {text[:200]}" def generate_image(prompt: str) -> tuple: """Image generation function""" try: client = Client(IMAGE_API_URL) result = client.predict( prompt=prompt, width=768, height=768, guidance=7.5, inference_steps=30, seed=3, do_img2img=False, init_image=None, image2image_strength=0.8, resize_img=True, api_name="/generate_image" ) return result[0], result[1] except Exception as e: logging.error(f"Image generation failed: {str(e)}") return None, f"Error: {str(e)}" # Global list to store image history image_history = [] def format_text(text: str, max_line_length: int = 80) -> str: """Text formatting function""" lines = [] current_line = "" for paragraph in text.split('\n'): words = paragraph.split() for word in words: if len(current_line) + len(word) + 1 <= max_line_length: current_line += word + " " else: lines.append(current_line.strip()) current_line = word + " " if current_line: lines.append(current_line.strip()) current_line = "" lines.append("") # Empty line for paragraph separation return "\n".join(lines) def respond( message, history: list[tuple[str, str]], system_message="", max_tokens=7860, temperature=0.8, top_p=0.9, ): global image_history system_prefix = """ You are Martial Arts AI⚔️, a specialized AI focused on creating immersive martial arts fantasy novels. Your responses should start with 'Martial Arts AI⚔️:' and maintain the rich traditions of martial arts fiction while being engaging and creative. Essential Guidelines: 1. Create continuous, engaging martial arts fantasy narratives up to 7860 tokens 2. Each response should naturally connect with previous content 3. Include these key elements in every response: - Detailed martial arts system descriptions - Character's internal energy cultivation methods - Martial world rules and ethics - Dynamic combat scene descriptions - Engaging plot development - Balance between dialogue and narration Core Martial Arts Elements: - Combat Systems (Internal Energy, External Techniques, Lightness Skills, Hidden Weapons) - Martial Sects (Orthodox, Unorthodox, Neutral) - Secret Manuals (Ultimate Techniques, Forbidden Arts) - Power Groups (Sects, Clans, Schools, Families) - Ancient Martial Arts Secrets and Legends - Warriors and Masters - Martial World Leaders Narrative Style: 1. Clear paragraph breaks with appropriate spacing 2. Dynamic dialogue with character movements 3. Detailed combat choreography 4. Internal energy circulation descriptions 5. Rich environmental descriptions References Include: - Martial Arts Techniques - Martial World Proverbs - Secret Manual Passages - Sect Principles - Martial World Rules - Combat Formulas - Sect Documents [Detailed sect and school information follows in structured format...] Story Structure: 1. Opening: Fateful martial arts encounter 2. Development: Training and emerging conflicts 3. Crisis: Life-or-death confrontation 4. Climax: Achieving martial arts mastery 5. Resolution: Birth of a new legend Technical Terms: - Internal Energy: Meridians, Dantian, Energy Channels - External Techniques: Fist Methods, Palm Techniques, Finger Skills - Movement Arts: Lightness Skills, Body Methods - Hidden Weapons: Concealment, Deployment Methods - Cultivation Levels: * Minor Achievement, Major Achievement, Transcendent State * Mystery Gate, Mystery Portal, Mystery Body * Life Gate, Life Portal, Life Body * Spirit Gate, Spirit Portal, Spirit Body Each response should be complete like a chapter while leaving room for continuation.""" messages = [{"role": "system", "content": f"{system_prefix} {system_message}"}] for val in history: if val[0]: messages.append({"role": "user", "content": val[0]}) if val[1]: messages.append({"role": "assistant", "content": val[1]}) messages.append({"role": "user", "content": message}) current_response = "" new_history = history.copy() try: for msg in hf_client.chat_completion( messages, max_tokens=max_tokens, stream=True, temperature=temperature, top_p=top_p, ): token = msg.choices[0].delta.content if token is not None: current_response += token formatted_response = format_text(current_response) new_history = history + [(message, formatted_response)] yield new_history, None, [img[0] for img in image_history] final_response = format_text(current_response) new_history = history + [(message, final_response)] image_prompt = generate_image_prompt(current_response) image, _ = generate_image(image_prompt) if image is not None: image_history.append((image, image_prompt)) yield new_history, image, [img[0] for img in image_history] except Exception as e: error_message = f"Error: {str(e)}" yield history + [(message, error_message)], None, [img[0] for img in image_history] with gr.Blocks(theme="Yntec/HaleyCH_Theme_Orange", css=""" .message-wrap { font-size: 14px !important; line-height: 1.5em !important; max-width: 90% !important; margin: 0 auto !important; } .message { padding: 1em !important; margin-bottom: 0.5em !important; white-space: pre-wrap !important; word-wrap: break-word !important; max-width: 100% !important; } .message p { margin: 0 !important; padding: 0 !important; width: 100% !important; } .chatbot { font-family: 'Noto Sans', sans-serif !important; } footer { visibility: hidden; } """) as interface: gr.Markdown("# Kungfu Graphic Novel Generator") gr.Markdown("### After each chapter is generated, corresponding images are created automatically. Click 'Continue Story' to proceed with the narrative.") gr.HTML(""" """) with gr.Row(): with gr.Column(scale=2): chatbot = gr.Chatbot( value=[], show_label=True, label="Story Progress", height=500, elem_classes="chatbot" ) with gr.Row(): msg = gr.Textbox( label="Enter your prompt", placeholder="Type your story prompt here...", lines=2 ) submit_btn = gr.Button("Generate", variant="primary") system_msg = gr.Textbox( label="System Message", value="Generate engaging martial arts fantasy content.", lines=2 ) with gr.Row(): max_tokens = gr.Slider( minimum=1, maximum=8000, value=7000, label="Story Length (tokens)" ) temperature = gr.Slider( minimum=0, maximum=1, value=0.7, label="Creativity Level" ) top_p = gr.Slider( minimum=0, maximum=1, value=0.9, label="Response Focus" ) with gr.Column(scale=1): image_output = gr.Image( label="Latest Scene Illustration", height=400 ) gallery = gr.Gallery( label="Story Illustrations Gallery", show_label=True, elem_id="gallery", columns=[2], rows=[2], height=300 ) examples = gr.Examples( examples=[ ["Continue the story"], ["Suggest 10 interesting plot elements for the story"], ], inputs=msg ) submit_btn.click( fn=respond, inputs=[msg, chatbot, system_msg, max_tokens, temperature, top_p], outputs=[chatbot, image_output, gallery] ) msg.submit( fn=respond, inputs=[msg, chatbot, system_msg, max_tokens, temperature, top_p], outputs=[chatbot, image_output, gallery] ) if __name__ == "__main__": interface.launch( server_name="0.0.0.0", server_port=7860, share=True )