quantalogic 0.2.15__tar.gz → 0.2.17__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 (76) hide show
  1. {quantalogic-0.2.15 → quantalogic-0.2.17}/PKG-INFO +21 -148
  2. {quantalogic-0.2.15 → quantalogic-0.2.17}/README.md +11 -147
  3. {quantalogic-0.2.15 → quantalogic-0.2.17}/pyproject.toml +24 -1
  4. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/__init__.py +3 -2
  5. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/agent.py +58 -37
  6. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/agent_config.py +18 -13
  7. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/coding_agent.py +9 -3
  8. quantalogic-0.2.15/quantalogic/print_event.py → quantalogic-0.2.17/quantalogic/console_print_events.py +1 -3
  9. quantalogic-0.2.17/quantalogic/console_print_token.py +16 -0
  10. quantalogic-0.2.17/quantalogic/docs_cli.py +50 -0
  11. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/generative_model.py +80 -77
  12. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/main.py +122 -29
  13. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/prompts.py +1 -0
  14. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/search_agent.py +15 -7
  15. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/server/agent_server.py +2 -2
  16. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/llm_tool.py +52 -11
  17. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/llm_vision_tool.py +23 -7
  18. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/xml_parser.py +109 -49
  19. {quantalogic-0.2.15 → quantalogic-0.2.17}/LICENSE +0 -0
  20. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/event_emitter.py +0 -0
  21. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/interactive_text_editor.py +0 -0
  22. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/memory.py +0 -0
  23. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/model_names.py +0 -0
  24. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/server/__init__.py +0 -0
  25. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/server/models.py +0 -0
  26. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/server/routes.py +0 -0
  27. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/server/state.py +0 -0
  28. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/server/static/js/event_visualizer.js +0 -0
  29. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/server/static/js/quantalogic.js +0 -0
  30. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/server/templates/index.html +0 -0
  31. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tool_manager.py +0 -0
  32. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/__init__.py +0 -0
  33. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/agent_tool.py +0 -0
  34. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/download_http_file_tool.py +0 -0
  35. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/duckduckgo_search_tool.py +0 -0
  36. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/edit_whole_content_tool.py +0 -0
  37. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/elixir_tool.py +0 -0
  38. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/execute_bash_command_tool.py +0 -0
  39. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/input_question_tool.py +0 -0
  40. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/language_handlers/__init__.py +0 -0
  41. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/language_handlers/c_handler.py +0 -0
  42. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/language_handlers/cpp_handler.py +0 -0
  43. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/language_handlers/go_handler.py +0 -0
  44. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/language_handlers/java_handler.py +0 -0
  45. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/language_handlers/javascript_handler.py +0 -0
  46. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/language_handlers/python_handler.py +0 -0
  47. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/language_handlers/rust_handler.py +0 -0
  48. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/language_handlers/scala_handler.py +0 -0
  49. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/language_handlers/typescript_handler.py +0 -0
  50. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/list_directory_tool.py +0 -0
  51. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/markitdown_tool.py +0 -0
  52. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/nodejs_tool.py +0 -0
  53. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/python_tool.py +0 -0
  54. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/read_file_block_tool.py +0 -0
  55. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/read_file_tool.py +0 -0
  56. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/replace_in_file_tool.py +0 -0
  57. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/ripgrep_tool.py +0 -0
  58. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/search_definition_names.py +0 -0
  59. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/serpapi_search_tool.py +0 -0
  60. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/task_complete_tool.py +0 -0
  61. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/tool.py +0 -0
  62. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/unified_diff_tool.py +0 -0
  63. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/wikipedia_search_tool.py +0 -0
  64. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/write_file_tool.py +0 -0
  65. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/utils/__init__.py +0 -0
  66. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/utils/ask_user_validation.py +0 -0
  67. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/utils/check_version.py +0 -0
  68. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/utils/download_http_file.py +0 -0
  69. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/utils/get_coding_environment.py +0 -0
  70. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/utils/get_environment.py +0 -0
  71. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/utils/get_quantalogic_rules_content.py +0 -0
  72. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/utils/git_ls.py +0 -0
  73. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/utils/read_file.py +0 -0
  74. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/utils/read_http_text_content.py +0 -0
  75. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/version.py +0 -0
  76. {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/xml_tool_parser.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quantalogic
3
- Version: 0.2.15
3
+ Version: 0.2.17
4
4
  Summary: QuantaLogic ReAct Agents
5
5
  Author: Raphaël MANSUY
6
6
  Author-email: raphael.mansuy@gmail.com
@@ -15,11 +15,20 @@ Requires-Dist: fastapi (>=0.115.6,<0.116.0)
15
15
  Requires-Dist: google-auth (>=2.20.0,<3.0.0)
16
16
  Requires-Dist: google-search-results (>=2.4.2,<3.0.0)
17
17
  Requires-Dist: litellm (>=1.56.4,<2.0.0)
18
+ Requires-Dist: llmlingua (>=0.2.2,<0.3.0)
18
19
  Requires-Dist: loguru (>=0.7.3,<0.8.0)
19
20
  Requires-Dist: markitdown (>=0.0.1a3,<0.0.2)
21
+ Requires-Dist: mkdocs-git-revision-date-localized-plugin (>=1.2.0,<2.0.0)
22
+ Requires-Dist: mkdocs-macros-plugin (>=1.0.4,<2.0.0)
23
+ Requires-Dist: mkdocs-material[imaging] (>=9.5.49,<10.0.0)
24
+ Requires-Dist: mkdocs-mermaid2-plugin (>=1.1.1,<2.0.0)
25
+ Requires-Dist: mkdocs-minify-plugin (>=0.7.1,<0.8.0)
26
+ Requires-Dist: mkdocstrings (>=0.24.0,<0.25.0)
27
+ Requires-Dist: mkdocstrings-python (>=1.7.0,<2.0.0)
20
28
  Requires-Dist: pathspec (>=0.12.1,<0.13.0)
21
29
  Requires-Dist: prompt-toolkit (>=3.0.48,<4.0.0)
22
30
  Requires-Dist: pydantic (>=2.10.4,<3.0.0)
31
+ Requires-Dist: pymdown-extensions (>=10.3.1,<11.0.0)
23
32
  Requires-Dist: rich (>=13.9.4,<14.0.0)
24
33
  Requires-Dist: serpapi (>=0.1.5,<0.2.0)
25
34
  Requires-Dist: tenacity (>=9.0.0,<10.0.0)
@@ -43,7 +52,7 @@ Description-Content-Type: text/markdown
43
52
 
44
53
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
45
54
  [![Python](https://img.shields.io/badge/Python-3.12+-blue.svg)](https://www.python.org/downloads/)
46
- [![Documentation](https://img.shields.io/badge/docs-latest-brightgreen.svg)]()
55
+ [![Documentation](https://img.shields.io/badge/docs-latest-brightgreen.svg)](https://quantalogic.github.io/quantalogic/)
47
56
 
48
57
  QuantaLogic is a ReAct (Reasoning & Action) framework for building advanced AI agents.
49
58
 
@@ -51,6 +60,8 @@ It seamlessly integrates large language models (LLMs) with a robust tool system,
51
60
 
52
61
  The `cli` version include coding capabilities comparable to Aider.
53
62
 
63
+ [📖 Documentation](https://quantalogic.github.io/quantalogic/)
64
+
54
65
 
55
66
  ## Why QuantaLogic?
56
67
 
@@ -80,6 +91,7 @@ We created [QuantaLogic](https://www.quantalogic.app) because we saw a significa
80
91
  - [Development](#-development)
81
92
  - [Contributing](#-contributing)
82
93
  - [License](#-license)
94
+ - [Documentation Development](#-documentation-development)
83
95
 
84
96
  ## 📦 Installation
85
97
 
@@ -128,12 +140,13 @@ Usage: quantalogic [OPTIONS] COMMAND [ARGS]...
128
140
  Options:
129
141
  --version Show version information.
130
142
  --model-name TEXT Specify the text model to use (litellm format,
131
- e.g. "openrouter/deepseek-chat").
143
+ e.g. "openrouter/deepseek/deepseek-chat").
132
144
  --vision-model-name TEXT Specify the vision model to use (litellm format,
133
- e.g. "openrouter/A/gpt-4o-mini").
145
+ e.g. "openrouter/openai/gpt-4o-mini").
134
146
  --log [info|debug|warning] Set logging level (info/debug/warning).
135
147
  --verbose Enable verbose output.
136
- --mode [code|basic|interpreter|full|code-basic|search]
148
+ --max-iterations INTEGER Maximum iterations for task solving (default: 30).
149
+ --mode [code|basic|interpreter|full|code-basic|search|search-full]
137
150
  Agent mode (code/search/full).
138
151
  --help Show this message and exit.
139
152
 
@@ -154,6 +167,7 @@ task Execute a task with the QuantaLogic AI Assistant
154
167
  - interpreter: Interactive code execution agent
155
168
  - full: Full-featured agent with all capabilities
156
169
  - code-basic: Coding agent with basic reasoning
170
+ - search: Web search agent with Wikipedia, DuckDuckGo and SERPApi integration
157
171
 
158
172
  #### Task Execution
159
173
 
@@ -249,7 +263,7 @@ from quantalogic.tools import PythonTool, ReadFileTool
249
263
 
250
264
  # Create agent with specific tools
251
265
  agent = Agent(
252
- model_name="openrouter/deepseek-chat",
266
+ model_name="openrouter/deepseek/deepseek-chat",
253
267
  tools=[
254
268
  PythonTool(),
255
269
  ReadFileTool()
@@ -842,148 +856,7 @@ print(results)
842
856
  ```
843
857
  ```
844
858
 
845
- #### Creating Custom Tools
846
-
847
- ```python
848
- from quantalogic.tools import Tool, ToolArgument
849
-
850
- class DatabaseTool(Tool):
851
- name: str = "database_tool"
852
- description: str = "Execute database operations"
853
- need_validation: bool = True
854
-
855
- arguments: list[ToolArgument] = [
856
- ToolArgument(
857
- name="query",
858
- arg_type="string",
859
- description="SQL query to execute",
860
- required=True
861
- )
862
- ]
863
-
864
- def execute(self, query: str) -> str:
865
- # Tool implementation
866
- return "Query results"
867
859
  ```
868
-
869
-
870
- ## 🌐 Web Interface
871
-
872
- Features:
873
- - Real-time event visualization
874
- - Task submission and monitoring
875
- - Interactive validation dialogs
876
- - Model selection
877
- - Event filtering and search
878
-
879
- ### API Endpoints
880
-
881
- | Endpoint | Method | Description |
882
- | ------------------ | ------ | --------------- |
883
- | `/tasks` | POST | Submit tasks |
884
- | `/tasks/{task_id}` | GET | Task status |
885
- | `/events` | GET | SSE endpoint |
886
- | `/validate` | POST | Task validation |
887
-
888
-
889
- ## 📖 Examples
890
-
891
- ### Python Tool Integration Example
892
-
893
- ```python
894
- import os
895
-
896
- from quantalogic import Agent, console_print_events
897
- from quantalogic.tools import (
898
- PythonTool,
899
- )
900
-
901
- # Verify API key is set - required for authentication with DeepSeek's API
902
- # This check ensures the agent won't fail during runtime due to missing credentials
903
- if not os.environ.get("DEEPSEEK_API_KEY"):
904
- raise ValueError("DEEPSEEK_API_KEY environment variable is not set")
905
-
906
- # Initialize agent with DeepSeek model and Python tool
907
- agent = Agent(model_name="deepseek/deepseek-chat", tools=[PythonTool()])
908
-
909
- # Configure comprehensive event monitoring system
910
- # Tracks all agent activities including:
911
- # - Code execution steps
912
- # - Tool interactions
913
- # - Error conditions
914
- # Essential for debugging and performance optimization
915
- agent.event_emitter.on(
916
- "*",
917
- console_print_events,
918
- )
919
-
920
- # Execute a precision mathematics task demonstrating:
921
- # - High-precision calculations
922
- # - PythonTool integration
923
- # - Real-time monitoring capabilities
924
- result = agent.solve_task("1. Calculate PI with 10000 decimal places.")
925
- print(result)
926
- ```
927
-
928
- ### Agent with Event Monitoring
929
-
930
- ```python
931
- import os
932
-
933
- from quantalogic import Agent, console_print_events
934
- from quantalogic.tools import (
935
- LLMTool,
936
- )
937
-
938
- # Verify API key is set - required for authentication with DeepSeek's API
939
- # This check ensures the agent won't fail during runtime due to missing credentials
940
- if not os.environ.get("DEEPSEEK_API_KEY"):
941
- raise ValueError("DEEPSEEK_API_KEY environment variable is not set")
942
-
943
- # Initialize agent with DeepSeek model and LLM tool
944
- # The LLM tool serves dual purpose:
945
- # 1. As a reasoning engine for the agent's cognitive processes
946
- # 2. As a latent space explorer, enabling the agent to:
947
- # - Discover novel solution paths
948
- # - Generate creative combinations of concepts
949
- # - Explore alternative reasoning strategies
950
- # Using the same model ensures consistent behavior across both roles
951
- agent = Agent(model_name="deepseek/deepseek-chat", tools=[LLMTool(model_name="deepseek/deepseek-chat")])
952
-
953
- # Set up event monitoring to track agent's lifecycle
954
- # This helps in debugging and understanding the agent's behavior
955
- agent.event_emitter.on(
956
- [
957
- "task_complete",
958
- "task_think_start",
959
- "task_think_end",
960
- "tool_execution_start",
961
- "tool_execution_end",
962
- "error_max_iterations_reached",
963
- "memory_full",
964
- "memory_compacted",
965
- "memory_summary",
966
- ],
967
- console_print_events,
968
- )
969
-
970
- # Execute a multi-step task showcasing agent's capabilities
971
- # Demonstrates:
972
- # 1. Creative content generation
973
- # 2. Language translation
974
- # 3. Style adaptation
975
- # 4. Multi-step reasoning and execution
976
- result = agent.solve_task(
977
- "1. Write a poem in English about a dog. "
978
- "2. Translate the poem into French. "
979
- "3. Choose 2 French authors"
980
- "4. Rewrite the translated poem with the style of the chosen authors. "
981
- )
982
- print(result)
983
- ```
984
-
985
-
986
-
987
860
  ### Project Documentation
988
861
 
989
862
  ```python
@@ -991,7 +864,7 @@ from quantalogic import Agent
991
864
  from quantalogic.tools import MarkitdownTool, ReadFileTool
992
865
 
993
866
  agent = Agent(
994
- model_name="openrouter/deepseek-chat",
867
+ model_name="openrouter/deepseek/deepseek-chat",
995
868
  tools=[MarkitdownTool(), ReadFileTool()]
996
869
  )
997
870
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
4
4
  [![Python](https://img.shields.io/badge/Python-3.12+-blue.svg)](https://www.python.org/downloads/)
5
- [![Documentation](https://img.shields.io/badge/docs-latest-brightgreen.svg)]()
5
+ [![Documentation](https://img.shields.io/badge/docs-latest-brightgreen.svg)](https://quantalogic.github.io/quantalogic/)
6
6
 
7
7
  QuantaLogic is a ReAct (Reasoning & Action) framework for building advanced AI agents.
8
8
 
@@ -10,6 +10,8 @@ It seamlessly integrates large language models (LLMs) with a robust tool system,
10
10
 
11
11
  The `cli` version include coding capabilities comparable to Aider.
12
12
 
13
+ [📖 Documentation](https://quantalogic.github.io/quantalogic/)
14
+
13
15
 
14
16
  ## Why QuantaLogic?
15
17
 
@@ -39,6 +41,7 @@ We created [QuantaLogic](https://www.quantalogic.app) because we saw a significa
39
41
  - [Development](#-development)
40
42
  - [Contributing](#-contributing)
41
43
  - [License](#-license)
44
+ - [Documentation Development](#-documentation-development)
42
45
 
43
46
  ## 📦 Installation
44
47
 
@@ -87,12 +90,13 @@ Usage: quantalogic [OPTIONS] COMMAND [ARGS]...
87
90
  Options:
88
91
  --version Show version information.
89
92
  --model-name TEXT Specify the text model to use (litellm format,
90
- e.g. "openrouter/deepseek-chat").
93
+ e.g. "openrouter/deepseek/deepseek-chat").
91
94
  --vision-model-name TEXT Specify the vision model to use (litellm format,
92
- e.g. "openrouter/A/gpt-4o-mini").
95
+ e.g. "openrouter/openai/gpt-4o-mini").
93
96
  --log [info|debug|warning] Set logging level (info/debug/warning).
94
97
  --verbose Enable verbose output.
95
- --mode [code|basic|interpreter|full|code-basic|search]
98
+ --max-iterations INTEGER Maximum iterations for task solving (default: 30).
99
+ --mode [code|basic|interpreter|full|code-basic|search|search-full]
96
100
  Agent mode (code/search/full).
97
101
  --help Show this message and exit.
98
102
 
@@ -113,6 +117,7 @@ task Execute a task with the QuantaLogic AI Assistant
113
117
  - interpreter: Interactive code execution agent
114
118
  - full: Full-featured agent with all capabilities
115
119
  - code-basic: Coding agent with basic reasoning
120
+ - search: Web search agent with Wikipedia, DuckDuckGo and SERPApi integration
116
121
 
117
122
  #### Task Execution
118
123
 
@@ -208,7 +213,7 @@ from quantalogic.tools import PythonTool, ReadFileTool
208
213
 
209
214
  # Create agent with specific tools
210
215
  agent = Agent(
211
- model_name="openrouter/deepseek-chat",
216
+ model_name="openrouter/deepseek/deepseek-chat",
212
217
  tools=[
213
218
  PythonTool(),
214
219
  ReadFileTool()
@@ -801,148 +806,7 @@ print(results)
801
806
  ```
802
807
  ```
803
808
 
804
- #### Creating Custom Tools
805
-
806
- ```python
807
- from quantalogic.tools import Tool, ToolArgument
808
-
809
- class DatabaseTool(Tool):
810
- name: str = "database_tool"
811
- description: str = "Execute database operations"
812
- need_validation: bool = True
813
-
814
- arguments: list[ToolArgument] = [
815
- ToolArgument(
816
- name="query",
817
- arg_type="string",
818
- description="SQL query to execute",
819
- required=True
820
- )
821
- ]
822
-
823
- def execute(self, query: str) -> str:
824
- # Tool implementation
825
- return "Query results"
826
809
  ```
827
-
828
-
829
- ## 🌐 Web Interface
830
-
831
- Features:
832
- - Real-time event visualization
833
- - Task submission and monitoring
834
- - Interactive validation dialogs
835
- - Model selection
836
- - Event filtering and search
837
-
838
- ### API Endpoints
839
-
840
- | Endpoint | Method | Description |
841
- | ------------------ | ------ | --------------- |
842
- | `/tasks` | POST | Submit tasks |
843
- | `/tasks/{task_id}` | GET | Task status |
844
- | `/events` | GET | SSE endpoint |
845
- | `/validate` | POST | Task validation |
846
-
847
-
848
- ## 📖 Examples
849
-
850
- ### Python Tool Integration Example
851
-
852
- ```python
853
- import os
854
-
855
- from quantalogic import Agent, console_print_events
856
- from quantalogic.tools import (
857
- PythonTool,
858
- )
859
-
860
- # Verify API key is set - required for authentication with DeepSeek's API
861
- # This check ensures the agent won't fail during runtime due to missing credentials
862
- if not os.environ.get("DEEPSEEK_API_KEY"):
863
- raise ValueError("DEEPSEEK_API_KEY environment variable is not set")
864
-
865
- # Initialize agent with DeepSeek model and Python tool
866
- agent = Agent(model_name="deepseek/deepseek-chat", tools=[PythonTool()])
867
-
868
- # Configure comprehensive event monitoring system
869
- # Tracks all agent activities including:
870
- # - Code execution steps
871
- # - Tool interactions
872
- # - Error conditions
873
- # Essential for debugging and performance optimization
874
- agent.event_emitter.on(
875
- "*",
876
- console_print_events,
877
- )
878
-
879
- # Execute a precision mathematics task demonstrating:
880
- # - High-precision calculations
881
- # - PythonTool integration
882
- # - Real-time monitoring capabilities
883
- result = agent.solve_task("1. Calculate PI with 10000 decimal places.")
884
- print(result)
885
- ```
886
-
887
- ### Agent with Event Monitoring
888
-
889
- ```python
890
- import os
891
-
892
- from quantalogic import Agent, console_print_events
893
- from quantalogic.tools import (
894
- LLMTool,
895
- )
896
-
897
- # Verify API key is set - required for authentication with DeepSeek's API
898
- # This check ensures the agent won't fail during runtime due to missing credentials
899
- if not os.environ.get("DEEPSEEK_API_KEY"):
900
- raise ValueError("DEEPSEEK_API_KEY environment variable is not set")
901
-
902
- # Initialize agent with DeepSeek model and LLM tool
903
- # The LLM tool serves dual purpose:
904
- # 1. As a reasoning engine for the agent's cognitive processes
905
- # 2. As a latent space explorer, enabling the agent to:
906
- # - Discover novel solution paths
907
- # - Generate creative combinations of concepts
908
- # - Explore alternative reasoning strategies
909
- # Using the same model ensures consistent behavior across both roles
910
- agent = Agent(model_name="deepseek/deepseek-chat", tools=[LLMTool(model_name="deepseek/deepseek-chat")])
911
-
912
- # Set up event monitoring to track agent's lifecycle
913
- # This helps in debugging and understanding the agent's behavior
914
- agent.event_emitter.on(
915
- [
916
- "task_complete",
917
- "task_think_start",
918
- "task_think_end",
919
- "tool_execution_start",
920
- "tool_execution_end",
921
- "error_max_iterations_reached",
922
- "memory_full",
923
- "memory_compacted",
924
- "memory_summary",
925
- ],
926
- console_print_events,
927
- )
928
-
929
- # Execute a multi-step task showcasing agent's capabilities
930
- # Demonstrates:
931
- # 1. Creative content generation
932
- # 2. Language translation
933
- # 3. Style adaptation
934
- # 4. Multi-step reasoning and execution
935
- result = agent.solve_task(
936
- "1. Write a poem in English about a dog. "
937
- "2. Translate the poem into French. "
938
- "3. Choose 2 French authors"
939
- "4. Rewrite the translated poem with the style of the chosen authors. "
940
- )
941
- print(result)
942
- ```
943
-
944
-
945
-
946
810
  ### Project Documentation
947
811
 
948
812
  ```python
@@ -950,7 +814,7 @@ from quantalogic import Agent
950
814
  from quantalogic.tools import MarkitdownTool, ReadFileTool
951
815
 
952
816
  agent = Agent(
953
- model_name="openrouter/deepseek-chat",
817
+ model_name="openrouter/deepseek/deepseek-chat",
954
818
  tools=[MarkitdownTool(), ReadFileTool()]
955
819
  )
956
820
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "quantalogic"
3
- version = "0.2.15"
3
+ version = "0.2.17"
4
4
  description = "QuantaLogic ReAct Agents"
5
5
  authors = ["Raphaël MANSUY <raphael.mansuy@gmail.com>"]
6
6
  readme = "README.md"
@@ -37,9 +37,21 @@ types-requests = "^2.32.0.20241016"
37
37
  google-search-results = "^2.4.2"
38
38
  serpapi = "^0.1.5"
39
39
  duckduckgo-search = "^7.2.1"
40
+ mkdocs-material = {extras = ["imaging"], version = "^9.5.49"}
41
+ mkdocs-mermaid2-plugin = "^1.1.1"
42
+ mkdocs-minify-plugin = "^0.7.1"
43
+ mkdocs-git-revision-date-localized-plugin = "^1.2.0"
44
+ mkdocs-macros-plugin = "^1.0.4"
45
+ mkdocstrings = "^0.24.0"
46
+ mkdocstrings-python = "^1.7.0"
47
+ pymdown-extensions = "^10.3.1"
48
+ llmlingua = "^0.2.2"
40
49
 
41
50
  [tool.poetry.scripts]
42
51
  quantalogic = "quantalogic.main:cli"
52
+ docs-serve = "quantalogic.docs_cli:serve_docs"
53
+ docs-build = "quantalogic.docs_cli:build_docs"
54
+ docs-deploy = "quantalogic.docs_cli:deploy_docs"
43
55
 
44
56
  [tool.poetry.group.dev.dependencies]
45
57
  ruff = "^0.8.4"
@@ -47,6 +59,17 @@ pytest = "^8.2.0"
47
59
  pytest-mock = "^3.14.0"
48
60
  litellm = "^1.55.9"
49
61
  ollama = "^0.4.4"
62
+ mkdocs = "^1.6.0"
63
+ mkdocs-material = "^9.5.0"
64
+
65
+ [tool.poetry.group.docs.dependencies]
66
+ mkdocs-material = {extras = ["imaging"], version = "^9.5.49"}
67
+ mkdocs-mermaid2-plugin = "^1.1.1"
68
+ mkdocs-git-revision-date-localized-plugin = "^1.2.0"
69
+ mkdocs-macros-plugin = "^1.0.4"
70
+ mkdocstrings = "^0.24.0"
71
+ mkdocstrings-python = "^1.7.0"
72
+ pymdown-extensions = "^10.3.1"
50
73
 
51
74
  [build-system]
52
75
  requires = ["poetry-core"]
@@ -11,10 +11,11 @@ warnings.filterwarnings(
11
11
 
12
12
 
13
13
  from .agent import Agent # noqa: E402
14
+ from .console_print_events import console_print_events # noqa: E402
15
+ from .console_print_token import console_print_token # noqa: E402
14
16
  from .event_emitter import EventEmitter # noqa: E402
15
17
  from .memory import AgentMemory, VariableMemory # noqa: E402
16
- from .print_event import console_print_events # noqa: E402
17
18
 
18
19
  """QuantaLogic package for AI-powered generative models."""
19
20
 
20
- __all__ = ["Agent", "EventEmitter", "AgentMemory", "VariableMemory", "console_print_events"]
21
+ __all__ = ["Agent", "EventEmitter", "AgentMemory", "VariableMemory", "console_print_events","console_print_token"]
@@ -8,7 +8,7 @@ from loguru import logger
8
8
  from pydantic import BaseModel, ConfigDict
9
9
 
10
10
  from quantalogic.event_emitter import EventEmitter
11
- from quantalogic.generative_model import GenerativeModel
11
+ from quantalogic.generative_model import GenerativeModel, ResponseStats, TokenUsage
12
12
  from quantalogic.memory import AgentMemory, Message, VariableMemory
13
13
  from quantalogic.prompts import system_prompt
14
14
  from quantalogic.tool_manager import ToolManager
@@ -85,6 +85,9 @@ class Agent(BaseModel):
85
85
  """Initialize the agent with model, memory, tools, and configurations."""
86
86
  try:
87
87
  logger.debug("Initializing agent...")
88
+ # Create event emitter first
89
+ event_emitter = EventEmitter()
90
+
88
91
  # Add TaskCompleteTool to the tools list if not already present
89
92
  if TaskCompleteTool() not in tools:
90
93
  tools.append(TaskCompleteTool())
@@ -108,7 +111,7 @@ class Agent(BaseModel):
108
111
 
109
112
  logger.debug("Base class init started ...")
110
113
  super().__init__(
111
- model=GenerativeModel(model=model_name),
114
+ model=GenerativeModel(model=model_name, event_emitter=event_emitter),
112
115
  memory=memory,
113
116
  variable_store=VariableMemory(),
114
117
  tools=tool_manager,
@@ -116,19 +119,21 @@ class Agent(BaseModel):
116
119
  ask_for_user_validation=ask_for_user_validation,
117
120
  task_to_solve=task_to_solve,
118
121
  specific_expertise=specific_expertise,
122
+ event_emitter=event_emitter,
119
123
  )
120
124
  logger.debug("Agent initialized successfully.")
121
125
  except Exception as e:
122
126
  logger.error(f"Failed to initialize agent: {str(e)}")
123
127
  raise
124
128
 
125
- def solve_task(self, task: str, max_iterations: int = 30) -> str:
129
+ def solve_task(self, task: str, max_iterations: int = 30, streaming: bool = False) -> str:
126
130
  """Solve the given task using the ReAct framework.
127
131
 
128
132
  Args:
129
133
  task (str): The task description.
130
134
  max_iterations (int, optional): Maximum number of iterations to attempt solving the task.
131
135
  Defaults to 30 to prevent infinite loops and ensure timely task completion.
136
+ streaming (bool, optional): Whether to use streaming mode for generating responses.
132
137
 
133
138
  Returns:
134
139
  str: The final response after task completion.
@@ -172,11 +177,34 @@ class Agent(BaseModel):
172
177
 
173
178
  self._compact_memory_if_needed(current_prompt)
174
179
 
175
- result = self.model.generate_with_history(messages_history=self.memory.memory, prompt=current_prompt)
180
+ if streaming:
181
+ # For streaming, collect the response chunks
182
+ content = ""
183
+ for chunk in self.model.generate_with_history(
184
+ messages_history=self.memory.memory, prompt=current_prompt, streaming=True
185
+ ):
186
+ content += chunk
187
+
188
+ # Create a response object similar to non-streaming mode
189
+ result = ResponseStats(
190
+ response=content,
191
+ usage=TokenUsage(
192
+ prompt_tokens=0, # We don't have token counts in streaming mode
193
+ completion_tokens=0,
194
+ total_tokens=0,
195
+ ),
196
+ model=self.model.model,
197
+ finish_reason="stop",
198
+ )
199
+ else:
200
+ result = self.model.generate_with_history(
201
+ messages_history=self.memory.memory, prompt=current_prompt, streaming=False
202
+ )
176
203
 
177
204
  content = result.response
178
- token_usage = result.usage
179
- self.total_tokens = token_usage.total_tokens
205
+ if not streaming: # Only update tokens for non-streaming mode
206
+ token_usage = result.usage
207
+ self.total_tokens = token_usage.total_tokens
180
208
 
181
209
  # Emit event: Task Think End
182
210
  self._emit_event(
@@ -187,7 +215,7 @@ class Agent(BaseModel):
187
215
  )
188
216
 
189
217
  # Process the assistant's response
190
- result = self._observe_response(result.response, iteration=self.current_iteration)
218
+ result = self._observe_response(content, iteration=self.current_iteration)
191
219
 
192
220
  current_prompt = result.next_prompt
193
221
 
@@ -292,9 +320,10 @@ class Agent(BaseModel):
292
320
  is_repeated_call = self._is_repeated_tool_call(tool_name, arguments_with_values)
293
321
 
294
322
  if is_repeated_call:
295
- return self._handle_repeated_tool_call(tool_name, arguments_with_values)
323
+ executed_tool, response = self._handle_repeated_tool_call(tool_name, arguments_with_values)
324
+ else:
325
+ executed_tool, response = self._execute_tool(tool_name, tool, arguments_with_values)
296
326
 
297
- executed_tool, response = self._execute_tool(tool_name, tool, arguments_with_values)
298
327
  if not executed_tool:
299
328
  return self._handle_tool_execution_failure(response)
300
329
 
@@ -406,7 +435,7 @@ class Agent(BaseModel):
406
435
 
407
436
  formatted_response = (
408
437
  "\n"
409
- f"--- Observations for iteration {iteration} ---\n"
438
+ f"--- Observations for iteration {iteration} / max {self.max_iterations} ---\n"
410
439
  "\n"
411
440
  f"\n --- Tool execution result stored in variable ${variable_name}$ --- \n"
412
441
  "\n"
@@ -427,34 +456,26 @@ class Agent(BaseModel):
427
456
 
428
457
  # Format the response message
429
458
  formatted_response = (
430
- "\n"
431
- f"--- Observations for iteration {iteration} ---\n"
432
- "\n"
433
- f"\n --- Tool execution result stored in variable ${variable_name}$ --- \n"
434
- "\n"
435
- f"<{variable_name}>\n{response_display}\n</{variable_name}>\n" + "\n"
436
- "\n"
437
- f"--- Tools --- \n"
438
- "\n"
439
- f"{self._get_tools_names_prompt()}"
440
- "\n"
441
- f"--- Variables --- \n"
442
- "\n"
443
- f"{self._get_variable_prompt()}"
444
- "\n"
445
- "You must analyze this answer and evaluate what to do next to solve the task.\n"
446
- "If the step failed, take a step back and rethink your approach.\n"
447
- "\n"
448
- "--- Task to solve summary ---\n"
449
- "\n"
450
- f"{self.task_to_solve_summary}"
451
- "\n"
459
+ f"\n--- Observations for iteration {iteration} / max {self.max_iterations} ---\n"
460
+ f"\n--- Tool execution result in ${variable_name}$ ---\n"
461
+ f"<{variable_name}>\n{response_display}\n</{variable_name}>\n\n"
462
+ f"--- Tools ---\n{self._get_tools_names_prompt()}\n"
463
+ f"--- Variables ---\n{self._get_variable_prompt()}\n"
464
+ "Analyze this response to determine the next steps. If the step failed, reconsider your approach.\n"
465
+ f"--- Task to solve summary ---\n{self.task_to_solve_summary}\n"
452
466
  "--- Format ---\n"
453
- "\n"
454
- "You MUST respond with exactly two XML blocks formatted in markdown:\n"
455
- "\n"
456
- " - One <thinking> block detailing your analysis,\n"
457
- " - One <tool_name> block specifying the chosen tool and its arguments, as outlined in the system prompt.\n"
467
+ "Respond only with two XML blocks in markdown as specified in system prompt.\n"
468
+ "No extra comments must be added.\n"
469
+ "```xml\n"
470
+ "<thinking>\n"
471
+ "...\n"
472
+ "</thinking>\n"
473
+ "```\n"
474
+ "```xml\n"
475
+ "< ...tool_name... >\n"
476
+ "...\n"
477
+ "</ ...tool_name... >\n"
478
+ "```"
458
479
  )
459
480
 
460
481
  return formatted_response