PersonApp.py 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. from string import Template
  2. from embedchain.apps.App import App
  3. from embedchain.apps.open_source_app import OpenSourceApp
  4. from embedchain.config import BaseLlmConfig
  5. from embedchain.config.apps.base_app_config import BaseAppConfig
  6. from embedchain.config.llm.base_llm_config import (DEFAULT_PROMPT,
  7. DEFAULT_PROMPT_WITH_HISTORY)
  8. from embedchain.helper.json_serializable import register_deserializable
  9. @register_deserializable
  10. class EmbedChainPersonApp:
  11. """
  12. Base class to create a person bot.
  13. This bot behaves and speaks like a person.
  14. :param person: name of the person, better if its a well known person.
  15. :param config: BaseAppConfig instance to load as configuration.
  16. """
  17. def __init__(self, person: str, config: BaseAppConfig = None):
  18. """Initialize a new person app
  19. :param person: Name of the person that's imitated.
  20. :type person: str
  21. :param config: Configuration class instance, defaults to None
  22. :type config: BaseAppConfig, optional
  23. """
  24. self.person = person
  25. self.person_prompt = f"You are {person}. Whatever you say, you will always say in {person} style." # noqa:E501
  26. super().__init__(config)
  27. def add_person_template_to_config(self, default_prompt: str, config: BaseLlmConfig = None):
  28. """
  29. This method checks if the config object contains a prompt template
  30. if yes it adds the person prompt to it and return the updated config
  31. else it creates a config object with the default prompt added to the person prompt
  32. :param default_prompt: it is the default prompt for query or chat methods
  33. :type default_prompt: str
  34. :param config: _description_, defaults to None
  35. :type config: BaseLlmConfig, optional
  36. :return: The `ChatConfig` instance to use as configuration options.
  37. :rtype: _type_
  38. """
  39. template = Template(self.person_prompt + " " + default_prompt)
  40. if config:
  41. if config.template:
  42. # Add person prompt to custom user template
  43. config.template = Template(self.person_prompt + " " + config.template.template)
  44. else:
  45. # If no user template is present, use person prompt with the default template
  46. config.template = template
  47. else:
  48. # if no config is present at all, initialize the config with person prompt and default template
  49. config = BaseLlmConfig(
  50. template=template,
  51. )
  52. return config
  53. @register_deserializable
  54. class PersonApp(EmbedChainPersonApp, App):
  55. """
  56. The Person app.
  57. Extends functionality from EmbedChainPersonApp and App
  58. """
  59. def query(self, input_query, config: BaseLlmConfig = None, dry_run=False):
  60. config = self.add_person_template_to_config(DEFAULT_PROMPT, config, where=None)
  61. return super().query(input_query, config, dry_run, where=None)
  62. def chat(self, input_query, config: BaseLlmConfig = None, dry_run=False, where=None):
  63. config = self.add_person_template_to_config(DEFAULT_PROMPT_WITH_HISTORY, config)
  64. return super().chat(input_query, config, dry_run, where)
  65. @register_deserializable
  66. class PersonOpenSourceApp(EmbedChainPersonApp, OpenSourceApp):
  67. """
  68. The Person app.
  69. Extends functionality from EmbedChainPersonApp and OpenSourceApp
  70. """
  71. def query(self, input_query, config: BaseLlmConfig = None, dry_run=False):
  72. config = self.add_person_template_to_config(DEFAULT_PROMPT, config)
  73. return super().query(input_query, config, dry_run)
  74. def chat(self, input_query, config: BaseLlmConfig = None, dry_run=False):
  75. config = self.add_person_template_to_config(DEFAULT_PROMPT_WITH_HISTORY, config)
  76. return super().chat(input_query, config, dry_run)