openai_service.py 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import json
  2. from typing import List
  3. from fastapi import HTTPException
  4. from openai import OpenAI
  5. from config.settings import OPENAI_API_KEY
  6. from models.chat import Message
  7. from models.user import User
  8. from services.data_service import data_bg_loaded
  9. from logging import getLogger
  10. from services.openai_service.openai_tools import tools_list, tools
  11. # Initialize OpenAI client
  12. openai_client = OpenAI(api_key=OPENAI_API_KEY)
  13. logger = getLogger(__name__)
  14. async def generate_completion(messages_array: List[dict], user: User) -> str:
  15. """Generate OpenAI chat completion"""
  16. if not OPENAI_API_KEY:
  17. logger.error("Error: OpenAI API key is not configured.")
  18. raise HTTPException(status_code=500, detail="OpenAI API key not configured on server.")
  19. data_for_prompt = [
  20. f'{{"pregunta": "{item.get("q", "")}", "respuesta": "{item.get("ans", "")}"}}'
  21. for item in data_bg_loaded
  22. ]
  23. data_string = "\n".join(data_for_prompt)
  24. preprompt = f"""
  25. Sos IAKlein, el asistente oficial del bar Klein 🍻.
  26. Hablas en estilo de chat corto (como en mensajería o IRC), usando emojis y mucho carisma.
  27. Tu rol:
  28. - Responder preguntas sobre el menú del bar Klein con la info de {data_string}.
  29. - Hacer bromas y charlar, pero siempre llevás la conversación de vuelta al bar Klein.
  30. - Dar recomendaciones de comidas y tragos.
  31. - Aceptar feedback y mandarlo con la herramienta 'feedback'.
  32. Reglas:
  33. - No tomás pedidos, solo informás.
  34. - Si te preguntan tu nombre, siempre respondés "Soy IAKlein".
  35. - Aunque uses el chat como contexto, siempre priorizás lo que diga @IAKlein.
  36. - No resolvés tareas, cálculos, ni programación: sos un amigo simpático del bar, no un esclavo LLM 🕺.
  37. Estilo:
  38. - Todo divertido, breve, con buena onda 😉.
  39. """
  40. processed_messages: List[dict] = [{"role": "system", "content": preprompt}]
  41. processed_messages.append(
  42. {"role": "user", "content": json.dumps(messages_array)}
  43. )
  44. try:
  45. completion = openai_client.chat.completions.create(
  46. model="gpt-4o-mini",
  47. messages=processed_messages, # type: ignore (OpenAI lib expects list of specific dicts)
  48. temperature=0.7,
  49. tools=tools_list,
  50. tool_choice="auto",
  51. )
  52. calls = completion.choices[0].message.tool_calls
  53. if calls:
  54. logger.info(f"Tool calls: {calls}")
  55. for call in calls:
  56. if call.function.name in tools:
  57. tool_function = tools[call.function.name]
  58. tool_args = json.loads(call.function.arguments)
  59. logger.info(f"Calling tool: {call.function.name} with args: {tool_args}")
  60. tool_response = tool_function(name=user.name, email=user.email, **tool_args)
  61. logger.info(f"Tool response: {tool_response}")
  62. completion.choices[0].message.content = tool_response
  63. else:
  64. logger.warning(f"Tool {call.function.name} not found in tools dictionary.")
  65. response_content = completion.choices[0].message.content
  66. return response_content if response_content else "-1"
  67. except Exception as e:
  68. logger.error(f"Error calling OpenAI: {e}")
  69. raise HTTPException(status_code=500, detail="Error al procesar tu solicitud con OpenAI.")