besser-agentic-framework 4.5.0__tar.gz → 4.5.2__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 (228) hide show
  1. {besser_agentic_framework-4.5.0/besser_agentic_framework.egg-info → besser_agentic_framework-4.5.2}/PKG-INFO +5 -1
  2. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/state.py +22 -2
  3. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/__init__.py +110 -0
  4. besser_agentic_framework-4.5.2/baf/nlp/llm/llm_anthropic.py +270 -0
  5. besser_agentic_framework-4.5.2/baf/nlp/llm/llm_deepseek.py +17 -0
  6. besser_agentic_framework-4.5.2/baf/nlp/llm/llm_google.py +21 -0
  7. besser_agentic_framework-4.5.2/baf/nlp/llm/llm_groq.py +18 -0
  8. besser_agentic_framework-4.5.2/baf/nlp/llm/llm_meta.py +18 -0
  9. besser_agentic_framework-4.5.2/baf/nlp/llm/llm_mistral.py +18 -0
  10. besser_agentic_framework-4.5.2/baf/nlp/llm/llm_openai_api.py +34 -0
  11. besser_agentic_framework-4.5.0/baf/nlp/llm/llm_openai_api.py → besser_agentic_framework-4.5.2/baf/nlp/llm/llm_openai_compatible.py +58 -33
  12. besser_agentic_framework-4.5.2/baf/nlp/llm/llm_openrouter.py +20 -0
  13. besser_agentic_framework-4.5.2/baf/nlp/llm/llm_qwen.py +18 -0
  14. besser_agentic_framework-4.5.2/baf/nlp/llm/llm_together.py +19 -0
  15. besser_agentic_framework-4.5.2/baf/nlp/llm/llm_xai.py +17 -0
  16. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/rag/rag.py +107 -0
  17. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/dependencies/test_extras.py +11 -0
  18. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/dependencies/test_llms.py +6 -0
  19. besser_agentic_framework-4.5.2/baf/test/examples/hybrid_rag_agent.py +126 -0
  20. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2/besser_agentic_framework.egg-info}/PKG-INFO +5 -1
  21. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/besser_agentic_framework.egg-info/SOURCES.txt +12 -0
  22. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/besser_agentic_framework.egg-info/requires.txt +4 -0
  23. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/requirements/requirements-extras.txt +1 -0
  24. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/requirements/requirements-llms.txt +1 -0
  25. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/setup.cfg +1 -1
  26. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/LICENSE +0 -0
  27. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/MANIFEST.in +0 -0
  28. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/README.md +0 -0
  29. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/__init__.py +0 -0
  30. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/__init__.py +0 -0
  31. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/agent.py +0 -0
  32. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/entity/__init__.py +0 -0
  33. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/entity/entity.py +0 -0
  34. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/entity/entity_entry.py +0 -0
  35. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/file.py +0 -0
  36. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/gui/__init__.py +0 -0
  37. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/gui/agent_gui.py +0 -0
  38. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/gui/gui_deserializer.py +0 -0
  39. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/gui/gui_llm.py +0 -0
  40. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/gui/gui_schema.py +0 -0
  41. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/gui/gui_serializer.py +0 -0
  42. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/intent/__init__.py +0 -0
  43. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/intent/intent.py +0 -0
  44. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/intent/intent_parameter.py +0 -0
  45. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/message.py +0 -0
  46. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/processors/__init__.py +0 -0
  47. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/processors/audio_language_detection_processor.py +0 -0
  48. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/processors/language_detection_processor.py +0 -0
  49. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/processors/processor.py +0 -0
  50. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/processors/user_adaptation_processor.py +0 -0
  51. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/property.py +0 -0
  52. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/session.py +0 -0
  53. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/transition/__init__.py +0 -0
  54. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/transition/condition.py +0 -0
  55. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/transition/event.py +0 -0
  56. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/transition/transition.py +0 -0
  57. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/core/transition/transition_builder.py +0 -0
  58. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/db/__init__.py +0 -0
  59. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/db/db_handler.py +0 -0
  60. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/db/monitoring_db.py +0 -0
  61. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/db/monitoring_ui/__init__.py +0 -0
  62. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/db/monitoring_ui/db_connection.py +0 -0
  63. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/db/monitoring_ui/flow_graph.py +0 -0
  64. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/db/monitoring_ui/home.py +0 -0
  65. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/db/monitoring_ui/intent_details.py +0 -0
  66. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/db/monitoring_ui/monitoring_ui.py +0 -0
  67. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/db/monitoring_ui/sidebar.py +0 -0
  68. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/db/monitoring_ui/table_overview.py +0 -0
  69. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/db/monitoring_ui/utils.py +0 -0
  70. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/exceptions/__init__.py +0 -0
  71. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/exceptions/exceptions.py +0 -0
  72. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/exceptions/logger.py +0 -0
  73. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/library/__init__.py +0 -0
  74. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/library/coroutine/__init__.py +0 -0
  75. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/library/coroutine/async_helpers.py +0 -0
  76. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/library/entity/__init__.py +0 -0
  77. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/library/entity/base_entities.py +0 -0
  78. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/library/intent/__init__.py +0 -0
  79. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/library/intent/intent_library.py +0 -0
  80. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/library/state/__init__.py +0 -0
  81. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/library/state/reasoning_state_library.py +0 -0
  82. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/library/state/state_library.py +0 -0
  83. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/library/tool/__init__.py +0 -0
  84. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/library/tool/task_tools.py +0 -0
  85. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/library/tool/workspace_tools.py +0 -0
  86. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/library/transition/__init__.py +0 -0
  87. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/library/transition/condition_functions.py +0 -0
  88. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/library/transition/conditions.py +0 -0
  89. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/library/transition/events/__init__.py +0 -0
  90. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/library/transition/events/base_events.py +0 -0
  91. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/library/transition/events/github_webhooks_events.py +0 -0
  92. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/library/transition/events/gitlab_webhooks_events.py +0 -0
  93. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/intent_classifier/__init__.py +0 -0
  94. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/intent_classifier/intent_classifier.py +0 -0
  95. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/intent_classifier/intent_classifier_configuration.py +0 -0
  96. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/intent_classifier/intent_classifier_prediction.py +0 -0
  97. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/intent_classifier/llm_intent_classifier.py +0 -0
  98. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/intent_classifier/simple_intent_classifier_pytorch.py +0 -0
  99. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/intent_classifier/simple_intent_classifier_tensorflow.py +0 -0
  100. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/llm/__init__.py +0 -0
  101. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/llm/llm.py +0 -0
  102. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/llm/llm_huggingface.py +0 -0
  103. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/llm/llm_huggingface_api.py +0 -0
  104. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/llm/llm_ollama.py +0 -0
  105. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/llm/llm_replicate_api.py +0 -0
  106. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/ner/__init__.py +0 -0
  107. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/ner/base/__init__.py +0 -0
  108. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/ner/base/any.py +0 -0
  109. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/ner/base/datetime.py +0 -0
  110. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/ner/base/number.py +0 -0
  111. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/ner/matched_parameter.py +0 -0
  112. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/ner/ner.py +0 -0
  113. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/ner/ner_prediction.py +0 -0
  114. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/ner/simple_ner.py +0 -0
  115. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/nlp_engine.py +0 -0
  116. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/preprocessing/__init__.py +0 -0
  117. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/preprocessing/pipelines.py +0 -0
  118. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/preprocessing/text_preprocessing.py +0 -0
  119. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/rag/__init__.py +0 -0
  120. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/speech2text/__init__.py +0 -0
  121. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/speech2text/api_speech2text.py +0 -0
  122. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/speech2text/hf_speech2text.py +0 -0
  123. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/speech2text/luxasr_speech2text.py +0 -0
  124. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/speech2text/openai_speech2text.py +0 -0
  125. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/speech2text/speech2text.py +0 -0
  126. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/text2speech/__init__.py +0 -0
  127. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/text2speech/hf_text2speech.py +0 -0
  128. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/text2speech/openai_text2speech.py +0 -0
  129. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/text2speech/piper_text2speech.py +0 -0
  130. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/text2speech/text2speech.py +0 -0
  131. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/nlp/utils.py +0 -0
  132. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/__init__.py +0 -0
  133. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/a2a/__init__.py +0 -0
  134. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/a2a/a2a_platform.py +0 -0
  135. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/a2a/agent_card.py +0 -0
  136. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/a2a/agent_registry.py +0 -0
  137. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/a2a/client.py +0 -0
  138. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/a2a/error_handler.py +0 -0
  139. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/a2a/message_router.py +0 -0
  140. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/a2a/server.py +0 -0
  141. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/a2a/task_protocol.py +0 -0
  142. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/github/__init__.py +0 -0
  143. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/github/github_actions.py +0 -0
  144. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/github/github_objects.py +0 -0
  145. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/github/github_platform.py +0 -0
  146. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/gitlab/__init__.py +0 -0
  147. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/gitlab/gitlab_actions.py +0 -0
  148. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/gitlab/gitlab_objects.py +0 -0
  149. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/gitlab/gitlab_platform.py +0 -0
  150. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/payload.py +0 -0
  151. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/platform.py +0 -0
  152. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/telegram/__init__.py +0 -0
  153. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/telegram/telegram_platform.py +0 -0
  154. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/websocket/__init__.py +0 -0
  155. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/websocket/streamlit_ui/__init__.py +0 -0
  156. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/websocket/streamlit_ui/audio_queue.py +0 -0
  157. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/websocket/streamlit_ui/chat.py +0 -0
  158. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/websocket/streamlit_ui/chat_interface_style.py +0 -0
  159. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/websocket/streamlit_ui/initialization.py +0 -0
  160. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/websocket/streamlit_ui/login.py +0 -0
  161. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/websocket/streamlit_ui/message_input.py +0 -0
  162. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/websocket/streamlit_ui/profile_selector.py +0 -0
  163. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/websocket/streamlit_ui/reasoning.py +0 -0
  164. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/websocket/streamlit_ui/session_management.py +0 -0
  165. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/websocket/streamlit_ui/sidebar.py +0 -0
  166. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/websocket/streamlit_ui/streamlit_ui.py +0 -0
  167. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/websocket/streamlit_ui/user_db.py +0 -0
  168. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/websocket/streamlit_ui/vars.py +0 -0
  169. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/websocket/streamlit_ui/websocket_callbacks.py +0 -0
  170. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/platforms/websocket/websocket_platform.py +0 -0
  171. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/reasoning/__init__.py +0 -0
  172. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/reasoning/skill.py +0 -0
  173. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/reasoning/tool.py +0 -0
  174. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/reasoning/workspace.py +0 -0
  175. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/__init__.py +0 -0
  176. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/components/__init__.py +0 -0
  177. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/components/conftest.py +0 -0
  178. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/components/test_core_agent.py +0 -0
  179. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/components/test_core_intent_entity.py +0 -0
  180. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/components/test_core_message.py +0 -0
  181. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/components/test_core_processor.py +0 -0
  182. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/components/test_core_property.py +0 -0
  183. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/components/test_core_session.py +0 -0
  184. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/components/test_core_state.py +0 -0
  185. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/components/test_core_transition.py +0 -0
  186. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/components/test_library_events.py +0 -0
  187. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/components/test_nlp_configurations.py +0 -0
  188. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/components/test_nlp_engine.py +0 -0
  189. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/components/test_nlp_preprocessing.py +0 -0
  190. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/components/test_platforms.py +0 -0
  191. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/components/test_workflows.py +0 -0
  192. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/dependencies/__init__.py +0 -0
  193. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/dependencies/conftest.py +0 -0
  194. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/dependencies/test_core.py +0 -0
  195. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/dependencies/test_docs.py +0 -0
  196. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/dependencies/test_framework.py +0 -0
  197. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/dependencies/test_tensorflow.py +0 -0
  198. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/dependencies/test_torch.py +0 -0
  199. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/examples/__init__.py +0 -0
  200. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/examples/a2a_multiagent.py +0 -0
  201. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/examples/api_speech2text_agent.py +0 -0
  202. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/examples/github_agent.py +0 -0
  203. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/examples/gitlab_agent.py +0 -0
  204. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/examples/greetings_agent.py +0 -0
  205. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/examples/llm_agent.py +0 -0
  206. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/examples/multiagent/__init__.py +0 -0
  207. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/examples/multiagent/coder_agent.py +0 -0
  208. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/examples/multiagent/main_agent.py +0 -0
  209. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/examples/multiagent/reviewer_agent.py +0 -0
  210. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/examples/rag_agent.py +0 -0
  211. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/examples/reasoning_agent.py +0 -0
  212. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/examples/speech2speech_agent.py +0 -0
  213. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/examples/speech2text_agent.py +0 -0
  214. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/examples/stargazer_agent.py +0 -0
  215. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/examples/telegram_agent.py +0 -0
  216. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/examples/text2speech_agent.py +0 -0
  217. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/examples/weather_agent.py +0 -0
  218. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/test/examples/web_crawl_agent.py +0 -0
  219. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/utils/__init__.py +0 -0
  220. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/baf/utils/web_crawl.py +0 -0
  221. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/besser_agentic_framework.egg-info/dependency_links.txt +0 -0
  222. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/besser_agentic_framework.egg-info/top_level.txt +0 -0
  223. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/pyproject.toml +0 -0
  224. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/requirements/requirements-core.txt +0 -0
  225. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/requirements/requirements-docs.txt +0 -0
  226. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/requirements/requirements-tensorflow.txt +0 -0
  227. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/requirements/requirements-torch.txt +0 -0
  228. {besser_agentic_framework-4.5.0 → besser_agentic_framework-4.5.2}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: besser-agentic-framework
