quantalogic 0.80__py3-none-any.whl → 0.93__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.
Files changed (55) hide show
  1. quantalogic/flow/__init__.py +16 -34
  2. quantalogic/main.py +11 -6
  3. quantalogic/tools/tool.py +8 -922
  4. quantalogic-0.93.dist-info/METADATA +475 -0
  5. {quantalogic-0.80.dist-info → quantalogic-0.93.dist-info}/RECORD +8 -54
  6. quantalogic/codeact/TODO.md +0 -14
  7. quantalogic/codeact/__init__.py +0 -0
  8. quantalogic/codeact/agent.py +0 -478
  9. quantalogic/codeact/cli.py +0 -50
  10. quantalogic/codeact/cli_commands/__init__.py +0 -0
  11. quantalogic/codeact/cli_commands/create_toolbox.py +0 -45
  12. quantalogic/codeact/cli_commands/install_toolbox.py +0 -20
  13. quantalogic/codeact/cli_commands/list_executor.py +0 -15
  14. quantalogic/codeact/cli_commands/list_reasoners.py +0 -15
  15. quantalogic/codeact/cli_commands/list_toolboxes.py +0 -47
  16. quantalogic/codeact/cli_commands/task.py +0 -215
  17. quantalogic/codeact/cli_commands/tool_info.py +0 -24
  18. quantalogic/codeact/cli_commands/uninstall_toolbox.py +0 -43
  19. quantalogic/codeact/config.yaml +0 -21
  20. quantalogic/codeact/constants.py +0 -9
  21. quantalogic/codeact/events.py +0 -85
  22. quantalogic/codeact/examples/README.md +0 -342
  23. quantalogic/codeact/examples/agent_sample.yaml +0 -29
  24. quantalogic/codeact/executor.py +0 -186
  25. quantalogic/codeact/history_manager.py +0 -94
  26. quantalogic/codeact/llm_util.py +0 -57
  27. quantalogic/codeact/plugin_manager.py +0 -92
  28. quantalogic/codeact/prompts/error_format.j2 +0 -11
  29. quantalogic/codeact/prompts/generate_action.j2 +0 -77
  30. quantalogic/codeact/prompts/generate_program.j2 +0 -52
  31. quantalogic/codeact/prompts/response_format.j2 +0 -11
  32. quantalogic/codeact/react_agent.py +0 -318
  33. quantalogic/codeact/reasoner.py +0 -185
  34. quantalogic/codeact/templates/toolbox/README.md.j2 +0 -10
  35. quantalogic/codeact/templates/toolbox/pyproject.toml.j2 +0 -16
  36. quantalogic/codeact/templates/toolbox/tools.py.j2 +0 -6
  37. quantalogic/codeact/templates.py +0 -7
  38. quantalogic/codeact/tools_manager.py +0 -258
  39. quantalogic/codeact/utils.py +0 -62
  40. quantalogic/codeact/xml_utils.py +0 -126
  41. quantalogic/flow/flow.py +0 -1070
  42. quantalogic/flow/flow_extractor.py +0 -783
  43. quantalogic/flow/flow_generator.py +0 -322
  44. quantalogic/flow/flow_manager.py +0 -676
  45. quantalogic/flow/flow_manager_schema.py +0 -287
  46. quantalogic/flow/flow_mermaid.py +0 -365
  47. quantalogic/flow/flow_validator.py +0 -479
  48. quantalogic/flow/flow_yaml.linkedin.md +0 -31
  49. quantalogic/flow/flow_yaml.md +0 -767
  50. quantalogic/flow/templates/prompt_check_inventory.j2 +0 -1
  51. quantalogic/flow/templates/system_check_inventory.j2 +0 -1
  52. quantalogic-0.80.dist-info/METADATA +0 -900
  53. {quantalogic-0.80.dist-info → quantalogic-0.93.dist-info}/LICENSE +0 -0
  54. {quantalogic-0.80.dist-info → quantalogic-0.93.dist-info}/WHEEL +0 -0
  55. {quantalogic-0.80.dist-info → quantalogic-0.93.dist-info}/entry_points.txt +0 -0
