-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathviews.py
More file actions
88 lines (72 loc) · 3.23 KB
/
views.py
File metadata and controls
88 lines (72 loc) · 3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
"""Django views for Dungeon Master LLM-powered narrative generation."""
import requests
from django.conf import settings
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.request import Request
from rest_framework.response import Response
# A fixed DM instruction for the system prompt
BASE_DM_INSTRUCTION = (
"You are a Dungeon Master. Narrate the story based solely on the following context. "
"Stay in character, do not add extraneous information, and follow the specified settings.\n\n"
)
def build_prompt(data: dict[str, str]) -> str:
"""Build a Dungeon Master prompt from incoming data.
Args:
data: Dictionary containing world context, genre, difficulty, etc.
Returns:
Complete prompt string for the LLM.
"""
# Extract variables from the incoming data
world_context = data.get("world_context", "")
genre = data.get("genre", "")
difficulty = data.get("difficulty", "")
narrative_tone = data.get("narrative_tone", "")
campaign_name = data.get("campaign_name", "")
user_question = data.get("user_question", "")
# Construct the dynamic part of the prompt
prompt_body = (
f"World Context: {world_context}\n"
f"Genre: {genre}\n"
f"Difficulty: {difficulty}\n"
f"Narrative Tone: {narrative_tone}\n"
f"Campaign Name: {campaign_name}\n\n"
f"Now, here is the player's prompt: {user_question}"
)
return BASE_DM_INSTRUCTION + prompt_body
@api_view(["POST"])
def dungeon_view(request: Request) -> Response:
"""API endpoint for generating Dungeon Master narratives using LLM.
Args:
request: Django REST framework request object with POST data.
Returns:
Response with generated narrative or error message.
"""
# Validate incoming data
required_fields = ["world_context", "genre", "difficulty", "narrative_tone", "campaign_name", "user_question"]
for field in required_fields:
if field not in request.data:
return Response({"error": f"Missing field: {field}"}, status=status.HTTP_400_BAD_REQUEST)
# Build the final prompt
final_prompt = build_prompt(request.data)
# Make the API call to the LLM provider using settings
api_endpoint = settings.LLM_API_ENDPOINT
api_key = settings.LLM_API_KEY
llm_model = settings.LLM_MODEL
# This is a simplified example assuming an OpenAI-like API; you might need to adapt it.
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
try:
payload = {
"model": f"{llm_model}",
"messages": [{"role": "system", "content": final_prompt}],
"max_tokens": 150,
}
print(payload)
response = requests.post(api_endpoint, json=payload, headers=headers)
response.raise_for_status()
llm_result = response.json()
narrative = llm_result.get("choices", [{}])[0].get("message", {}).get("content", "").strip()
except Exception as e:
error_details = response.text if response is not None else "No response content"
return Response({"error": f"{str(e)}: {error_details}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
return Response({"narrative": narrative})