3
- Version: 4.5.0
3
+ Version: 4.5.2
4
4
  Summary: BESSER Agentic Framework (BAF)
5
5
  Author: Luxembourg Institute of Science and Technology
6
6
  License: MIT
@@ -53,10 +53,12 @@ Requires-Dist: langchain-community==0.3.10; python_version >= "3.13" and extra =
53
53
  Requires-Dist: pypdf==4.3.1; extra == "extras"
54
54
  Requires-Dist: python-docx==1.2.0; extra == "extras"
55
55
  Requires-Dist: tiktoken==0.9.0; extra == "extras"
56
+ Requires-Dist: rank_bm25==0.2.2; extra == "extras"
56
57
  Provides-Extra: llms
57
58
  Requires-Dist: openai==1.93.0; extra == "llms"
58
59
  Requires-Dist: replicate==0.23.1; extra == "llms"
59
60
  Requires-Dist: transformers==4.53.0; extra == "llms"
61
+ Requires-Dist: anthropic>=0.40.0; extra == "llms"
60
62
  Provides-Extra: tensorflow
61
63
  Requires-Dist: keras==3.12.0; extra == "tensorflow"
62
64
  Requires-Dist: tensorflow-cpu==2.20.0; extra == "tensorflow"
@@ -86,9 +88,11 @@ Requires-Dist: langchain-community==0.3.10; python_version >= "3.13" and extra =
86
88
  Requires-Dist: pypdf==4.3.1; extra == "all"
