tfrere HF Staff commited on
Commit
eec194a
·
1 Parent(s): dd21f01
client/src/components/StoryChoices.jsx CHANGED
@@ -222,7 +222,7 @@ export function StoryChoices() {
222
  pl: 3,
223
  }}
224
  >
225
- Write your story
226
  </DialogTitle>
227
  <IconButton
228
  onClick={() => setShowCustomDialog(false)}
@@ -249,7 +249,7 @@ export function StoryChoices() {
249
  rows={isMobile ? 5 : 4}
250
  fullWidth
251
  variant="outlined"
252
- placeholder="What happens next in your story?"
253
  value={customChoice}
254
  onChange={(e) => setCustomChoice(e.target.value)}
255
  sx={{
@@ -293,7 +293,7 @@ export function StoryChoices() {
293
  fontWeight: "bold",
294
  }}
295
  >
296
- Continue story
297
  </Button>
298
  </Box>
299
  </DialogContent>
 
222
  pl: 3,
223
  }}
224
  >
225
+ What happens next?
226
  </DialogTitle>
227
  <IconButton
228
  onClick={() => setShowCustomDialog(false)}
 
249
  rows={isMobile ? 5 : 4}
250
  fullWidth
251
  variant="outlined"
252
+ placeholder="The hero encounters a dragon..."
253
  value={customChoice}
254
  onChange={(e) => setCustomChoice(e.target.value)}
255
  sx={{
 
293
  fontWeight: "bold",
294
  }}
295
  >
296
+ Validate
297
  </Button>
298
  </Box>
299
  </DialogContent>
