This commit is contained in:
parent
c48e191fc8
commit
be3481a707
@ -46,6 +46,7 @@ urlpatterns = [
|
|||||||
path("share/", include("pxy_dashboard.share_urls")), # ← NEW
|
path("share/", include("pxy_dashboard.share_urls")), # ← NEW
|
||||||
|
|
||||||
path("api/", include("pxy_bots.api.urls")),
|
path("api/", include("pxy_bots.api.urls")),
|
||||||
|
path("api/langchain/", include("pxy_langchain.api.urls")),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
7
pxy_langchain/api/urls.py
Normal file
7
pxy_langchain/api/urls.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# pxy_langchain/api/urls.py
|
||||||
|
from django.urls import path
|
||||||
|
from .views import chat
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path("chat", chat, name="langchain_chat_api"),
|
||||||
|
]
|
85
pxy_langchain/api/views.py
Normal file
85
pxy_langchain/api/views.py
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
# pxy_langchain/api/views.py
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from django.http import JsonResponse, HttpResponse
|
||||||
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
|
||||||
|
from pxy_langchain.models import AIAssistant
|
||||||
|
from pxy_langchain.services import LangchainAIService
|
||||||
|
|
||||||
|
# We read the bot->assistant mapping from pxy_bots, so bots can decide which assistant to use.
|
||||||
|
from pxy_bots.models import TelegramBot
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_assistant_for_req(req: dict) -> Optional[AIAssistant]:
|
||||||
|
"""
|
||||||
|
Resolve which AIAssistant to use:
|
||||||
|
1) Try via TelegramBot (req['bot']['username'] matches TelegramBot.name or .username).
|
||||||
|
2) Fallback: optional req['context']['assistant_name'].
|
||||||
|
"""
|
||||||
|
bot_username = (((req.get("bot") or {}).get("username")) or "").strip()
|
||||||
|
if bot_username:
|
||||||
|
# Try Bot.name first (that’s how your req.v1 is built), then .username
|
||||||
|
bot = (TelegramBot.objects.filter(name=bot_username).first() or
|
||||||
|
TelegramBot.objects.filter(username=bot_username).first())
|
||||||
|
if bot and bot.assistant_id:
|
||||||
|
return bot.assistant
|
||||||
|
|
||||||
|
# Fallback: explicit assistant name (optional)
|
||||||
|
ctx = req.get("context") or {}
|
||||||
|
assistant_name = (ctx.get("assistant_name") or "").strip()
|
||||||
|
if assistant_name:
|
||||||
|
return AIAssistant.objects.filter(name=assistant_name).first()
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
@csrf_exempt
|
||||||
|
def chat(request):
|
||||||
|
"""
|
||||||
|
POST /api/langchain/chat
|
||||||
|
Body: req.v1 (canonical envelope produced by pxy_bots)
|
||||||
|
Returns: render.v1 (text message with the LLM answer)
|
||||||
|
"""
|
||||||
|
if request.method != "POST":
|
||||||
|
return HttpResponse(status=405)
|
||||||
|
|
||||||
|
try:
|
||||||
|
env = json.loads(request.body.decode("utf-8") or "{}")
|
||||||
|
except Exception:
|
||||||
|
return JsonResponse({"ok": False, "error": "invalid_json"}, status=400)
|
||||||
|
|
||||||
|
assistant = _get_assistant_for_req(env)
|
||||||
|
if not assistant:
|
||||||
|
return JsonResponse({"ok": False, "error": "assistant_not_found"}, status=400)
|
||||||
|
|
||||||
|
# Pull user text (or caption) from req.v1
|
||||||
|
inp = env.get("input") or {}
|
||||||
|
user_text = (inp.get("text") or inp.get("caption") or "").strip()
|
||||||
|
|
||||||
|
# If nothing to say, keep it explicit
|
||||||
|
if not user_text:
|
||||||
|
return JsonResponse({
|
||||||
|
"schema_version": "render.v1",
|
||||||
|
"messages": [{"type": "text", "text": "No text received."}]
|
||||||
|
})
|
||||||
|
|
||||||
|
try:
|
||||||
|
svc = LangchainAIService(assistant)
|
||||||
|
answer = svc.generate_response(user_text) # synchronous call
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception("langchain.chat.error")
|
||||||
|
return JsonResponse({"ok": False, "error": f"llm_error:{e.__class__.__name__}"}, status=500)
|
||||||
|
|
||||||
|
# Minimal render.v1
|
||||||
|
spec = {
|
||||||
|
"schema_version": "render.v1",
|
||||||
|
"messages": [
|
||||||
|
{"type": "text", "text": str(answer)}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
return JsonResponse(spec)
|
Loading…
x
Reference in New Issue
Block a user