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.
- {quantalogic-0.2.15 → quantalogic-0.2.17}/PKG-INFO +21 -148
- {quantalogic-0.2.15 → quantalogic-0.2.17}/README.md +11 -147
- {quantalogic-0.2.15 → quantalogic-0.2.17}/pyproject.toml +24 -1
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/__init__.py +3 -2
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/agent.py +58 -37
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/agent_config.py +18 -13
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/coding_agent.py +9 -3
- quantalogic-0.2.15/quantalogic/print_event.py → quantalogic-0.2.17/quantalogic/console_print_events.py +1 -3
- quantalogic-0.2.17/quantalogic/console_print_token.py +16 -0
- quantalogic-0.2.17/quantalogic/docs_cli.py +50 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/generative_model.py +80 -77
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/main.py +122 -29
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/prompts.py +1 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/search_agent.py +15 -7
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/server/agent_server.py +2 -2
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/llm_tool.py +52 -11
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/llm_vision_tool.py +23 -7
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/xml_parser.py +109 -49
- {quantalogic-0.2.15 → quantalogic-0.2.17}/LICENSE +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/event_emitter.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/interactive_text_editor.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/memory.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/model_names.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/server/__init__.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/server/models.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/server/routes.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/server/state.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/server/static/js/event_visualizer.js +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/server/static/js/quantalogic.js +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/server/templates/index.html +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tool_manager.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/__init__.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/agent_tool.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/download_http_file_tool.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/duckduckgo_search_tool.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/edit_whole_content_tool.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/elixir_tool.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/execute_bash_command_tool.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/input_question_tool.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/language_handlers/__init__.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/language_handlers/c_handler.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/language_handlers/cpp_handler.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/language_handlers/go_handler.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/language_handlers/java_handler.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/language_handlers/javascript_handler.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/language_handlers/python_handler.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/language_handlers/rust_handler.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/language_handlers/scala_handler.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/language_handlers/typescript_handler.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/list_directory_tool.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/markitdown_tool.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/nodejs_tool.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/python_tool.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/read_file_block_tool.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/read_file_tool.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/replace_in_file_tool.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/ripgrep_tool.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/search_definition_names.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/serpapi_search_tool.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/task_complete_tool.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/tool.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/unified_diff_tool.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/wikipedia_search_tool.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/tools/write_file_tool.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/utils/__init__.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/utils/ask_user_validation.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/utils/check_version.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/utils/download_http_file.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/utils/get_coding_environment.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/utils/get_environment.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/utils/get_quantalogic_rules_content.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/utils/git_ls.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/utils/read_file.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/utils/read_http_text_content.py +0 -0
- {quantalogic-0.2.15 → quantalogic-0.2.17}/quantalogic/version.py +0 -0
- {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.
|
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
|
[](https://opensource.org/licenses/Apache-2.0)
|
45
54
|
[](https://www.python.org/downloads/)
|
46
|
-
[]()
|
55
|
+
[](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/
|
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
|
-
--
|
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
|
[](https://opensource.org/licenses/Apache-2.0)
|
4
4
|
[](https://www.python.org/downloads/)
|
5
|
-
[]()
|
5
|
+
[](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/
|
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
|
-
--
|
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.
|
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
|
-
|
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
|
-
|
179
|
-
|
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(
|
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
|
-
|
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"---
|
432
|
-
"\n"
|
433
|
-
f"
|
434
|
-
"\n"
|
435
|
-
|
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
|
-
"
|
454
|
-
"
|
455
|
-
"\n"
|
456
|
-
"
|
457
|
-
"
|
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
|