Spaces:
Runtime error
Runtime error
| import os | |
| import logging | |
| import time | |
| import json | |
| from fastapi import FastAPI, Request | |
| from fastapi.responses import StreamingResponse | |
| from phonikud import Phonikud, phonemize # ืืืืื ืจืฉืื ืืืกืคืจืืื | |
| from google import genai | |
| from google.genai import types | |
| logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') | |
| logger = logging.getLogger(__name__) | |
| app = FastAPI() | |
| # ืืขืื ืช ืืืืื (ืืงืืืฅ ืืืื ืืืืืช ืืชืืงืืื ืืจืืฉืืช ืฉื ื-Space) | |
| MODEL_PATH = "./phonikud-1.0.int8.onnx" | |
| pk = Phonikud(MODEL_PATH) if os.path.exists(MODEL_PATH) else None | |
| client = genai.Client(api_key=os.getenv("GEMINI_API_KEY")) | |
| async def chat_proxy(request: Request): | |
| try: | |
| body = await request.json() | |
| messages = body.get("messages", []) | |
| # ืื ืืืช ืืืงืฉืจ ืืื ืืื | |
| system_instruction = "" | |
| contents = [] | |
| for msg in messages: | |
| if msg["role"] == "system": | |
| system_instruction = msg["content"] | |
| else: | |
| role = "user" if msg["role"] == "user" else "model" | |
| contents.append(types.Content(role=role, parts=[types.Part(text=msg["content"])])) | |
| # 1. ืงืืืช ืชืฉืืื ื-Gemini | |
| response = client.models.generate_content( | |
| model='gemini-2.5-flash', | |
| contents=contents, | |
| config=types.GenerateContentConfig(system_instruction=system_instruction) | |
| ) | |
| original_text = response.text or "" | |
| logger.info(f"Gemini: {original_text}") | |
| # 2. ืืคืืื ืืคืื ืืืช IPA (ืืฉืืื ืืืืืืจ) | |
| final_output = original_text | |
| if pk and original_text: | |
| try: | |
| # ืืืกืคืช ื ืืงืื | |
| vocalized = pk.add_diacritics(original_text) | |
| # ืืืจื ืืคืื ืืืช IPA | |
| ipa = phonemize(vocalized) | |
| # ืขืืืคื ืืงืจืืกืื (ื ืืงืื ืชืืืื ืืื ืืื ืืืืืช ืืฆืืจื) | |
| final_output = f"<<{ipa.replace('|', '')}>>" | |
| logger.info(f"IPA for Cartesia: {final_output}") | |
| except Exception as e: | |
| logger.error(f"Phonemization failed: {e}") | |
| # 3. ืืืจืื ืืคืืจืื ืฉืืืืคื ืืืื ื | |
| def generate_vapi_stream(): | |
| chat_id = f"chatcmpl-{int(time.time())}" | |
| chunk = { | |
| "id": chat_id, | |
| "object": "chat.completion.chunk", | |
| "choices": [{ | |
| "index": 0, | |
| "delta": {"role": "assistant", "content": final_output}, | |
| "finish_reason": "stop" | |
| }] | |
| } | |
| yield f"data: {json.dumps(chunk)}\n\n" | |
| yield "data: [DONE]\n\n" | |
| return StreamingResponse(generate_vapi_stream(), media_type="text/event-stream") | |
| except Exception as e: | |
| logger.error(f"Error: {str(e)}") | |
| return {"error": str(e)}, 500 | |
| if __name__ == "__main__": | |
| import uvicorn | |
| uvicorn.run(app, host="0.0.0.0", port=7860) |