ChatterBot 1.2.3__py3-none-any.whl → 1.2.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
chatterbot/__init__.py CHANGED
@@ -4,7 +4,7 @@ ChatterBot is a machine learning, conversational dialog engine.
4
4
  from .chatterbot import ChatBot
5
5
 
6
6
 
7
- __version__ = '1.2.3'
7
+ __version__ = '1.2.5'
8
8
 
9
9
  __all__ = (
10
10
  'ChatBot',
chatterbot/__main__.py CHANGED
@@ -1,7 +1,16 @@
1
+ """
2
+ Example usage for ChatterBot command line arguments:
3
+
4
+ python -m chatterbot --help
5
+ """
6
+
1
7
  import sys
2
8
 
3
9
 
4
10
  def get_chatterbot_version():
11
+ """
12
+ Return the version of the current package.
13
+ """
5
14
  from chatterbot import __version__
6
15
 
7
16
  return __version__
@@ -10,3 +19,9 @@ def get_chatterbot_version():
10
19
  if __name__ == '__main__':
11
20
  if '--version' in sys.argv:
12
21
  print(get_chatterbot_version())
22
+ elif '--help' in sys.argv:
23
+ print('usage: chatterbot [--version, --help]')
24
+ print(' --version: Print the version of ChatterBot')
25
+ print(' --help: Print this help message')
26
+ print()
27
+ print('Documentation at https://docs.chatterbot.us')
chatterbot/chatterbot.py CHANGED
@@ -3,6 +3,7 @@ from chatterbot.storage import StorageAdapter
3
3
  from chatterbot.logic import LogicAdapter
4
4
  from chatterbot.search import TextSearch, IndexedTextSearch
5
5
  from chatterbot.tagging import PosLemmaTagger
6
+ from chatterbot.conversation import Statement
6
7
  from chatterbot import languages
7
8
  from chatterbot import utils
8
9
  import spacy
@@ -11,11 +12,41 @@ import spacy
11
12
  class ChatBot(object):
12
13
  """
13
14
  A conversational dialog chat bot.
15
+
16
+ :param name: A name is the only required parameter for the ChatBot class.
17
+ :type name: str
18
+
19
+ :keyword storage_adapter: The dot-notated import path to a storage adapter class.
20
+ Defaults to ``"chatterbot.storage.SQLStorageAdapter"``.
21
+ :type storage_adapter: str
22
+
23
+ :param logic_adapters: A list of dot-notated import paths to each logic adapter the bot uses.
24
+ Defaults to ``["chatterbot.logic.BestMatch"]``.
25
+ :type logic_adapters: list
26
+
27
+ :param tagger: The tagger to use for the chat bot.
28
+ Defaults to :class:`~chatterbot.tagging.PosLemmaTagger`
29
+ :type tagger: object
30
+
31
+ :param tagger_language: The language to use for the tagger.
32
+ Defaults to :class:`~chatterbot.languages.ENG`.
33
+ :type tagger_language: object
34
+
35
+ :param preprocessors: A list of preprocessor functions to use for the chat bot.
36
+ :type preprocessors: list
37
+
38
+ :param read_only: If True, the chat bot will not save any input it receives, defaults to False.
39
+ :type read_only: bool
40
+
41
+ :param logger: A ``Logger`` object.
42
+ :type logger: logging.Logger
14
43
  """
15
44
 
16
45
  def __init__(self, name, **kwargs):
17
46
  self.name = name
18
47
 
48
+ self.logger = kwargs.get('logger', logging.getLogger(__name__))
49
+
19
50
  storage_adapter = kwargs.get('storage_adapter', 'chatterbot.storage.SQLStorageAdapter')
20
51
 
21
52
  logic_adapters = kwargs.get('logic_adapters', [
@@ -30,11 +61,29 @@ class ChatBot(object):
30
61
 
31
62
  self.storage = utils.initialize_class(storage_adapter, **kwargs)
32
63
 
33
- Tagger = kwargs.get('tagger', PosLemmaTagger)
64
+ tagger_language = kwargs.get('tagger_language', languages.ENG)
34
65
 
35
- self.tagger = Tagger(language=kwargs.get(
36
- 'tagger_language', languages.ENG
37
- ))
66
+ try:
67
+ Tagger = kwargs.get('tagger', PosLemmaTagger)
68
+
69
+ self.tagger = Tagger(language=tagger_language)
70
+ except IOError as io_error:
71
+ # Return a more helpful error message if possible
72
+ if "Can't find model" in str(io_error):
73
+ model_name = utils.get_model_for_language(tagger_language)
74
+ if hasattr(tagger_language, 'ENGLISH_NAME'):
75
+ language_name = tagger_language.ENGLISH_NAME
76
+ else:
77
+ language_name = tagger_language
78
+ raise self.ChatBotException(
79
+ 'Setup error:\n'
80
+ f'The Spacy model for "{language_name}" language is missing.\n'
81
+ 'Please install the model using the command:\n\n'
82
+ f'python -m spacy download {model_name}\n\n'
83
+ 'See https://spacy.io/usage/models for more information about available models.'
84
+ ) from io_error
85
+ else:
86
+ raise io_error
38
87
 
39
88
  primary_search_algorithm = IndexedTextSearch(self, **kwargs)
40
89
  text_search_algorithm = TextSearch(self, **kwargs)
@@ -63,18 +112,15 @@ class ChatBot(object):
63
112
  # NOTE: 'xx' is the language code for a multi-language model
64
113
  self.nlp = spacy.blank(self.tagger.language.ISO_639_1)
65
114
 
66
- self.logger = kwargs.get('logger', logging.getLogger(__name__))
67
-
68
115
  # Allow the bot to save input it receives so that it can learn
69
116
  self.read_only = kwargs.get('read_only', False)
70
117
 
71
- def get_response(self, statement=None, **kwargs):
118
+ def get_response(self, statement=None, **kwargs) -> Statement:
72
119
  """
73
120
  Return the bot's response based on the input.
74
121
 
75
122
  :param statement: An statement object or string.
76
123
  :returns: A response to the input.
77
- :rtype: Statement
78
124
 
79
125
  :param additional_response_selection_parameters: Parameters to pass to the
80
126
  chat bot's logic adapters to control response selection.
@@ -268,7 +314,7 @@ class ChatBot(object):
268
314
  # Save the response statement
269
315
  return self.storage.create(**statement.serialize())
270
316
 
271
- def get_latest_response(self, conversation):
317
+ def get_latest_response(self, conversation: str):
272
318
  """
273
319
  Returns the latest response in a conversation if it exists.
274
320
  Returns None if a matching conversation cannot be found.
chatterbot/comparisons.py CHANGED
@@ -2,7 +2,7 @@
2
2
  This module contains various text-comparison algorithms
3
3
  designed to compare one statement to another.
4
4
  """
5
- from chatterbot import constants
5
+ from chatterbot.utils import get_model_for_language
6
6
  from difflib import SequenceMatcher
7
7
  import spacy
8
8
 
@@ -19,19 +19,17 @@ class Comparator:
19
19
  def __call__(self, statement_a, statement_b):
20
20
  return self.compare(statement_a, statement_b)
21
21
 
22
- def compare_text(self, text_a, text_b):
22
+ def compare_text(self, text_a: str, text_b: str) -> float:
23
23
  """
24
24
  Implemented in subclasses: compare text_a to text_b.
25
25
 
26
26
  :return: The percent of similarity between the statements based on the implemented algorithm.
27
- :rtype: float
28
27
  """
29
28
  return 0
30
29
 
31
- def compare(self, statement_a, statement_b):
30
+ def compare(self, statement_a, statement_b) -> float:
32
31
  """
33
32
  :return: The percent of similarity between the statements based on the implemented algorithm.
34
- :rtype: float
35
33
  """
36
34
  return self.compare_text(statement_a.text, statement_b.text)
37
35
 
@@ -46,12 +44,11 @@ class LevenshteinDistance(Comparator):
46
44
  based on the Levenshtein distance algorithm.
47
45
  """
48
46
 
49
- def compare_text(self, text_a, text_b):
47
+ def compare_text(self, text_a: str, text_b: str) -> float:
50
48
  """
51
49
  Compare the two pieces of text.
52
50
 
53
51
  :return: The percent of similarity between the text of the statements.
54
- :rtype: float
55
52
  """
56
53
 
57
54
  # Return 0 if either statement has a None text value
@@ -100,22 +97,16 @@ class SpacySimilarity(Comparator):
100
97
  def __init__(self, language):
101
98
  super().__init__(language)
102
99
 
103
- try:
104
- model = constants.DEFAULT_LANGUAGE_TO_SPACY_MODEL_MAP[self.language]
105
- except KeyError as e:
106
- raise KeyError(
107
- f'Spacy model is not available for language {self.language}'
108
- ) from e
100
+ model = get_model_for_language(language)
109
101
 
110
102
  # Disable the Named Entity Recognition (NER) component because it is not necessary
111
103
  self.nlp = spacy.load(model, exclude=['ner'])
112
104
 
113
- def compare_text(self, text_a, text_b):
105
+ def compare_text(self, text_a: str, text_b: str) -> float:
114
106
  """
115
107
  Compare the similarity of two strings.
116
108
 
117
109
  :return: The percent of similarity between the closest synset distance.
118
- :rtype: float
119
110
  """
120
111
 
121
112
  # Return 0 if either statement has a None text value
@@ -157,17 +148,12 @@ class JaccardSimilarity(Comparator):
157
148
  def __init__(self, language):
158
149
  super().__init__(language)
159
150
 
160
- try:
161
- model = constants.DEFAULT_LANGUAGE_TO_SPACY_MODEL_MAP[self.language]
162
- except KeyError as e:
163
- raise KeyError(
164
- f'Spacy model is not available for language {self.language}'
165
- ) from e
151
+ model = get_model_for_language(language)
166
152
 
167
153
  # Disable the Named Entity Recognition (NER) component because it is not necessary
168
154
  self.nlp = spacy.load(model, exclude=['ner'])
169
155
 
170
- def compare_text(self, text_a, text_b):
156
+ def compare_text(self, text_a: str, text_b: str) -> float:
171
157
  """
172
158
  Return the calculated similarity of two
173
159
  statements based on the Jaccard index.
@@ -40,10 +40,9 @@ class StatementMixin(object):
40
40
  """
41
41
  self.tags.extend(tags)
42
42
 
43
- def serialize(self):
43
+ def serialize(self) -> dict:
44
44
  """
45
45
  :returns: A dictionary representation of the statement object.
46
- :rtype: dict
47
46
  """
48
47
  data = {}
49
48
 
@@ -32,7 +32,8 @@ class AbstractBaseTag(models.Model):
32
32
 
33
33
  name = models.SlugField(
34
34
  max_length=constants.TAG_NAME_MAX_LENGTH,
35
- unique=True
35
+ unique=True,
36
+ help_text='The unique name of the tag.'
36
37
  )
37
38
 
38
39
  class Meta:
@@ -49,16 +50,19 @@ class AbstractBaseStatement(models.Model, StatementMixin):
49
50
  """
50
51
 
51
52
  text = models.CharField(
52
- max_length=constants.STATEMENT_TEXT_MAX_LENGTH
53
+ max_length=constants.STATEMENT_TEXT_MAX_LENGTH,
54
+ help_text='The text of the statement.'
53
55
  )
54
56
 
55
57
  search_text = models.CharField(
56
58
  max_length=constants.STATEMENT_TEXT_MAX_LENGTH,
57
- blank=True
59
+ blank=True,
60
+ help_text='A modified version of the statement text optimized for searching.'
58
61
  )
59
62
 
60
63
  conversation = models.CharField(
61
- max_length=constants.CONVERSATION_LABEL_MAX_LENGTH
64
+ max_length=constants.CONVERSATION_LABEL_MAX_LENGTH,
65
+ help_text='A label used to link this statement to a conversation.'
62
66
  )
63
67
 
64
68
  created_at = models.DateTimeField(
@@ -68,21 +72,25 @@ class AbstractBaseStatement(models.Model, StatementMixin):
68
72
 
69
73
  in_response_to = models.CharField(
70
74
  max_length=constants.STATEMENT_TEXT_MAX_LENGTH,
71
- null=True
75
+ null=True,
76
+ help_text='The text of the statement that this statement is in response to.'
72
77
  )
73
78
 
74
79
  search_in_response_to = models.CharField(
75
80
  max_length=constants.STATEMENT_TEXT_MAX_LENGTH,
76
- blank=True
81
+ blank=True,
82
+ help_text='A modified version of the in_response_to text optimized for searching.'
77
83
  )
78
84
 
79
85
  persona = models.CharField(
80
- max_length=constants.PERSONA_MAX_LENGTH
86
+ max_length=constants.PERSONA_MAX_LENGTH,
87
+ help_text='A label used to link this statement to a persona.'
81
88
  )
82
89
 
83
90
  tags = models.ManyToManyField(
84
91
  TAG_MODEL,
85
- related_name='statements'
92
+ related_name='statements',
93
+ help_text='The tags that are associated with this statement.'
86
94
  )
87
95
 
88
96
  # This is the confidence with which the chat bot believes
@@ -6,3 +6,10 @@ class DjangoChatterBotConfig(AppConfig):
6
6
  name = 'chatterbot.ext.django_chatterbot'
7
7
  label = 'django_chatterbot'
8
8
  verbose_name = 'Django ChatterBot'
9
+
10
+ def ready(self):
11
+ from chatterbot.ext.django_chatterbot import settings as defaults
12
+ from django.conf import settings
13
+
14
+ settings.CHATTERBOT = getattr(settings, 'CHATTERBOT', {})
15
+ settings.CHATTERBOT.update(defaults.CHATTERBOT_DEFAULTS)
@@ -0,0 +1,53 @@
1
+ # Generated by Django 4.1 on 2025-03-29 23:27
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('django_chatterbot', '0019_alter_statement_id_alter_tag_id_and_more'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name='statement',
15
+ name='conversation',
16
+ field=models.CharField(help_text='A label used to link this statement to a conversation.', max_length=32),
17
+ ),
18
+ migrations.AlterField(
19
+ model_name='statement',
20
+ name='in_response_to',
21
+ field=models.CharField(help_text='The text of the statement that this statement is in response to.', max_length=255, null=True),
22
+ ),
23
+ migrations.AlterField(
24
+ model_name='statement',
25
+ name='persona',
26
+ field=models.CharField(help_text='A label used to link this statement to a persona.', max_length=50),
27
+ ),
28
+ migrations.AlterField(
29
+ model_name='statement',
30
+ name='search_in_response_to',
31
+ field=models.CharField(blank=True, help_text='A modified version of the in_response_to text optimized for searching.', max_length=255),
32
+ ),
33
+ migrations.AlterField(
34
+ model_name='statement',
35
+ name='search_text',
36
+ field=models.CharField(blank=True, help_text='A modified version of the statement text optimized for searching.', max_length=255),
37
+ ),
38
+ migrations.AlterField(
39
+ model_name='statement',
40
+ name='tags',
41
+ field=models.ManyToManyField(help_text='The tags that are associated with this statement.', related_name='statements', to='django_chatterbot.tag'),
42
+ ),
43
+ migrations.AlterField(
44
+ model_name='statement',
45
+ name='text',
46
+ field=models.CharField(help_text='The text of the statement.', max_length=255),
47
+ ),
48
+ migrations.AlterField(
49
+ model_name='tag',
50
+ name='name',
51
+ field=models.SlugField(help_text='The unique name of the tag.', unique=True),
52
+ ),
53
+ ]
@@ -5,7 +5,7 @@ from django.conf import settings
5
5
  from chatterbot import constants
6
6
 
7
7
 
8
- CHATTERBOT_SETTINGS = getattr(settings, 'CHATTERBOT', {})
8
+ CHATTERBOT = getattr(settings, 'CHATTERBOT', {})
9
9
 
10
10
  CHATTERBOT_DEFAULTS = {
11
11
  'name': 'ChatterBot',
@@ -13,5 +13,4 @@ CHATTERBOT_DEFAULTS = {
13
13
  'django_app_name': constants.DEFAULT_DJANGO_APP_NAME
14
14
  }
15
15
 
16
- CHATTERBOT = CHATTERBOT_DEFAULTS.copy()
17
- CHATTERBOT.update(CHATTERBOT_SETTINGS)
16
+ CHATTERBOT.update(CHATTERBOT_DEFAULTS)
@@ -1,7 +1,7 @@
1
1
  from sqlalchemy import Table, Column, Integer, String, DateTime, ForeignKey
2
- from sqlalchemy.orm import relationship
2
+ from sqlalchemy.orm import relationship, declarative_base
3
3
  from sqlalchemy.sql import func
4
- from sqlalchemy.ext.declarative import declared_attr, declarative_base
4
+ from sqlalchemy.ext.declarative import declared_attr
5
5
 
6
6
  from chatterbot.conversation import StatementMixin
7
7
  from chatterbot import constants
@@ -4,6 +4,7 @@ from chatterbot.adapters import Adapter
4
4
  from chatterbot.storage import StorageAdapter
5
5
  from chatterbot.search import IndexedTextSearch
6
6
  from chatterbot.conversation import Statement
7
+ from chatterbot import utils
7
8
 
8
9
 
9
10
  class LogicAdapter(Adapter):
@@ -28,7 +29,7 @@ class LogicAdapter(Adapter):
28
29
  :type response_selection_method: collections.abc.Callable
29
30
 
30
31
  :param default_response:
31
- The default response returned by this logic adaper
32
+ The default response returned by this logic adapter
32
33
  if there is no other possible response to return.
33
34
  :type default_response: str or list or tuple
34
35
  """
@@ -50,6 +51,14 @@ class LogicAdapter(Adapter):
50
51
  'maximum_similarity_threshold', 0.95
51
52
  )
52
53
 
54
+ if response_selection_method := kwargs.get('response_selection_method'):
55
+ if isinstance(response_selection_method, str):
56
+ # If an import path is provided, import the method
57
+ response_selection_method = utils.import_module(
58
+ response_selection_method
59
+ )
60
+ kwargs['response_selection_method'] = response_selection_method
61
+
53
62
  # By default, select the first available response
54
63
  self.select_response = kwargs.get(
55
64
  'response_selection_method',
@@ -68,18 +77,16 @@ class LogicAdapter(Adapter):
68
77
  Statement(text=default) for default in default_responses
69
78
  ]
70
79
 
71
- def can_process(self, statement):
80
+ def can_process(self, statement) -> bool:
72
81
  """
73
82
  A preliminary check that is called to determine if a
74
83
  logic adapter can process a given statement. By default,
75
84
  this method returns true but it can be overridden in
76
85
  child classes as needed.
77
-
78
- :rtype: bool
79
86
  """
80
87
  return True
81
88
 
82
- def process(self, statement, additional_response_selection_parameters=None):
89
+ def process(self, statement, additional_response_selection_parameters=None) -> Statement:
83
90
  """
84
91
  Override this method and implement your logic for selecting a response to an input statement.
85
92
 
@@ -97,12 +104,10 @@ class LogicAdapter(Adapter):
97
104
  :param additional_response_selection_parameters: Parameters to be used when
98
105
  filtering results to choose a response from.
99
106
  :type additional_response_selection_parameters: dict
100
-
101
- :rtype: Statement
102
107
  """
103
108
  raise self.AdapterMethodNotImplementedError()
104
109
 
105
- def get_default_response(self, input_statement):
110
+ def get_default_response(self, input_statement: Statement) -> Statement:
106
111
  """
107
112
  This method is called when a logic adapter is unable to generate any
108
113
  other meaningful response.
@@ -125,7 +130,7 @@ class LogicAdapter(Adapter):
125
130
  return response
126
131
 
127
132
  @property
128
- def class_name(self):
133
+ def class_name(self) -> str:
129
134
  """
130
135
  Return the name of the current logic adapter class.
131
136
  This is typically used for logging and debugging.
@@ -1,6 +1,7 @@
1
1
  from chatterbot.logic import LogicAdapter
2
2
  from chatterbot.conversation import Statement
3
- from chatterbot import constants, languages
3
+ from chatterbot import languages
4
+ from chatterbot.utils import get_model_for_language
4
5
  import spacy
5
6
 
6
7
 
@@ -35,12 +36,7 @@ class SpecificResponseAdapter(LogicAdapter):
35
36
  self._output_text = kwargs.get('output_text')
36
37
 
37
38
  def _initialize_nlp(self, language):
38
- try:
39
- model = constants.DEFAULT_LANGUAGE_TO_SPACY_MODEL_MAP[language]
40
- except KeyError as e:
41
- raise KeyError(
42
- f'Spacy model is not available for language {language}'
43
- ) from e
39
+ model = get_model_for_language(language)
44
40
 
45
41
  return spacy.load(model)
46
42
 
@@ -1,7 +1,8 @@
1
1
  from datetime import datetime
2
- from chatterbot import constants, languages
2
+ from chatterbot import languages
3
3
  from chatterbot.logic import LogicAdapter
4
4
  from chatterbot.conversation import Statement
5
+ from chatterbot.utils import get_model_for_language
5
6
  import spacy
6
7
 
7
8
 
@@ -36,12 +37,7 @@ class TimeLogicAdapter(LogicAdapter):
36
37
 
37
38
  language = kwargs.get('language', languages.ENG)
38
39
 
39
- try:
40
- model = constants.DEFAULT_LANGUAGE_TO_SPACY_MODEL_MAP[language]
41
- except KeyError as e:
42
- raise KeyError(
43
- f'Spacy model is not available for language {language}'
44
- ) from e
40
+ model = get_model_for_language(language)
45
41
 
46
42
  self.nlp = spacy.load(model)
47
43
 
@@ -1,12 +1,13 @@
1
1
  """
2
2
  Statement pre-processors.
3
3
  """
4
+ from chatterbot.conversation import Statement
4
5
  from unicodedata import normalize
5
6
  from re import sub as re_sub
6
7
  from html import unescape
7
8
 
8
9
 
9
- def clean_whitespace(statement):
10
+ def clean_whitespace(statement: Statement) -> Statement:
10
11
  """
11
12
  Remove any consecutive whitespace characters from the statement text.
12
13
  """
@@ -24,7 +25,7 @@ def clean_whitespace(statement):
24
25
  return statement
25
26
 
26
27
 
27
- def unescape_html(statement):
28
+ def unescape_html(statement: Statement) -> Statement:
28
29
  """
29
30
  Convert escaped html characters into unescaped html characters.
30
31
  For example: "&lt;b&gt;" becomes "<b>".
@@ -34,7 +35,7 @@ def unescape_html(statement):
34
35
  return statement
35
36
 
36
37
 
37
- def convert_to_ascii(statement):
38
+ def convert_to_ascii(statement: Statement) -> Statement:
38
39
  """
39
40
  Converts unicode characters to ASCII character equivalents.
40
41
  For example: "på fédéral" becomes "pa federal".
@@ -2,10 +2,11 @@
2
2
  Response selection methods determines which response should be used in
3
3
  the event that multiple responses are generated within a logic adapter.
4
4
  """
5
+ from chatterbot.conversation import Statement
5
6
  import logging
6
7
 
7
8
 
8
- def get_most_frequent_response(input_statement, response_list, storage=None):
9
+ def get_most_frequent_response(input_statement, response_list, storage=None) -> Statement:
9
10
  """
10
11
  :param input_statement: A statement, that closely matches an input to the chat bot.
11
12
  :type input_statement: Statement
@@ -18,7 +19,6 @@ def get_most_frequent_response(input_statement, response_list, storage=None):
18
19
  :type storage: StorageAdapter
19
20
 
20
21
  :return: The response statement with the greatest number of occurrences.
21
- :rtype: Statement
22
22
  """
23
23
  matching_response = None
24
24
  occurrence_count = -1
@@ -41,7 +41,7 @@ def get_most_frequent_response(input_statement, response_list, storage=None):
41
41
  return matching_response
42
42
 
43
43
 
44
- def get_first_response(input_statement, response_list, storage=None):
44
+ def get_first_response(input_statement, response_list, storage=None) -> Statement:
45
45
  """
46
46
  :param input_statement: A statement, that closely matches an input to the chat bot.
47
47
  :type input_statement: Statement
@@ -54,7 +54,6 @@ def get_first_response(input_statement, response_list, storage=None):
54
54
  :type storage: StorageAdapter
55
55
 
56
56
  :return: Return the first statement in the response list.
57
- :rtype: Statement
58
57
  """
59
58
  logger = logging.getLogger(__name__)
60
59
  logger.info('Selecting first response from list of {} options.'.format(
@@ -63,7 +62,7 @@ def get_first_response(input_statement, response_list, storage=None):
63
62
  return response_list[0]
64
63
 
65
64
 
66
- def get_random_response(input_statement, response_list, storage=None):
65
+ def get_random_response(input_statement, response_list, storage=None) -> Statement:
67
66
  """
68
67
  :param input_statement: A statement, that closely matches an input to the chat bot.
69
68
  :type input_statement: Statement
@@ -76,7 +75,6 @@ def get_random_response(input_statement, response_list, storage=None):
76
75
  :type storage: StorageAdapter
77
76
 
78
77
  :return: Choose a random response from the selection.
79
- :rtype: Statement
80
78
  """
81
79
  from random import choice
82
80
  logger = logging.getLogger(__name__)
chatterbot/search.py CHANGED
@@ -149,58 +149,3 @@ class TextSearch:
149
149
  ))
150
150
 
151
151
  yield statement
152
-
153
-
154
- class VectorSearch:
155
- """
156
- .. note:: BETA feature: this search method is new and experimental.
157
-
158
- Search for similar text based on a :term:`vector database`.
159
- """
160
-
161
- name = 'vector_search'
162
-
163
- def __init__(self, chatbot, **kwargs):
164
- from chatterbot.storage import RedisVectorStorageAdapter
165
-
166
- # Good documentation:
167
- # https://python.langchain.com/docs/integrations/vectorstores/redis/
168
- #
169
- # https://hub.docker.com/r/redis/redis-stack
170
-
171
- # Mondodb:
172
- # > Vector Search is only supported on Atlas Clusters
173
- # https://www.mongodb.com/community/forums/t/can-a-local-mongodb-instance-be-used-when-working-with-langchain-mongodbatlasvectorsearch/265356
174
-
175
- # FAISS:
176
- # https://python.langchain.com/docs/integrations/vectorstores/faiss/
177
-
178
- print("Starting Redis Vector Store")
179
-
180
- # TODO: look into:
181
- # https://python.langchain.com/api_reference/redis/chat_message_history/langchain_redis.chat_message_history.RedisChatMessageHistory.html
182
-
183
- # The VectorSearch class is only compatible with the RedisVectorStorageAdapter
184
- if not isinstance(chatbot.storage, RedisVectorStorageAdapter):
185
- raise Exception(
186
- 'The VectorSearch search method requires the RedisVectorStorageAdapter storage adapter.'
187
- )
188
-
189
- def search(self, input_statement, **additional_parameters):
190
- print("Querying Vector Store")
191
-
192
- # Similarity search with score and filter
193
- # NOTE: It looks like `return_all` is needed to return the full document
194
- # specifically what we need here is the ID
195
- scored_results = self.storage.vector_store.similarity_search_with_score(
196
- input_statement.text, k=2, return_all=True
197
- )
198
- # sort_by="score", filter={"category": "likes"})
199
-
200
- print("Similarity Search with Score Results:\n")
201
- for doc, score in scored_results:
202
- print(f"Content: {doc.page_content[:150]}...")
203
- print(f"ID: {doc.id}")
204
- print(f"Metadata: {doc.metadata}")
205
- print(f"Score: {score}")
206
- print()