ChatterBot 1.2.11__tar.gz → 1.2.13__tar.gz

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.
Files changed (100) hide show
  1. {chatterbot-1.2.11 → chatterbot-1.2.13}/ChatterBot.egg-info/PKG-INFO +14 -14
  2. {chatterbot-1.2.11 → chatterbot-1.2.13}/ChatterBot.egg-info/SOURCES.txt +3 -3
  3. {chatterbot-1.2.11 → chatterbot-1.2.13}/ChatterBot.egg-info/requires.txt +8 -8
  4. {chatterbot-1.2.11 → chatterbot-1.2.13}/PKG-INFO +14 -14
  5. {chatterbot-1.2.11 → chatterbot-1.2.13}/README.md +3 -3
  6. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/__init__.py +1 -1
  7. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/chatterbot.py +37 -16
  8. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/constants.py +4 -4
  9. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/conversation.py +1 -1
  10. chatterbot-1.2.13/chatterbot/ext/django_chatterbot/migrations/0021_increase_text_max_length_to_1100.py +55 -0
  11. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/logic/__init__.py +8 -0
  12. chatterbot-1.2.13/chatterbot/logic/best_match.py +150 -0
  13. chatterbot-1.2.13/chatterbot/logic/llm_adapters.py +887 -0
  14. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/logic/mathematical_evaluation.py +52 -1
  15. chatterbot-1.2.13/chatterbot/logic/mcp_tools.py +209 -0
  16. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/logic/time_adapter.py +26 -1
  17. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/logic/unit_conversion.py +49 -1
  18. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/parsing.py +4 -1
  19. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/search.py +23 -2
  20. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/storage/redis.py +176 -183
  21. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/trainers.py +39 -7
  22. {chatterbot-1.2.11 → chatterbot-1.2.13}/pyproject.toml +10 -10
  23. {chatterbot-1.2.11 → chatterbot-1.2.13}/setup.cfg +1 -1
  24. {chatterbot-1.2.11 → chatterbot-1.2.13}/tests/test_chatbot.py +15 -11
  25. chatterbot-1.2.13/tests/test_conversations.py +117 -0
  26. chatterbot-1.2.11/chatterbot/llm.py +0 -145
  27. chatterbot-1.2.11/chatterbot/logic/best_match.py +0 -123
  28. chatterbot-1.2.11/tests/test_connection_pool.py +0 -268
  29. chatterbot-1.2.11/tests/test_conversations.py +0 -12
  30. chatterbot-1.2.11/tests/test_poc_vulnerability.py +0 -152
  31. {chatterbot-1.2.11 → chatterbot-1.2.13}/ChatterBot.egg-info/dependency_links.txt +0 -0
  32. {chatterbot-1.2.11 → chatterbot-1.2.13}/ChatterBot.egg-info/top_level.txt +0 -0
  33. {chatterbot-1.2.11 → chatterbot-1.2.13}/LICENSE +0 -0
  34. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/__main__.py +0 -0
  35. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/adapters.py +0 -0
  36. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/comparisons.py +0 -0
  37. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/components.py +0 -0
  38. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/corpus.py +0 -0
  39. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/exceptions.py +0 -0
  40. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/__init__.py +0 -0
  41. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/__init__.py +0 -0
  42. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/abstract_models.py +0 -0
  43. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/admin.py +0 -0
  44. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/apps.py +0 -0
  45. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/migrations/0001_initial.py +0 -0
  46. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/migrations/0002_statement_extra_data.py +0 -0
  47. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/migrations/0003_change_occurrence_default.py +0 -0
  48. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/migrations/0004_rename_in_response_to.py +0 -0
  49. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/migrations/0005_statement_created_at.py +0 -0
  50. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/migrations/0006_create_conversation.py +0 -0
  51. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/migrations/0007_response_created_at.py +0 -0
  52. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/migrations/0008_update_conversations.py +0 -0
  53. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/migrations/0009_tags.py +0 -0
  54. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/migrations/0010_statement_text.py +0 -0
  55. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/migrations/0011_blank_extra_data.py +0 -0
  56. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/migrations/0012_statement_created_at.py +0 -0
  57. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/migrations/0013_change_conversations.py +0 -0
  58. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/migrations/0014_remove_statement_extra_data.py +0 -0
  59. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/migrations/0015_statement_persona.py +0 -0
  60. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/migrations/0016_statement_stemmed_text.py +0 -0
  61. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/migrations/0017_tags_unique.py +0 -0
  62. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/migrations/0018_text_max_length.py +0 -0
  63. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/migrations/0019_alter_statement_id_alter_tag_id_and_more.py +0 -0
  64. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/migrations/0020_alter_statement_conversation_and_more.py +0 -0
  65. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/migrations/__init__.py +0 -0
  66. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/model_admin.py +0 -0
  67. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/models.py +0 -0
  68. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/django_chatterbot/settings.py +0 -0
  69. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/sqlalchemy_app/__init__.py +0 -0
  70. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/ext/sqlalchemy_app/models.py +0 -0
  71. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/filters.py +0 -0
  72. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/languages.py +0 -0
  73. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/logic/logic_adapter.py +0 -0
  74. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/logic/specific_response.py +0 -0
  75. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/preprocessors.py +0 -0
  76. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/response_selection.py +0 -0
  77. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/storage/__init__.py +0 -0
  78. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/storage/django_storage.py +0 -0
  79. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/storage/mongodb.py +0 -0
  80. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/storage/sql_storage.py +0 -0
  81. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/storage/storage_adapter.py +0 -0
  82. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/tagging.py +0 -0
  83. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/utils.py +0 -0
  84. {chatterbot-1.2.11 → chatterbot-1.2.13}/chatterbot/vectorstores.py +0 -0
  85. {chatterbot-1.2.11 → chatterbot-1.2.13}/tests/test_adapter_validation.py +0 -0
  86. {chatterbot-1.2.11 → chatterbot-1.2.13}/tests/test_benchmarks.py +0 -0
  87. {chatterbot-1.2.11 → chatterbot-1.2.13}/tests/test_cli.py +0 -0
  88. {chatterbot-1.2.11 → chatterbot-1.2.13}/tests/test_comparisons.py +0 -0
  89. {chatterbot-1.2.11 → chatterbot-1.2.13}/tests/test_corpus.py +0 -0
  90. {chatterbot-1.2.11 → chatterbot-1.2.13}/tests/test_examples.py +0 -0
  91. {chatterbot-1.2.11 → chatterbot-1.2.13}/tests/test_filters.py +0 -0
  92. {chatterbot-1.2.11 → chatterbot-1.2.13}/tests/test_initialization.py +0 -0
  93. {chatterbot-1.2.11 → chatterbot-1.2.13}/tests/test_languages.py +0 -0
  94. {chatterbot-1.2.11 → chatterbot-1.2.13}/tests/test_parsing.py +0 -0
  95. {chatterbot-1.2.11 → chatterbot-1.2.13}/tests/test_preprocessors.py +0 -0
  96. {chatterbot-1.2.11 → chatterbot-1.2.13}/tests/test_response_selection.py +0 -0
  97. {chatterbot-1.2.11 → chatterbot-1.2.13}/tests/test_search.py +0 -0
  98. {chatterbot-1.2.11 → chatterbot-1.2.13}/tests/test_tagging.py +0 -0
  99. {chatterbot-1.2.11 → chatterbot-1.2.13}/tests/test_turing.py +0 -0
  100. {chatterbot-1.2.11 → chatterbot-1.2.13}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ChatterBot
