quantalogic 0.33.4__py3-none-any.whl → 0.40.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- quantalogic/__init__.py +0 -4
- quantalogic/agent.py +603 -362
- quantalogic/agent_config.py +260 -28
- quantalogic/agent_factory.py +43 -17
- quantalogic/coding_agent.py +20 -12
- quantalogic/config.py +7 -4
- quantalogic/console_print_events.py +4 -8
- quantalogic/console_print_token.py +2 -2
- quantalogic/docs_cli.py +15 -10
- quantalogic/event_emitter.py +258 -83
- quantalogic/flow/__init__.py +23 -0
- quantalogic/flow/flow.py +595 -0
- quantalogic/flow/flow_extractor.py +672 -0
- quantalogic/flow/flow_generator.py +89 -0
- quantalogic/flow/flow_manager.py +407 -0
- quantalogic/flow/flow_manager_schema.py +169 -0
- quantalogic/flow/flow_yaml.md +419 -0
- quantalogic/generative_model.py +109 -77
- quantalogic/get_model_info.py +6 -6
- quantalogic/interactive_text_editor.py +100 -73
- quantalogic/main.py +36 -23
- quantalogic/model_info_list.py +12 -0
- quantalogic/model_info_litellm.py +14 -14
- quantalogic/prompts.py +2 -1
- quantalogic/{llm.py → quantlitellm.py} +29 -39
- quantalogic/search_agent.py +4 -4
- quantalogic/server/models.py +4 -1
- quantalogic/task_file_reader.py +5 -5
- quantalogic/task_runner.py +21 -20
- quantalogic/tool_manager.py +10 -21
- quantalogic/tools/__init__.py +98 -68
- quantalogic/tools/composio/composio.py +416 -0
- quantalogic/tools/{generate_database_report_tool.py → database/generate_database_report_tool.py} +4 -9
- quantalogic/tools/database/sql_query_tool_advanced.py +261 -0
- quantalogic/tools/document_tools/markdown_to_docx_tool.py +620 -0
- quantalogic/tools/document_tools/markdown_to_epub_tool.py +438 -0
- quantalogic/tools/document_tools/markdown_to_html_tool.py +362 -0
- quantalogic/tools/document_tools/markdown_to_ipynb_tool.py +319 -0
- quantalogic/tools/document_tools/markdown_to_latex_tool.py +420 -0
- quantalogic/tools/document_tools/markdown_to_pdf_tool.py +623 -0
- quantalogic/tools/document_tools/markdown_to_pptx_tool.py +319 -0
- quantalogic/tools/duckduckgo_search_tool.py +2 -4
- quantalogic/tools/finance/alpha_vantage_tool.py +440 -0
- quantalogic/tools/finance/ccxt_tool.py +373 -0
- quantalogic/tools/finance/finance_llm_tool.py +387 -0
- quantalogic/tools/finance/google_finance.py +192 -0
- quantalogic/tools/finance/market_intelligence_tool.py +520 -0
- quantalogic/tools/finance/technical_analysis_tool.py +491 -0
- quantalogic/tools/finance/tradingview_tool.py +336 -0
- quantalogic/tools/finance/yahoo_finance.py +236 -0
- quantalogic/tools/git/bitbucket_clone_repo_tool.py +181 -0
- quantalogic/tools/git/bitbucket_operations_tool.py +326 -0
- quantalogic/tools/git/clone_repo_tool.py +189 -0
- quantalogic/tools/git/git_operations_tool.py +532 -0
- quantalogic/tools/google_packages/google_news_tool.py +480 -0
- quantalogic/tools/grep_app_tool.py +123 -186
- quantalogic/tools/{dalle_e.py → image_generation/dalle_e.py} +37 -27
- quantalogic/tools/jinja_tool.py +6 -10
- quantalogic/tools/language_handlers/__init__.py +22 -9
- quantalogic/tools/list_directory_tool.py +131 -42
- quantalogic/tools/llm_tool.py +45 -15
- quantalogic/tools/llm_vision_tool.py +59 -7
- quantalogic/tools/markitdown_tool.py +17 -5
- quantalogic/tools/nasa_packages/models.py +47 -0
- quantalogic/tools/nasa_packages/nasa_apod_tool.py +232 -0
- quantalogic/tools/nasa_packages/nasa_neows_tool.py +147 -0
- quantalogic/tools/nasa_packages/services.py +82 -0
- quantalogic/tools/presentation_tools/presentation_llm_tool.py +396 -0
- quantalogic/tools/product_hunt/product_hunt_tool.py +258 -0
- quantalogic/tools/product_hunt/services.py +63 -0
- quantalogic/tools/rag_tool/__init__.py +48 -0
- quantalogic/tools/rag_tool/document_metadata.py +15 -0
- quantalogic/tools/rag_tool/query_response.py +20 -0
- quantalogic/tools/rag_tool/rag_tool.py +566 -0
- quantalogic/tools/rag_tool/rag_tool_beta.py +264 -0
- quantalogic/tools/read_html_tool.py +24 -38
- quantalogic/tools/replace_in_file_tool.py +10 -10
- quantalogic/tools/safe_python_interpreter_tool.py +10 -24
- quantalogic/tools/search_definition_names.py +2 -2
- quantalogic/tools/sequence_tool.py +14 -23
- quantalogic/tools/sql_query_tool.py +17 -19
- quantalogic/tools/tool.py +39 -15
- quantalogic/tools/unified_diff_tool.py +1 -1
- quantalogic/tools/utilities/csv_processor_tool.py +234 -0
- quantalogic/tools/utilities/download_file_tool.py +179 -0
- quantalogic/tools/utilities/mermaid_validator_tool.py +661 -0
- quantalogic/tools/utils/__init__.py +1 -4
- quantalogic/tools/utils/create_sample_database.py +24 -38
- quantalogic/tools/utils/generate_database_report.py +74 -82
- quantalogic/tools/wikipedia_search_tool.py +17 -21
- quantalogic/utils/ask_user_validation.py +1 -1
- quantalogic/utils/async_utils.py +35 -0
- quantalogic/utils/check_version.py +3 -5
- quantalogic/utils/get_all_models.py +2 -1
- quantalogic/utils/git_ls.py +21 -7
- quantalogic/utils/lm_studio_model_info.py +9 -7
- quantalogic/utils/python_interpreter.py +113 -43
- quantalogic/utils/xml_utility.py +178 -0
- quantalogic/version_check.py +1 -1
- quantalogic/welcome_message.py +7 -7
- quantalogic/xml_parser.py +0 -1
- {quantalogic-0.33.4.dist-info → quantalogic-0.40.0.dist-info}/METADATA +44 -1
- quantalogic-0.40.0.dist-info/RECORD +148 -0
- quantalogic-0.33.4.dist-info/RECORD +0 -102
- {quantalogic-0.33.4.dist-info → quantalogic-0.40.0.dist-info}/LICENSE +0 -0
- {quantalogic-0.33.4.dist-info → quantalogic-0.40.0.dist-info}/WHEEL +0 -0
- {quantalogic-0.33.4.dist-info → quantalogic-0.40.0.dist-info}/entry_points.txt +0 -0
quantalogic/agent_config.py
CHANGED
@@ -3,24 +3,51 @@
|
|
3
3
|
# Standard library imports
|
4
4
|
|
5
5
|
# Local application imports
|
6
|
+
import logging
|
7
|
+
import os
|
8
|
+
from typing import Any
|
9
|
+
|
6
10
|
from dotenv import load_dotenv
|
7
11
|
|
8
12
|
from quantalogic.agent import Agent
|
9
13
|
from quantalogic.console_print_token import console_print_token
|
14
|
+
from quantalogic.event_emitter import EventEmitter
|
15
|
+
from quantalogic.memory import AgentMemory
|
10
16
|
from quantalogic.tools import (
|
11
17
|
AgentTool,
|
18
|
+
BitbucketCloneTool,
|
19
|
+
BitbucketOperationsTool,
|
20
|
+
CloneRepoTool,
|
21
|
+
ComposioTool,
|
22
|
+
CSVProcessorTool,
|
12
23
|
DownloadHttpFileTool,
|
13
24
|
DuckDuckGoSearchTool,
|
14
25
|
EditWholeContentTool,
|
15
26
|
ExecuteBashCommandTool,
|
27
|
+
GitOperationsTool,
|
28
|
+
GoogleNewsTool,
|
16
29
|
InputQuestionTool,
|
17
30
|
ListDirectoryTool,
|
18
31
|
LLMImageGenerationTool,
|
19
32
|
LLMTool,
|
20
33
|
LLMVisionTool,
|
34
|
+
MarkdownToDocxTool,
|
35
|
+
MarkdownToEpubTool,
|
36
|
+
MarkdownToHtmlTool,
|
37
|
+
MarkdownToIpynbTool,
|
38
|
+
MarkdownToLatexTool,
|
39
|
+
MarkdownToPdfTool,
|
40
|
+
MarkdownToPptxTool,
|
21
41
|
MarkitdownTool,
|
42
|
+
MermaidValidatorTool,
|
43
|
+
NasaApodTool,
|
44
|
+
NasaNeoWsTool,
|
22
45
|
NodeJsTool,
|
46
|
+
PrepareDownloadTool,
|
47
|
+
PresentationLLMTool,
|
48
|
+
ProductHuntTool,
|
23
49
|
PythonTool,
|
50
|
+
RagTool,
|
24
51
|
ReadFileBlockTool,
|
25
52
|
ReadFileTool,
|
26
53
|
ReadHTMLTool,
|
@@ -28,6 +55,9 @@ from quantalogic.tools import (
|
|
28
55
|
RipgrepTool,
|
29
56
|
SafePythonInterpreterTool,
|
30
57
|
SearchDefinitionNames,
|
58
|
+
SequenceTool,
|
59
|
+
SQLQueryTool,
|
60
|
+
SQLQueryToolAdvanced,
|
31
61
|
TaskCompleteTool,
|
32
62
|
WikipediaSearchTool,
|
33
63
|
WriteFileTool,
|
@@ -37,21 +67,24 @@ load_dotenv()
|
|
37
67
|
|
38
68
|
MODEL_NAME = "deepseek/deepseek-chat"
|
39
69
|
|
70
|
+
logger = logging.getLogger(__name__)
|
40
71
|
|
41
72
|
_current_model_name: str = ""
|
42
73
|
|
74
|
+
|
43
75
|
def get_current_model() -> str:
|
44
76
|
"""Retrieve the currently active model name."""
|
45
77
|
if not _current_model_name:
|
46
78
|
raise ValueError("No model initialized")
|
47
79
|
return _current_model_name
|
48
80
|
|
81
|
+
|
49
82
|
def create_agent(
|
50
|
-
model_name: str,
|
51
|
-
vision_model_name: str | None,
|
52
|
-
no_stream: bool = False,
|
83
|
+
model_name: str,
|
84
|
+
vision_model_name: str | None,
|
85
|
+
no_stream: bool = False,
|
53
86
|
compact_every_n_iteration: int | None = None,
|
54
|
-
max_tokens_working_memory: int | None = None
|
87
|
+
max_tokens_working_memory: int | None = None,
|
55
88
|
) -> Agent:
|
56
89
|
global _current_model_name
|
57
90
|
_current_model_name = model_name
|
@@ -81,18 +114,18 @@ def create_agent(
|
|
81
114
|
SearchDefinitionNames(),
|
82
115
|
MarkitdownTool(),
|
83
116
|
LLMTool(model_name=model_name, on_token=console_print_token if not no_stream else None),
|
84
|
-
DownloadHttpFileTool(),
|
117
|
+
DownloadHttpFileTool(),
|
85
118
|
LLMImageGenerationTool(
|
86
|
-
|
87
|
-
|
88
|
-
on_token=console_print_token if not no_stream else None
|
89
|
-
),
|
119
|
+
provider="dall-e", model_name="openai/dall-e-3", on_token=console_print_token if not no_stream else None
|
120
|
+
),
|
90
121
|
ReadHTMLTool(),
|
91
122
|
# SafePythonInterpreterTool(allowed_modules=["math", "numpy"])
|
92
123
|
]
|
93
124
|
|
94
125
|
if vision_model_name:
|
95
|
-
tools.append(
|
126
|
+
tools.append(
|
127
|
+
LLMVisionTool(model_name=vision_model_name, on_token=console_print_token if not no_stream else None)
|
128
|
+
)
|
96
129
|
|
97
130
|
return Agent(
|
98
131
|
model_name=model_name,
|
@@ -103,11 +136,11 @@ def create_agent(
|
|
103
136
|
|
104
137
|
|
105
138
|
def create_interpreter_agent(
|
106
|
-
model_name: str,
|
107
|
-
vision_model_name: str | None,
|
108
|
-
no_stream: bool = False,
|
139
|
+
model_name: str,
|
140
|
+
vision_model_name: str | None,
|
141
|
+
no_stream: bool = False,
|
109
142
|
compact_every_n_iteration: int | None = None,
|
110
|
-
max_tokens_working_memory: int | None = None
|
143
|
+
max_tokens_working_memory: int | None = None,
|
111
144
|
) -> Agent:
|
112
145
|
"""Create an interpreter agent with the specified model and tools.
|
113
146
|
|
@@ -141,7 +174,7 @@ def create_interpreter_agent(
|
|
141
174
|
ReadHTMLTool(),
|
142
175
|
]
|
143
176
|
return Agent(
|
144
|
-
model_name=model_name,
|
177
|
+
model_name=model_name,
|
145
178
|
tools=tools,
|
146
179
|
compact_every_n_iterations=compact_every_n_iteration,
|
147
180
|
max_tokens_working_memory=max_tokens_working_memory,
|
@@ -149,11 +182,11 @@ def create_interpreter_agent(
|
|
149
182
|
|
150
183
|
|
151
184
|
def create_full_agent(
|
152
|
-
model_name: str,
|
153
|
-
vision_model_name: str | None,
|
154
|
-
no_stream: bool = False,
|
185
|
+
model_name: str,
|
186
|
+
vision_model_name: str | None,
|
187
|
+
no_stream: bool = False,
|
155
188
|
compact_every_n_iteration: int | None = None,
|
156
|
-
max_tokens_working_memory: int | None = None
|
189
|
+
max_tokens_working_memory: int | None = None,
|
157
190
|
) -> Agent:
|
158
191
|
"""Create an agent with the specified model and many tools.
|
159
192
|
|
@@ -188,11 +221,13 @@ def create_full_agent(
|
|
188
221
|
WikipediaSearchTool(),
|
189
222
|
DuckDuckGoSearchTool(),
|
190
223
|
ReadHTMLTool(),
|
191
|
-
|
224
|
+
# SafePythonInterpreterTool(allowed_modules=["math", "numpy"])
|
192
225
|
]
|
193
226
|
|
194
227
|
if vision_model_name:
|
195
|
-
tools.append(
|
228
|
+
tools.append(
|
229
|
+
LLMVisionTool(model_name=vision_model_name, on_token=console_print_token if not no_stream else None)
|
230
|
+
)
|
196
231
|
|
197
232
|
return Agent(
|
198
233
|
model_name=model_name,
|
@@ -203,11 +238,11 @@ def create_full_agent(
|
|
203
238
|
|
204
239
|
|
205
240
|
def create_basic_agent(
|
206
|
-
model_name: str,
|
207
|
-
vision_model_name: str | None = None,
|
208
|
-
no_stream: bool = False,
|
241
|
+
model_name: str,
|
242
|
+
vision_model_name: str | None = None,
|
243
|
+
no_stream: bool = False,
|
209
244
|
compact_every_n_iteration: int | None = None,
|
210
|
-
max_tokens_working_memory: int | None = None
|
245
|
+
max_tokens_working_memory: int | None = None,
|
211
246
|
) -> Agent:
|
212
247
|
"""Create an agent with the specified model and tools.
|
213
248
|
|
@@ -224,7 +259,6 @@ def create_basic_agent(
|
|
224
259
|
# Rebuild AgentTool to resolve forward references
|
225
260
|
AgentTool.model_rebuild()
|
226
261
|
|
227
|
-
|
228
262
|
tools = [
|
229
263
|
TaskCompleteTool(),
|
230
264
|
ListDirectoryTool(),
|
@@ -239,11 +273,13 @@ def create_basic_agent(
|
|
239
273
|
ExecuteBashCommandTool(),
|
240
274
|
LLMTool(model_name=model_name, on_token=console_print_token if not no_stream else None),
|
241
275
|
ReadHTMLTool(),
|
242
|
-
|
276
|
+
# SafePythonInterpreterTool(allowed_modules=["math", "numpy"])
|
243
277
|
]
|
244
278
|
|
245
279
|
if vision_model_name:
|
246
|
-
tools.append(
|
280
|
+
tools.append(
|
281
|
+
LLMVisionTool(model_name=vision_model_name, on_token=console_print_token if not no_stream else None)
|
282
|
+
)
|
247
283
|
|
248
284
|
return Agent(
|
249
285
|
model_name=model_name,
|
@@ -251,3 +287,199 @@ def create_basic_agent(
|
|
251
287
|
compact_every_n_iterations=compact_every_n_iteration,
|
252
288
|
max_tokens_working_memory=max_tokens_working_memory,
|
253
289
|
)
|
290
|
+
|
291
|
+
|
292
|
+
def create_custom_agent(
|
293
|
+
model_name: str,
|
294
|
+
vision_model_name: str | None = None,
|
295
|
+
no_stream: bool = False,
|
296
|
+
compact_every_n_iteration: int | None = None,
|
297
|
+
max_tokens_working_memory: int | None = None,
|
298
|
+
specific_expertise: str = "",
|
299
|
+
tools: list[Any] | None = None,
|
300
|
+
memory: AgentMemory | None = None
|
301
|
+
) -> Agent:
|
302
|
+
"""Create an agent with the specified model and tools.
|
303
|
+
|
304
|
+
Args:
|
305
|
+
model_name (str): Name of the model to use
|
306
|
+
vision_model_name (str | None): Name of the vision model to use
|
307
|
+
no_stream (bool, optional): If True, the agent will not stream results.
|
308
|
+
compact_every_n_iteration (int | None, optional): Frequency of memory compaction.
|
309
|
+
max_tokens_working_memory (int | None, optional): Maximum tokens for working memory.
|
310
|
+
specific_expertise (str, optional): Specific expertise of the agent.
|
311
|
+
tools (list[Any], optional): List of tool configurations to add to the agent.
|
312
|
+
Each tool config should have:
|
313
|
+
- type: str - The type of tool
|
314
|
+
- parameters: dict - The parameters required for the tool
|
315
|
+
memory (AgentMemory, optional): Memory object to use for the agent.
|
316
|
+
|
317
|
+
Returns:
|
318
|
+
Agent: An agent with the specified model and tools
|
319
|
+
"""
|
320
|
+
storage_dir = os.path.join(os.path.dirname(__file__), "storage", "rag")
|
321
|
+
os.makedirs(storage_dir, exist_ok=True)
|
322
|
+
|
323
|
+
# Rebuild AgentTool to resolve forward references
|
324
|
+
AgentTool.model_rebuild()
|
325
|
+
|
326
|
+
# Create event emitter
|
327
|
+
event_emitter = EventEmitter()
|
328
|
+
|
329
|
+
# Define tool mapping with their parameter requirements
|
330
|
+
tool_mapping = {
|
331
|
+
"llm": lambda params: LLMTool(
|
332
|
+
model_name=params.get("model_name", model_name),
|
333
|
+
on_token=console_print_token if not no_stream else None,
|
334
|
+
event_emitter=event_emitter
|
335
|
+
),
|
336
|
+
"llm_vision": lambda params: LLMVisionTool(
|
337
|
+
model_name=params.get("vision_model_name") or vision_model_name,
|
338
|
+
on_token=console_print_token if not no_stream else None,
|
339
|
+
event_emitter=event_emitter
|
340
|
+
),
|
341
|
+
"llm_image_generation": lambda params: LLMImageGenerationTool(
|
342
|
+
# provider=params.get("provider", "dall-e"),
|
343
|
+
provider="dall-e",
|
344
|
+
# model_name=params.get("model_name", "openai/dall-e-3"),
|
345
|
+
model_name="openai/dall-e-3",
|
346
|
+
on_token=console_print_token if not no_stream else None,
|
347
|
+
# event_emitter=event_emitter
|
348
|
+
),
|
349
|
+
"download_http_file": lambda params: DownloadHttpFileTool(),
|
350
|
+
"duck_duck_go_search": lambda params: DuckDuckGoSearchTool(),
|
351
|
+
"edit_whole_content": lambda params: EditWholeContentTool(),
|
352
|
+
"execute_bash_command": lambda params: ExecuteBashCommandTool(),
|
353
|
+
"input_question": lambda params: InputQuestionTool(),
|
354
|
+
"list_directory": lambda params: ListDirectoryTool(),
|
355
|
+
"markitdown": lambda params: MarkitdownTool(),
|
356
|
+
"nodejs": lambda params: NodeJsTool(),
|
357
|
+
"python": lambda params: PythonTool(),
|
358
|
+
"read_file_block": lambda params: ReadFileBlockTool(),
|
359
|
+
"read_file": lambda params: ReadFileTool(),
|
360
|
+
"read_html": lambda params: ReadHTMLTool(),
|
361
|
+
"replace_in_file": lambda params: ReplaceInFileTool(),
|
362
|
+
"ripgrep": lambda params: RipgrepTool(),
|
363
|
+
"safe_python_interpreter": lambda params: SafePythonInterpreterTool(),
|
364
|
+
"search_definition_names": lambda params: SearchDefinitionNames(),
|
365
|
+
"wikipedia_search": lambda params: WikipediaSearchTool(),
|
366
|
+
"write_file": lambda params: WriteFileTool(),
|
367
|
+
"google_news": lambda params: GoogleNewsTool(
|
368
|
+
# model_name=params.get("model_name", model_name),
|
369
|
+
# on_token=console_print_token if not no_stream else None,
|
370
|
+
# event_emitter=event_emitter
|
371
|
+
),
|
372
|
+
"presentation_llm": lambda params: PresentationLLMTool(
|
373
|
+
model_name=params.get("model_name", model_name),
|
374
|
+
additional_info=params.get("additional_info", ""),
|
375
|
+
on_token=console_print_token if not no_stream else None,
|
376
|
+
event_emitter=event_emitter
|
377
|
+
),
|
378
|
+
"sequence": lambda params: SequenceTool(
|
379
|
+
model_name=params.get("model_name", model_name),
|
380
|
+
on_token=console_print_token if not no_stream else None,
|
381
|
+
# event_emitter=event_emitter
|
382
|
+
),
|
383
|
+
"sql_query": lambda params: SQLQueryTool(
|
384
|
+
connection_string=params.get("connection_string", ""),
|
385
|
+
model_name=params.get("model_name", model_name),
|
386
|
+
on_token=console_print_token if not no_stream else None,
|
387
|
+
# event_emitter=event_emitter
|
388
|
+
),
|
389
|
+
"sql_query_advanced": lambda params: SQLQueryToolAdvanced(
|
390
|
+
connection_string=params.get("connection_string", ""),
|
391
|
+
model_name=params.get("model_name", model_name),
|
392
|
+
on_token=console_print_token if not no_stream else None,
|
393
|
+
# event_emitter=event_emitter
|
394
|
+
),
|
395
|
+
"clone_repo_tool": lambda params: CloneRepoTool(auth_token=params.get("auth_token", "")),
|
396
|
+
"bitbucket_clone_repo_tool": lambda params: BitbucketCloneTool(access_token=params.get("access_token", "")),
|
397
|
+
"bitbucket_operations_tool": lambda params: BitbucketOperationsTool(access_token=params.get("access_token", "")),
|
398
|
+
"git_operations_tool": lambda params: GitOperationsTool(auth_token=params.get("auth_token", "")),
|
399
|
+
"markdown_to_pdf": lambda params: MarkdownToPdfTool(),
|
400
|
+
"markdown_to_pptx": lambda params: MarkdownToPptxTool(),
|
401
|
+
"markdown_to_html": lambda params: MarkdownToHtmlTool(),
|
402
|
+
"markdown_to_epub": lambda params: MarkdownToEpubTool(),
|
403
|
+
"markdown_to_ipynb": lambda params: MarkdownToIpynbTool(),
|
404
|
+
"markdown_to_latex": lambda params: MarkdownToLatexTool(),
|
405
|
+
"markdown_to_docx": lambda params: MarkdownToDocxTool(),
|
406
|
+
"csv_processor": lambda params: CSVProcessorTool(),
|
407
|
+
"mermaid_validator_tool": lambda params: MermaidValidatorTool(),
|
408
|
+
"download_file_tool": lambda params: PrepareDownloadTool(),
|
409
|
+
"email_tool": lambda params: ComposioTool(
|
410
|
+
action="GMAIL_SEND_EMAIL",
|
411
|
+
name="email_tool",
|
412
|
+
description="Send emails via Gmail",
|
413
|
+
need_validation=False
|
414
|
+
),
|
415
|
+
"callendar_tool": lambda params: ComposioTool(
|
416
|
+
action="GOOGLECALENDAR_CREATE_EVENT",
|
417
|
+
name="callendar_tool",
|
418
|
+
description="Create events in Google Calendar",
|
419
|
+
need_validation=False
|
420
|
+
),
|
421
|
+
"weather_tool": lambda params: ComposioTool(
|
422
|
+
action="WEATHERMAP_WEATHER",
|
423
|
+
name="weather_tool",
|
424
|
+
description="Get weather information for a location"
|
425
|
+
),
|
426
|
+
"nasa_neows_tool": lambda params: NasaNeoWsTool(),
|
427
|
+
"nasa_apod_tool": lambda params: NasaApodTool(),
|
428
|
+
"product_hunt_tool": lambda params : ProductHuntTool(),
|
429
|
+
"rag_tool": lambda params: RagTool(
|
430
|
+
vector_store=params.get("vector_store", "chroma"),
|
431
|
+
embedding_model=params.get("embedding_model", "openai"),
|
432
|
+
persist_dir=storage_dir,
|
433
|
+
document_paths=params.get("document_paths", [])
|
434
|
+
)
|
435
|
+
}
|
436
|
+
|
437
|
+
# Define write tools that should trigger automatic download tool addition
|
438
|
+
write_tools = {"write_file", "edit_whole_content", "replace_in_file"}
|
439
|
+
|
440
|
+
agent_tools = []
|
441
|
+
has_write_tool = any(
|
442
|
+
tool_config.get("type") in write_tools
|
443
|
+
for tool_config in (tools or [])
|
444
|
+
)
|
445
|
+
|
446
|
+
# Add tools only if they are provided
|
447
|
+
if tools:
|
448
|
+
for tool_config in tools:
|
449
|
+
tool_type = tool_config.get("type")
|
450
|
+
logger.debug(f"Processing tool type: {tool_type}")
|
451
|
+
|
452
|
+
if tool_type in tool_mapping:
|
453
|
+
try:
|
454
|
+
# Get tool parameters or empty dict if not provided
|
455
|
+
tool_params = tool_config.get("parameters", {})
|
456
|
+
|
457
|
+
# Create tool instance with parameters
|
458
|
+
tool = tool_mapping[tool_type](tool_params)
|
459
|
+
logger.debug(f"Created tool instance: {tool}")
|
460
|
+
|
461
|
+
if tool: # Some tools (like llm_vision) might return None
|
462
|
+
agent_tools.append(tool)
|
463
|
+
logger.info(f"Added tool: {tool_type}")
|
464
|
+
except Exception as e:
|
465
|
+
logger.error(f"Failed to create tool {tool_type}: {str(e)}")
|
466
|
+
|
467
|
+
# If any write tool was added, also add the download tool
|
468
|
+
if has_write_tool:
|
469
|
+
try:
|
470
|
+
agent_tools.append(PrepareDownloadTool())
|
471
|
+
logger.info("Added download tool automatically")
|
472
|
+
except Exception as e:
|
473
|
+
logger.error(f"Failed to add download tool: {str(e)}")
|
474
|
+
|
475
|
+
agent_tools.append(TaskCompleteTool())
|
476
|
+
|
477
|
+
return Agent(
|
478
|
+
model_name=model_name,
|
479
|
+
tools=agent_tools,
|
480
|
+
event_emitter=event_emitter,
|
481
|
+
compact_every_n_iterations=compact_every_n_iteration,
|
482
|
+
max_tokens_working_memory=max_tokens_working_memory,
|
483
|
+
specific_expertise=specific_expertise,
|
484
|
+
memory=memory,
|
485
|
+
)
|
quantalogic/agent_factory.py
CHANGED
@@ -1,20 +1,22 @@
|
|
1
|
-
from typing import Dict, Optional
|
1
|
+
from typing import Any, Dict, List, Optional
|
2
2
|
|
3
3
|
from loguru import logger
|
4
4
|
|
5
5
|
from quantalogic.agent import Agent
|
6
6
|
from quantalogic.agent_config import (
|
7
7
|
create_basic_agent,
|
8
|
+
create_custom_agent,
|
8
9
|
create_full_agent,
|
9
10
|
create_interpreter_agent,
|
10
11
|
)
|
11
12
|
from quantalogic.coding_agent import create_coding_agent
|
13
|
+
from quantalogic.memory import AgentMemory
|
12
14
|
from quantalogic.search_agent import create_search_agent # noqa: E402
|
13
15
|
|
14
16
|
|
15
17
|
class AgentRegistry:
|
16
18
|
"""Registry for managing agent instances by name."""
|
17
|
-
|
19
|
+
|
18
20
|
_instance = None
|
19
21
|
_agents: Dict[str, Agent] = {}
|
20
22
|
|
@@ -26,7 +28,7 @@ class AgentRegistry:
|
|
26
28
|
@classmethod
|
27
29
|
def register_agent(cls, name: str, agent: Agent) -> None:
|
28
30
|
"""Register an agent instance with a name.
|
29
|
-
|
31
|
+
|
30
32
|
Args:
|
31
33
|
name: Unique name for the agent
|
32
34
|
agent: Agent instance to register
|
@@ -38,13 +40,13 @@ class AgentRegistry:
|
|
38
40
|
@classmethod
|
39
41
|
def get_agent(cls, name: str) -> Agent:
|
40
42
|
"""Retrieve a registered agent by name.
|
41
|
-
|
43
|
+
|
42
44
|
Args:
|
43
45
|
name: Name of the agent to retrieve
|
44
|
-
|
46
|
+
|
45
47
|
Returns:
|
46
48
|
Registered Agent instance
|
47
|
-
|
49
|
+
|
48
50
|
Raises:
|
49
51
|
KeyError: If no agent with that name exists
|
50
52
|
"""
|
@@ -53,12 +55,13 @@ class AgentRegistry:
|
|
53
55
|
@classmethod
|
54
56
|
def list_agents(cls) -> Dict[str, str]:
|
55
57
|
"""List all registered agents.
|
56
|
-
|
58
|
+
|
57
59
|
Returns:
|
58
60
|
Dictionary mapping agent names to their types
|
59
61
|
"""
|
60
62
|
return {name: type(agent).__name__ for name, agent in cls._agents.items()}
|
61
63
|
|
64
|
+
|
62
65
|
"""Agent factory module for creating different types of agents."""
|
63
66
|
|
64
67
|
|
@@ -66,23 +69,33 @@ def create_agent_for_mode(
|
|
66
69
|
mode: str,
|
67
70
|
model_name: str,
|
68
71
|
vision_model_name: Optional[str],
|
72
|
+
thinking_model_name: Optional[str],
|
69
73
|
no_stream: bool = False,
|
70
74
|
compact_every_n_iteration: Optional[int] = None,
|
71
|
-
max_tokens_working_memory: Optional[int] = None
|
75
|
+
max_tokens_working_memory: Optional[int] = None,
|
76
|
+
tools: Optional[List[Any]] = None,
|
77
|
+
event_emitter: Any = None,
|
78
|
+
specific_expertise: str = "",
|
79
|
+
memory: AgentMemory | None = None
|
72
80
|
) -> Agent:
|
73
81
|
"""Create an agent based on the specified mode.
|
74
|
-
|
82
|
+
|
75
83
|
Args:
|
76
84
|
mode: The mode of operation for the agent
|
77
85
|
model_name: The name of the language model to use
|
78
86
|
vision_model_name: Optional name of the vision model
|
87
|
+
thinking_model_name: Optional name for a thinking model
|
79
88
|
no_stream: Whether to disable streaming mode
|
80
89
|
compact_every_n_iteration: Optional number of iterations before compacting memory
|
81
90
|
max_tokens_working_memory: Optional maximum tokens for working memory
|
91
|
+
tools: Optional list of tools to include in the agent
|
92
|
+
event_emitter: Optional event emitter to use in the agent
|
93
|
+
specific_expertise: Optional specific expertise for the agent
|
94
|
+
memory: Optional AgentMemory instance to use in the agent
|
82
95
|
|
83
96
|
Returns:
|
84
97
|
Agent: The created agent instance
|
85
|
-
|
98
|
+
|
86
99
|
Raises:
|
87
100
|
ValueError: If an unknown agent mode is specified
|
88
101
|
"""
|
@@ -97,10 +110,11 @@ def create_agent_for_mode(
|
|
97
110
|
agent = create_coding_agent(
|
98
111
|
model_name,
|
99
112
|
vision_model_name,
|
113
|
+
thinking_model_name,
|
100
114
|
basic=False,
|
101
115
|
no_stream=no_stream,
|
102
116
|
compact_every_n_iteration=compact_every_n_iteration,
|
103
|
-
max_tokens_working_memory=max_tokens_working_memory
|
117
|
+
max_tokens_working_memory=max_tokens_working_memory,
|
104
118
|
)
|
105
119
|
return agent
|
106
120
|
if mode == "code-basic":
|
@@ -110,7 +124,7 @@ def create_agent_for_mode(
|
|
110
124
|
basic=True,
|
111
125
|
no_stream=no_stream,
|
112
126
|
compact_every_n_iteration=compact_every_n_iteration,
|
113
|
-
max_tokens_working_memory=max_tokens_working_memory
|
127
|
+
max_tokens_working_memory=max_tokens_working_memory,
|
114
128
|
)
|
115
129
|
return agent
|
116
130
|
elif mode == "basic":
|
@@ -119,7 +133,7 @@ def create_agent_for_mode(
|
|
119
133
|
vision_model_name,
|
120
134
|
no_stream=no_stream,
|
121
135
|
compact_every_n_iteration=compact_every_n_iteration,
|
122
|
-
max_tokens_working_memory=max_tokens_working_memory
|
136
|
+
max_tokens_working_memory=max_tokens_working_memory,
|
123
137
|
)
|
124
138
|
return agent
|
125
139
|
elif mode == "full":
|
@@ -128,7 +142,7 @@ def create_agent_for_mode(
|
|
128
142
|
vision_model_name,
|
129
143
|
no_stream=no_stream,
|
130
144
|
compact_every_n_iteration=compact_every_n_iteration,
|
131
|
-
max_tokens_working_memory=max_tokens_working_memory
|
145
|
+
max_tokens_working_memory=max_tokens_working_memory,
|
132
146
|
)
|
133
147
|
return agent
|
134
148
|
elif mode == "interpreter":
|
@@ -137,7 +151,7 @@ def create_agent_for_mode(
|
|
137
151
|
vision_model_name,
|
138
152
|
no_stream=no_stream,
|
139
153
|
compact_every_n_iteration=compact_every_n_iteration,
|
140
|
-
max_tokens_working_memory=max_tokens_working_memory
|
154
|
+
max_tokens_working_memory=max_tokens_working_memory,
|
141
155
|
)
|
142
156
|
return agent
|
143
157
|
elif mode == "search":
|
@@ -145,7 +159,7 @@ def create_agent_for_mode(
|
|
145
159
|
model_name,
|
146
160
|
no_stream=no_stream,
|
147
161
|
compact_every_n_iteration=compact_every_n_iteration,
|
148
|
-
max_tokens_working_memory=max_tokens_working_memory
|
162
|
+
max_tokens_working_memory=max_tokens_working_memory,
|
149
163
|
)
|
150
164
|
return agent
|
151
165
|
if mode == "search-full":
|
@@ -154,7 +168,19 @@ def create_agent_for_mode(
|
|
154
168
|
mode_full=True,
|
155
169
|
no_stream=no_stream,
|
156
170
|
compact_every_n_iteration=compact_every_n_iteration,
|
157
|
-
max_tokens_working_memory=max_tokens_working_memory
|
171
|
+
max_tokens_working_memory=max_tokens_working_memory,
|
172
|
+
)
|
173
|
+
return agent
|
174
|
+
if mode == "custom":
|
175
|
+
agent = create_custom_agent(
|
176
|
+
model_name,
|
177
|
+
vision_model_name,
|
178
|
+
no_stream=no_stream,
|
179
|
+
compact_every_n_iteration=compact_every_n_iteration,
|
180
|
+
max_tokens_working_memory=max_tokens_working_memory,
|
181
|
+
specific_expertise=specific_expertise,
|
182
|
+
tools=tools,
|
183
|
+
memory=memory
|
158
184
|
)
|
159
185
|
return agent
|
160
186
|
else:
|
quantalogic/coding_agent.py
CHANGED
@@ -15,9 +15,7 @@ from quantalogic.tools import (
|
|
15
15
|
ReadHTMLTool,
|
16
16
|
ReplaceInFileTool,
|
17
17
|
RipgrepTool,
|
18
|
-
SafePythonInterpreterTool,
|
19
18
|
SearchDefinitionNames,
|
20
|
-
SequenceTool,
|
21
19
|
TaskCompleteTool,
|
22
20
|
WriteFileTool,
|
23
21
|
)
|
@@ -26,18 +24,20 @@ from quantalogic.utils.get_quantalogic_rules_content import get_quantalogic_rule
|
|
26
24
|
|
27
25
|
|
28
26
|
def create_coding_agent(
|
29
|
-
model_name: str,
|
30
|
-
vision_model_name: str | None = None,
|
31
|
-
|
32
|
-
|
27
|
+
model_name: str,
|
28
|
+
vision_model_name: str | None = None,
|
29
|
+
thinking_model_name: str | None = None,
|
30
|
+
basic: bool = False,
|
31
|
+
no_stream: bool = False,
|
33
32
|
compact_every_n_iteration: int | None = None,
|
34
|
-
max_tokens_working_memory: int | None = None
|
33
|
+
max_tokens_working_memory: int | None = None,
|
35
34
|
) -> Agent:
|
36
35
|
"""Creates and configures a coding agent with a comprehensive set of tools.
|
37
36
|
|
38
37
|
Args:
|
39
38
|
model_name (str): Name of the language model to use for the agent's core capabilities
|
40
39
|
vision_model_name (str | None): Name of the vision model to use for the agent's core capabilities
|
40
|
+
thinking_model_name (str | None): Name of the thinking model to use for the agent's core capabilities
|
41
41
|
basic (bool, optional): If True, the agent will be configured with a basic set of tools.
|
42
42
|
no_stream (bool, optional): If True, the agent will not stream results.
|
43
43
|
compact_every_n_iteration (int | None, optional): Frequency of memory compaction.
|
@@ -82,10 +82,20 @@ def create_coding_agent(
|
|
82
82
|
GrepAppTool(),
|
83
83
|
# SafePythonInterpreterTool(allowed_modules=["math", "numpy","decimal"])
|
84
84
|
]
|
85
|
-
|
86
|
-
|
85
|
+
|
87
86
|
if vision_model_name:
|
88
|
-
tools.append(
|
87
|
+
tools.append(
|
88
|
+
LLMVisionTool(model_name=vision_model_name, on_token=console_print_token if not no_stream else None)
|
89
|
+
)
|
90
|
+
|
91
|
+
if thinking_model_name:
|
92
|
+
tools.append(
|
93
|
+
LLMTool(
|
94
|
+
model_name=thinking_model_name,
|
95
|
+
name="smartest_code_expert",
|
96
|
+
on_token=console_print_token if not no_stream else None,
|
97
|
+
)
|
98
|
+
)
|
89
99
|
|
90
100
|
if not basic:
|
91
101
|
tools.append(
|
@@ -115,8 +125,6 @@ def create_coding_agent(
|
|
115
125
|
on_token=console_print_token if not no_stream else None,
|
116
126
|
)
|
117
127
|
)
|
118
|
-
|
119
|
-
|
120
128
|
|
121
129
|
return Agent(
|
122
130
|
model_name=model_name,
|
quantalogic/config.py
CHANGED
@@ -1,15 +1,18 @@
|
|
1
1
|
from dataclasses import dataclass
|
2
|
+
from typing import Optional
|
2
3
|
|
3
4
|
|
4
5
|
@dataclass
|
5
6
|
class QLConfig:
|
6
7
|
"""Central configuration for QuantaLogic agent parameters."""
|
8
|
+
|
7
9
|
model_name: str
|
8
10
|
verbose: bool
|
9
11
|
mode: str
|
10
12
|
log: str
|
11
|
-
vision_model_name: str
|
13
|
+
vision_model_name: Optional[str]
|
12
14
|
max_iterations: int
|
13
|
-
compact_every_n_iteration: int
|
14
|
-
max_tokens_working_memory: int
|
15
|
-
no_stream: bool
|
15
|
+
compact_every_n_iteration: Optional[int]
|
16
|
+
max_tokens_working_memory: Optional[int]
|
17
|
+
no_stream: bool
|
18
|
+
thinking_model_name: str
|