quantalogic 0.2.20__py3-none-any.whl → 0.2.22__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.
@@ -176,7 +176,7 @@ def create_full_agent(
176
176
  )
177
177
 
178
178
 
179
- def create_orchestrator_agent(
179
+ def create_basic_agent(
180
180
  model_name: str,
181
181
  vision_model_name: str | None = None,
182
182
  no_stream: bool = False,
@@ -198,16 +198,20 @@ def create_orchestrator_agent(
198
198
  # Rebuild AgentTool to resolve forward references
199
199
  AgentTool.model_rebuild()
200
200
 
201
- coding_agent_instance = create_coding_agent(model_name)
202
201
 
203
202
  tools = [
204
203
  TaskCompleteTool(),
205
204
  ListDirectoryTool(),
206
205
  ReadFileBlockTool(),
207
- RipgrepTool(),
208
206
  SearchDefinitionNames(),
207
+ ReadFileTool(),
208
+ ReplaceInFileTool(),
209
+ WriteFileTool(),
210
+ EditWholeContentTool(),
211
+ ReplaceInFileTool(),
212
+ InputQuestionTool(),
213
+ ExecuteBashCommandTool(),
209
214
  LLMTool(model_name=model_name, on_token=console_print_token if not no_stream else None),
210
- AgentTool(agent=coding_agent_instance, agent_role="software expert", name="coder_agent_tool"),
211
215
  ]
212
216
 
213
217
  if vision_model_name:
quantalogic/main.py CHANGED
@@ -31,7 +31,7 @@ from quantalogic.agent_config import ( # noqa: E402
31
31
  create_coding_agent,
32
32
  create_full_agent,
33
33
  create_interpreter_agent,
34
- create_orchestrator_agent,
34
+ create_basic_agent,
35
35
  )
36
36
  from quantalogic.interactive_text_editor import get_multiline_input # noqa: E402
37
37
  from quantalogic.search_agent import create_search_agent # noqa: E402
@@ -52,7 +52,7 @@ def create_agent_for_mode(mode: str, model_name: str, vision_model_name: str | N
52
52
  if mode == "code-basic":
53
53
  return create_coding_agent(model_name, vision_model_name, basic=True, no_stream=no_stream, compact_every_n_iteration=compact_every_n_iteration, max_tokens_working_memory=max_tokens_working_memory)
54
54
  elif mode == "basic":
55
- return create_orchestrator_agent(model_name, vision_model_name, no_stream=no_stream, compact_every_n_iteration=compact_every_n_iteration, max_tokens_working_memory=max_tokens_working_memory)
55
+ return create_basic_agent(model_name, vision_model_name, no_stream=no_stream, compact_every_n_iteration=compact_every_n_iteration, max_tokens_working_memory=max_tokens_working_memory)
56
56
  elif mode == "full":
57
57
  return create_full_agent(model_name, vision_model_name, no_stream=no_stream, compact_every_n_iteration=compact_every_n_iteration, max_tokens_working_memory=max_tokens_working_memory)
58
58
  elif mode == "interpreter":
@@ -159,7 +159,8 @@ def display_welcome_message(
159
159
  vision_model_name: str | None,
160
160
  max_iterations: int = 50,
161
161
  compact_every_n_iteration: int | None = None,
162
- max_tokens_working_memory: int | None = None
162
+ max_tokens_working_memory: int | None = None,
163
+ mode: str = "basic"
163
164
  ) -> None:
164
165
  """Display the welcome message and instructions."""
165
166
  version = get_version()
@@ -174,6 +175,7 @@ def display_welcome_message(
174
175
  "\n"
175
176
  f"- Model: {model_name}\n"
176
177
  f"- Vision Model: {vision_model_name}\n"
178
+ f"- Mode: {mode}\n"
177
179
  f"- Max Iterations: {max_iterations}\n"
178
180
  f"- Memory Compact Frequency: {compact_every_n_iteration or 'Default (Max Iterations)'}\n"
179
181
  f"- Max Working Memory Tokens: {max_tokens_working_memory or 'Default'}\n\n"
@@ -208,7 +210,7 @@ def display_welcome_message(
208
210
  help="Set logging level (info/debug/warning).",
209
211
  )
210
212
  @click.option("--verbose", is_flag=True, help="Enable verbose output.")
211
- @click.option("--mode", type=click.Choice(AGENT_MODES), default="code", help="Agent mode (code/search/full).")
213
+ @click.option("--mode", type=click.Choice(AGENT_MODES), default="basic", help="Agent mode (code/search/full).")
212
214
  @click.option(
213
215
  "--vision-model-name",
214
216
  default=None,
@@ -266,7 +268,7 @@ def cli(
266
268
  help='Specify the model to use (litellm format, e.g. "openrouter/deepseek/deepseek-chat").',
267
269
  )
268
270
  @click.option("--verbose", is_flag=True, help="Enable verbose output.")
269
- @click.option("--mode", type=click.Choice(AGENT_MODES), default="code", help="Agent mode (code/search/full).")
271
+ @click.option("--mode", type=click.Choice(AGENT_MODES), default="basic", help="Agent mode (code/search/full).")
270
272
  @click.option(
271
273
  "--log",
272
274
  type=click.Choice(["info", "debug", "warning"]),
@@ -333,7 +335,8 @@ def task(
333
335
  vision_model_name,
334
336
  max_iterations=max_iterations,
335
337
  compact_every_n_iteration=compact_every_n_iteration,
336
- max_tokens_working_memory=max_tokens_working_memory
338
+ max_tokens_working_memory=max_tokens_working_memory,
339
+ mode=mode
337
340
  )
338
341
  check_new_version()
339
342
  logger.debug("Waiting for user input...")
@@ -28,7 +28,7 @@ from quantalogic.agent_config import (
28
28
  MODEL_NAME,
29
29
  create_agent,
30
30
  create_coding_agent, # noqa: F401
31
- create_orchestrator_agent, # noqa: F401
31
+ create_basic_agent, # noqa: F401
32
32
  )
33
33
  from quantalogic.console_print_events import console_print_events
34
34
 
quantalogic/tools/tool.py CHANGED
@@ -6,7 +6,6 @@ with type-validated arguments and execution methods.
6
6
 
7
7
  from typing import Any, Literal
8
8
 
9
- from loguru import logger
10
9
  from pydantic import BaseModel, ConfigDict, Field, field_validator
11
10
 
12
11
 
@@ -1,15 +1,20 @@
1
1
  import os
2
2
 
3
+ from loguru import logger
4
+
3
5
  from quantalogic.utils.get_environment import get_environment
4
6
  from quantalogic.utils.git_ls import git_ls
5
7
 
6
8
 
7
9
  def get_coding_environment() -> str:
8
10
  """Retrieve coding environment details."""
9
- return (
11
+ logger.debug("Retrieving coding environment details.")
12
+ result = (
10
13
  f"{get_environment()}"
11
14
  "\n\n"
12
15
  "<codebase_first_level>\n"
13
- f"{git_ls(directory_path=os.getcwd())}"
16
+ f"{git_ls(directory_path=os.getcwd(), recursive=False, max_depth=1)}"
14
17
  "\n</codebase_first_level>\n"
15
18
  )
19
+ logger.debug(f"Coding environment details:\n{result}")
20
+ return result
@@ -29,6 +29,10 @@ def git_ls(
29
29
 
30
30
  # Expand paths and get absolute path
31
31
  path = Path(os.path.expanduser(directory_path)).absolute()
32
+
33
+ # Verify access to base directory
34
+ if not os.access(path, os.R_OK):
35
+ return f"==== Error: No read access to directory {path} ====\n==== End of Block ===="
32
36
 
33
37
  # Load .gitignore patterns
34
38
  ignore_spec = load_gitignore_spec(path)
@@ -49,9 +53,13 @@ def load_gitignore_spec(path: Path) -> PathSpec:
49
53
  while current != current.parent: # Stop at root
50
54
  gitignore_path = current / ".gitignore"
51
55
  if gitignore_path.exists():
52
- with open(gitignore_path) as f:
53
- # Prepend parent patterns to maintain precedence
54
- ignore_patterns = f.readlines() + ignore_patterns
56
+ try:
57
+ if os.access(gitignore_path, os.R_OK):
58
+ with open(gitignore_path) as f:
59
+ # Prepend parent patterns to maintain precedence
60
+ ignore_patterns = f.readlines() + ignore_patterns
61
+ except (PermissionError, OSError):
62
+ continue
55
63
  current = current.parent
56
64
 
57
65
  return PathSpec.from_lines(GitWildMatchPattern, ignore_patterns)
@@ -68,12 +76,25 @@ def generate_file_tree(
68
76
  return {}
69
77
 
70
78
  if path.is_file():
71
- return {"name": path.name, "type": "file", "size": f"{path.stat().st_size} bytes"}
79
+ try:
80
+ if not os.access(path, os.R_OK):
81
+ return {"name": path.name, "type": "file", "size": "no access"}
82
+ return {"name": path.name, "type": "file", "size": f"{path.stat().st_size} bytes"}
83
+ except (PermissionError, OSError):
84
+ return {"name": path.name, "type": "file", "size": "no access"}
72
85
 
73
86
  tree = {"name": path.name, "type": "directory", "children": []}
74
87
 
75
- # Always list direct children, but only recursively list if recursive is True
76
- children = sorted(path.iterdir(), key=lambda x: x.name.lower())
88
+ try:
89
+ if not os.access(path, os.R_OK | os.X_OK):
90
+ tree["children"].append({"name": "no access", "type": "error"})
91
+ return tree
92
+
93
+ # Always list direct children, but only recursively list if recursive is True
94
+ children = sorted(path.iterdir(), key=lambda x: x.name.lower())
95
+ except (PermissionError, OSError):
96
+ tree["children"].append({"name": "no access", "type": "error"})
97
+ return tree
77
98
  for child in children:
78
99
  if not ignore_spec.match_file(child):
79
100
  if child.is_file():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quantalogic
3
- Version: 0.2.20
3
+ Version: 0.2.22
4
4
  Summary: QuantaLogic ReAct Agents
5
5
  Author: Raphaël MANSUY
6
6
  Author-email: raphael.mansuy@gmail.com
@@ -54,7 +54,7 @@ Description-Content-Type: text/markdown
54
54
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
55
55
  [![Python](https://img.shields.io/badge/Python-3.12+-blue.svg)](https://www.python.org/downloads/)
56
56
  [![Documentation](https://img.shields.io/badge/docs-latest-brightgreen.svg)](https://quantalogic.github.io/quantalogic/)
57
- [HowTo Guide](./docs/howto/howto.md)
57
+
58
58
 
59
59
  QuantaLogic is a ReAct (Reasoning & Action) framework for building advanced AI agents.
60
60
 
@@ -66,6 +66,8 @@ The `cli` version include coding capabilities comparable to Aider.
66
66
 
67
67
  ![Video](./examples/generated_tutorials/python/quantalogic_8s.gif)
68
68
 
69
+ [HowTo Guide](./docs/howto/howto.md)
70
+
69
71
  ## Why QuantaLogic?
70
72
 
71
73
  We created [QuantaLogic](https://www.quantalogic.app) because we saw a significant gap between the advanced AI models developed by companies like OpenAI, Anthropic, DeepSeek and their practical implementation in everyday business processes.
@@ -1,6 +1,6 @@
1
1
  quantalogic/__init__.py,sha256=kX0c_xmD9OslWnAE92YHMGuD7xZcTo8ZOF_5R64HKps,784
2
2
  quantalogic/agent.py,sha256=yYRfp5NM9GhWWiAJnsLbgq-Yf9ikGGsEGwFL3MbUHXA,31227
3
- quantalogic/agent_config.py,sha256=H-YkaNkVglBlnN00Htrs3bPPoD2hirBfGBpoSbKgdMU,7232
3
+ quantalogic/agent_config.py,sha256=OA6GCUPYUWYYPvIjPsnrpbDm4GzXM8BzkFm39rn6EcU,7241
4
4
  quantalogic/coding_agent.py,sha256=cFw-D6yLNsQpotj8z5-kLaudUMjHJf3XW3ZOyScZTSc,4894
5
5
  quantalogic/console_print_events.py,sha256=KB-DGi52As8M96eUs1N_vgNqKIFtqv_H8NTOd3TLTgQ,2163
6
6
  quantalogic/console_print_token.py,sha256=qSU-3kmoZk4T5-1ybrEBi8tIXDPcz7eyWKhGh3E8uIg,395
@@ -8,13 +8,13 @@ quantalogic/docs_cli.py,sha256=3giVbUpespB9ZdTSJ955A3BhcOaBl5Lwsn1AVy9XAeY,1663
8
8
  quantalogic/event_emitter.py,sha256=jqot2g4JRXc88K6PW837Oqxbf7shZfO-xdPaUWmzupk,7901
9
9
  quantalogic/generative_model.py,sha256=s94heYFPSA2IO4E3ay3CF1k9hXKNAzX1KVmxHlQgF_8,12397
10
10
  quantalogic/interactive_text_editor.py,sha256=kYeTA2qej5kxtPvAUHy_Dr2MhrGQAyenLFpW9mU9Rmw,6855
11
- quantalogic/main.py,sha256=nyqwQwrzmiurCwR5gkkx16BNW9XN69fTHvqOZ_qK9CU,16655
11
+ quantalogic/main.py,sha256=VTJ8kbhirebijVSujgkqO-w3dK9BB4me0ZF07CFclas,16731
12
12
  quantalogic/memory.py,sha256=zbtRuM05jaS2lJll-92dt5JfYVLERnF_m_9xqp2x-k0,6304
13
13
  quantalogic/model_names.py,sha256=UZlz25zG9B2dpfwdw_e1Gw5qFsKQ7iME9FJh9Ts4u6s,938
14
14
  quantalogic/prompts.py,sha256=CW4CRgW1hTpXeWdeJNbPaRPUeUm-xKuGHJrT8mOtvkw,3602
15
15
  quantalogic/search_agent.py,sha256=EA_FAPP0dVuUbJ_lAGKfYq1FIJ6oLYzGMgKLMvBL4ZQ,2472
16
16
  quantalogic/server/__init__.py,sha256=8sz_PYAUCrkM6JM5EAUeIzNM4NPW6j6UT72JVkc21WQ,91
17
- quantalogic/server/agent_server.py,sha256=JNginXlkgBfJLqgKffoTBSvBWI8ZO1uXUgTOqLINk_g,22517
17
+ quantalogic/server/agent_server.py,sha256=VXaaWqReUSZOCX7CaKS14jria8yZn1kLEc52E2hV7ZA,22510
18
18
  quantalogic/server/models.py,sha256=nVUGWElOsUw8QnRCGJylk25wCew_5gohe6nldYighUA,1322
19
19
  quantalogic/server/routes.py,sha256=00nFe6s0T4Gv8vCp0wQFjWGo1tC8FViH8h0koAJdWs4,4216
20
20
  quantalogic/server/state.py,sha256=TwtL0BTp_LT-fynF1IR4k8WVXuxXWtSv3NgWG9fuUME,7369
@@ -54,7 +54,7 @@ quantalogic/tools/ripgrep_tool.py,sha256=sRzHaWac9fa0cCGhECJN04jw_Ko0O3u45KDWzMI
54
54
  quantalogic/tools/search_definition_names.py,sha256=Qj9ex226vHs8Jf-kydmTh7B_R8O5buIsJpQu3CvYw7k,18601
55
55
  quantalogic/tools/serpapi_search_tool.py,sha256=sX-Noch77kGP2XiwislPNFyy3_4TH6TwMK6C81L3q9Y,5316
56
56
  quantalogic/tools/task_complete_tool.py,sha256=L8tuyVoN07Q2hOsxx17JTW0C5Jd_N-C0i_0PtCUQUKU,929
57
- quantalogic/tools/tool.py,sha256=hrTzzAohrOatTIZTtCyTYVg1_L5z4ySP7E2aJISbws8,9826
57
+ quantalogic/tools/tool.py,sha256=fdD-wwAOgfua2RRk1FHv_mlNBQ1FTzPO8vMIKiRirZM,9800
58
58
  quantalogic/tools/unified_diff_tool.py,sha256=wTKXIoBEPcC_EcQmpJZVi95vq0Ncvsw1Kyc7XqPO6dU,14147
59
59
  quantalogic/tools/wikipedia_search_tool.py,sha256=bdZ_0dYTxpEfU04tBFsatnLM5P9Z3kAZgKQEjsopJLA,5405
60
60
  quantalogic/tools/write_file_tool.py,sha256=_mx9_Zjg2oMAAVzlcHEKjZVZUxQVgbRfcoMKgWnoZcg,3764
@@ -62,17 +62,17 @@ quantalogic/utils/__init__.py,sha256=Ltq7tzLuHCl9BpCvfRVA9Sjrtp1RJesrn7G980lbl_c
62
62
  quantalogic/utils/ask_user_validation.py,sha256=F0jkbFJVXAImcSSP7op6dov5i80hRvZGRvBHbfcZrxg,340
63
63
  quantalogic/utils/check_version.py,sha256=grxTfJE85GMue1OAk8z8_q8tjEJxQ8RO6fN3fJ_qedg,1136
64
64
  quantalogic/utils/download_http_file.py,sha256=FTN3brq9WvCFvuBX-lYAhjsdYTzQT4m9m2vqlcyjkNk,3472
65
- quantalogic/utils/get_coding_environment.py,sha256=ujZ2_nDryrLWe6ZUalSu9WDG6t53UJFn7FJ_ER7Jixc,389
65
+ quantalogic/utils/get_coding_environment.py,sha256=oMK5ZanOqX_SFaJxUZQGlsAAaiLUgJufCJYDrHnHPuQ,584
66
66
  quantalogic/utils/get_environment.py,sha256=7wWruSHYTUlnQWW27qU3WFYZnncqqqdofsxAsUU7lhw,875
67
67
  quantalogic/utils/get_quantalogic_rules_content.py,sha256=fnEFTyClXzpI0MLaM-gB9R6l4CJlu2NnaYiR09ciJC8,673
68
- quantalogic/utils/git_ls.py,sha256=_aXg2TwqYv9CoOrhQ1gqHCqu1j8wOVigQNWbGncSDlM,4361
68
+ quantalogic/utils/git_ls.py,sha256=_k6QIQtc0aM1bsG340jBp4VrdevbcH8Pg2CV4r9oHok,5264
69
69
  quantalogic/utils/read_file.py,sha256=tSRVHk8dIP4nNLL89v5kRki4hOTjVyjbmuEb2zwvwCY,2077
70
70
  quantalogic/utils/read_http_text_content.py,sha256=n3IayT5KcqctIVVF2gOQQAMf3Ow6eenlVgfXTpLcQbw,4410
71
71
  quantalogic/version.py,sha256=ea_cRutaQk5_lwlLbUUvPFuOT7Of7-gAsDl7wdveS-g,107
72
72
  quantalogic/xml_parser.py,sha256=uMLQNHTRCg116FwcjRoquZmSwVtE4LEH-6V2E3RD-dA,11466
73
73
  quantalogic/xml_tool_parser.py,sha256=Vz4LEgDbelJynD1siLOVkJ3gLlfHsUk65_gCwbYJyGc,3784
74
- quantalogic-0.2.20.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
75
- quantalogic-0.2.20.dist-info/METADATA,sha256=4W7djzID_a6qyVJwlVrGPRPXThIs86wrP59so57CJ2g,20077
76
- quantalogic-0.2.20.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
77
- quantalogic-0.2.20.dist-info/entry_points.txt,sha256=h74O_Q3qBRCrDR99qvwB4BpBGzASPUIjCfxHq6Qnups,183
78
- quantalogic-0.2.20.dist-info/RECORD,,
74
+ quantalogic-0.2.22.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
75
+ quantalogic-0.2.22.dist-info/METADATA,sha256=fsOAHh2H8db1iZnejR9VbIx5vTUer0uf_p8AJkjHbw8,20079
76
+ quantalogic-0.2.22.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
77
+ quantalogic-0.2.22.dist-info/entry_points.txt,sha256=h74O_Q3qBRCrDR99qvwB4BpBGzASPUIjCfxHq6Qnups,183
78
+ quantalogic-0.2.22.dist-info/RECORD,,