3
- Version: 1.2.11
3
+ Version: 1.2.13
4
4
  Summary: ChatterBot is a machine learning, conversational dialog engine
5
5
  Author: Gunther Cox
6
6
  License-Expression: BSD-3-Clause
@@ -26,9 +26,9 @@ Classifier: Topic :: Text Processing :: Indexing
26
26
  Classifier: Topic :: Text Processing :: Linguistic
27
27
  Classifier: Programming Language :: Python
28
28
  Classifier: Programming Language :: Python :: 3
29
- Classifier: Programming Language :: Python :: 3.9
29
+ Classifier: Programming Language :: Python :: 3.10
30
30
  Classifier: Programming Language :: Python :: 3 :: Only
31
- Requires-Python: <3.14,>=3.9
31
+ Requires-Python: <3.15,>=3.10
32
32
  Description-Content-Type: text/markdown
33
33
  License-File: LICENSE
34
34
  Requires-Dist: mathparse<0.3,>=0.2
@@ -39,10 +39,10 @@ Requires-Dist: tqdm
39
39
  Provides-Extra: test
40
40
  Requires-Dist: flake8; extra == "test"
41
41
  Requires-Dist: coverage; extra == "test"
42
- Requires-Dist: sphinx<8.2,>=5.3; extra == "test"
42
+ Requires-Dist: sphinx<9.2,>=5.3; extra == "test"
43
43
  Requires-Dist: sphinx-sitemap>=2.6.0; extra == "test"
