quantalogic 0.56.0__py3-none-any.whl → 0.58.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/agent.py +28 -4
- quantalogic/create_custom_agent.py +146 -71
- quantalogic/flow/flow.py +257 -103
- quantalogic/flow/flow_extractor.py +6 -15
- quantalogic/flow/flow_generator.py +28 -32
- quantalogic/flow/flow_manager.py +17 -3
- quantalogic/flow/flow_manager_schema.py +53 -5
- quantalogic/flow/flow_mermaid.py +2 -2
- quantalogic/flow/flow_yaml.linkedin.md +31 -0
- quantalogic/flow/flow_yaml.md +74 -56
- quantalogic/flow/templates/prompt_check_inventory.j2 +1 -0
- quantalogic/flow/templates/system_check_inventory.j2 +1 -0
- quantalogic/server/agent_server.py +19 -4
- quantalogic/tools/google_packages/google_news_tool.py +26 -187
- quantalogic/tools/utilities/__init__.py +2 -0
- quantalogic/tools/utilities/download_file_tool.py +4 -2
- quantalogic/tools/utilities/vscode_tool.py +123 -0
- quantalogic/utils/ask_user_validation.py +26 -6
- {quantalogic-0.56.0.dist-info → quantalogic-0.58.0.dist-info}/METADATA +1 -1
- {quantalogic-0.56.0.dist-info → quantalogic-0.58.0.dist-info}/RECORD +23 -19
- {quantalogic-0.56.0.dist-info → quantalogic-0.58.0.dist-info}/LICENSE +0 -0
- {quantalogic-0.56.0.dist-info → quantalogic-0.58.0.dist-info}/WHEEL +0 -0
- {quantalogic-0.56.0.dist-info → quantalogic-0.58.0.dist-info}/entry_points.txt +0 -0
quantalogic/agent.py
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
|
3
3
|
import asyncio
|
4
4
|
import os
|
5
|
-
|
5
|
+
import uuid
|
6
|
+
from collections.abc import Awaitable, Callable
|
6
7
|
from datetime import datetime
|
7
8
|
from pathlib import Path
|
8
9
|
from typing import Any
|
@@ -75,7 +76,7 @@ class Agent(BaseModel):
|
|
75
76
|
config: AgentConfig
|
76
77
|
task_to_solve: str
|
77
78
|
task_to_solve_summary: str = ""
|
78
|
-
ask_for_user_validation: Callable[[str], bool] = console_ask_for_user_validation
|
79
|
+
ask_for_user_validation: Callable[[str, str], Awaitable[bool]] = console_ask_for_user_validation
|
79
80
|
last_tool_call: dict[str, Any] = {} # Stores the last tool call information
|
80
81
|
total_tokens: int = 0 # Total tokens in the conversation
|
81
82
|
current_iteration: int = 0
|
@@ -93,7 +94,7 @@ class Agent(BaseModel):
|
|
93
94
|
memory: AgentMemory = AgentMemory(),
|
94
95
|
variable_store: VariableMemory = VariableMemory(),
|
95
96
|
tools: list[Tool] = [TaskCompleteTool()],
|
96
|
-
ask_for_user_validation: Callable[[str], bool] = console_ask_for_user_validation,
|
97
|
+
ask_for_user_validation: Callable[[str, str], Awaitable[bool]] = console_ask_for_user_validation,
|
97
98
|
task_to_solve: str = "",
|
98
99
|
specific_expertise: str = "General AI assistant with coding and problem-solving capabilities",
|
99
100
|
get_environment: Callable[[], str] = get_environment,
|
@@ -399,6 +400,18 @@ class Agent(BaseModel):
|
|
399
400
|
Tuple of (executed_tool_name, response)
|
400
401
|
"""
|
401
402
|
if tool.need_validation:
|
403
|
+
logger.info(f"Tool '{tool_name}' requires validation.")
|
404
|
+
validation_id = str(uuid.uuid4())
|
405
|
+
logger.info(f"Validation ID: {validation_id}")
|
406
|
+
|
407
|
+
self._emit_event(
|
408
|
+
"tool_execute_validation_start",
|
409
|
+
{
|
410
|
+
"validation_id": validation_id,
|
411
|
+
"tool_name": tool_name,
|
412
|
+
"arguments": arguments_with_values
|
413
|
+
},
|
414
|
+
)
|
402
415
|
question_validation = (
|
403
416
|
"Do you permit the execution of this tool?\n"
|
404
417
|
f"Tool: {tool_name}\nArguments:\n"
|
@@ -406,7 +419,18 @@ class Agent(BaseModel):
|
|
406
419
|
+ "\n".join([f" <{key}>{value}</{key}>" for key, value in arguments_with_values.items()])
|
407
420
|
+ "\n</arguments>\nYes or No"
|
408
421
|
)
|
409
|
-
permission_granted = self.ask_for_user_validation(question_validation)
|
422
|
+
permission_granted = await self.ask_for_user_validation(validation_id=validation_id, question=question_validation)
|
423
|
+
|
424
|
+
self._emit_event(
|
425
|
+
"tool_execute_validation_end",
|
426
|
+
{
|
427
|
+
"validation_id": validation_id,
|
428
|
+
"tool_name": tool_name,
|
429
|
+
"arguments": arguments_with_values,
|
430
|
+
"granted": permission_granted
|
431
|
+
},
|
432
|
+
)
|
433
|
+
|
410
434
|
if not permission_granted:
|
411
435
|
return "", f"Error: execution of tool '{tool_name}' was denied by the user."
|
412
436
|
|
@@ -55,14 +55,14 @@ def create_tool_instance(tool_class, **kwargs):
|
|
55
55
|
return None
|
56
56
|
|
57
57
|
try:
|
58
|
-
#
|
59
|
-
if 'name' not in kwargs:
|
58
|
+
# Only set name if the class doesn't already define it
|
59
|
+
if 'name' not in kwargs and not hasattr(tool_class, 'name'):
|
60
60
|
class_name = tool_class.__name__
|
61
61
|
kwargs['name'] = class_name.lower().replace('tool', '')
|
62
62
|
|
63
63
|
# Create and return the tool instance
|
64
64
|
instance = tool_class(**kwargs)
|
65
|
-
logger.debug(f"Successfully created tool instance: {
|
65
|
+
logger.debug(f"Successfully created tool instance: {tool_class.__name__}")
|
66
66
|
return instance
|
67
67
|
except Exception as e:
|
68
68
|
logger.error(f"Failed to instantiate {tool_class.__name__}: {str(e)}")
|
@@ -72,33 +72,33 @@ def create_tool_instance(tool_class, **kwargs):
|
|
72
72
|
TOOL_IMPORTS = {
|
73
73
|
# LLM Tools
|
74
74
|
"llm": lambda: _import_tool("quantalogic.tools.llm_tool", "LLMTool"),
|
75
|
-
"llm_vision": lambda: _import_tool("quantalogic.tools.
|
76
|
-
"llm_image_generation": lambda: _import_tool("quantalogic.tools.
|
75
|
+
"llm_vision": lambda: _import_tool("quantalogic.tools.llm_vision_tool", "LLMVisionTool"),
|
76
|
+
"llm_image_generation": lambda: _import_tool("quantalogic.tools.image_generation.dalle_e", "LLMImageGenerationTool"),
|
77
77
|
|
78
78
|
# File Tools
|
79
|
-
"download_http_file": lambda: _import_tool("quantalogic.tools.
|
79
|
+
"download_http_file": lambda: _import_tool("quantalogic.tools.utilities", "PrepareDownloadTool"),
|
80
80
|
"write_file": lambda: _import_tool("quantalogic.tools.write_file_tool", "WriteFileTool"),
|
81
|
-
"edit_whole_content": lambda: _import_tool("quantalogic.tools
|
82
|
-
"read_file_block": lambda: _import_tool("quantalogic.tools
|
83
|
-
"read_file": lambda: _import_tool("quantalogic.tools
|
84
|
-
"replace_in_file": lambda: _import_tool("quantalogic.tools
|
85
|
-
"list_directory": lambda: _import_tool("quantalogic.tools
|
81
|
+
"edit_whole_content": lambda: _import_tool("quantalogic.tools", "EditWholeContentTool"),
|
82
|
+
"read_file_block": lambda: _import_tool("quantalogic.tools", "ReadFileBlockTool"),
|
83
|
+
"read_file": lambda: _import_tool("quantalogic.tools", "ReadFileTool"),
|
84
|
+
"replace_in_file": lambda: _import_tool("quantalogic.tools", "ReplaceInFileTool"),
|
85
|
+
"list_directory": lambda: _import_tool("quantalogic.tools", "ListDirectoryTool"),
|
86
86
|
|
87
87
|
# Search Tools
|
88
88
|
"duck_duck_go_search": lambda: _import_tool("quantalogic.tools", "DuckDuckGoSearchTool"),
|
89
89
|
"wikipedia_search": lambda: _import_tool("quantalogic.tools", "WikipediaSearchTool"),
|
90
|
-
"google_news": lambda: _import_tool("quantalogic.tools", "GoogleNewsTool"),
|
90
|
+
"google_news": lambda: _import_tool("quantalogic.tools.google_packages", "GoogleNewsTool"),
|
91
91
|
"search_definition_names": lambda: _import_tool("quantalogic.tools", "SearchDefinitionNames"),
|
92
92
|
"ripgrep": lambda: _import_tool("quantalogic.tools", "RipgrepTool"),
|
93
93
|
|
94
94
|
# Execution Tools
|
95
|
-
"execute_bash_command": lambda: _import_tool("quantalogic.tools
|
96
|
-
"nodejs": lambda: _import_tool("quantalogic.tools
|
97
|
-
"python": lambda: _import_tool("quantalogic.tools
|
98
|
-
"safe_python_interpreter": lambda: _import_tool("quantalogic.tools
|
95
|
+
"execute_bash_command": lambda: _import_tool("quantalogic.tools", "ExecuteBashCommandTool"),
|
96
|
+
"nodejs": lambda: _import_tool("quantalogic.tools", "NodeJsTool"),
|
97
|
+
"python": lambda: _import_tool("quantalogic.tools", "PythonTool"),
|
98
|
+
"safe_python_interpreter": lambda: _import_tool("quantalogic.tools", "SafePythonInterpreterTool"),
|
99
99
|
|
100
100
|
# Database Tools
|
101
|
-
"sql_query": lambda: _import_tool("quantalogic.tools
|
101
|
+
"sql_query": lambda: _import_tool("quantalogic.tools", "SQLQueryTool"),
|
102
102
|
"sql_query_advanced": lambda: _import_tool("quantalogic.tools.database", "SQLQueryToolAdvanced"),
|
103
103
|
|
104
104
|
# Document Tools
|
@@ -140,7 +140,8 @@ TOOL_IMPORTS = {
|
|
140
140
|
"sequence": lambda: _import_tool("quantalogic.tools.utilities", "SequenceTool"),
|
141
141
|
"csv_processor": lambda: _import_tool("quantalogic.tools.utilities", "CSVProcessorTool"),
|
142
142
|
"mermaid_validator_tool": lambda: _import_tool("quantalogic.tools.utilities", "MermaidValidatorTool"),
|
143
|
-
"download_file_tool": lambda: _import_tool("quantalogic.tools.
|
143
|
+
"download_file_tool": lambda: _import_tool("quantalogic.tools.utilities", "PrepareDownloadTool"),
|
144
|
+
"vscode_server_tool": lambda: _import_tool("quantalogic.tools.utilities.vscode_tool", "VSCodeServerTool"),
|
144
145
|
}
|
145
146
|
|
146
147
|
def create_custom_agent(
|
@@ -175,61 +176,135 @@ def create_custom_agent(
|
|
175
176
|
# Create event emitter
|
176
177
|
event_emitter = EventEmitter()
|
177
178
|
|
178
|
-
|
179
|
+
def get_llm_params(params: dict) -> dict:
|
180
|
+
"""Get common parameters for LLM-based tools."""
|
181
|
+
return {
|
182
|
+
"model_name": params.get("model_name", model_name),
|
183
|
+
"on_token": console_print_token if not no_stream else None,
|
184
|
+
"event_emitter": event_emitter
|
185
|
+
}
|
186
|
+
|
187
|
+
# Define tool configurations with default parameters
|
179
188
|
tool_configs = {
|
180
|
-
|
181
|
-
"
|
182
|
-
"
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
"
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
"
|
195
|
-
"
|
196
|
-
"
|
197
|
-
"
|
198
|
-
"
|
199
|
-
"
|
200
|
-
"
|
201
|
-
"
|
202
|
-
"
|
203
|
-
"
|
204
|
-
"
|
205
|
-
"
|
206
|
-
"
|
207
|
-
"
|
208
|
-
"
|
209
|
-
"
|
210
|
-
"
|
211
|
-
"
|
212
|
-
"
|
213
|
-
|
214
|
-
|
215
|
-
"
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
"
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
"
|
225
|
-
|
226
|
-
|
227
|
-
|
189
|
+
# LLM Tools with shared parameters
|
190
|
+
"llm": lambda params: create_tool_instance(TOOL_IMPORTS["llm"](), **get_llm_params(params)),
|
191
|
+
"llm_vision": lambda params: create_tool_instance(TOOL_IMPORTS["llm_vision"](),
|
192
|
+
model_name=params.get("vision_model_name") or vision_model_name,
|
193
|
+
on_token=console_print_token if not no_stream else None,
|
194
|
+
event_emitter=event_emitter
|
195
|
+
) if vision_model_name else None,
|
196
|
+
"llm_image_generation": lambda params: create_tool_instance(TOOL_IMPORTS["llm_image_generation"](),
|
197
|
+
provider="dall-e",
|
198
|
+
model_name="openai/dall-e-3",
|
199
|
+
on_token=console_print_token if not no_stream else None
|
200
|
+
),
|
201
|
+
|
202
|
+
# Simple tools without parameters
|
203
|
+
"download_http_file": lambda _: create_tool_instance(TOOL_IMPORTS["download_http_file"]()),
|
204
|
+
"duck_duck_go_search": lambda _: create_tool_instance(TOOL_IMPORTS["duck_duck_go_search"]()),
|
205
|
+
"write_file": lambda _: create_tool_instance(TOOL_IMPORTS["write_file"]()),
|
206
|
+
"task_complete": lambda _: create_tool_instance(TOOL_IMPORTS["task_complete"]()),
|
207
|
+
"edit_whole_content": lambda _: create_tool_instance(TOOL_IMPORTS["edit_whole_content"]()),
|
208
|
+
"execute_bash_command": lambda _: create_tool_instance(TOOL_IMPORTS["execute_bash_command"]()),
|
209
|
+
"input_question": lambda _: create_tool_instance(TOOL_IMPORTS["input_question"]()),
|
210
|
+
"list_directory": lambda _: create_tool_instance(TOOL_IMPORTS["list_directory"]()),
|
211
|
+
"markitdown": lambda _: create_tool_instance(TOOL_IMPORTS["markitdown"]()),
|
212
|
+
"nodejs": lambda _: create_tool_instance(TOOL_IMPORTS["nodejs"]()),
|
213
|
+
"python": lambda _: create_tool_instance(TOOL_IMPORTS["python"]()),
|
214
|
+
"read_file_block": lambda _: create_tool_instance(TOOL_IMPORTS["read_file_block"]()),
|
215
|
+
"read_file": lambda _: create_tool_instance(TOOL_IMPORTS["read_file"]()),
|
216
|
+
"read_html": lambda _: create_tool_instance(TOOL_IMPORTS["read_html"]()),
|
217
|
+
"replace_in_file": lambda _: create_tool_instance(TOOL_IMPORTS["replace_in_file"]()),
|
218
|
+
"ripgrep": lambda _: create_tool_instance(TOOL_IMPORTS["ripgrep"]()),
|
219
|
+
"search_definition_names": lambda _: create_tool_instance(TOOL_IMPORTS["search_definition_names"]()),
|
220
|
+
"wikipedia_search": lambda _: create_tool_instance(TOOL_IMPORTS["wikipedia_search"]()),
|
221
|
+
"google_news": lambda _: create_tool_instance(TOOL_IMPORTS["google_news"]()),
|
222
|
+
|
223
|
+
# Tools with specific configurations
|
224
|
+
"safe_python_interpreter": lambda _: create_tool_instance(TOOL_IMPORTS["safe_python_interpreter"](),
|
225
|
+
allowed_modules=["math", "numpy", "pandas", "datetime", "random", "statistics", "decimal"]
|
226
|
+
),
|
227
|
+
|
228
|
+
# LLM-based tools with additional parameters
|
229
|
+
"presentation_llm": lambda params: create_tool_instance(TOOL_IMPORTS["presentation_llm"](),
|
230
|
+
**get_llm_params(params),
|
231
|
+
additional_info=params.get("additional_info", "")
|
232
|
+
),
|
233
|
+
"sequence": lambda params: create_tool_instance(TOOL_IMPORTS["sequence"](),
|
234
|
+
**get_llm_params(params)
|
235
|
+
),
|
236
|
+
|
237
|
+
# Database tools
|
238
|
+
"sql_query": lambda params: create_tool_instance(TOOL_IMPORTS["sql_query"](),
|
239
|
+
**get_llm_params(params),
|
240
|
+
connection_string=params.get("connection_string", "")
|
241
|
+
),
|
242
|
+
"sql_query_advanced": lambda params: create_tool_instance(TOOL_IMPORTS["sql_query_advanced"](),
|
243
|
+
**get_llm_params(params),
|
244
|
+
connection_string=params.get("connection_string", "")
|
245
|
+
),
|
246
|
+
|
247
|
+
# Git tools
|
248
|
+
"clone_repo_tool": lambda params: create_tool_instance(TOOL_IMPORTS["clone_repo_tool"](),
|
249
|
+
auth_token=params.get("auth_token", "")
|
250
|
+
),
|
251
|
+
"bitbucket_clone_repo_tool": lambda params: create_tool_instance(TOOL_IMPORTS["bitbucket_clone_repo_tool"](),
|
252
|
+
access_token=params.get("access_token", "")
|
253
|
+
),
|
254
|
+
"bitbucket_operations_tool": lambda params: create_tool_instance(TOOL_IMPORTS["bitbucket_operations_tool"](),
|
255
|
+
access_token=params.get("access_token", "")
|
256
|
+
),
|
257
|
+
"git_operations_tool": lambda params: create_tool_instance(TOOL_IMPORTS["git_operations_tool"](),
|
258
|
+
auth_token=params.get("auth_token", "")
|
259
|
+
),
|
260
|
+
|
261
|
+
# Document conversion tools
|
262
|
+
"markdown_to_pdf": lambda _: create_tool_instance(TOOL_IMPORTS["markdown_to_pdf"]()),
|
263
|
+
"markdown_to_pptx": lambda _: create_tool_instance(TOOL_IMPORTS["markdown_to_pptx"]()),
|
264
|
+
"markdown_to_html": lambda _: create_tool_instance(TOOL_IMPORTS["markdown_to_html"]()),
|
265
|
+
"markdown_to_epub": lambda _: create_tool_instance(TOOL_IMPORTS["markdown_to_epub"]()),
|
266
|
+
"markdown_to_ipynb": lambda _: create_tool_instance(TOOL_IMPORTS["markdown_to_ipynb"]()),
|
267
|
+
"markdown_to_latex": lambda _: create_tool_instance(TOOL_IMPORTS["markdown_to_latex"]()),
|
268
|
+
"markdown_to_docx": lambda _: create_tool_instance(TOOL_IMPORTS["markdown_to_docx"]()),
|
269
|
+
|
270
|
+
# Utility tools
|
271
|
+
"csv_processor": lambda _: create_tool_instance(TOOL_IMPORTS["csv_processor"]()),
|
272
|
+
"mermaid_validator_tool": lambda _: create_tool_instance(TOOL_IMPORTS["mermaid_validator_tool"]()),
|
273
|
+
"download_file_tool": lambda _: create_tool_instance(TOOL_IMPORTS["download_file_tool"]()),
|
274
|
+
|
275
|
+
# Composio tools
|
276
|
+
"email_tool": lambda _: create_tool_instance(TOOL_IMPORTS["email_tool"](),
|
277
|
+
action="GMAIL_SEND_EMAIL",
|
278
|
+
name="email_tool",
|
279
|
+
description="Send emails via Gmail",
|
280
|
+
need_validation=False
|
281
|
+
),
|
282
|
+
"callendar_tool": lambda _: create_tool_instance(TOOL_IMPORTS["callendar_tool"](),
|
283
|
+
action="GOOGLECALENDAR_CREATE_EVENT",
|
284
|
+
name="callendar_tool",
|
285
|
+
description="Create events in Google Calendar",
|
286
|
+
need_validation=False
|
287
|
+
),
|
288
|
+
"weather_tool": lambda _: create_tool_instance(TOOL_IMPORTS["weather_tool"](),
|
289
|
+
action="WEATHERMAP_WEATHER",
|
290
|
+
name="weather_tool",
|
291
|
+
description="Get weather information for a location"
|
292
|
+
),
|
293
|
+
|
294
|
+
# NASA tools
|
295
|
+
"nasa_neows_tool": lambda _: create_tool_instance(TOOL_IMPORTS["nasa_neows_tool"]()),
|
296
|
+
"nasa_apod_tool": lambda _: create_tool_instance(TOOL_IMPORTS["nasa_apod_tool"]()),
|
297
|
+
"product_hunt_tool": lambda _: create_tool_instance(TOOL_IMPORTS["product_hunt_tool"]()),
|
298
|
+
|
299
|
+
# RAG tool
|
300
|
+
"rag_tool": lambda params: create_tool_instance(TOOL_IMPORTS["rag_tool"](),
|
301
|
+
vector_store=params.get("vector_store", "chroma"),
|
302
|
+
embedding_model=params.get("embedding_model", "openai"),
|
303
|
+
persist_dir=storage_dir,
|
304
|
+
document_paths=params.get("document_paths", [])
|
305
|
+
),
|
228
306
|
|
229
|
-
|
230
|
-
"email_tool": lambda params: create_tool_instance(TOOL_IMPORTS["email_tool"](), action="EMAIL", name="email_tool", **params),
|
231
|
-
"callendar_tool": lambda params: create_tool_instance(TOOL_IMPORTS["callendar_tool"](), action="CALLENDAR", name="callendar_tool", **params),
|
232
|
-
"weather_tool": lambda params: create_tool_instance(TOOL_IMPORTS["weather_tool"](), action="WEATHER", name="weather_tool", **params),
|
307
|
+
"vscode_server_tool": lambda _: create_tool_instance(TOOL_IMPORTS["vscode_server_tool"]())
|
233
308
|
}
|
234
309
|
|
235
310
|
# Log available tool types before processing
|