@@ -1,47 +0,0 @@
1
- import typer
2
- from loguru import logger
3
- from rich.console import Console
4
-
5
- from quantalogic.codeact.cli import plugin_manager # Import shared plugin_manager from cli.py
6
-
7
- app = typer.Typer()
8
-
9
- console = Console()
10
-
11
- @app.command()
12
- def list_toolboxes(
13
- detail: bool = typer.Option(False, "--detail", "-d", help="Show detailed documentation for each tool")
14
- ) -> None:
15
- """List all loaded toolboxes and their associated tools from entry points.
16
-
17
- When --detail flag is used, displays the full documentation for each tool using its to_docstring() method.
18
- """
19
- logger.debug("Listing toolboxes from entry points")
20
- tools = plugin_manager.tools.get_tools()
21
-
22
- if not tools:
23
- console.print("[yellow]No toolboxes found.[/yellow]")
24
- else:
25
- console.print("[bold cyan]Available Toolboxes and Tools:[/bold cyan]")
26
- toolbox_dict = {}
27
- for tool in tools:
28
- toolbox_name = tool.toolbox_name if tool.toolbox_name else 'Unknown Toolbox'
29
- if toolbox_name not in toolbox_dict:
30
- toolbox_dict[toolbox_name] = []
31
- toolbox_dict[toolbox_name].append(tool)
32
-
33
- for toolbox_name, tools_list in toolbox_dict.items():
34
- console.print(f"[bold green]Toolbox: {toolbox_name}[/bold green]")
35
- for tool in sorted(tools_list, key=lambda x: x.name):
36
- if detail:
37
- # Use to_docstring() method for detailed documentation
38
- docstring = tool.to_docstring()
39
- console.print(f" - [bold]{tool.name}[/bold]")
40
- console.print(f" Documentation:\n {docstring.replace('\n', '\n ')}")
41
- console.print("")
42
- else:
43
- console.print(f" - {tool.name}")
44
- console.print("")
45
-
46
- if __name__ == "__main__":
47
- app()
@@ -1,215 +0,0 @@
1
- import asyncio
2
- import json
3
- import sys
4
-
5
- import typer
6
- from loguru import logger
7
- from rich.console import Console
8
-
9
- from quantalogic.codeact.agent import Agent, AgentConfig
10
- from quantalogic.codeact.constants import DEFAULT_MODEL, LOG_FILE
11
- from quantalogic.codeact.events import (
12
- ActionExecutedEvent,
13
- ActionGeneratedEvent,
14
- ErrorOccurredEvent,
15
- StepCompletedEvent,
16
- StepStartedEvent,
17
- StreamTokenEvent,
18
- TaskCompletedEvent,
19
- TaskStartedEvent,
20
- ThoughtGeneratedEvent,
21
- ToolExecutionCompletedEvent,
22
- ToolExecutionErrorEvent,
23
- ToolExecutionStartedEvent,
24
- )
25
- from quantalogic.codeact.tools_manager import get_default_tools
26
- from quantalogic.codeact.utils import process_tools
27
- from quantalogic.codeact.xml_utils import XMLResultHandler
28
-
29
- console = Console()
30
-
31
- class ProgressMonitor:
32
- """Handles progress monitoring for agent events."""
33
- def __init__(self):
34
- self._token_buffer = ""
35
-
36
- async def on_task_started(self, event: TaskStartedEvent):
37
- console.print(f"[bold green]Task Started: {event.task_description}[/bold green]")
38
- console.print(f"Timestamp: {event.timestamp.strftime('%Y-%m-%d %H:%M:%S')}")
39
- console.print("-" * 50)
40
-
41
- async def on_thought_generated(self, event: ThoughtGeneratedEvent):
42
- console.print(f"[bold cyan]Step {event.step_number} - Thought Generated:[/bold cyan]")
43
- console.print(f"Thought: {event.thought}")
44
- console.print(f"Generation Time: {event.generation_time:.2f} seconds")
45
- console.print("-" * 50)
46
-
47
- async def on_action_generated(self, event: ActionGeneratedEvent):
48
- console.print(f"[bold blue]Step {event.step_number} - Action Generated:[/bold blue]")
49
- console.print(f"Action Code:\n{event.action_code}")
50
- console.print(f"Generation Time: {event.generation_time:.2f} seconds")
51
- console.print("-" * 50)
52
-
53
- async def on_action_executed(self, event: ActionExecutedEvent):
54
- summary = XMLResultHandler.format_result_summary(event.result_xml)
55
- console.print(f"[bold magenta]Step {event.step_number} - Action Executed:[/bold magenta]")
56
- console.print(f"Result Summary:\n{summary}")
57
- console.print(f"Execution Time: {event.execution_time:.2f} seconds")
58
- console.print("-" * 50)
59
-
60
- async def on_step_completed(self, event: StepCompletedEvent):
61
- console.print(f"[bold yellow]Step {event.step_number} - Completed[/bold yellow]")
62
- console.print("-" * 50)
63
-
64
- async def on_error_occurred(self, event: ErrorOccurredEvent):
65
- console.print(f"[bold red]Error Occurred{' at Step ' + str(event.step_number) if event.step_number else ''}:[/bold red]")
66
- console.print(f"Message: {event.error_message}")
67
- console.print(f"Timestamp: {event.timestamp.strftime('%Y-%m-%d %H:%M:%S')}")
68
- console.print("-" * 50)
69
-
70
- async def on_task_completed(self, event: TaskCompletedEvent):
71
- if event.final_answer:
72
- console.print("[bold green]Task Completed Successfully:[/bold green]")
73
- console.print(f"Final Answer:\n{event.final_answer}")
74
- else:
75
- console.print("[bold red]Task Did Not Complete Successfully:[/bold red]")
76
- console.print(f"Reason: {event.reason}")
77
- console.print(f"Timestamp: {event.timestamp.strftime('%Y-%m-%d %H:%M:%S')}")
78
- console.print("-" * 50)
79
-
80
- async def on_step_started(self, event: StepStartedEvent):
81
- console.print(f"[bold yellow]Starting Step {event.step_number}[/bold yellow]")
82
- console.print("-" * 50)
83
-
84
- async def on_tool_execution_started(self, event: ToolExecutionStartedEvent):
85
- console.print(f"[cyan]Tool {event.tool_name} started execution at step {event.step_number}[/cyan]")
86
- console.print(f"Parameters: {event.parameters_summary}")
87
-
88
- async def on_tool_execution_completed(self, event: ToolExecutionCompletedEvent):
89
- console.print(f"[green]Tool {event.tool_name} completed execution at step {event.step_number}[/green]")
90
- console.print(f"Result: {event.result_summary}")
91
-
92
- async def on_tool_execution_error(self, event: ToolExecutionErrorEvent):
93
- console.print(f"[red]Tool {event.tool_name} encountered an error at step {event.step_number}[/red]")
94
- console.print(f"Error: {event.error}")
95
-
96
- async def on_stream_token(self, event: StreamTokenEvent):
97
- console.print(event.token, end="")
98
-
99
- async def flush_buffer(self):
100
- pass
101
-
102
- async def __call__(self, event):
103
- if isinstance(event, TaskStartedEvent):
104
- await self.on_task_started(event)
105
- elif isinstance(event, ThoughtGeneratedEvent):
106
- await self.on_thought_generated(event)
107
- elif isinstance(event, ActionGeneratedEvent):
108
- await self.on_action_generated(event)
109
- await self.flush_buffer()
110
- elif isinstance(event, ActionExecutedEvent):
111
- await self.on_action_executed(event)
112
- elif isinstance(event, StepCompletedEvent):
113
- await self.on_step_completed(event)
114
- elif isinstance(event, ErrorOccurredEvent):
115
- await self.on_error_occurred(event)
116
- elif isinstance(event, TaskCompletedEvent):
117
- await self.on_task_completed(event)
118
- await self.flush_buffer()
119
- elif isinstance(event, StepStartedEvent):
120
- await self.on_step_started(event)
121
- elif isinstance(event, ToolExecutionStartedEvent):
122
- await self.on_tool_execution_started(event)
123
- elif isinstance(event, ToolExecutionCompletedEvent):
124
- await self.on_tool_execution_completed(event)
125
- elif isinstance(event, ToolExecutionErrorEvent):
126
- await self.on_tool_execution_error(event)
127
- elif isinstance(event, StreamTokenEvent):
128
- await self.on_stream_token(event)
129
-
130
- async def run_react_agent(
131
- task: str,
132
- model: str,
133
- max_iterations: int,
134
- success_criteria: str = None,
135
- tools=None,
136
- personality=None,
137
- backstory=None,
138
- sop=None,
139
- debug: bool = False,
140
- streaming: bool = False,
141
- reasoner_name=None,
142
- executor_name=None,
143
- tools_config=None,
144
- profile=None,
145
- customizations=None
146
- ) -> None:
147
- """Run the Agent with detailed event monitoring."""
148
- logger.remove()
149
- logger.add(sys.stderr, level="DEBUG" if debug else "INFO")
150
- logger.add(LOG_FILE, level="DEBUG" if debug else "INFO")
151
-
152
- tools = tools if tools is not None else get_default_tools(model, tools_config=tools_config)
153
- processed_tools = process_tools(tools)
154
-
155
- # Create AgentConfig with all parameters
156
- config = AgentConfig(
157
- model=model,
158
- max_iterations=max_iterations,
159
- tools=processed_tools,
160
- personality=personality,
161
- backstory=backstory,
162
- sop=sop,
163
- reasoner_name=reasoner_name if reasoner_name else "default",
164
- executor_name=executor_name if executor_name else "default",
165
- tools_config=tools_config,
166
- profile=profile,
167
- customizations=customizations
168
- )
169
-
170
- agent = Agent(config=config)
171
-
172
- progress_monitor = ProgressMonitor()
173
- solve_agent = agent
174
- solve_agent.add_observer(progress_monitor, [
175
- "TaskStarted", "ThoughtGenerated", "ActionGenerated", "ActionExecuted",
176
- "StepCompleted", "ErrorOccurred", "TaskCompleted", "StepStarted",
177
- "ToolExecutionStarted", "ToolExecutionCompleted", "ToolExecutionError",
178
- "StreamToken"
179
- ])
180
-
181
- console.print(f"[bold green]Starting task: {task}[/bold green]")
182
- _history = await agent.solve(task, success_criteria, streaming=streaming,
183
- reasoner_name=reasoner_name, executor_name=executor_name)
184
-
185
- def task(
186
- task: str = typer.Argument(..., help="The task to solve"),
187
- model: str = typer.Option(DEFAULT_MODEL, help="The litellm model to use"),
188
- max_iterations: int = typer.Option(5, help="Maximum reasoning steps"),
189
- success_criteria: str = typer.Option(None, help="Optional criteria to determine task completion"),
190
- personality: str = typer.Option(None, help="Agent personality (e.g., 'witty')"),
191
- backstory: str = typer.Option(None, help="Agent backstory"),
192
- sop: str = typer.Option(None, help="Standard operating procedure"),
193
- debug: bool = typer.Option(False, help="Enable debug logging to stderr"),
194
- streaming: bool = typer.Option(False, help="Enable streaming output for real-time token generation"),
195
- reasoner: str = typer.Option(None, help="Name of the reasoner to use"),
196
- executor: str = typer.Option(None, help="Name of the executor to use"),
197
- tools_config: str = typer.Option(None, help="JSON/YAML string for tools_config"),
198
- profile: str = typer.Option(None, help="Agent profile (e.g., 'math_expert')"),
199
- customizations: str = typer.Option(None, help="JSON/YAML string for customizations")
200
- ) -> None:
201
- """CLI command to run the Agent with detailed event monitoring."""
202
- try:
203
- # Parse optional JSON/YAML strings
204
- tools_config_list = json.loads(tools_config) if tools_config else None
205
- customizations_dict = json.loads(customizations) if customizations else None
206
- asyncio.run(run_react_agent(
207
- task, model, max_iterations, success_criteria,
208
- personality=personality, backstory=backstory, sop=sop, debug=debug,
209
- streaming=streaming, reasoner_name=reasoner, executor_name=executor,
210
- tools_config=tools_config_list, profile=profile, customizations=customizations_dict
211
- ))
212
- except Exception as e:
213
- logger.error(f"Agent failed: {e}")
214
- typer.echo(f"Error: {e}", err=True)
215
- raise typer.Exit(code=1)
@@ -1,24 +0,0 @@
1
- import typer
2
- from rich.console import Console
3
-
4
- from quantalogic.codeact.cli import plugin_manager # Import shared plugin_manager from cli.py
5
-
6
- app = typer.Typer()
7
-
8
- console = Console()
9
-
10
- @app.command()
11
- def tool_info(tool_name: str = typer.Argument(..., help="Name of the tool")) -> None:
12
- """Display information about a specific tool."""
13
- tools = plugin_manager.tools.get_tools()
14
- tool = next((t for t in tools if t.name == tool_name), None)
15
- if tool:
16
- console.print(f"[bold green]Tool: {tool.name}[/bold green]")
17
- console.print(f"Description: {tool.description}")
18
- console.print(f"Toolbox: {tool.toolbox_name or 'N/A'}")
19
- console.print("Arguments:")
20
- for arg in tool.arguments:
21
- console.print(f" - {arg.name} ({arg.arg_type}): {arg.description} {'(required)' if arg.required else ''}")
22
- console.print(f"Return Type: {tool.return_type}")
23
- else:
24
- console.print(f"[red]Tool '{tool_name}' not found[/red]")
@@ -1,43 +0,0 @@
1
- import importlib.metadata
2
- import subprocess
3
-
4
- import typer
5
- from rich.console import Console
6
-
7
- app = typer.Typer()
8
-
9
- console = Console()
10
-
11
- @app.command()
12
- def uninstall_toolbox(
13
- toolbox_name: str = typer.Argument(..., help="Name of the toolbox or package to uninstall")
14
- ) -> None:
15
- """Uninstall a toolbox by its name or the package name that provides it."""
16
- try:
17
- # Get all entry points in the "quantalogic.tools" group
18
- eps = importlib.metadata.entry_points(group="quantalogic.tools")
19
-
20
- # Step 1: Check if the input is a toolbox name (entry point name)
21
- for ep in eps:
22
- if ep.name == toolbox_name:
23
- package_name = ep.dist.name
24
- subprocess.run(["uv", "pip", "uninstall", package_name], check=True)
25
- console.print(f"[green]Toolbox '{toolbox_name}' (package '{package_name}') uninstalled successfully[/green]")
26
- return
27
-
28
- # Step 2: Check if the input is a package name providing any toolbox
29
- package_eps = [ep for ep in eps if ep.dist.name == toolbox_name]
30
- if package_eps:
31
- subprocess.run(["uv", "pip", "uninstall", toolbox_name], check=True)
32
- toolboxes = ", ".join(ep.name for ep in package_eps)
33
- console.print(f"[green]Package '{toolbox_name}' providing toolbox(es) '{toolboxes}' uninstalled successfully[/green]")
34
- return
35
-
36
- # If neither a toolbox nor a package is found
37
- console.print(f"[yellow]No toolbox or package '{toolbox_name}' found to uninstall[/yellow]")
38
- except subprocess.CalledProcessError as e:
39
- console.print(f"[red]Failed to uninstall: {e}[/red]")
40
- raise typer.Exit(code=1)
41
- except Exception as e:
42
- console.print(f"[red]An error occurred: {e}[/red]")
43
- raise typer.Exit(code=1)
@@ -1,21 +0,0 @@
1
- model: "gemini/gemini-2.0-flash"
2
- max_iterations: 5
3
- max_history_tokens: 2000
4
- enabled_toolboxes:
5
- - math_tools
6
- reasoner:
7
- name: "default"
8
- config:
9
- temperature: 0.7
10
- executor:
11
- name: "default"
12
- profile: "math_expert"
13
- personality:
14
- traits:
15
- - witty
16
- - helpful
17
- tools_config:
18
- - name: math_tools
19
- enabled: true
20
- config:
21
- precision: "high"
@@ -1,9 +0,0 @@
1
- from pathlib import Path
2
-
3
- BASE_DIR = Path(__file__).parent
4
- TEMPLATE_DIR = BASE_DIR / "prompts"
5
- LOG_FILE = "react_agent.log"
6
- DEFAULT_MODEL = "gemini/gemini-2.0-flash"
7
- MAX_TOKENS = 4000
8
- MAX_GENERATE_PROGRAM_TOKENS = 1000
9
- MAX_HISTORY_TOKENS = 8000
@@ -1,85 +0,0 @@
1
- from datetime import datetime
2
- from typing import Optional
3
-
4
- from pydantic import BaseModel, Field
5
-
6
-
7
- class Event(BaseModel):
8
- event_type: str
9
- timestamp: datetime = Field(default_factory=datetime.now)
10
-
11
-
12
- class TaskStartedEvent(Event):
13
- task_description: str
14
- system_prompt: str = "" # Added for persistent context
15
-
16
-
17
- class ThoughtGeneratedEvent(Event):
18
- step_number: int
19
- thought: str
20
- generation_time: float
21
-
22
-
23
- class ActionGeneratedEvent(Event):
24
- step_number: int
25
- action_code: str
26
- generation_time: float
27
-
28
-
29
- class ActionExecutedEvent(Event):
30
- step_number: int
31
- result_xml: str
32
- execution_time: float
33
-
34
-
35
- class StepCompletedEvent(Event):
36
- step_number: int
37
- thought: str
38
- action: str
39
- result: str
40
- is_complete: bool
41
- final_answer: str | None = None
42
-
43
-
44
- class ErrorOccurredEvent(Event):
45
- error_message: str
46
- step_number: int | None = None
47
-
48
-
49
- class TaskCompletedEvent(Event):
50
- final_answer: str | None
51
- reason: str
52
-
53
-
54
- class StepStartedEvent(Event):
55
- step_number: int
56
- system_prompt: str = "" # Added for persistent context
57
- task_description: str = "" # Added for persistent context
58
-
59
-
60
- class ToolExecutionStartedEvent(Event):
61
- step_number: int
62
- tool_name: str
63
- parameters_summary: dict
64
-
65
-
66
- class ToolExecutionCompletedEvent(Event):
67
- step_number: int
68
- tool_name: str
69
- result_summary: str
70
-
71
-
72
- class ToolExecutionErrorEvent(Event):
73
- step_number: int
74
- tool_name: str
75
- error: str
76
-
77
-
78
- class StreamTokenEvent(Event):
79
- token: str
80
- step_number: Optional[int] = None
81
-
82
-
83
- class PromptGeneratedEvent(Event):
84
- step_number: int
85
- prompt: str