87
89
  Requires-Dist: python-docx==1.2.0; extra == "all"
88
90
  Requires-Dist: tiktoken==0.9.0; extra == "all"
91
+ Requires-Dist: rank_bm25==0.2.2; extra == "all"
89
92
  Requires-Dist: openai==1.93.0; extra == "all"
90
93
  Requires-Dist: replicate==0.23.1; extra == "all"
91
94
  Requires-Dist: transformers==4.53.0; extra == "all"
95
+ Requires-Dist: anthropic>=0.40.0; extra == "all"
92
96
  Requires-Dist: keras==3.12.0; extra == "all"
93
97
  Requires-Dist: tensorflow-cpu==2.20.0; extra == "all"
94
98
  Requires-Dist: torch==2.6.0; extra == "all"
@@ -139,6 +139,24 @@ class State:
139
139
  raise BodySignatureError(self._agent, self, body, body_template_signature, body_signature)
140
140
  self._body = body
141
141
 
142
+ def body(self, func: Callable[[Session], None]) -> Callable[[Session], None]:
143
+ """Decorator to set the state body.
144
+
145
+ Usage::
146
+
147
+ @state.body
148
+ def my_body(session: Session):
149
+ ...
150
+
151
+ Args:
152
+ func (Callable[[Session], None]): the body function
153
+
154
+ Returns:
155
+ Callable[[Session], None]: the body function unchanged
156
+ """
157
+ self.set_body(func)
158
+ return func
159
+
142
160
  def set_fallback_body(self, body: Callable[[Session], None]):
