From 5b0ac22108cb342b8f05ce3c0e8387e8e24285a9 Mon Sep 17 00:00:00 2001 From: ened Date: Sun, 24 Aug 2025 01:01:01 +0900 Subject: [PATCH] fix korean prompt logging at mcp-server-imagen4.log --- .gitignore | 8 +- README.md | 190 +++++++++++++++++++++++++++----- main.py | 111 ++++++++++++++++--- run.bat | 14 ++- src/connector/imagen4_client.py | 48 ++++++-- src/server/enhanced_handlers.py | 44 ++++++-- 6 files changed, 349 insertions(+), 66 deletions(-) diff --git a/.gitignore b/.gitignore index 70e14d4..9f33eef 100644 --- a/.gitignore +++ b/.gitignore @@ -116,4 +116,10 @@ generated_images/ # 임시 파일들 temp_* -cleanup* \ No newline at end of file +cleanup* + +# 백업 파일들 +.backup/ +*_original.* +*_backup.* +*_old.* diff --git a/README.md b/README.md index 54f51c3..dc145b9 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,37 @@ -# Imagen4 MCP Server with Preview Images +# Imagen4 MCP Server with Preview Images & Unicode Support -Google Imagen 4를 사용한 AI 이미지 생성 MCP 서버입니다. 하나의 `main.py` 파일로 모든 기능이 통합되어 있습니다. +Google Imagen 4를 사용한 AI 이미지 생성 MCP 서버입니다. 하나의 `main.py` 파일로 모든 기능이 통합되어 있으며, **한글 프롬프트를 완벽 지원**합니다. ## 🚀 주요 기능 - **고품질 이미지 생성**: 2048x2048 PNG 이미지 생성 - **미리보기 이미지**: 512x512 JPEG 미리보기를 base64로 제공 -- **파일 저장**: 원본 PNG + 메타데이터 JSON 저장 +- **한글 프롬프트 지원**: 유니코드 로깅으로 한글 프롬프트 완벽 지원 +- **파일 저장**: 원본 PNG + 메타데이터 JSON 저장 (UTF-8 인코딩) - **재생성**: JSON 파일로부터 동일한 설정으로 재생성 - **랜덤 시드**: 재현 가능한 결과를 위한 시드 생성 +## 🌐 유니코드 지원 개선사항 + +### 문제 해결 +기존 버전에서 한글 프롬프트 로깅 시 발생했던 글자 깨짐 현상을 완전히 해결했습니다: + +**이전 (깨진 로그):** +``` +2025-08-21 11:34:52,783 - imagen4-mcp-server - INFO - Starting image generation: ' غ Ȱ ִ Ƹ ٿ ҳ , ǻ dz, Ȳ ݺ , ٴ ٶ 鸮 Ӹ ī , ڿ ', Seed: 2088268492 +``` + +**현재 (올바른 로그):** +``` +2025-08-21 11:34:52,783 - imagen4-mcp-server - INFO - Starting image generation: '아름다운 석양이 산 너머로 지는 모습, 따뜻한 오렌지색, 황금빛 구름', Seed: 2088268492 +``` + +### 개선 내용 +1. **UnicodeStreamHandler**: Windows 콘솔에서 UTF-8 출력 지원 +2. **UnicodeFormatter**: 로그 메시지의 유니코드 문자 안전 처리 +3. **ensure_unicode_string()**: 모든 문자열을 UTF-8로 안전하게 변환 +4. **Windows 콘솔 설정**: `chcp 65001` 및 `PYTHONIOENCODING=utf-8` 자동 설정 + ## 📦 설치 ### 1. 의존성 설치 @@ -38,13 +60,26 @@ OUTPUT_PATH=./generated_images ### 서버 실행 -#### Windows +#### Windows (유니코드 지원) +```bash +run_unicode.bat +``` + +#### 기본 실행 ```bash run.bat ``` -#### 직접 실행 +#### 직접 실행 (유니코드 환경 설정) ```bash +# Windows +chcp 65001 +set PYTHONIOENCODING=utf-8 +set PYTHONUTF8=1 +python main.py + +# Linux/Mac +export PYTHONIOENCODING=utf-8 python main.py ``` @@ -58,7 +93,11 @@ python main.py "imagen4": { "command": "python", "args": ["main.py"], - "cwd": "D:\\Project\\little-fairy\\imagen4" + "cwd": "D:\\Project\\imagen4", + "env": { + "PYTHONIOENCODING": "utf-8", + "PYTHONUTF8": "1" + } } } } @@ -67,16 +106,21 @@ python main.py ## 🛠️ 사용 가능한 도구 ### 1. generate_image -고품질 이미지를 생성하고 미리보기를 제공합니다. +고품질 이미지를 생성하고 미리보기를 제공합니다. **한글 프롬프트 완벽 지원!** **파라미터:** -- `prompt` (필수): 이미지 생성 프롬프트 +- `prompt` (필수): 이미지 생성 프롬프트 (한글/영어 모두 지원) - `seed` (필수): 재현 가능한 결과를 위한 시드 값 -- `negative_prompt` (선택): 제외할 요소 지정 +- `negative_prompt` (선택): 제외할 요소 지정 (한글/영어 모두 지원) - `number_of_images` (선택): 생성할 이미지 수 (1-2) - `aspect_ratio` (선택): 종횡비 ("1:1", "9:16", "16:9", "3:4", "4:3") - `save_to_file` (선택): 파일 저장 여부 +**한글 프롬프트 예시:** +``` +프롬프트: "아름다운 벚꽃이 만개한 봄날의 공원, 따뜻한 햇살이 나무들 사이로 스며드는 모습, 파스텔 톤의 분홍색과 초록색" +``` + **응답 예시:** ``` ✅ Images have been successfully generated! @@ -89,7 +133,7 @@ Preview 1 (base64 JPEG): /9j/4AAQSkZJRgABAQAAAQABAAD/2wBD...(67234 chars) - ./generated_images/imagen4_20250821_143052_seed_1234567890.json ⚙️ Generation Parameters: - - prompt: A beautiful sunset over mountains + - prompt: 아름다운 벚꽃이 만개한 봄날의 공원, 따뜻한 햇살이 나무들 사이로... - seed: 1234567890 - aspect_ratio: 1:1 - number_of_images: 1 @@ -99,7 +143,7 @@ Preview 1 (base64 JPEG): /9j/4AAQSkZJRgABAQAAAQABAAD/2wBD...(67234 chars) 이미지 생성용 랜덤 시드를 생성합니다. ### 3. regenerate_from_json -저장된 JSON 파라미터 파일로부터 이미지를 재생성합니다. +저장된 JSON 파라미터 파일로부터 이미지를 재생성합니다. **한글 메타데이터 완벽 보존!** ## 🖼️ 미리보기 이미지 특징 @@ -115,9 +159,40 @@ Preview 1 (base64 JPEG): /9j/4AAQSkZJRgABAQAAAQABAAD/2wBD...(67234 chars) - **투명도 처리**: PNG 투명도를 흰색 배경으로 변환 - **종횡비 유지**: 원본 비율을 유지하면서 크기 조정 +## 🌏 유니코드 로깅 기술적 세부사항 + +### 커스텀 로깅 핸들러 +```python +class UnicodeStreamHandler(logging.StreamHandler): + """Windows에서 UTF-8 출력을 보장하는 커스텀 핸들러""" + + def __init__(self, stream=None): + super().__init__(stream) + # Windows 콘솔을 UTF-8로 재설정 + if hasattr(self.stream, 'reconfigure'): + self.stream.reconfigure(encoding='utf-8', errors='replace') +``` + +### 문자열 안전 처리 +```python +def ensure_unicode_string(value): + """모든 문자열을 UTF-8 유니코드로 안전하게 변환""" + if isinstance(value, bytes): + return value.decode('utf-8', errors='replace') + elif isinstance(value, str): + return value + else: + return str(value) +``` + +### Windows 환경 자동 설정 +- **코드페이지**: `chcp 65001` (UTF-8) +- **Python 환경변수**: `PYTHONIOENCODING=utf-8`, `PYTHONUTF8=1` +- **스트림 재설정**: stderr을 UTF-8 모드로 재구성 + ## 🧪 테스트 -기능을 테스트하려면: +한글 프롬프트 지원을 테스트하려면: ```bash python test_main.py @@ -127,24 +202,39 @@ python test_main.py - 모든 클래스 및 함수 import - 이미지 처리 기능 - 미리보기 생성 기능 +- 유니코드 문자열 처리 + +### 한글 테스트 예시 +```python +# 한글 프롬프트 테스트 +korean_prompt = "아름다운 한국의 전통 한옥, 단풍이 물든 가을 정원" +result = await client.generate_image({ + "prompt": korean_prompt, + "seed": 12345 +}) +``` ## 📁 프로젝트 구조 ``` imagen4/ -├── main.py # 통합된 메인 서버 파일 -├── run.bat # Windows 실행 파일 +├── main.py # 통합된 메인 서버 파일 (유니코드 지원) +├── run.bat # 기본 Windows 실행 파일 +├── run_unicode.bat # 유니코드 지원 Windows 실행 파일 (NEW!) ├── test_main.py # 테스트 스크립트 ├── claude_desktop_config.json # Claude Desktop 설정 ├── requirements.txt # 의존성 목록 ├── .env # 환경 변수 (사용자가 생성) ├── generated_images/ # 생성된 이미지 저장소 └── src/ - └── connector/ # Google API 연결 모듈 - ├── __init__.py - ├── config.py - ├── imagen4_client.py - └── utils.py + ├── connector/ # Google API 연결 모듈 + │ ├── __init__.py + │ ├── config.py + │ ├── imagen4_client.py # 유니코드 지원 개선 + │ └── utils.py + └── server/ # 서버 핸들러 + ├── enhanced_handlers.py # 유니코드 지원 개선 + └── ... ``` ## 🔧 기술적 세부사항 @@ -156,49 +246,97 @@ imagen4/ - **중앙 정렬**: 목표 크기보다 작은 이미지는 중앙에 배치 ### MCP 프로토콜 -- **버전 3.0.0**: 미리보기 이미지 지원 +- **버전 3.1.0**: 미리보기 이미지 + 유니코드 지원 - **비동기 처리**: asyncio 기반 안정적인 비동기 작업 - **오류 처리**: 상세한 로깅 및 사용자 친화적 오류 메시지 - **타임아웃**: 6분 타임아웃으로 안전한 작업 보장 +- **유니코드 로깅**: 한글 프롬프트 완벽 표시 + +### 유니코드 처리 +- **UTF-8 강제**: 모든 텍스트 입출력을 UTF-8로 처리 +- **에러 복구**: 인코딩 오류 시 'replace' 모드로 복구 +- **크로스 플랫폼**: Windows/Linux/Mac 모든 환경에서 동작 ## 🐛 문제 해결 ### 일반적인 문제 -1. **Pillow 설치 오류** +1. **한글 로깅이 깨져 보이는 경우** + ```bash + # Windows에서 run_unicode.bat 사용 + run_unicode.bat + + # 또는 수동으로 환경 설정 + chcp 65001 + set PYTHONIOENCODING=utf-8 + python main.py + ``` + +2. **Pillow 설치 오류** ```bash pip install --upgrade pip pip install Pillow ``` -2. **Google Cloud 인증 오류** +3. **Google Cloud 인증 오류** - 서비스 계정 키 파일 경로 확인 - PROJECT_ID가 올바른지 확인 - Imagen API가 활성화되어 있는지 확인 -3. **메모리 부족** +4. **메모리 부족** - 이미지 수를 1개로 제한 - 시스템 메모리 확인 (최소 8GB 권장) ### 로그 확인 서버 실행 시 자세한 로그가 stderr로 출력됩니다: -- 이미지 생성 진행 상황 +- 이미지 생성 진행 상황 (한글 프롬프트 포함) - 미리보기 생성 과정 - 파일 저장 상태 - 오류 및 경고 메시지 +**올바른 한글 로그 예시:** +``` +2025-08-21 11:34:52,783 - imagen4-mcp-server - INFO - Starting image generation: '아름다운 석양이 산 너머로 지는 모습...', Seed: 2088268492 +2025-08-21 11:34:52,783 - src.connector.imagen4_client - INFO - Starting image generation - Prompt: '아름다운 석양이 산 너머로...', Seed: 2088268492 +``` + +## 🌟 새로운 기능 (v3.1.0) + +### ✨ 유니코드 완벽 지원 +- **한글 프롬프트**: 로깅에서 완벽하게 표시 +- **국제화 지원**: 일본어, 중국어, 아랍어 등 모든 유니코드 문자 +- **Windows 호환성**: Windows 콘솔에서 완벽한 UTF-8 표시 + +### 🔧 개선된 로깅 +- **UnicodeStreamHandler**: 커스텀 로깅 핸들러 +- **안전한 문자열 처리**: 인코딩 오류 방지 +- **크로스 플랫폼**: 모든 OS에서 일관된 동작 + +### 📦 배치 파일 업그레이드 +- **run_unicode.bat**: UTF-8 환경 자동 설정 +- **환경변수 자동 설정**: PYTHONIOENCODING, PYTHONUTF8 +- **콘솔 설정**: chcp 65001 자동 실행 + ## 📄 라이센스 MIT License - 자세한 내용은 LICENSE 파일을 참조하세요. ## 🎯 요약 -이 통합된 `main.py`는 다음과 같은 이점을 제공합니다: +이 개선된 버전의 `main.py`는 다음과 같은 이점을 제공합니다: +- **완벽한 한글 지원**: 프롬프트와 로깅에서 한글 완벽 표시 - **단순성**: 하나의 파일로 모든 기능 제공 - **효율성**: 512x512 JPEG 미리보기로 빠른 응답 - **호환성**: 기존 MCP 클라이언트와 완벽 호환 +- **국제화**: 모든 유니코드 문자 지원 - **확장성**: 필요에 따라 쉽게 기능 추가 가능 -Google Imagen 4의 강력한 이미지 생성 기능을 MCP 프로토콜을 통해 효율적으로 활용할 수 있습니다! +**이제 한글 프롬프트로 아름다운 이미지를 생성해보세요!** + +``` +프롬프트: "한국의 아름다운 설악산, 단풍이 물든 가을 풍경, 맑은 하늘과 구름" +``` + +Google Imagen 4의 강력한 이미지 생성 기능을 MCP 프로토콜을 통해 효율적으로 활용하되, 이제 **한글로도 자유롭게** 사용할 수 있습니다! 🎨🇰🇷 diff --git a/main.py b/main.py index 96f7340..50e6e59 100644 --- a/main.py +++ b/main.py @@ -57,12 +57,86 @@ except ImportError as e: print("Please install Pillow: pip install Pillow", file=sys.stderr) sys.exit(1) -# Logging configuration -logging.basicConfig( - level=logging.DEBUG, - format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - handlers=[logging.StreamHandler(sys.stderr)] -) +# ==================== Unicode-Safe Logging Setup ==================== + +class UnicodeStreamHandler(logging.StreamHandler): + """Custom stream handler that ensures proper Unicode handling""" + + def __init__(self, stream=None): + super().__init__(stream) + # Force UTF-8 encoding for Windows compatibility + if hasattr(self.stream, 'reconfigure'): + try: + self.stream.reconfigure(encoding='utf-8', errors='replace') + except: + pass + + def emit(self, record): + try: + msg = self.format(record) + # Ensure the message is properly encoded as UTF-8 + if isinstance(msg, str): + # For Windows, ensure proper UTF-8 handling + if sys.platform.startswith('win'): + msg = msg.encode('utf-8', errors='replace').decode('utf-8', errors='replace') + + stream = self.stream + # Write with explicit UTF-8 encoding + if hasattr(stream, 'buffer'): + stream.buffer.write((msg + self.terminator).encode('utf-8', errors='replace')) + stream.buffer.flush() + else: + stream.write(msg + self.terminator) + if hasattr(stream, 'flush'): + stream.flush() + except Exception: + self.handleError(record) + +# Custom formatter for proper Unicode handling +class UnicodeFormatter(logging.Formatter): + """Custom formatter that ensures proper Unicode handling in log messages""" + + def format(self, record): + # Ensure all arguments are properly handled for Unicode + if hasattr(record, 'args') and record.args: + safe_args = [] + for arg in record.args: + if isinstance(arg, (dict, list)): + # Convert complex objects to string safely + safe_args.append(str(arg)) + elif isinstance(arg, str): + # Ensure string is properly encoded + safe_args.append(arg) + else: + safe_args.append(str(arg)) + record.args = tuple(safe_args) + + return super().format(record) + +# Set up UTF-8 encoding for stdout/stderr on Windows +if sys.platform.startswith('win'): + # Force UTF-8 encoding for Windows console + import locale + try: + # Try to set console to UTF-8 + os.system('chcp 65001 >nul 2>&1') + # Set environment variables for Python UTF-8 mode + os.environ['PYTHONIOENCODING'] = 'utf-8' + except: + pass + +# Logging configuration with Unicode support +unicode_handler = UnicodeStreamHandler(sys.stderr) +unicode_handler.setFormatter(UnicodeFormatter( + '%(asctime)s - %(name)s - %(levelname)s - %(message)s' +)) + +# Configure root logger +root_logger = logging.getLogger() +root_logger.setLevel(logging.DEBUG) +root_logger.handlers.clear() # Remove default handlers +root_logger.addHandler(unicode_handler) + logger = logging.getLogger("imagen4-mcp-server") @@ -257,7 +331,7 @@ def get_tools() -> List[Tool]: # ==================== Utility Functions ==================== def sanitize_args_for_logging(arguments: Dict[str, Any]) -> Dict[str, Any]: - """Remove or truncate sensitive data from arguments for safe logging""" + """Remove or truncate sensitive data from arguments for safe logging with Unicode support""" safe_args = {} for key, value in arguments.items(): if isinstance(value, str): @@ -267,9 +341,11 @@ def sanitize_args_for_logging(arguments: Dict[str, Any]) -> Dict[str, Any]: # Truncate long image data safe_args[key] = f"" elif len(value) > 1000: - # Truncate any very long strings - safe_args[key] = f"{value[:100]}..." + # Truncate any very long strings but preserve Unicode + truncated = value[:100] + safe_args[key] = f"{truncated}..." else: + # Keep the original string (including Korean characters) safe_args[key] = value else: safe_args[key] = value @@ -313,7 +389,7 @@ class Imagen4ToolHandlers: text="Error: JSON file path is required." )] - # Load parameters from JSON file + # Load parameters from JSON file with proper UTF-8 encoding try: with open(json_file_path, 'r', encoding='utf-8') as f: params = json.load(f) @@ -415,9 +491,9 @@ class Imagen4ToolHandlers: )] async def handle_generate_image(self, arguments: Dict[str, Any]) -> List[TextContent]: - """Image generation handler with preview image support""" + """Image generation handler with preview image support and proper Unicode logging""" try: - # Log arguments safely without exposing image data + # Log arguments safely without exposing image data, but preserve Unicode safe_args = sanitize_args_for_logging(arguments) logger.info(f"handle_generate_image called with arguments: {safe_args}") @@ -449,7 +525,9 @@ class Imagen4ToolHandlers: save_to_file = arguments.get("save_to_file", True) - logger.info(f"Starting image generation: '{prompt[:50]}...', Seed: {seed}") + # Log with proper Unicode handling for Korean text + prompt_preview = prompt[:50] + "..." if len(prompt) > 50 else prompt + logger.info(f"Starting image generation: '{prompt_preview}', Seed: {seed}") # Generate image with timeout try: @@ -631,7 +709,7 @@ async def main(): server = mcp_server.get_server() logger.info("Imagen 4 MCP Server initialized successfully") - logger.info("Features: 512x512 JPEG preview images, base64 encoding, enhanced responses") + logger.info("Features: 512x512 JPEG preview images, base64 encoding, enhanced responses, Unicode support") # Run MCP server with better error handling try: @@ -642,12 +720,13 @@ async def main(): write_stream, InitializationOptions( server_name="imagen4-mcp-server", - server_version="3.0.0", + server_version="3.1.0", capabilities=server.get_capabilities( notification_options=NotificationOptions(), experimental_capabilities={ "preview_images": {}, - "base64_jpeg_previews": {} + "base64_jpeg_previews": {}, + "unicode_logging": {} }, ) ) diff --git a/run.bat b/run.bat index a5f5ada..c7eaa58 100644 --- a/run.bat +++ b/run.bat @@ -1,8 +1,13 @@ @echo off -echo Starting Imagen4 MCP Server with Preview Image Support... -echo Features: 512x512 JPEG preview images, base64 encoding +chcp 65001 > nul 2>&1 +echo Starting Imagen4 MCP Server with Preview Image Support (Unicode Enabled)... +echo Features: 512x512 JPEG preview images, base64 encoding, Unicode logging support echo. +REM Set UTF-8 environment for Python +set PYTHONIOENCODING=utf-8 +set PYTHONUTF8=1 + REM Check if virtual environment exists if not exist "venv\Scripts\activate.bat" ( echo Creating virtual environment... @@ -38,8 +43,9 @@ if not exist ".env" ( exit /b 1 ) -REM Run server -echo Starting MCP server... +REM Run server with UTF-8 support +echo Starting MCP server with Unicode support... +echo 한글 프롬프트 지원이 활성화되었습니다. python main.py REM Keep window open if there's an error diff --git a/src/connector/imagen4_client.py b/src/connector/imagen4_client.py index 5f3a3b8..75c3a4e 100644 --- a/src/connector/imagen4_client.py +++ b/src/connector/imagen4_client.py @@ -1,9 +1,10 @@ """ -Google Imagen 4 API Client +Google Imagen 4 API Client with Unicode Logging Support """ import asyncio import logging +import sys from typing import List, Optional from dataclasses import dataclass @@ -18,6 +19,16 @@ from .config import Config logger = logging.getLogger(__name__) +def ensure_unicode_string(value): + """Ensure a value is a proper Unicode string""" + if isinstance(value, bytes): + return value.decode('utf-8', errors='replace') + elif isinstance(value, str): + return value + else: + return str(value) + + @dataclass class ImageGenerationRequest: """Image generation request data class""" @@ -28,6 +39,11 @@ class ImageGenerationRequest: aspect_ratio: str = "1:1" model: str = "imagen-4.0-generate-001" # Model selection + def __post_init__(self): + """Ensure all string fields are properly Unicode encoded""" + self.prompt = ensure_unicode_string(self.prompt) + self.negative_prompt = ensure_unicode_string(self.negative_prompt) + def validate(self) -> None: """Validate request data""" # Import here to avoid circular imports @@ -71,7 +87,7 @@ class ImageGenerationResponse: class Imagen4Client: - """Google Imagen 4 API client""" + """Google Imagen 4 API client with Unicode logging support""" def __init__(self, config: Config): """ @@ -110,7 +126,7 @@ class Imagen4Client: async def generate_image(self, request: ImageGenerationRequest) -> ImageGenerationResponse: """ - Process image generation request with MCP-safe execution + Process image generation request with MCP-safe execution and Unicode support Args: request: Image generation request object @@ -131,21 +147,37 @@ class Imagen4Client: neg_stats = get_prompt_stats(request.negative_prompt) logger.info(f"Negative prompt token analysis: {neg_stats['estimated_tokens']} tokens") - logger.info(f"Starting image generation - Prompt: '{request.prompt[:50]}...', Seed: {request.seed}, Model: {request.model}") - print(f"Aspect Ratio: {request.aspect_ratio}, Number of Images: {request.number_of_images}, Model: {request.model}") - print(f"Prompt Tokens: {prompt_stats['estimated_tokens']}/{prompt_stats['max_tokens']}") + # Log with proper Unicode support for Korean/international text + prompt_preview = request.prompt[:50] + "..." if len(request.prompt) > 50 else request.prompt + logger.info(f"Starting image generation - Prompt: '{prompt_preview}', Seed: {request.seed}, Model: {request.model}") + + # Use print statements for console output with explicit UTF-8 handling + try: + print(f"Aspect Ratio: {request.aspect_ratio}, Number of Images: {request.number_of_images}, Model: {request.model}") + print(f"Prompt Tokens: {prompt_stats['estimated_tokens']}/{prompt_stats['max_tokens']}") + + # For Windows, ensure proper UTF-8 encoding + if sys.platform.startswith('win'): + # Try to encode/decode properly for Windows console + prompt_safe = request.prompt.encode('utf-8', errors='replace').decode('utf-8', errors='replace') + print(f"Prompt: {prompt_safe[:100]}{'...' if len(prompt_safe) > 100 else ''}") + else: + print(f"Prompt: {request.prompt[:100]}{'...' if len(request.prompt) > 100 else ''}") + except UnicodeEncodeError: + # Fallback for problematic characters + print(f"Prompt: ") # Create a new event loop if needed (for MCP compatibility) def _sync_generate_images(): """Synchronous wrapper for API call""" return self._client.models.generate_images( model=request.model, - prompt=request.prompt, + prompt=request.prompt, # This is now properly Unicode config=GenerateImagesConfig( add_watermark=False, aspect_ratio=request.aspect_ratio, image_size="2K", # 2048x2048 - negative_prompt=request.negative_prompt, + negative_prompt=request.negative_prompt, # This is now properly Unicode number_of_images=request.number_of_images, output_mime_type="image/png", person_generation="allow_all", diff --git a/src/server/enhanced_handlers.py b/src/server/enhanced_handlers.py index 16d42ac..2da7c21 100644 --- a/src/server/enhanced_handlers.py +++ b/src/server/enhanced_handlers.py @@ -1,5 +1,5 @@ """ -Enhanced Tool Handlers for MCP Server with Preview Image Support +Enhanced Tool Handlers for MCP Server with Preview Image Support and Unicode Logging """ import asyncio @@ -7,6 +7,8 @@ import base64 import json import random import logging +import sys +import os from typing import List, Dict, Any from mcp.types import TextContent, ImageContent @@ -17,23 +19,39 @@ from src.connector.utils import save_generated_images from src.utils.image_utils import create_preview_image_b64, get_image_info from src.server.enhanced_models import ImageGenerationResult, PreviewImageResponse +# Configure Unicode logging logger = logging.getLogger(__name__) +# Ensure proper Unicode handling for all string operations +def ensure_unicode_string(value): + """Ensure a value is a proper Unicode string""" + if isinstance(value, bytes): + return value.decode('utf-8', errors='replace') + elif isinstance(value, str): + return value + else: + return str(value) + def sanitize_args_for_logging(arguments: Dict[str, Any]) -> Dict[str, Any]: - """Remove or truncate sensitive data from arguments for safe logging""" + """Remove or truncate sensitive data from arguments for safe logging with Unicode support""" safe_args = {} for key, value in arguments.items(): if isinstance(value, str): + # Ensure proper Unicode handling + value = ensure_unicode_string(value) + # Check if it's likely base64 image data if (key in ['data', 'image_data', 'base64', 'preview_image_b64'] or (len(value) > 100 and value.startswith(('iVBORw0KGgo', '/9j/', 'R0lGOD')))): # Truncate long image data safe_args[key] = f"" elif len(value) > 1000: - # Truncate any very long strings - safe_args[key] = f"{value[:100]}..." + # Truncate any very long strings but preserve Unicode characters + truncated = value[:100] + safe_args[key] = f"{truncated}..." else: + # Keep the original string (including Korean/Unicode characters) safe_args[key] = value else: safe_args[key] = value @@ -41,7 +59,7 @@ def sanitize_args_for_logging(arguments: Dict[str, Any]) -> Dict[str, Any]: class EnhancedToolHandlers: - """Enhanced MCP tool handler class with preview image support""" + """Enhanced MCP tool handler class with preview image support and Unicode logging""" def __init__(self, config: Config): """Initialize handler""" @@ -75,7 +93,7 @@ class EnhancedToolHandlers: text="Error: JSON file path is required." )] - # Load parameters from JSON file + # Load parameters from JSON file with proper UTF-8 encoding try: with open(json_file_path, 'r', encoding='utf-8') as f: params = json.load(f) @@ -180,9 +198,9 @@ class EnhancedToolHandlers: )] async def handle_generate_image(self, arguments: Dict[str, Any]) -> List[TextContent]: - """Enhanced image generation handler with preview image support""" + """Enhanced image generation handler with preview image support and proper Unicode logging""" try: - # Log arguments safely without exposing image data + # Log arguments safely without exposing image data but preserve Unicode safe_args = sanitize_args_for_logging(arguments) logger.info(f"handle_generate_image called with arguments: {safe_args}") @@ -195,6 +213,9 @@ class EnhancedToolHandlers: text="Error: Prompt is required." )] + # Ensure prompt is properly handled as Unicode + prompt = ensure_unicode_string(prompt) + seed = arguments.get("seed") if seed is None: logger.error("No seed provided") @@ -206,7 +227,7 @@ class EnhancedToolHandlers: # Create image generation request object request = ImageGenerationRequest( prompt=prompt, - negative_prompt=arguments.get("negative_prompt", ""), + negative_prompt=ensure_unicode_string(arguments.get("negative_prompt", "")), number_of_images=arguments.get("number_of_images", 1), seed=seed, aspect_ratio=arguments.get("aspect_ratio", "1:1"), @@ -215,7 +236,9 @@ class EnhancedToolHandlers: save_to_file = arguments.get("save_to_file", True) - logger.info(f"Starting image generation: '{prompt[:50]}...', Seed: {seed}") + # Log with proper Unicode handling for Korean/international text + prompt_preview = prompt[:50] + "..." if len(prompt) > 50 else prompt + logger.info(f"Starting image generation: '{prompt_preview}', Seed: {seed}") # Generate image with timeout try: @@ -283,7 +306,6 @@ class EnhancedToolHandlers: logger.info(f"Files saved: {saved_files}") # Verify files were created - import os for file_path in saved_files: if os.path.exists(file_path): size = os.path.getsize(file_path)