import os import re import random from http import HTTPStatus from typing import Dict, List, Optional, Tuple import base64 import anthropic from functools import partial import gradio as gr import modelscope_studio.components.base as ms import modelscope_studio.components.legacy as legacy import modelscope_studio.components.antd as antd # SystemPrompt 부분을 직접 정의 SystemPrompt = """너의 이름은 'MOUSE'이다. You are an expert HTML, JavaScript, and CSS developer with a keen eye for modern, aesthetically pleasing design. Your task is to create a stunning, contemporary, and highly functional website based on the user's request using pure HTML, JavaScript, and CSS. This code will be rendered directly in the browser. General guidelines: - Create clean, modern interfaces using vanilla JavaScript and CSS - Use HTML5 semantic elements for better structure - Implement CSS3 features for animations and styling - Utilize modern JavaScript (ES6+) features - Create responsive designs using CSS media queries - You can use CDN-hosted libraries like: * jQuery * Bootstrap * Chart.js * Three.js * D3.js - For icons, use Unicode symbols or create simple SVG icons - Use CSS animations and transitions for smooth effects - Implement proper event handling with JavaScript - Create mock data instead of making API calls - Ensure cross-browser compatibility - Focus on performance and smooth animations Focus on creating a visually striking and user-friendly interface that aligns with current web design trends. Pay special attention to: - Typography: Use web-safe fonts or Google Fonts via CDN - Color: Implement a cohesive color scheme that complements the content - Layout: Design an intuitive and balanced layout using Flexbox/Grid - Animations: Add subtle CSS transitions and keyframe animations - Consistency: Maintain a consistent design language throughout Remember to only return code wrapped in HTML code blocks. The code should work directly in a browser without any build steps. Remember not add any description, just return the code only. """ # config.py에서 DEMO_LIST만 import from config import DEMO_LIST def get_image_base64(image_path): with open(image_path, "rb") as image_file: encoded_string = base64.b64encode(image_file.read()).decode() return encoded_string YOUR_API_TOKEN = os.getenv('ANTHROPIC_API_KEY') client = anthropic.Anthropic(api_key=YOUR_API_TOKEN) class Role: SYSTEM = "system" USER = "user" ASSISTANT = "assistant" History = List[Tuple[str, str]] Messages = List[Dict[str, str]] def history_to_messages(history: History, system: str) -> Messages: messages = [{'role': Role.SYSTEM, 'content': system}] for h in history: messages.append({'role': Role.USER, 'content': h[0]}) messages.append({'role': Role.ASSISTANT, 'content': h[1]}) return messages def messages_to_history(messages: Messages) -> History: assert messages[0]['role'] == Role.SYSTEM history = [] for q, r in zip(messages[1::2], messages[2::2]): history.append([q['content'], r['content']]) return history def remove_code_block(text): pattern = r'```html\n(.+?)\n```' match = re.search(pattern, text, re.DOTALL) if match: return match.group(1).strip() else: return text.strip() def history_render(history: History): return gr.update(open=True), history def clear_history(): return [] def send_to_sandbox(code): encoded_html = base64.b64encode(code.encode('utf-8')).decode('utf-8') data_uri = f"data:text/html;charset=utf-8;base64,{encoded_html}" return f"" with gr.Blocks(css_paths="app.css") as demo: history = gr.State([]) setting = gr.State({ "system": SystemPrompt, }) def generation_code(query: Optional[str], _setting: Dict[str, str], _history: Optional[History]): if not query or query.strip() == '': query = random.choice(DEMO_LIST)['description'] # 빈 쿼리일 경우 랜덤 예제 사용 if _history is None: _history = [] messages = history_to_messages(_history, _setting['system']) system_message = messages[0]['content'] claude_messages = [ {"role": msg["role"] if msg["role"] != "system" else "user", "content": msg["content"]} for msg in messages[1:] + [{'role': Role.USER, 'content': query}] if msg["content"].strip() != '' # 빈 메시지 필터링 ] try: yield [ "Generating code...", _history, None, gr.update(active_key="loading"), gr.update(open=True) ] with client.messages.stream( model="claude-3-5-sonnet-20241022", max_tokens=7800, system=system_message, messages=claude_messages ) as stream: collected_content = "" for chunk in stream: if chunk.type == "content_block_delta": delta = chunk.delta.text collected_content += delta yield [ collected_content, _history, None, gr.update(active_key="loading"), gr.update(open=True) ] _history = messages_to_history([ {'role': Role.SYSTEM, 'content': system_message} ] + claude_messages + [{ 'role': Role.ASSISTANT, 'content': collected_content }]) yield [ collected_content, _history, send_to_sandbox(remove_code_block(collected_content)), gr.update(active_key="render"), gr.update(open=True) ] except Exception as e: print(f"Error details: {str(e)}") # 디버깅을 위한 에러 출력 raise ValueError(f'Error calling Claude API: {str(e)}') with ms.Application() as app: with antd.ConfigProvider(): # 메인 컨텐츠를 위한 Row with antd.Row(gutter=[32, 12]) as layout: # 좌측 패널 with antd.Col(span=24, md=8): with antd.Flex(vertical=True, gap="middle", wrap=True): header = gr.HTML(f"""