143
161
  """Set the state fallback body.
144
162
 
@@ -337,8 +355,10 @@ class State:
337
355
  if (isinstance(session.event, ReceiveTextEvent) and session.event.human) or (isinstance(session.event, ReceiveJSONEvent) and session.event.contains_message and session.event.human):
338
356
  # There is a ReceiveTextEvent or ReceiveJSONEvent (with message) and we couldn't match any transition so far
339
357
  run_fallback = True
340
- if i < len(self.transitions)-1:
341
- # We only append ReceiveTextEvent or ReceiveJSONEvent (human with message) if we didn't finish checking all transitions
358
+ if any(t.is_event() for t in self.transitions[i+1:]):
359
+ # Only preserve the event if there are more event-based transitions left to check.
360
+ # Condition-based transitions don't consume events, so preserving the event for them
361
+ # would cause it to remain in the queue after the fallback fires, creating an infinite loop.
342
362
  fallback_deque.appendleft(session.event)
343
363
  else:
344
364
  fallback_deque.appendleft(session.event)
@@ -111,6 +111,116 @@ type: ``str``
111
111
  default value: ``None``
112
112
  """
113
113
 
114
+ MISTRAL_API_KEY = Property('nlp.mistral.api_key', str, None)
115
+ """
116
+ The Mistral AI API key, necessary to use a Mistral LLM.
117
+
118
+ name: ``nlp.mistral.api_key``
119
+
120
+ type: ``str``
121
+
122
+ default value: ``None``
123
+ """
124
+
125
+ DEEPSEEK_API_KEY = Property('nlp.deepseek.api_key', str, None)
126
+ """
127
+ The DeepSeek API key, necessary to use a DeepSeek LLM.
128
+
129
+ name: ``nlp.deepseek.api_key``
130
+
131
+ type: ``str``
132
+
133
+ default value: ``None``
134
+ """
135
+
136
+ GOOGLE_API_KEY = Property('nlp.google.api_key', str, None)
137
+ """
138
+ The Google AI (Gemini) API key, necessary to use a Google LLM.
139
+
140
+ name: ``nlp.google.api_key``
141
+
142
+ type: ``str``
143
+
144
+ default value: ``None``
145
+ """
146
+
147
+ META_API_KEY = Property('nlp.meta.api_key', str, None)
148
+ """
149
+ The Meta AI API key, necessary to use a Meta Llama LLM via Meta's hosted API.
150
+
151
+ name: ``nlp.meta.api_key``
152
+
153
+ type: ``str``
154
+
155
+ default value: ``None``
156
+ """
157
+
158
+ ANTHROPIC_API_KEY = Property('nlp.anthropic.api_key', str, None)
159
+ """
160
+ The Anthropic API key, necessary to use an Anthropic Claude LLM.
161
+
162
+ name: ``nlp.anthropic.api_key``
163
+
164
+ type: ``str``
165
+
166
+ default value: ``None``
167
+ """
168
+
169
+ QWEN_API_KEY = Property('nlp.qwen.api_key', str, None)
170
+ """
171
+ The Alibaba DashScope API key, necessary to use a Qwen LLM.
172
+
173
+ name: ``nlp.qwen.api_key``
174
+
175
+ type: ``str``
176
+
177
+ default value: ``None``
178
+ """
179
+
180
+ XAI_API_KEY = Property('nlp.xai.api_key', str, None)
181
+ """
182
+ The xAI API key, necessary to use an xAI Grok LLM.
183
+
184
+ name: ``nlp.xai.api_key``
185
+
186
+ type: ``str``
187
+
188
+ default value: ``None``
189
+ """
190
+
191
+ GROQ_API_KEY = Property('nlp.groq.api_key', str, None)
192
+ """
193
+ The Groq API key, necessary to use a Groq-hosted LLM.
194
+
195
+ name: ``nlp.groq.api_key``
196
+
197
+ type: ``str``
198
+
199
+ default value: ``None``
200
+ """
201
+
202
+ TOGETHER_API_KEY = Property('nlp.together.api_key', str, None)
203
+ """
204
+ The Together AI API key, necessary to use a Together AI-hosted LLM.
205
+
206
+ name: ``nlp.together.api_key``
207
+
208
+ type: ``str``
209
+
210
+ default value: ``None``
211
+ """
212
+
213
+ OPENROUTER_API_KEY = Property('nlp.openrouter.api_key', str, None)
214
+ """
215
+ The OpenRouter API key, necessary to use an OpenRouter-proxied LLM.
216
+
217
+ name: ``nlp.openrouter.api_key``
218
+
219
+ type: ``str``
220
+
221
+ default value: ``None``
222
+ """
223
+
114
224
  OLLAMA_BASE_URL = Property('nlp.ollama.base_url', str, 'http://localhost:11434')