44
44
  Requires-Dist: huggingface_hub; extra == "test"
45
- Requires-Dist: django<6.0,<=4.1; extra == "test"
45
+ Requires-Dist: django<6.0,>=4.1; extra == "test"
46
46
  Provides-Extra: dev
47
47
  Requires-Dist: pint>=0.8.1; extra == "dev"
48
48
  Requires-Dist: pyyaml<7.0,>=6.0; extra == "dev"
@@ -50,13 +50,13 @@ Requires-Dist: chatterbot-corpus<1.3.0,>=1.2.2; extra == "dev"
50
50
  Requires-Dist: ollama<1.0,>=0.6.0; extra == "dev"
51
51
  Requires-Dist: openai; extra == "dev"
52
52
  Provides-Extra: redis
53
- Requires-Dist: redis[hiredis]<7.0; extra == "redis"
54
- Requires-Dist: langchain-redis<=0.2.5; extra == "redis"
55
- Requires-Dist: langchain-huggingface<=0.1.2; extra == "redis"
56
- Requires-Dist: accelerate<=1.6.0; extra == "redis"
57
- Requires-Dist: sentence-transformers<=4.0.2; extra == "redis"
53
+ Requires-Dist: redis[hiredis]<7.3,>=7.0; extra == "redis"
54
+ Requires-Dist: langchain-redis<0.3.0; extra == "redis"
55
+ Requires-Dist: langchain-huggingface<1.3.0,>=0.1.2; extra == "redis"
56
+ Requires-Dist: accelerate<1.14,>=1.6.0; extra == "redis"
57
+ Requires-Dist: sentence-transformers<5.3.0,>=4.0.2; extra == "redis"
58
58
  Provides-Extra: mongodb
59
- Requires-Dist: pymongo<4.16,>=4.11; extra == "mongodb"
59
+ Requires-Dist: pymongo<4.17,>=4.11; extra == "mongodb"
60
60
  Dynamic: license-file
61
61
 
