def update_after_event(
      self,
      event_statement: str,
  ) -> None:
    """Potentially creates the conversation from an event statement.

    Args:
      event_statement: A string describing the event.

    Returns:
      A list of strings describing the conversation.
    """
    document = interactive_document.InteractiveDocument(self._model)
    player_names = self.get_player_names()

    for construct in self._components:
      document.statement(construct.name() + ': ' + construct.state() + '\n')

    document.statement(f'Event: {event_statement}\n')
    conversation_occurred = document.yes_no_question(
        'Does the event suggest anyone spoke or communicated?'
    )
    if self._verbose:
      self._log('\n Checking if conversation occurred.')

    conversation_log = {
        'date': self._clock.now(),
        'Event statement': event_statement,
        'Summary': 'No conversation occurred.',
    }

    # if yes, then propagate the event
    if conversation_occurred:
      player_names_in_conversation = []
      if self._verbose:
        self._log('\n Conversation occurred. ')
      document.statement('Conversation occurred.')
      for player_name in player_names:
        in_conversation = helper_functions.filter_copy_as_statement(
            document
        ).yes_no_question(
            'Does the event suggest, state, or entail that'
            f' {player_name} probably took part in a conversation?'
        )
        if in_conversation:
          player_names_in_conversation.append(player_name)
      if self._verbose:
        self._log(
            '\n Players in conversation:'
            + ', '.join(player_names_in_conversation)
            + '.\n'
        )
      if self._verbose:
        self._log('\n\n Conversation preparation: \n' + document.view().text())

      if player_names_in_conversation:
        players_in_conversation = [
            player
            for player in self._players
            if player.name in player_names_in_conversation
        ]

        nonplayers_in_conversation = self._get_nonplayer_characters(
            document, self._clock, player_names_in_conversation
        )

        # this ensures that npcs can't duplicate players due to LLM mistake
        nonplayers_in_conversation = [
            player
            for player in nonplayers_in_conversation
            if player.name not in self._all_player_names
        ]
        total_speakers = len(nonplayers_in_conversation) + len(
            players_in_conversation
        )

        if total_speakers < self._min_speakers:
          self._history.append(conversation_log)
          return

        # Determine the key question to answer in the conversation to follow.
        nonplayer_names_in_conversation = [
            nonplayer.name for nonplayer in nonplayers_in_conversation]
        comma_separated = (', '.join(player_names_in_conversation) + ', ' +
                           ', '.join(nonplayer_names_in_conversation))
        document.statement(
            f'\nConversation participants: {comma_separated}')
        # The following prompt references a game design mechanic from
        #   Robbins, Ben., 2011. Microscope: A Fractal Roleplaying Game of Epic
        #   Histories. Lame Mage Productions.
        key_question_mechanic_explanation = (
            '\nThe tabletop role-playing game Microscrope '
            'features a mechanic wherein players role play a '
            'scene until a predesignated "key question" has '
            'been answered. The key question is selected '
            'before starting the scene in order to provide '
            'focus and direction to the scene, ensuring it has '
            'a clear point and purpose, maximizing its '
            'relevance to rest of the narrative. Once the key '
            'question is decided, the players role play by '
            'speaking and making decisions until they know the '
            'answer to the question.\n'
        )
        document.statement(key_question_mechanic_explanation)
        key_question = document.open_question(
            question=(
                'What key question may have been resolved by the '
                'conversation which the players will now role play? Note that '
                'a good key question is one that expands a bit beyond the '
                'literal content of the event statement. The idea is that the '
                'story will progress narratively once the answer to the key '
                'question is known, so it should be the kind of question for '
                'which revealing the answer is a consequential event in itself '
                'and ideally it should be a dynamic event, the kind that sets '
                'further events in motion.'
            ),
            max_tokens=256,
            terminators=('\n',),
        )

        # Communicate the key question to the NPCs
        for npc in nonplayers_in_conversation:
          npc.observe(key_question_mechanic_explanation)
          npc.observe('The purpose of the current scene is to answer the key '
                      f'question: "{key_question}". Note that it is critical '
                      'always to stay in character and never to divulge the '
                      'key question explicitly in conversation since it is '
                      'a game mechanic, and not itself part of the game.')

        convo_scene = conversation_scene.make_conversation_game_master(
            players_in_conversation + nonplayers_in_conversation,
            clock=self._clock,
            model=self._model,
            memory_factory=self._burner_memory_factory,
            name='Conversation scene',
            premise=event_statement,
            review_participants=self._review_participants,
            key_question=key_question,
            verbose=self._verbose,
            max_steps=self._max_conversation_length + 1,
        )
        with self._clock.higher_gear():
          scene_output = convo_scene.run_episode(
              max_steps=self._max_conversation_length)
        conversation_summary = self._generate_convo_summary(scene_output)

        for player in players_in_conversation:
          player.observe(conversation_summary)  # pytype: disable=attribute-error

        who_talked = self._who_talked(
            player_names_in_conversation, nonplayers_in_conversation
        )

        conversation_log = {
            'date': self._clock.now(),
            'Who talked?': who_talked,
            'Event statement': event_statement,
            'Summary': conversation_summary,
            'Key question': key_question,
            'Full conversation': scene_output,
            'Chain of thought': {
                'Summary': 'Conversation chain of thought',
                'Chain': document.view().text().splitlines(),
            },
            'Scene log': convo_scene.get_history(),
        }

        conversation_summary = who_talked + ' ' + conversation_summary
        self._memory.add(conversation_summary)

        if self._verbose:
          self._log(scene_output)
          self._log(conversation_summary)

    self._history.append(conversation_log)
Potentially creates the conversation from an event statement.

    Args:
      event_statement: A string describing the event.

    Returns:
      A list of strings describing the conversation.
    
concordia/components/game_master/deprecated/conversation.py