115
225
  """
116
226
  The base URL for a locally hosted Ollama server.
@@ -0,0 +1,270 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from typing import TYPE_CHECKING, Any
5
+
6
+ from baf import nlp
7
+ from baf.core.message import MessageType, Message
8
+ from baf.exceptions.logger import logger
9
+ from baf.nlp.intent_classifier.intent_classifier_prediction import IntentClassifierPrediction
10
+ from baf.nlp.llm.llm import LLM, LLMResponse, ToolCall
11
+
12
+ if TYPE_CHECKING:
13
+ from baf.core.agent import Agent
14
+ from baf.core.session import Session
15
+ from baf.nlp.intent_classifier.llm_intent_classifier import LLMIntentClassifier
16
+
17
+ try:
18
+ import anthropic as anthropic_sdk
19
+ except ImportError:
20
+ anthropic_sdk = None
21
+ logger.warning("anthropic dependencies in LLMAnthropic could not be imported. You can install them via "
22
+ "'pip install anthropic' or by adding it to requirements/requirements-llms.txt")
23
+
24
+ _DEFAULT_MAX_TOKENS = 4096
25
+ """Default ``max_tokens`` used when the caller does not supply one.
26
+
27
+ The Anthropic Messages API requires ``max_tokens`` to be provided explicitly; this
28
+ constant is used as a safe default when it is absent from ``self.parameters``.
29
+ """
30
+
31
+
32
+ class LLMAnthropic(LLM):
33
+ """LLM wrapper for Anthropic Claude models using the native ``anthropic`` SDK.
34
+
35
+ Anthropic's API differs enough from the OpenAI shape (system-prompt placement,
36
+ tool-use schema, required ``max_tokens``, streaming model) that a dedicated
37
+ implementation is cleaner than relying on the OpenAI-compat endpoint.
38
+
39
+ Requires ``nlp.anthropic.api_key`` to be set in the agent config file (or
40
+ passed as ``"api_key"`` inside ``parameters`` for a one-time override).
41
+
42
+ Args:
43
+ agent (Agent): the agent the LLM belongs to
44
+ name (str): the model identifier (e.g. ``"claude-opus-4-5"``,
45
+ ``"claude-sonnet-4-5"``, ``"claude-haiku-4-5-20251001"``).
46
+ parameters (dict): parameters forwarded to ``messages.create``
47
+ (e.g. ``{"temperature": 0.7, "max_tokens": 2048}``). May also contain
48
+ ``"api_key"`` which is consumed by :meth:`initialize` and not forwarded.
49
+ num_previous_messages (int): number of previous conversation turns to include
50
+ in :meth:`chat` calls (must be > 0).
51
+ global_context (str): system-level context injected into every request.
52
+
53
+ Attributes:
54
+ client: the ``anthropic.Anthropic`` client, instantiated in :meth:`initialize`.
55
+ num_previous_messages (int): number of previous messages used in :meth:`chat`.
56
+ """
57
+
58
+ def __init__(self, agent: 'Agent', name: str, parameters: dict, num_previous_messages: int = 1,
59
+ global_context: str = None):
60
+ super().__init__(agent, name, parameters, global_context=global_context)
61
+ self.client: Any = None
62
+ self.num_previous_messages: int = num_previous_messages
63
+
64
+ def set_model(self, name: str) -> None:
65
+ """Set the Claude model identifier.
66
+
67
+ Args:
68
+ name (str): the new model identifier
69
+ """
70
+ self.name = name
71
+
72
+ def set_num_previous_messages(self, num_previous_messages: int) -> None:
73
+ """Set the number of previous messages used in :meth:`chat`.
74
+
75
+ Args:
76
+ num_previous_messages (int): the new number of previous messages
77
+ """
78
+ self.num_previous_messages = num_previous_messages
79
+
80
+ def initialize(self) -> None:
81
+ """Instantiate the Anthropic client.
82
+
83
+ Reads ``api_key`` from ``self.parameters`` first (popping it so it is not
84
+ forwarded to the API call), then falls back to the ``nlp.anthropic.api_key``
85
+ config-file property.
86
+ """
87
+ if anthropic_sdk is None:
88
+ raise ImportError(
89
+ "The 'anthropic' package is required for LLMAnthropic. "
90
+ "Install it with: pip install anthropic"
91
+ )
92
+ api_key = self.parameters.pop('api_key', None) \
93
+ or self._nlp_engine.get_property(nlp.ANTHROPIC_API_KEY)
94
+ self.client = anthropic_sdk.Anthropic(api_key=api_key)
95
+
96
+ # ------------------------------------------------------------------
97
+ # Internal helpers
98
+ # ------------------------------------------------------------------
99
+
100
+ def _build_system(self, system_message: str = None, session: 'Session' = None) -> str | anthropic_sdk.NOT_GIVEN:
101
+ """Assemble the Anthropic ``system`` parameter.
102
+
103
+ Anthropic's API requires a single top-level ``system`` string (or ``NOT_GIVEN``),
104
+ not a list of system-role messages. We concatenate global context, session user
105
+ context, and the per-call system message in that order.
106
+ """
107
+ parts = []
108
+ if self._global_context:
109
+ parts.append(self._global_context)
110
+ if session and session.id in self._user_context:
111
+ parts.append(self._user_context[session.id])
112
+ if system_message:
113
+ parts.append(system_message)
114
+ if parts:
115
+ return "\n\n".join(parts)
116
+ return anthropic_sdk.NOT_GIVEN
117
+
118
+ def _resolve_params(self, parameters: dict) -> dict:
119
+ """Merge call-time parameters with defaults.
120
+
121
+ Ensures ``max_tokens`` is always present (Anthropic requires it).
122
+ """
123
+ params = dict(self.parameters) if not parameters else dict(parameters)
124
+ params.setdefault('max_tokens', _DEFAULT_MAX_TOKENS)
125
+ return params
126
+
127
+ @staticmethod
128
+ def _openai_tools_to_anthropic(tools: list[dict]) -> list[dict]:
129
+ """Convert OpenAI-style tool schemas to Anthropic tool format.
130
+
131
+ OpenAI: ``{"type": "function", "function": {"name", "description", "parameters"}}``
132
+ Anthropic: ``{"name", "description", "input_schema"}``
133
+ """
134
+ result = []
135
+ for t in tools:
136
+ fn = t.get("function", {}) if t.get("type") == "function" else t
137
+ result.append({
138
+ "name": fn.get("name", ""),
139
+ "description": fn.get("description", ""),
140
+ "input_schema": fn.get("parameters", {"type": "object", "properties": {}}),
141
+ })
142
+ return result
143
+
144
+ # ------------------------------------------------------------------
145
+ # Public API (implements LLM abstract methods)
146
+ # ------------------------------------------------------------------
147
+
148
+ def predict(self, message: str, parameters: dict = None, session: 'Session' = None,
149
+ system_message: str = None) -> str:
150
+ params = self._resolve_params(parameters)
151
+ system = self._build_system(system_message=system_message, session=session)
152
+ response = self.client.messages.create(
153
+ model=self.name,
154
+ system=system,
155
+ messages=[{"role": "user", "content": message}],
156
+ **params,
157
+ )
158
+ return response.content[0].text
159
+
160
+ def chat(self, session: 'Session', parameters: dict = None, system_message: str = None) -> str:
161
+ if self.num_previous_messages <= 0:
162
+ raise ValueError('The number of previous messages to send to the LLM must be > 0')
163
+ params = self._resolve_params(parameters)
164
+ system = self._build_system(system_message=system_message, session=session)
165
+ chat_history: list[Message] = session.get_chat_history(n=self.num_previous_messages)
166
+ messages = [
167
+ {'role': 'user' if message.is_user else 'assistant', 'content': message.content}
168
+ for message in chat_history
169
+ if message.type in [MessageType.STR, MessageType.LOCATION, MessageType.JSON]
170
+ ]
171
+ response = self.client.messages.create(
172
+ model=self.name,
173
+ system=system,
174
+ messages=messages,
175
+ **params,
176
+ )
177
+ return response.content[0].text
178
+
179
+ def predict_with_tools(
180
+ self,
181
+ messages: list[dict],
182
+ tools: list[dict],
183
+ parameters: dict = None,
184
+ system_message: str = None,
185
+ ) -> LLMResponse:
186
+ """Make a tool-calling prediction using the native Anthropic SDK.
187
+
188
+ Input ``messages`` and ``tools`` use OpenAI schema; this method translates them
189
+ to the Anthropic format and maps the response back to the shared
190
+ :class:`~baf.nlp.llm.llm.LLMResponse` / :class:`~baf.nlp.llm.llm.ToolCall`
191
+ types so callers remain provider-agnostic.
192
+
193
+ Args:
194
+ messages (list[dict]): OpenAI-style chat messages. Tool result messages must
195
+ include ``"tool_call_id"`` matching the call they answer.
196
+ tools (list[dict]): OpenAI-style tool schemas.
197
+ parameters (dict): extra parameters (e.g. ``temperature``, ``max_tokens``).
198
+ system_message (str): high-priority system message.
199
+
200
+ Returns:
201
+ LLMResponse: final text or list of tool calls.
202
+ """
203
+ params = self._resolve_params(parameters)
204
+ system = self._build_system(system_message=system_message)
205
+ anthropic_tools = self._openai_tools_to_anthropic(tools) if tools else anthropic_sdk.NOT_GIVEN
206
+
207
+ # Convert OpenAI tool-result messages (role=tool) to Anthropic's user/tool_result format.
208
+ converted: list[dict] = []
209
+ for msg in messages:
210
+ if msg.get("role") == "tool":
211
+ converted.append({
212
+ "role": "user",
213
+ "content": [{
214
+ "type": "tool_result",
215
+ "tool_use_id": msg.get("tool_call_id", ""),
216
+ "content": msg.get("content", ""),
217
+ }]
218
+ })
219
+ else:
220
+ converted.append(msg)
221
+
222
+ response = self.client.messages.create(
223
+ model=self.name,
224
+ system=system,
225
+ messages=converted,
226
+ tools=anthropic_tools,
227
+ **params,
228
+ )
229
+
230
+ # Map Anthropic response blocks back to the shared LLMResponse shape.
231
+ tool_use_blocks = [b for b in response.content if b.type == "tool_use"]
232
+ if tool_use_blocks:
233
+ calls = [
234
+ ToolCall(id=b.id, name=b.name, arguments=b.input if isinstance(b.input, dict) else {})
235
+ for b in tool_use_blocks
236
+ ]
237
+ return LLMResponse(text=None, tool_calls=calls, raw=response)
238
+
239
+ text_blocks = [b for b in response.content if b.type == "text"]
240
+ text = text_blocks[0].text if text_blocks else ""
241
+ return LLMResponse(text=text, tool_calls=None, raw=response)
242
+
243
+ def intent_classification(
244
+ self,
245
+ intent_classifier: 'LLMIntentClassifier',
246
+ message: str,
247
+ parameters: dict = None
248
+ ) -> list[IntentClassifierPrediction]:
249
+ """Classify intent via the Anthropic API, returning the same shape as LLMOpenAI.
250
+
251
+ The output is fed to
252
+ :meth:`~baf.nlp.intent_classifier.llm_intent_classifier.LLMIntentClassifier.default_json_to_intent_classifier_predictions`
253
+ so that intent classifiers remain provider-agnostic.
254
+ """
255
+ params = self._resolve_params(parameters)
256
+ response = self.client.messages.create(
257
+ model=self.name,
258
+ messages=[{"role": "user", "content": message}],
259
+ **params,
260
+ )
261
+ raw_text = response.content[0].text
262
+ try:
263
+ response_json = json.loads(raw_text)
264
+ except json.JSONDecodeError:
265
+ logger.warning(f"LLMAnthropic: could not JSON-decode intent response: {raw_text!r}")
266
+ response_json = {}
267
+ return intent_classifier.default_json_to_intent_classifier_predictions(
268
+ message=message,
269
+ response_json=response_json
270
+ )
@@ -0,0 +1,17 @@
1
+ from __future__ import annotations
2
+
3
+ from baf import nlp
4
+ from baf.nlp.llm.llm_openai_compatible import LLMOpenAICompatible
5
+
6
+
7
+ class LLMDeepSeek(LLMOpenAICompatible):
8
+ """LLM wrapper for DeepSeek models via DeepSeek's OpenAI-compatible API.
9
+
10
+ Requires ``nlp.deepseek.api_key`` to be set in the agent config file.
11
+ The default base URL points to ``https://api.deepseek.com``.
12
+
13
+ Example model names: ``"deepseek-chat"``, ``"deepseek-reasoner"``.
14
+ """
15
+
16
+ DEFAULT_BASE_URL = "https://api.deepseek.com"
17
+ API_KEY_PROPERTY = nlp.DEEPSEEK_API_KEY
@@ -0,0 +1,21 @@
1
+ from __future__ import annotations
2
+
3
+ from baf import nlp
4
+ from baf.nlp.llm.llm_openai_compatible import LLMOpenAICompatible
5
+
6
+
7
+ class LLMGoogle(LLMOpenAICompatible):
8
+ """LLM wrapper for Google Gemini models via Google's OpenAI-compatible endpoint.
9
+
10
+ Requires ``nlp.google.api_key`` to be set in the agent config file.
11
+ The default base URL points to the Gemini OpenAI-compatible endpoint.
12
+
13
+ Example model names: ``"gemini-2.5-pro"``, ``"gemini-2.5-flash"``,
14
+ ``"gemini-2.0-flash"``, ``"gemini-1.5-pro"``.
15
+
16
+ Note: for advanced Gemini-specific features (grounding, multimodal tool use, etc.)
17
+ a native ``google-genai`` SDK wrapper can be added separately.
18
+ """
19
+
20
+ DEFAULT_BASE_URL = "https://generativelanguage.googleapis.com/v1beta/openai/"
21
+ API_KEY_PROPERTY = nlp.GOOGLE_API_KEY
@@ -0,0 +1,18 @@
1
+ from __future__ import annotations
2
+
3
+ from baf import nlp
4
+ from baf.nlp.llm.llm_openai_compatible import LLMOpenAICompatible
5
+
6
+
7
+ class LLMGroq(LLMOpenAICompatible):
8
+ """LLM wrapper for Groq-hosted models via Groq's OpenAI-compatible API.
9
+
10
+ Requires ``nlp.groq.api_key`` to be set in the agent config file.
11
+ The default base URL points to ``https://api.groq.com/openai/v1``.
12
+
13
+ Example model names: ``"llama-3.3-70b-versatile"``, ``"llama3-8b-8192"``,
14
+ ``"gemma2-9b-it"``, ``"mixtral-8x7b-32768"``.
15
+ """
16
+
17
+ DEFAULT_BASE_URL = "https://api.groq.com/openai/v1"
18
+ API_KEY_PROPERTY = nlp.GROQ_API_KEY
@@ -0,0 +1,18 @@
1
+ from __future__ import annotations
2
+
3
+ from baf import nlp
4
+ from baf.nlp.llm.llm_openai_compatible import LLMOpenAICompatible
5
+
6
+
7
+ class LLMMeta(LLMOpenAICompatible):
8
+ """LLM wrapper for Meta Llama models via Meta's OpenAI-compatible API.
9
+
10
+ Requires ``nlp.meta.api_key`` to be set in the agent config file.
11
+ The default base URL points to ``https://api.llama.com/compat/v1/``.
12
+
13
+ Example model names: ``"Llama-4-Scout-17B-16E-Instruct-FP8"``,
14
+ ``"Llama-4-Maverick-17B-128E-Instruct-FP8"``, ``"Llama-3.3-70B-Instruct"``.
15
+ """
16
+
17
+ DEFAULT_BASE_URL = "https://api.llama.com/compat/v1/"
18
+ API_KEY_PROPERTY = nlp.META_API_KEY
@@ -0,0 +1,18 @@
1
+ from __future__ import annotations
2
+
3
+ from baf import nlp
4
+ from baf.nlp.llm.llm_openai_compatible import LLMOpenAICompatible
5
+
6
+
7
+ class LLMMistral(LLMOpenAICompatible):
8
+ """LLM wrapper for Mistral AI models via Mistral's OpenAI-compatible API.
9
+
10
+ Requires ``nlp.mistral.api_key`` to be set in the agent config file.
11
+ The default base URL points to ``https://api.mistral.ai/v1``.
12
+
13
+ Example model names: ``"mistral-small-latest"``, ``"mistral-large-latest"``,
14
+ ``"mistral-medium-latest"``, ``"open-mistral-nemo"``.
15
+ """
16
+
17
+ DEFAULT_BASE_URL = "https://api.mistral.ai/v1"
18
+ API_KEY_PROPERTY = nlp.MISTRAL_API_KEY
@@ -0,0 +1,34 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from baf import nlp
6
+ from baf.nlp.llm.llm_openai_compatible import LLMOpenAICompatible
7
+
8
+ if TYPE_CHECKING:
9
+ from baf.core.agent import Agent
10
+
11
+
12
+ class LLMOpenAI(LLMOpenAICompatible):
13
+ """An LLM wrapper for OpenAI's models through the OpenAI API.
14
+
15
+ Inherits all prediction logic from :class:`~baf.nlp.llm.llm_openai_compatible.LLMOpenAICompatible`.
16
+ The OpenAI client is initialised with the ``nlp.openai.api_key`` config property and the
17
+ standard ``https://api.openai.com`` base URL.
18
+
19
+ Args:
20
+ agent (Agent): the agent the LLM belongs to
21
+ name (str): the model identifier (e.g. ``"gpt-4o-mini"``)
22
+ parameters (dict): parameters forwarded to ``chat.completions.create``
23
+ (e.g. ``{"temperature": 0.7}``).
24
+ num_previous_messages (int): number of previous turns to include in :meth:`chat`
25
+ calls (must be > 0).
26
+ global_context (str): system-level context injected into every request.
27
+
28
+ Attributes:
29
+ client (OpenAI): the OpenAI client, instantiated in :meth:`initialize`.
30
+ num_previous_messages (int): number of previous messages used in :meth:`chat`.
31
+ """
32
+
33
+ DEFAULT_BASE_URL: str | None = None # use the OpenAI SDK default
34
+ API_KEY_PROPERTY = nlp.OPENAI_API_KEY