62
62
  ![ChatterBot: Machine learning in Python](https://i.imgur.com/b3SCmGT.png)
@@ -162,9 +162,9 @@ https://docs.chatterbot.us/contributing/
162
162
 
163
163
  ChatterBot is sponsored by:
164
164
 
165
- <p style="font-size:21px; color:black;">Browser testing via
166
- <a href="https://www.lambdatest.com/?utm_source=chatterbot&utm_medium=sponsor" target="_blank">
167
- <img src="https://www.lambdatest.com/blue-logo.png" style="vertical-align: middle;" width="250" height="45" />
165
+ <p>
166
+ <a href="https://www.testmuai.com/?utm_source=chatterbot&utm_medium=sponsor" target="_blank">
167
+ <img src="docs/_static/testmu-ai-white-logo.png" style="vertical-align: middle;" width="250" height="80" />
168
168
  </a>
169
169
  </p>
170
170
 
@@ -19,7 +19,6 @@ chatterbot/corpus.py
19
19
  chatterbot/exceptions.py
20
20
  chatterbot/filters.py
21
21
  chatterbot/languages.py
22
- chatterbot/llm.py
23
22
  chatterbot/parsing.py
24
23
  chatterbot/preprocessors.py
25
24
  chatterbot/response_selection.py
@@ -56,13 +55,16 @@ chatterbot/ext/django_chatterbot/migrations/0017_tags_unique.py
56
55
  chatterbot/ext/django_chatterbot/migrations/0018_text_max_length.py
57
56
  chatterbot/ext/django_chatterbot/migrations/0019_alter_statement_id_alter_tag_id_and_more.py
58
57
  chatterbot/ext/django_chatterbot/migrations/0020_alter_statement_conversation_and_more.py
58
+ chatterbot/ext/django_chatterbot/migrations/0021_increase_text_max_length_to_1100.py
59
59
  chatterbot/ext/django_chatterbot/migrations/__init__.py
60
60
  chatterbot/ext/sqlalchemy_app/__init__.py
61
61
  chatterbot/ext/sqlalchemy_app/models.py
62
62
  chatterbot/logic/__init__.py
63
63
  chatterbot/logic/best_match.py
64
+ chatterbot/logic/llm_adapters.py
64
65
  chatterbot/logic/logic_adapter.py
65
66
  chatterbot/logic/mathematical_evaluation.py
67
+ chatterbot/logic/mcp_tools.py
66
68
  chatterbot/logic/specific_response.py
67
69
  chatterbot/logic/time_adapter.py
68
70
  chatterbot/logic/unit_conversion.py
@@ -77,7 +79,6 @@ tests/test_benchmarks.py
77
79
  tests/test_chatbot.py
78
80
  tests/test_cli.py
79
81
  tests/test_comparisons.py
80
- tests/test_connection_pool.py
81
82
  tests/test_conversations.py
82
83
  tests/test_corpus.py
83
84
  tests/test_examples.py
@@ -85,7 +86,6 @@ tests/test_filters.py
85
86
  tests/test_initialization.py
86
87
  tests/test_languages.py
87
88
  tests/test_parsing.py
88
- tests/test_poc_vulnerability.py
89
89
  tests/test_preprocessors.py
90
90
  tests/test_response_selection.py
91
91
  tests/test_search.py
@@ -12,19 +12,19 @@ ollama<1.0,>=0.6.0
12
12
  openai
13
13
 
14
14
  [mongodb]
15
- pymongo<4.16,>=4.11
15
+ pymongo<4.17,>=4.11
16
16
 
17
17
  [redis]
18
- redis[hiredis]<7.0
19
- langchain-redis<=0.2.5
20
- langchain-huggingface<=0.1.2
21
- accelerate<=1.6.0
22
- sentence-transformers<=4.0.2
18
+ redis[hiredis]<7.3,>=7.0
19
+ langchain-redis<0.3.0
20
+ langchain-huggingface<1.3.0,>=0.1.2
21
+ accelerate<1.14,>=1.6.0
22
+ sentence-transformers<5.3.0,>=4.0.2
23
23
 
24
24
  [test]
25
25
  flake8
26
26
  coverage
27
- sphinx<8.2,>=5.3
27
+ sphinx<9.2,>=5.3
28
28
  sphinx-sitemap>=2.6.0
29
29
  huggingface_hub
30
- django<6.0,<=4.1
30
+ django<6.0,>=4.1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ChatterBot
3
- Version: 1.2.11
3
+ Version: 1.2.13
4
4
  Summary: ChatterBot is a machine learning, conversational dialog engine
5
5
  Author: Gunther Cox
6
6
  License-Expression: BSD-3-Clause
@@ -26,9 +26,9 @@ Classifier: Topic :: Text Processing :: Indexing
26
26
  Classifier: Topic :: Text Processing :: Linguistic
27
27
  Classifier: Programming Language :: Python
28
28
  Classifier: Programming Language :: Python :: 3
29
- Classifier: Programming Language :: Python :: 3.9
29
+ Classifier: Programming Language :: Python :: 3.10
30
30
  Classifier: Programming Language :: Python :: 3 :: Only
31
- Requires-Python: <3.14,>=3.9
31
+ Requires-Python: <3.15,>=3.10
32
32
  Description-Content-Type: text/markdown
33
33
  License-File: LICENSE
34
34
  Requires-Dist: mathparse<0.3,>=0.2
@@ -39,10 +39,10 @@ Requires-Dist: tqdm
39
39
  Provides-Extra: test
40
40
  Requires-Dist: flake8; extra == "test"
41
41
  Requires-Dist: coverage; extra == "test"
42
- Requires-Dist: sphinx<8.2,>=5.3; extra == "test"
42
+ Requires-Dist: sphinx<9.2,>=5.3; extra == "test"
43
43
  Requires-Dist: sphinx-sitemap>=2.6.0; extra == "test"
44
44
  Requires-Dist: huggingface_hub; extra == "test"
45
- Requires-Dist: django<6.0,<=4.1; extra == "test"
45
+ Requires-Dist: django<6.0,>=4.1; extra == "test"
46
46
  Provides-Extra: dev
47
47
  Requires-Dist: pint>=0.8.1; extra == "dev"
48
48
  Requires-Dist: pyyaml<7.0,>=6.0; extra == "dev"
@@ -50,13 +50,13 @@ Requires-Dist: chatterbot-corpus<1.3.0,>=1.2.2; extra == "dev"
50
50
  Requires-Dist: ollama<1.0,>=0.6.0; extra == "dev"
51
51
  Requires-Dist: openai; extra == "dev"
52
52
  Provides-Extra: redis
53
- Requires-Dist: redis[hiredis]<7.0; extra == "redis"
54
- Requires-Dist: langchain-redis<=0.2.5; extra == "redis"
55
- Requires-Dist: langchain-huggingface<=0.1.2; extra == "redis"
56
- Requires-Dist: accelerate<=1.6.0; extra == "redis"
57
- Requires-Dist: sentence-transformers<=4.0.2; extra == "redis"
53
+ Requires-Dist: redis[hiredis]<7.3,>=7.0; extra == "redis"
54
+ Requires-Dist: langchain-redis<0.3.0; extra == "redis"
55
+ Requires-Dist: langchain-huggingface<1.3.0,>=0.1.2; extra == "redis"
56
+ Requires-Dist: accelerate<1.14,>=1.6.0; extra == "redis"
57
+ Requires-Dist: sentence-transformers<5.3.0,>=4.0.2; extra == "redis"
58
58
  Provides-Extra: mongodb
59
- Requires-Dist: pymongo<4.16,>=4.11; extra == "mongodb"
59
+ Requires-Dist: pymongo<4.17,>=4.11; extra == "mongodb"
60
60
  Dynamic: license-file
61
61
 
62
62
  ![ChatterBot: Machine learning in Python](https://i.imgur.com/b3SCmGT.png)
@@ -162,9 +162,9 @@ https://docs.chatterbot.us/contributing/
162
162
 
163
163
  ChatterBot is sponsored by:
164
164
 
165
- <p style="font-size:21px; color:black;">Browser testing via
166
- <a href="https://www.lambdatest.com/?utm_source=chatterbot&utm_medium=sponsor" target="_blank">
167
- <img src="https://www.lambdatest.com/blue-logo.png" style="vertical-align: middle;" width="250" height="45" />
165
+ <p>
166
+ <a href="https://www.testmuai.com/?utm_source=chatterbot&utm_medium=sponsor" target="_blank">
167
+ <img src="docs/_static/testmu-ai-white-logo.png" style="vertical-align: middle;" width="250" height="80" />
168
168
  </a>
169
169
  </p>
170
170
 
@@ -101,9 +101,9 @@ https://docs.chatterbot.us/contributing/
101
101
 
102
102
  ChatterBot is sponsored by:
103
103
 
104
- <p style="font-size:21px; color:black;">Browser testing via
105
- <a href="https://www.lambdatest.com/?utm_source=chatterbot&utm_medium=sponsor" target="_blank">
106
- <img src="https://www.lambdatest.com/blue-logo.png" style="vertical-align: middle;" width="250" height="45" />
104
+ <p>
105
+ <a href="https://www.testmuai.com/?utm_source=chatterbot&utm_medium=sponsor" target="_blank">
106
+ <img src="docs/_static/testmu-ai-white-logo.png" style="vertical-align: middle;" width="250" height="80" />
107
107
  </a>
108
108
  </p>
109
109
 
@@ -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.11'
7
+ __version__ = '1.2.13'
8
8
 
9
9
  __all__ = (
10
10
  'ChatBot',
@@ -1,4 +1,5 @@
1
1
  import logging
2
+ import uuid
2
3
  from typing import Union
3
4
  from chatterbot.storage import StorageAdapter
4
5
  from chatterbot.logic import LogicAdapter
@@ -56,6 +57,14 @@ class ChatBot(object):
56
57
 
57
58
  self.stream = stream
58
59
 
60
+ # Generate a default conversation ID for this ChatBot instance.
61
+ # This is used as a fallback when callers don't provide an explicit
62
+ # conversation ID, ensuring that conversation history is tracked
63
+ # within a session. Conversation IDs are necessary for cases such as
64
+ # the LLM-based logic adapters which require it to retrieve previous
65
+ # messages.
66
+ self.default_conversation = uuid.uuid4().hex
67
+
59
68
  self.logger = kwargs.get('logger', logging.getLogger(__name__))
60
69
 
61
70
  storage_adapter = kwargs.get('storage_adapter', 'chatterbot.storage.SQLStorageAdapter')
@@ -147,11 +156,6 @@ class ChatBot(object):
147
156
  # NOTE: 'xx' is the language code for a multi-language model
148
157
  self.nlp = spacy.blank(self.tagger.language.ISO_639_1)
149
158
 
150
- self.model = None
151
- if model := kwargs.get('model'):
152
- import_path = model.pop('client')
153
- self.model = utils.initialize_class(import_path, self, **model)
154
-
155
159
  # Allow the bot to save input it receives so that it can learn
156
160
  self.read_only = kwargs.get('read_only', False)
157
161
 
@@ -199,6 +203,13 @@ class ChatBot(object):
199
203
 
200
204
  input_statement.add_tags(*tags)
201
205
 
206
+ # If no conversation ID was provided, use the default session ID
207
+ # so that conversation history is tracked across calls. Callers
208
+ # can override this by passing an explicit conversation kwarg or
209
+ # setting it on the Statement object.
210
+ if not input_statement.conversation:
211
+ input_statement.conversation = self.default_conversation
212
+
202
213
  # Preprocess the input statement
203
214
  for preprocessor in self.preprocessors:
204
215
  input_statement = preprocessor(input_statement)
@@ -269,12 +280,6 @@ class ChatBot(object):
269
280
  result = None
270
281
  max_confidence = -1
271
282
 
272
- # If a model is provided, use it to process the input statement
273
- # instead of the logic adapters
274
- if self.model:
275
- model_response = self.model.process(input_statement)
276
- return model_response
277
-
278
283
  for adapter in self.logic_adapters:
279
284
  if adapter.can_process(input_statement):
280
285
 
@@ -349,24 +354,40 @@ class ChatBot(object):
349
354
 
350
355
  if not previous_statement:
351
356
  previous_statement = self.get_latest_response(statement.conversation)
352
- if previous_statement:
353
- previous_statement = previous_statement.text
354
357
 
355
358
  previous_statement_text = previous_statement
356
359
 
357
- if not isinstance(previous_statement, (str, type(None), )):
360
+ if isinstance(previous_statement, Statement):
358
361
  statement.in_response_to = previous_statement.text
362
+ previous_statement_text = previous_statement.text
363
+
364
+ # Set search_in_response_to from the previous statement's search_text
365
+ if previous_statement.search_text:
366
+ statement.search_in_response_to = previous_statement.search_text
367
+ elif previous_statement.text:
368
+ statement.search_in_response_to = self.tagger.get_text_index_string(
369
+ previous_statement.text
370
+ )
359
371
  elif isinstance(previous_statement, str):
360
372
  statement.in_response_to = previous_statement
373
+ statement.search_in_response_to = self.tagger.get_text_index_string(
374
+ previous_statement
375
+ )
361
376
 
362
377
  self.logger.info('Adding "{}" as a response to "{}"'.format(
363
- previous_statement_text,
364
- statement.text
378
+ statement.text,
379
+ previous_statement_text
365
380
  ))
366
381
 
367
382
  if not statement.persona:
368
383
  statement.persona = 'bot:' + self.name
369
384
 
385
+ # Ensure search_text is set for the statement being saved
386
+ if not statement.search_text and statement.text:
387
+ statement.search_text = self.tagger.get_text_index_string(
388
+ statement.text
389
+ )
390
+
370
391
  # Save the response statement
371
392
  return self.storage.create(**statement.serialize())
372
393
 
@@ -5,11 +5,11 @@ from chatterbot import languages
5
5
 
6
6
  '''
7
7
  The maximum length of characters that the text of a statement can contain.
8
- The number 255 is used because that is the maximum length of a char field
9
- in most databases. This value should be enforced on a per-model basis by
10
- the data model for each storage adapter.
8
+ The number 1100 is used to support longer conversational statements while
9
+ remaining within VARCHAR limits for most databases. This value should be
10
+ enforced on a per-model basis by the data model for each storage adapter.
11
11
  '''
12
- STATEMENT_TEXT_MAX_LENGTH = 255
12
+ STATEMENT_TEXT_MAX_LENGTH = 1100
13
13
 
14
14
  '''
15
15
  The maximum length of characters that the text label of a conversation can contain.
@@ -101,7 +101,7 @@ class Statement(StatementMixin):
101
101
  # This is the confidence with which the chat bot believes
102
102
  # this is an accurate response. This value is set when the
103
103
  # statement is returned by the chat bot.
104
- self.confidence = 0
104
+ self.confidence = kwargs.get('confidence', 0)
105
105
 
106
106
  self.storage = None
107
107
 
@@ -0,0 +1,55 @@
1
+ """
2
+ Django migration to increase text field max_length from 255 to 1100.
3
+
4
+ This migration alters all text-related fields in the Statement model:
5
+ - text
6
+ - search_text
7
+ - in_response_to
8
+ - search_in_response_to
9
+
10
+ This change supports longer conversational statements while remaining
11
+ within VARCHAR limits for most databases.
12
+ """
13
+ from django.db import migrations, models
14
+
15
+
16
+ class Migration(migrations.Migration):
17
+
18
+ dependencies = [
19
+ ('django_chatterbot', '0020_alter_statement_conversation_and_more'),
20
+ ]
21
+
22
+ operations = [
23
+ migrations.AlterField(
24
+ model_name='statement',
25
+ name='text',
26
+ field=models.CharField(max_length=1100, help_text='The text of the statement.'),
27
+ ),
28
+ migrations.AlterField(
29
+ model_name='statement',
30
+ name='search_text',
31
+ field=models.CharField(
32
+ blank=True,
33
+ max_length=1100,
34
+ help_text='A modified version of the statement text optimized for searching.'
35
+ ),
36
+ ),
37
+ migrations.AlterField(
38
+ model_name='statement',
39
+ name='in_response_to',
40
+ field=models.CharField(
41
+ max_length=1100,
42
+ null=True,
43
+ help_text='The text of the statement that this statement is in response to.'
44
+ ),
45
+ ),
46
+ migrations.AlterField(
47
+ model_name='statement',
48
+ name='search_in_response_to',
49
+ field=models.CharField(
50
+ blank=True,
51
+ max_length=1100,
52
+ help_text='A modified version of the in_response_to text optimized for searching.'
53
+ ),
54
+ ),
55
+ ]
@@ -4,6 +4,11 @@ from chatterbot.logic.mathematical_evaluation import MathematicalEvaluation
4
4
  from chatterbot.logic.specific_response import SpecificResponseAdapter
5
5
  from chatterbot.logic.time_adapter import TimeLogicAdapter
6
6
  from chatterbot.logic.unit_conversion import UnitConversion
7
+ from chatterbot.logic.llm_adapters import (
8
+ LLMLogicAdapter,
9
+ OllamaLogicAdapter,
10
+ OpenAILogicAdapter,
11
+ )
7
12
 
8
13
 
9
14
  __all__ = (
@@ -13,4 +18,7 @@ __all__ = (
13
18
  'SpecificResponseAdapter',
14
19
  'TimeLogicAdapter',
15
20
  'UnitConversion',
21
+ 'LLMLogicAdapter',
22
+ 'OllamaLogicAdapter',
23
+ 'OpenAILogicAdapter',
16
24
  )
@@ -0,0 +1,150 @@
1
+ from chatterbot.logic import LogicAdapter
2
+ from chatterbot.conversation import Statement
3
+ from chatterbot import filters
4
+
5
+
6
+ class BestMatch(LogicAdapter):
7
+ """
8
+ A logic adapter that returns a response based on known responses to
9
+ the closest matches to the input statement.
10
+
11
+ :param excluded_words:
12
+ The excluded_words parameter allows a list of words to be set that will
13
+ prevent the logic adapter from returning statements that have text
14
+ containing any of those words. This can be useful for preventing your
15
+ chat bot from saying swears when it is being demonstrated in front of
16
+ an audience.
17
+ Defaults to None
18
+ :type excluded_words: list
19
+ """
20
+
21
+ def __init__(self, chatbot, **kwargs):
22
+ super().__init__(chatbot, **kwargs)
23
+
24
+ self.excluded_words = kwargs.get('excluded_words')
25
+
26
+ def process(self, input_statement: Statement, additional_response_selection_parameters=None) -> Statement:
27
+
28
+ # Get all statements that have a response text similar to the input statement
29
+ search_results = self.search_algorithm.search(input_statement)
30
+
31
+ # Use the input statement as the closest match if no other results are found
32
+ input_statement.confidence = 0 # Use 0 confidence when no other results are found
33
+ closest_match = input_statement
34
+
35
+ # Search for the closest match to the input statement
36
+ for result in search_results:
37
+ closest_match = result
38
+
39
+ # Stop searching if a match that is close enough is found
40
+ if result.confidence >= self.maximum_similarity_threshold:
41
+ break
42
+
43
+ self.chatbot.logger.info('Selecting "{}" as a response to "{}" with a confidence of {}'.format(
44
+ closest_match.text, input_statement.text, closest_match.confidence
45
+ ))
46
+
47
+ # Semantic vector search vs indexed text search have different architectures:
48
+ #
49
+ # For SQL with indexed text search:
50
+ # - Phase 1 finds a match based on string similarity (Levenshtein distance)
51
+ # - Phase 2 finds variations of that match to get diverse responses
52
+ # - This makes sense because you might have multiple instances of similar statements
53
+ # learned from different conversations that provide different response options
54
+ #
55
+ # For Redis with semantic vectors:
56
+ # - Phase 1 finds semantically similar responses using vector embeddings
57
+ # - The semantic similarity already captures the "closeness" we want
58
+ # - Phase 2 would be redundant - we already have the best semantic match
59
+ # - The vector search inherently considers the entire semantic space, not just
60
+ # exact string matches, so additional variation searching is unnecessary
61
+ #
62
+ # NOTE: This difference of functionality may need to be modified in the future
63
+ # if the redis adapter is determined to benefit from a Phase 2 style response
64
+ # selection. The main symptom that would drive such a change would be low
65
+ # quality or repetitive responses when using semantic vector search.
66
+ #
67
+ # Therefore, semantic vector search returns the Phase 1 result directly.
68
+ if self.search_algorithm.name == 'semantic_vector_search' and closest_match.confidence > 0:
69
+ response = closest_match
70
+ self.chatbot.logger.info('Using semantic search result directly: "{}"'.format(response.text))
71
+ else:
72
+ # For other search algorithms (indexed_text_search, text_search),
73
+ # we need to find responses to the closest match
74
+ recent_repeated_responses = filters.get_recent_repeated_responses(
75
+ self.chatbot,
76
+ input_statement.conversation
77
+ )
78
+
79
+ for index, recent_repeated_response in enumerate(recent_repeated_responses):
80
+ self.chatbot.logger.info('{}. Excluding recent repeated response of "{}"'.format(
81
+ index, recent_repeated_response
82
+ ))
83
+
84
+ response_selection_parameters = {
85
+ 'search_text': closest_match.search_text,
86
+ 'persona_not_startswith': 'bot:',
87
+ 'exclude_text': recent_repeated_responses,
88
+ 'exclude_text_words': self.excluded_words
89
+ }
90
+
91
+ alternate_response_selection_parameters = {
92
+ 'search_in_response_to': input_statement.search_text or self.chatbot.tagger.get_text_index_string(
93
+ input_statement.text
94
+ ),
95
+ 'persona_not_startswith': 'bot:',
96
+ 'exclude_text': recent_repeated_responses,
97
+ 'exclude_text_words': self.excluded_words
98
+ }
99
+
100
+ if additional_response_selection_parameters:
101
+ response_selection_parameters.update(
102
+ additional_response_selection_parameters
103
+ )
104
+ alternate_response_selection_parameters.update(
105
+ additional_response_selection_parameters
106
+ )
107
+
108
+ # Get all statements with text similar to the closest match
109
+ response_list = list(self.chatbot.storage.filter(**response_selection_parameters))
110
+
111
+ if response_list:
112
+ response = self.select_response(
113
+ input_statement,
114
+ response_list,
115
+ self.chatbot.storage
116
+ )
117
+
118
+ response.confidence = closest_match.confidence
119
+ self.chatbot.logger.info('Selecting "{}" from {} optimal responses.'.format(
120
+ response.text,
121
+ len(response_list)
122
+ ))
123
+ else:
124
+ '''
125
+ The case where there was no responses returned for the selected match
126
+ but a value exists for the statement the match is in response to.
127
+ '''
128
+ self.chatbot.logger.info('No responses found. Generating alternate response list.')
129
+
130
+ alternate_response_list = list(self.chatbot.storage.filter(
131
+ **alternate_response_selection_parameters
132
+ ))
133
+
134
+ if alternate_response_list:
135
+ response = self.select_response(
136
+ input_statement,
137
+ alternate_response_list,
138
+ self.chatbot.storage
139
+ )
140
+
141
+ response.confidence = closest_match.confidence
142
+ self.chatbot.logger.info('Selected alternative response "{}" from {} options'.format(
143
+ response.text,
144
+ len(alternate_response_list)
145
+ ))
146
+ else:
147
+ response = self.get_default_response(input_statement)
148
+ self.chatbot.logger.info('Using "%s" as a default response.', response.text)
149
+
150
+ return response