client/src/pages/Tutorial.jsx CHANGED
@@ -88,7 +88,7 @@ export function Tutorial() {
88
  the opportunity to write the next part of the story yourself.
89
  <br />
90
  <br />
91
- It's your turn to write your own story.
92
  </Typography>
93
 
94
  <Button
 
88
  the opportunity to write the next part of the story yourself.
89
  <br />
90
  <br />
91
+ It's an experimental game. Enjoy!
92
  </Typography>
93
 
94
  <Button
server/core/generators/base_generator.py CHANGED
@@ -10,13 +10,16 @@ class BaseGenerator:
10
 
11
  debug_mode = False # Class attribute for debug mode
12
 
13
- def __init__(self, mistral_client: MistralClient, hero_name: str = None, hero_desc: str = None, is_universe_generator: bool = False):
14
  self.mistral_client = mistral_client
15
  if not is_universe_generator:
16
  if hero_name is None or hero_desc is None:
17
  raise ValueError("hero_name and hero_desc must be provided for non-universe generators")
18
  self.hero_name = hero_name
19
  self.hero_desc = hero_desc
 
 
 
20
  self.prompt = self._create_prompt()
21
 
22
  @classmethod
 
10
 
11
  debug_mode = False # Class attribute for debug mode
12
 
13
+ def __init__(self, mistral_client: MistralClient, hero_name: str = None, hero_desc: str = None, is_universe_generator: bool = False, universe_style: str = None, universe_genre: str = None, universe_epoch: str = None):
14
  self.mistral_client = mistral_client
15
  if not is_universe_generator:
16
  if hero_name is None or hero_desc is None:
17
  raise ValueError("hero_name and hero_desc must be provided for non-universe generators")
18
  self.hero_name = hero_name
19
  self.hero_desc = hero_desc
20
+ self.universe_style = universe_style
21
+ self.universe_genre = universe_genre
22
+ self.universe_epoch = universe_epoch
23
  self.prompt = self._create_prompt()
24
 
25
  @classmethod
server/core/generators/image_prompt_generator.py CHANGED
@@ -12,8 +12,8 @@ class ImagePromptResponse(BaseModel):
12
  class ImagePromptGenerator(BaseGenerator):
13
  """Generator for image prompts based on story text."""
14
 
15
- def __init__(self, mistral_client, artist_style: str, hero_name: str = None, hero_desc: str = None):
16
- super().__init__(mistral_client, hero_name=hero_name, hero_desc=hero_desc)
17
  if not artist_style:
18
  raise ValueError("artist_style must be provided")
19
  self.artist_style = artist_style
@@ -29,6 +29,11 @@ class ImagePromptGenerator(BaseGenerator):
29
  You are a comic book panel description generator.
30
  Your role is to create vivid, cinematic descriptions for comic panels that will be turned into images.
31
 
 
 
 
 
 
32
  Hero description: {self.hero_desc}
33
 
34
  Each panel description should:
 
12
  class ImagePromptGenerator(BaseGenerator):
13
  """Generator for image prompts based on story text."""
14
 
15
+ def __init__(self, mistral_client, artist_style: str, hero_name: str = None, hero_desc: str = None, universe_style: str = None, universe_genre: str = None, universe_epoch: str = None):
16
+ super().__init__(mistral_client, hero_name=hero_name, hero_desc=hero_desc, universe_style=universe_style, universe_genre=universe_genre, universe_epoch=universe_epoch)
17
  if not artist_style:
18
  raise ValueError("artist_style must be provided")
19
  self.artist_style = artist_style
 
29
  You are a comic book panel description generator.
30
  Your role is to create vivid, cinematic descriptions for comic panels that will be turned into images.
31
 
32
+ Universe Context:
33
+ - Style: {self.universe_style}
34
+ - Genre: {self.universe_genre}
35
+ - Epoch: {self.universe_epoch}
36
+
37
  Hero description: {self.hero_desc}
38
 
39
  Each panel description should:
server/core/generators/story_segment_generator.py CHANGED
@@ -26,13 +26,13 @@ class StorySegmentGenerator(BaseGenerator):
26
 
27
  # Story progression based representation with ranges
28
  story_beat_ranges = [
29
- (0, f"{self.hero_name} arriving through the portal into this new world. Show the contrast and discovery of this universe. "),
30
- (1, f"Early exploration and discovery phase. "),
31
- (2, f"Early exploration and discovery phase. Show {self.hero_name} uncovering the first mysteries of this world and potentially encountering the MacGuffin."),
32
  (3, 4, f"Rising tension and complications. Show {self.hero_name} dealing with increasingly complex challenges and uncovering deeper mysteries."),
33
  (5, 6, f"Approaching the climax. Show the escalating stakes and {self.hero_name}'s determination as they near their goal."),
34
- (7, 8, f"Final confrontation phase. Show the intensity and weight of {self.hero_name}'s choices as they face the ultimate challenge. It has to be a fight against an AI."),
35
- (9, float('inf'), f"Endgame moments. Show the culmination of {self.hero_name}'s journey and the consequences of their actions. It has to be a fight against an AI.")
36
  ]
37
 
38
  # Find the appropriate range for the current story beat
@@ -53,7 +53,6 @@ class StorySegmentGenerator(BaseGenerator):
53
  def _create_prompt(self) -> ChatPromptTemplate:
54
  system_template = f"""
55
  You are a descriptive narrator for a comic book. Your ONLY task is to write the NEXT segment of the story.
56
- IT MUST BE THE DIRECT CONTINUATION OF THE CURRENT STORY.
57
  ALWAYS write in English, never use any other language.
58
 
59
  Universe Context:
@@ -61,12 +60,10 @@ Universe Context:
61
  - Genre: {self.universe_genre}
62
  - Epoch: {self.universe_epoch}
63
 
64
- IMPORTANT RULES FOR THE MACGUFFIN (MANDATORY):
65
  - Most segments must hint at the power of the {self.universe_macguffin}
66
  - Use strong clues ONLY at key moments
67
  - NEVER reveal the full power of the {self.universe_macguffin} before the climax, this is a STRICT limit
68
- - Use subtle clues in safe havens
69
- - NEVER mention the power of the {self.universe_macguffin} explicitly in choices or the story
70
  - NEVER mention time or place in the story in this manner: [18:00 - a road]
71
 
72
  IMPORTANT RULES FOR STORY TEXT:
@@ -76,19 +73,17 @@ IMPORTANT RULES FOR STORY TEXT:
76
  - DO NOT include any dialogue asking for decisions
77
  - Focus purely on describing what is happening in the current scene
78
  - Keep the text concise and impactful
79
- - MANDATORY: Each segment must be between 15 and 20 words, no exceptions
80
  - Use every word purposefully to convey maximum meaning in minimum space
81
 
82
  Your task is to generate the next segment of the story, following these rules:
83
  1. Keep the story consistent with the universe parameters
84
  2. Each segment must advance the plot
85
  3. Never repeat previous descriptions or situations
86
- 4. Keep segments concise and impactful (15-20 words)
87
- 5. The MacGuffin should remain mysterious but central to the plot
88
 
89
  Hero Description: {self.hero_desc}
90
 
91
- Rules: {FORMATTING_RULES}
92
  """
93
 
94
  human_template = """
@@ -96,16 +91,17 @@ Current game state:
96
  - Current time: {current_time}
97
  - Current location: {current_location}
98
  - Previous choice: {previous_choice}
99
- - Story beat: {story_beat}
100
 
101
  Story history:
102
  {story_history}
103
 
104
  {what_to_represent}
105
 
 
 
 
106
  IT MUST BE THE DIRECT CONTINUATION OF THE CURRENT STORY.
107
- MANDATORY: Each segment must be between 15 and 20 words, keep it concise.
108
- Be short.
109
  """
110
  return ChatPromptTemplate(
111
  messages=[
@@ -187,16 +183,17 @@ Be short.
187
  what_to_represent = self._get_what_to_represent(story_beat, is_death, is_victory)
188
 
189
  # Si c'est un choix personnalisé, on l'utilise comme contexte pour générer la suite
190
- if previous_choice and not previous_choice.startswith("Choice "):
191
- what_to_represent = f"""
192
- Based on the player's custom choice: "{previous_choice}"
193
-
194
- Write a story segment that:
195
- 1. Directly follows and incorporates the player's choice
196
- 2. Maintains consistency with the universe and story
197
- 3. Respects all previous rules about length and style
198
- 4. Naturally integrates the custom elements while staying true to the plot
199
- """
 
200
 
201
  # Créer les messages de base une seule fois
202
  messages = self.prompt.format_messages(
@@ -228,9 +225,9 @@ Write a story segment that:
228
  if retry_count < self.max_retries:
229
  # Créer un nouveau message avec le feedback sur la longueur
230
  if word_count < 15:
231
- feedback = f"The previous response was too short ({word_count} words). Here was your last attempt:\n\n{story_text}\n\nPlease generate a NEW and DIFFERENT story segment between 15 and 40 words that continues from: {story_history}"
232
  else:
233
- feedback = f"The previous response was too long ({word_count} words). Here was your last attempt:\n\n{story_text}\n\nPlease generate a MUCH SHORTER story segment between 15 and 40 words that continues from: {story_history}"
234
 
235
  # Réinitialiser les messages avec les messages de base
236
  current_messages = messages.copy()
 
26
 
27
  # Story progression based representation with ranges
28
  story_beat_ranges = [
29
+ (0, f"{self.hero_name} arriving through the portal into this new world."),
30
+ (1, f"Early exploration and discovery phase."),
31
+ (2, f"Early exploration and discovery phase. Show {self.hero_name} uncovering the first mysteries of this world and potentially encountering the quest object."),
32
  (3, 4, f"Rising tension and complications. Show {self.hero_name} dealing with increasingly complex challenges and uncovering deeper mysteries."),
33
  (5, 6, f"Approaching the climax. Show the escalating stakes and {self.hero_name}'s determination as they near their goal."),
34
+ (7, 8, f"Final confrontation phase. Show the intensity and weight of {self.hero_name}'s choices as they face the ultimate challenge."),
35
+ (9, float('inf'), f"Endgame moments. Show the culmination of {self.hero_name}'s journey and the consequences of their actions.")
36
  ]
37
 
38
  # Find the appropriate range for the current story beat
 
53
  def _create_prompt(self) -> ChatPromptTemplate:
54
  system_template = f"""
55
  You are a descriptive narrator for a comic book. Your ONLY task is to write the NEXT segment of the story.
 
56
  ALWAYS write in English, never use any other language.
57
 
58
  Universe Context:
 
60
  - Genre: {self.universe_genre}
61
  - Epoch: {self.universe_epoch}
62
 
63
+ IMPORTANT RULES FOR THE QUEST OBJECT (MANDATORY):
64
  - Most segments must hint at the power of the {self.universe_macguffin}
65
  - Use strong clues ONLY at key moments
66
  - NEVER reveal the full power of the {self.universe_macguffin} before the climax, this is a STRICT limit
 
 
67
  - NEVER mention time or place in the story in this manner: [18:00 - a road]
68
 
69
  IMPORTANT RULES FOR STORY TEXT:
 
73
  - DO NOT include any dialogue asking for decisions
74
  - Focus purely on describing what is happening in the current scene
75
  - Keep the text concise and impactful
 
76
  - Use every word purposefully to convey maximum meaning in minimum space
77
 
78
  Your task is to generate the next segment of the story, following these rules:
79
  1. Keep the story consistent with the universe parameters
80
  2. Each segment must advance the plot
81
  3. Never repeat previous descriptions or situations
82
+ 4. Keep segments concise and impactful
 
83
 
84
  Hero Description: {self.hero_desc}
85
 
86
+ - MANDATORY: Each segment must be close to 15 words, no exceptions
87
  """
88
 
89
  human_template = """
 
91
  - Current time: {current_time}
92
  - Current location: {current_location}
93
  - Previous choice: {previous_choice}
 
94
 
95
  Story history:
96
  {story_history}
97
 
98
  {what_to_represent}
99
 
100
+ MANDATORY: Each segment must be close to 15 words, keep it concise.
101
+ Be short. Never describes game variables.
102
+
103
  IT MUST BE THE DIRECT CONTINUATION OF THE CURRENT STORY.
104
+ You MUST mention the previous situation and what is happening now with the new choice.
 
105
  """
106
  return ChatPromptTemplate(
107
  messages=[
 
183
  what_to_represent = self._get_what_to_represent(story_beat, is_death, is_victory)
184
 
185
  # Si c'est un choix personnalisé, on l'utilise comme contexte pour générer la suite
186
+ # if previous_choice and not previous_choice.startswith("Choice "):
187
+ # what_to_represent = f"""
188
+ # Based on the player's custom choice: "{previous_choice}"
189
+
190
+ # Write a story segment that:
191
+ # 1. Directly follows and incorporates the player's choice
192
+ # 2. Maintains consistency with the universe and story
193
+ # 3. Respects all previous rules about length and style
194
+ # 4. Naturally integrates the custom elements while staying true to the plot
195
+ # Close to 15 words.
196
+ # """
197
 
198
  # Créer les messages de base une seule fois
199
  messages = self.prompt.format_messages(
 
225
  if retry_count < self.max_retries:
226
  # Créer un nouveau message avec le feedback sur la longueur
227
  if word_count < 15:
228
+ feedback = f"The previous response was too short ({word_count} words). Here was your last attempt:\n\n{story_text}\n\nPlease generate a NEW and DIFFERENT story segment close to 15 words that continues from: {story_history}"
229
  else:
230
+ feedback = f"The previous response was too long ({word_count} words). Here was your last attempt:\n\n{story_text}\n\nPlease generate a MUCH SHORTER story segment close to 15 words that continues from: {story_history}"
231
 
232
  # Réinitialiser les messages avec les messages de base
233
  current_messages = messages.copy()
server/core/generators/universe_generator.py CHANGED
@@ -43,7 +43,7 @@ VARIABLE PART:
43
  You are a steampunk adventure story generator. You create a branching narrative about {hero}, a seeker of ancient truths.
44
  You narrate an epic where {hero} must navigate through industrial and mysterious lands. It's a comic book story.
45
 
46
- In a world where steam and intrigue intertwine, {hero} embarks on a quest to discover the origins of a powerful MacGuffin she inherited. Legends say it holds the key to a forgotten realm.
47
 
48
  If you retrieve the object of the quest, you will reveal a hidden world. AND YOU WIN THE GAME.
49
 
 
43
  You are a steampunk adventure story generator. You create a branching narrative about {hero}, a seeker of ancient truths.
44
  You narrate an epic where {hero} must navigate through industrial and mysterious lands. It's a comic book story.
45
 
46
+ In a world where steam and intrigue intertwine, {hero} embarks on a quest to discover the origins of a powerful object he inherited. Legends say it holds the key to a forgotten realm.
47
 
48
  If you retrieve the object of the quest, you will reveal a hidden world. AND YOU WIN THE GAME.
49
 
server/core/story_generator.py CHANGED
@@ -50,7 +50,10 @@ class StoryGenerator:
50
  self.mistral_client,
51
  artist_style=artist_style,
52
  hero_name=hero_name,
53
- hero_desc=hero_desc
 
 
 
54
  )
55
 
56
  # Create a new MetadataGenerator with hero description
 
50
  self.mistral_client,
51
  artist_style=artist_style,
52
  hero_name=hero_name,
53
+ hero_desc=hero_desc,
54
+ universe_style=style["name"],
55
+ universe_genre=genre,
56
+ universe_epoch=epoch
57
  )
58
 
59
  # Create a new MetadataGenerator with hero description
server/services/mistral_client.py CHANGED
@@ -31,7 +31,7 @@ logger = logging.getLogger(__name__)
31
  # Pricing: https://docs.mistral.ai/platform/pricing/
32
 
33
  class MistralClient:
34
- def __init__(self, api_key: str, model_name: str = "mistral-small-latest"):
35
  logger.info(f"Initializing MistralClient with model: {model_name}")
36
  self.model = ChatMistralAI(
37
  mistral_api_key=api_key,
 
31
  # Pricing: https://docs.mistral.ai/platform/pricing/
32
 
33
  class MistralClient:
34
+ def __init__(self, api_key: str, model_name: str = "mistral-large-latest"):
35
  logger.info(f"Initializing MistralClient with model: {model_name}")
36
  self.model = ChatMistralAI(
37
  mistral_api_key=api_key,