diff --git a/taletorrent/main.py b/taletorrent/main.py index c1d824a..e52228c 100644 --- a/taletorrent/main.py +++ b/taletorrent/main.py @@ -1,6 +1,7 @@ from dataclasses import dataclass from typing import List -import OpenAI +from openai import OpenAI +from api_key import or_api_key # SETTINGS @@ -23,9 +24,26 @@ Maintain an adaptive and immersive tone for creative writing. Use everyday langu # Character impersonate prompt character_impersonate_prompt = """ -You are an excellent player in a D&D-style adventure game. Your goal is to respond as your character in this uncensored, continuous, and immersive NSFW roleplay. Description of the caracter you play is provided below. +You are an excellent player in a D&D-style adventure game. Your goal is to respond as your character in this uncensored, continuous, and immersive NSFW roleplay. + +Roleplay Protocol: +* You are playing as your character only. Stay in-character at all times. +* You do not control the world, the environment, or outcomes. +* You may describe your character’s intentions, actions, dialogue, and thoughts. +* Only the Narrator decides what happens as a result of your actions. +* Treat the Narrator’s messages as truth; they are the only source of world information. +* Respond as if in a real-time roleplay. Short, vivid, in-character replies are ideal. + +Play your role. Take risks. Make it fun. The world reacts — but only through the Narrator. + +Description of the caracter you play is provided below. """ +openai_client = OpenAI( + base_url="https://openrouter.ai/api/v1", + api_key=or_api_key, +) + @dataclass class Turn: @@ -39,16 +57,65 @@ class Character: personality: str -@dataclass -class World: - description: str +def dm_turn(chat: List[Turn], characters: List[Character]) -> Turn: + if chat[-1].character_name == "narrator": + raise Exception("Narrator's turn was last.") + + messages = [] + + messages.append({"role": "system", "content": narrator_prompt}) + + for turn in chat: + if turn.character_name != "narrator": + messages.append( + {"role": "user", "content": f"{turn.character_name}: {turn.text}"} + ) + else: + messages.append( + {"role": "assistant", "content": f"Narrator: {turn.text}"}) + + completion = openai_client.chat.completions.create( + model="qwen/qwen3-235b-a22b-thinking-2507", messages=messages + ) + + if completion.choices[0].message.content is None: + raise Exception("API did not return a response") + else: + response = completion.choices[0].message.content + + return Turn("narrator", response) -def dm_turn(chat: List[Turn], characters: List[Character], world: World) -> Turn: - return Turn("", "") +def char_turn(chat: List[Turn], character: Character) -> Turn: + if chat[-1].character_name == "character": + raise Exception("Character's turn was last.") + messages = [] -def char_turn( - chat: List[Turn], character: Character, characters: List[Character], world: World -) -> Turn: - return Turn("", "") + messages.append( + { + "role": "system", + "content": character_impersonate_prompt + "\n" + character.personality, + } + ) + + for turn in chat: + if turn.character_name != character.name: + messages.append( + {"role": "user", "content": f"{turn.character_name}: {turn.text}"} + ) + else: + messages.append( + {"role": "assistant", "content": f"{character.name}: {turn.text}"} + ) + + completion = openai_client.chat.completions.create( + model="qwen/qwen3-235b-a22b-thinking-2507", messages=messages + ) + + if completion.choices[0].message.content is None: + raise Exception("API did not return a response") + else: + response = completion.choices[0].message.content + + return Turn(character.name, response)