quantalogic 0.2.10__py3-none-any.whl → 0.2.13__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 (33) hide show
  1. quantalogic/agent.py +5 -7
  2. quantalogic/agent_config.py +1 -1
  3. quantalogic/coding_agent.py +2 -2
  4. quantalogic/generative_model.py +14 -15
  5. quantalogic/main.py +51 -9
  6. quantalogic/print_event.py +3 -1
  7. quantalogic/search_agent.py +41 -0
  8. quantalogic/server/agent_server.py +13 -13
  9. quantalogic/server/state.py +5 -5
  10. quantalogic/tool_manager.py +4 -4
  11. quantalogic/tools/__init__.py +4 -0
  12. quantalogic/tools/agent_tool.py +1 -1
  13. quantalogic/tools/elixir_tool.py +1 -1
  14. quantalogic/tools/llm_tool.py +12 -3
  15. quantalogic/tools/llm_vision_tool.py +4 -17
  16. quantalogic/tools/nodejs_tool.py +2 -2
  17. quantalogic/tools/python_tool.py +2 -2
  18. quantalogic/tools/replace_in_file_tool.py +3 -3
  19. quantalogic/tools/ripgrep_tool.py +3 -3
  20. quantalogic/tools/serpapi_search_tool.py +169 -0
  21. quantalogic/tools/tool.py +3 -3
  22. quantalogic/tools/unified_diff_tool.py +1 -0
  23. quantalogic/tools/wikipedia_search_tool.py +169 -0
  24. quantalogic/tools/write_file_tool.py +1 -0
  25. quantalogic/utils/check_version.py +37 -0
  26. quantalogic/utils/download_http_file.py +4 -4
  27. quantalogic/utils/read_http_text_content.py +2 -2
  28. quantalogic/version.py +3 -2
  29. {quantalogic-0.2.10.dist-info → quantalogic-0.2.13.dist-info}/METADATA +61 -8
  30. {quantalogic-0.2.10.dist-info → quantalogic-0.2.13.dist-info}/RECORD +33 -29
  31. {quantalogic-0.2.10.dist-info → quantalogic-0.2.13.dist-info}/LICENSE +0 -0
  32. {quantalogic-0.2.10.dist-info → quantalogic-0.2.13.dist-info}/WHEEL +0 -0
  33. {quantalogic-0.2.10.dist-info → quantalogic-0.2.13.dist-info}/entry_points.txt +0 -0
@@ -204,7 +204,7 @@ class ReplaceInFileTool(Tool):
204
204
  if not block.search:
205
205
  if block.replace:
206
206
  content += f"\n{block.replace}"
207
- logger.info(f"Block {idx}: Appended content")
207
+ logger.debug(f"Block {idx}: Appended content")
208
208
  continue
209
209
 
210
210
  match_found = False
@@ -218,7 +218,7 @@ class ReplaceInFileTool(Tool):
218
218
  content = f"{content[:start]}{content[end:]}"
219
219
  changes.append((start, start + len(block.replace) if block.replace else start))
220
220
  match_found = True
221
- logger.info(f"Block {idx}: Exact match {'replaced' if block.replace else 'deleted'}")
221
+ logger.debug(f"Block {idx}: Exact match {'replaced' if block.replace else 'deleted'}")
222
222
 
223
223
  if not match_found:
224
224
  similarity, matched_str = self.find_similar_match(block.search, content)
@@ -232,7 +232,7 @@ class ReplaceInFileTool(Tool):
232
232
  else:
233
233
  content = f"{content[:start]}{content[end:]}"
234
234
  changes.append((start, start + len(block.replace) if block.replace else start))
235
- logger.info(
235
+ logger.debug(
236
236
  f"Block {idx}: Similar match (similarity={similarity:.1%}) "
237
237
  f"{'replaced' if block.replace else 'deleted'}"
238
238
  )
@@ -136,7 +136,7 @@ class RipgrepTool(Tool):
136
136
  return "No files matching the pattern (after .gitignore filtering)"
137
137
 
138
138
  try:
139
- logger.info(f"Executing ripgrep with args: {args}")
139
+ logger.debug(f"Executing ripgrep with args: {args}")
140
140
  # Add filtered files to ripgrep command
141
141
  args.extend(filtered_files)
142
142
  output = subprocess.check_output([rg_path] + args, text=True, cwd=cwd)
@@ -194,7 +194,7 @@ class RipgrepTool(Tool):
194
194
  for path in system_paths + node_paths:
195
195
  full_path = Path(__file__).parent.parent / path if str(path).startswith("node_modules") else path
196
196
  if full_path.exists():
197
- logger.info(f"Found ripgrep at: {full_path}")
197
+ logger.debug(f"Found ripgrep at: {full_path}")
198
198
  return str(full_path)
199
199
 
200
200
  # Check system PATH using which/where
@@ -202,7 +202,7 @@ class RipgrepTool(Tool):
202
202
  command = "where" if os.name == "nt" else "which"
203
203
  rg_path = subprocess.check_output([command, bin_name], text=True).strip()
204
204
  if rg_path:
205
- logger.info(f"Found ripgrep in PATH at: {rg_path}")
205
+ logger.debug(f"Found ripgrep in PATH at: {rg_path}")
206
206
  return rg_path
207
207
  except subprocess.CalledProcessError:
208
208
  logger.debug("Ripgrep not found in system PATH")
@@ -0,0 +1,169 @@
1
+ """Tool for interacting with SerpApi for search results."""
2
+
3
+ import os
4
+
5
+ from serpapi.google_search import GoogleSearch
6
+
7
+ from quantalogic.tools.tool import Tool, ToolArgument
8
+
9
+
10
+ class SerpApiSearchTool(Tool):
11
+ """Tool for retrieving paginated search results from SerpApi.
12
+
13
+ This tool provides a convenient interface to SerpAPI's search capabilities,
14
+ supporting pagination and structured result formatting.
15
+
16
+ Example usage:
17
+ ```python
18
+ tool = SerpApiTool()
19
+ results = tool.execute(
20
+ query="machine learning",
21
+ page=1,
22
+ num_results=10
23
+ )
24
+ print(results)
25
+ ```
26
+
27
+ The tool handles:
28
+ - Query validation
29
+ - Pagination management
30
+ - API error handling
31
+ - Result formatting
32
+ """
33
+
34
+ name: str = "serpapi_tool"
35
+ description: str = (
36
+ "Retrieves search results from SerpAPI (Google Search) with pagination support. "
37
+ "Handles multiple pages of results and provides structured output."
38
+ )
39
+ arguments: list = [
40
+ ToolArgument(
41
+ name="query",
42
+ arg_type="string",
43
+ description="The search query to execute",
44
+ required=True,
45
+ example="machine learning",
46
+ ),
47
+ ToolArgument(
48
+ name="page",
49
+ arg_type="int",
50
+ description="The page number to retrieve (1-based)",
51
+ required=True,
52
+ default="1",
53
+ example="2",
54
+ ),
55
+ ToolArgument(
56
+ name="num_results",
57
+ arg_type="int",
58
+ description="Number of results to retrieve per page",
59
+ required=True,
60
+ default="10",
61
+ example="20",
62
+ ),
63
+ ]
64
+
65
+ def execute(self, query: str, page: int = 1, num_results: int = 10) -> str:
66
+ """Execute a search query using SerpAPI and return results.
67
+
68
+ Args:
69
+ query: The search query to execute
70
+ page: The page number to retrieve (1-based)
71
+ num_results: Number of results to retrieve per page (1-100)
72
+
73
+ Returns:
74
+ Formatted search results as a string with the following format:
75
+ ==== Page X of results ====
76
+ 1. Title
77
+ URL
78
+ Description
79
+ 2. Title
80
+ URL
81
+ Description
82
+ ==== End of page X ====
83
+
84
+ Raises:
85
+ ValueError: If any parameter is invalid
86
+ RuntimeError: If API request fails or environment variable is missing
87
+ """
88
+ # Validate and convert query
89
+ if not query:
90
+ raise ValueError("Query must be a non-empty string")
91
+ try:
92
+ query = str(query)
93
+ except (TypeError, ValueError) as e:
94
+ raise ValueError(f"Query must be convertible to string: {str(e)}")
95
+
96
+ # Validate and convert page
97
+ try:
98
+ page = int(page)
99
+ if page < 1:
100
+ raise ValueError("Page number must be positive")
101
+ except (TypeError, ValueError) as e:
102
+ raise ValueError(f"Invalid page number: {str(e)}")
103
+
104
+ # Validate and convert num_results
105
+ try:
106
+ num_results = int(num_results)
107
+ if num_results < 1 or num_results > 100:
108
+ raise ValueError("Number of results must be between 1 and 100")
109
+ except (TypeError, ValueError) as e:
110
+ raise ValueError(f"Invalid number of results: {str(e)}")
111
+
112
+ api_key = os.getenv("SERPAPI_API_KEY")
113
+ if not api_key:
114
+ raise RuntimeError("SERPAPI_API_KEY environment variable is not set")
115
+
116
+ try:
117
+ params = {"q": query, "start": (page - 1) * num_results, "num": num_results, "api_key": api_key}
118
+
119
+ search = GoogleSearch(params)
120
+ results = search.get_dict()
121
+
122
+ if "error" in results:
123
+ raise RuntimeError(f"API error: {results['error']}")
124
+
125
+ # Format results
126
+ output = []
127
+ if "organic_results" in results:
128
+ for idx, result in enumerate(results["organic_results"], 1):
129
+ output.append(f"{idx}. {result.get('title', 'No title')}")
130
+ output.append(f" {result.get('link', 'No URL')}")
131
+ output.append(f" {result.get('snippet', 'No description')}")
132
+ output.append("")
133
+
134
+ if not output:
135
+ return "No results found"
136
+
137
+ # Add pagination info
138
+ output.insert(0, f"==== Page {page} of results ====")
139
+ output.append(f"==== End of page {page} ====")
140
+
141
+ return "\n".join(output)
142
+
143
+ except Exception as e:
144
+ raise RuntimeError(f"Search failed: {str(e)}")
145
+
146
+
147
+ def main():
148
+ """Demonstrate SerpApiTool functionality."""
149
+ try:
150
+ tool = SerpApiSearchTool()
151
+
152
+ # Test basic search functionality
153
+ print("Testing SerpApiTool with sample query...")
154
+ results = tool.execute(query="Python programming", page=1, num_results=3)
155
+ print(results)
156
+
157
+ # Test error handling
158
+ print("\nTesting error handling with invalid query...")
159
+ try:
160
+ tool.execute(query="")
161
+ except ValueError as e:
162
+ print(f"Caught expected ValueError: {e}")
163
+
164
+ except Exception as e:
165
+ print(f"Error in main: {e}")
166
+
167
+
168
+ if __name__ == "__main__":
169
+ main()
quantalogic/tools/tool.py CHANGED
@@ -25,10 +25,10 @@ class ToolArgument(BaseModel):
25
25
  arg_type: Literal["string", "int", "float", "boolean"] = Field(
26
26
  ..., description="The type of the argument. Must be one of: string, integer, float, boolean."
27
27
  )
28
- description: str | None = Field(None, description="A brief description of the argument.")
28
+ description: str | None = Field(default=None, description="A brief description of the argument.")
29
29
  required: bool = Field(default=False, description="Indicates if the argument is required.")
30
- default: str | None = Field(None, description="The default value for the argument.")
31
- example: str | None = Field(None, description="An example value to illustrate the argument's usage.")
30
+ default: str | None = Field(default=None, description="The default value for the argument. This parameter is required.")
31
+ example: str | None = Field(default=None, description="An example value to illustrate the argument's usage.")
32
32
  need_validation: bool = Field(default=False, description="Indicates if the argument needs validation.")
33
33
 
34
34
 
@@ -153,6 +153,7 @@ class PatchError(Exception):
153
153
  super().__init__(message)
154
154
 
155
155
  def __str__(self):
156
+ """Override the default exception string to include context."""
156
157
  msg = [super().__str__()]
157
158
  if self.context:
158
159
  for key, value in self.context.items():
@@ -0,0 +1,169 @@
1
+ from typing import Union
2
+
3
+ """Tool for interacting with Wikipedia API for search results."""
4
+
5
+ import requests # noqa: E402
6
+
7
+ from quantalogic.tools.tool import Tool, ToolArgument # noqa: E402
8
+
9
+
10
+ class WikipediaSearchTool(Tool):
11
+ """Tool for retrieving paginated search results from Wikipedia.
12
+
13
+ This tool provides a convenient interface to Wikipedia's search API,
14
+ supporting pagination and structured result formatting.
15
+
16
+ Example usage:
17
+ ```python
18
+ tool = WikipediaSearchTool()
19
+ results = tool.execute(
20
+ query="machine learning",
21
+ page=1,
22
+ num_results=10
23
+ )
24
+ print(results)
25
+ ```
26
+
27
+ The tool handles:
28
+ - Query validation
29
+ - Pagination management
30
+ - API error handling
31
+ - Result formatting
32
+ """
33
+
34
+ name: str = "wikipedia_tool"
35
+ description: str = (
36
+ "Retrieves search results from Wikipedia with pagination support. "
37
+ "Handles multiple pages of results and provides structured output."
38
+ )
39
+ arguments: list = [
40
+ ToolArgument(
41
+ name="query",
42
+ arg_type="string",
43
+ description="The search query to execute",
44
+ required=True,
45
+ example="machine learning",
46
+ ),
47
+ ToolArgument(
48
+ name="page",
49
+ arg_type="int",
50
+ description="The page number to retrieve (1-based)",
51
+ required=True,
52
+ default="1",
53
+ example="2",
54
+ ),
55
+ ToolArgument(
56
+ name="num_results",
57
+ arg_type="int",
58
+ description="Number of results to retrieve per page (1-50)",
59
+ required=True,
60
+ default="10",
61
+ example="20",
62
+ ),
63
+ ]
64
+
65
+ def execute(self, query: str, page: Union[str, int] = 1, num_results: Union[str, int] = 10) -> str:
66
+ """Execute a search query using Wikipedia API and return results.
67
+
68
+ Args:
69
+ query: The search query to execute
70
+ page: The page number to retrieve (1-based)
71
+ num_results: Number of results to retrieve per page (1-50)
72
+
73
+ Returns:
74
+ Formatted search results as a string with the following format:
75
+ ==== Page X of results ====
76
+ 1. Title
77
+ URL
78
+ Description
79
+ 2. Title
80
+ URL
81
+ Description
82
+ ==== End of page X ====
83
+
84
+ Raises:
85
+ ValueError: If any parameter is invalid
86
+ RuntimeError: If API request fails
87
+ """
88
+ if not query or not isinstance(query, str):
89
+ raise ValueError("Query must be a non-empty string")
90
+
91
+ try:
92
+ page = int(page) if str(page).strip() else 1
93
+ num_results = int(num_results) if str(num_results).strip() else 10
94
+ except (ValueError, TypeError) as e:
95
+ raise ValueError(f"Invalid parameter type: {e}. Expected integers for page and num_results")
96
+
97
+ if page < 1:
98
+ raise ValueError("Page number must be positive")
99
+
100
+ if num_results < 1 or num_results > 50:
101
+ raise ValueError("Number of results must be between 1 and 50")
102
+
103
+ try:
104
+ # Wikipedia API endpoint
105
+ url = "https://en.wikipedia.org/w/api.php"
106
+ params = {
107
+ "action": "query",
108
+ "format": "json",
109
+ "list": "search",
110
+ "srsearch": query,
111
+ "srlimit": num_results,
112
+ "sroffset": (page - 1) * num_results
113
+ }
114
+
115
+ response = requests.get(url, params=params)
116
+ response.raise_for_status()
117
+ data = response.json()
118
+
119
+ output = []
120
+ if "query" in data and "search" in data["query"]:
121
+ for idx, result in enumerate(data["query"]["search"], 1):
122
+ title = result.get("title", "No title")
123
+ snippet = result.get("snippet", "No description")
124
+ url = f"https://en.wikipedia.org/wiki/{title.replace(' ', '_')}"
125
+
126
+ output.append(f"{idx}. {title}")
127
+ output.append(f" {url}")
128
+ output.append(f" {snippet}")
129
+ output.append("")
130
+
131
+ if not output:
132
+ return "No results found"
133
+
134
+ output.insert(0, f"==== Page {page} of results ====")
135
+ output.append(f"==== End of page {page} ====")
136
+
137
+ return "\n".join(output)
138
+
139
+ except Exception as e:
140
+ raise RuntimeError(f"Search failed: {str(e)}")
141
+
142
+
143
+ def main():
144
+ """Demonstrate WikipediaSearchTool functionality."""
145
+ try:
146
+ tool = WikipediaSearchTool()
147
+
148
+ # Test basic search functionality
149
+ print("Testing WikipediaSearchTool with sample query...")
150
+ results = tool.execute(
151
+ query="Python programming",
152
+ page=1,
153
+ num_results=3
154
+ )
155
+ print(results)
156
+
157
+ # Test error handling
158
+ print("\nTesting error handling with invalid query...")
159
+ try:
160
+ tool.execute(query="")
161
+ except ValueError as e:
162
+ print(f"Caught expected ValueError: {e}")
163
+
164
+ except Exception as e:
165
+ print(f"Error in main: {e}")
166
+
167
+
168
+ if __name__ == "__main__":
169
+ main()
@@ -43,6 +43,7 @@ class WriteFileTool(Tool):
43
43
  description="Overwrite mode. If true, existing files can be overwritten. Defaults to False.",
44
44
  required=False,
45
45
  example="False",
46
+ default="False",
46
47
  ),
47
48
  ]
48
49
 
@@ -0,0 +1,37 @@
1
+
2
+ import requests
3
+ from packaging import version
4
+
5
+ from quantalogic.version import get_version
6
+
7
+
8
+ def check_if_is_latest_version() -> (bool,str|None):
9
+ """Check if the current version is the latest version on PyPI.
10
+
11
+ Returns:
12
+ bool: True if the current version is the latest, False otherwise
13
+ """
14
+ try:
15
+ current_version = get_version()
16
+ response = requests.get("https://pypi.org/pypi/quantalogic/json", timeout=5)
17
+ response.raise_for_status()
18
+ latest_version = response.json()["info"]["version"]
19
+ return version.parse(current_version) < version.parse(latest_version), latest_version
20
+ except (requests.RequestException, KeyError):
21
+ return False, None
22
+
23
+
24
+ def main():
25
+ """Test the version checking functionality."""
26
+ is_latest, latest_version = check_if_is_latest_version()
27
+ if is_latest:
28
+ print("✅ You're running the latest version")
29
+ elif latest_version:
30
+ print(f"⚠️ Update available: {latest_version}")
31
+ else:
32
+ print("❌ Could not check version")
33
+
34
+ if __name__ == "__main__":
35
+ main()
36
+
37
+
@@ -35,18 +35,18 @@ def download_http_file(
35
35
 
36
36
  for attempt in range(max_retries):
37
37
  try:
38
- logger.info(f"Attempt {attempt + 1} of {max_retries} to download {url}")
38
+ logger.debug(f"Attempt {attempt + 1} of {max_retries} to download {url}")
39
39
  response = requests.get(url, headers=headers, stream=True, timeout=timeout)
40
40
  response.raise_for_status()
41
41
 
42
42
  content_type = response.headers.get("Content-Type", "unknown")
43
- logger.info(f"Downloading content with Content-Type: {content_type}")
43
+ logger.debug(f"Downloading content with Content-Type: {content_type}")
44
44
 
45
45
  with open(local_path, "wb") as file:
46
46
  for chunk in response.iter_content(chunk_size=chunk_size):
47
47
  file.write(chunk)
48
48
 
49
- logger.info(f"File successfully downloaded and saved to {local_path}")
49
+ logger.debug(f"File successfully downloaded and saved to {local_path}")
50
50
  return local_path
51
51
 
52
52
  except HTTPError as http_err:
@@ -70,7 +70,7 @@ def download_http_file(
70
70
 
71
71
  if attempt < max_retries - 1:
72
72
  sleep_duration = delay * (2**attempt) # Exponential backoff
73
- logger.info(f"Retrying in {sleep_duration} seconds...")
73
+ logger.debug(f"Retrying in {sleep_duration} seconds...")
74
74
  sleep(sleep_duration)
75
75
 
76
76
  logger.error("Max retries reached. Download failed.")
@@ -45,7 +45,7 @@ def read_http_text_content(
45
45
 
46
46
  for attempt in range(retries):
47
47
  try:
48
- logger.info(f"Attempt {attempt + 1} of {retries} to fetch {url}")
48
+ logger.debug(f"Attempt {attempt + 1} of {retries} to fetch {url}")
49
49
  response = requests.get(url, headers=headers, timeout=timeout)
50
50
  response.raise_for_status() # Raise an HTTPError for bad responses (4xx and 5xx)
51
51
 
@@ -87,7 +87,7 @@ def read_http_text_content(
87
87
 
88
88
  if attempt < retries - 1:
89
89
  sleep_duration = delay * (2**attempt) # Exponential backoff
90
- logger.info(f"Retrying in {sleep_duration} seconds...")
90
+ logger.debug(f"Retrying in {sleep_duration} seconds...")
91
91
  sleep(sleep_duration)
92
92
 
93
93
  return None, error_msg
quantalogic/version.py CHANGED
@@ -1,4 +1,5 @@
1
+ import importlib.metadata
2
+
1
3
 
2
- VERSION = "0.2.10"
3
4
  def get_version() -> str:
4
- return VERSION
5
+ return importlib.metadata.version("quantalogic")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quantalogic
3
- Version: 0.2.10
3
+ Version: 0.2.13
4
4
  Summary: QuantaLogic ReAct Agents
5
5
  Author: Raphaël MANSUY
6
6
  Author-email: raphael.mansuy@gmail.com
@@ -12,6 +12,7 @@ Requires-Dist: boto3 (>=1.35.86,<2.0.0)
12
12
  Requires-Dist: click (>=8.1.8,<9.0.0)
13
13
  Requires-Dist: fastapi (>=0.115.6,<0.116.0)
14
14
  Requires-Dist: google-auth (>=2.20.0,<3.0.0)
15
+ Requires-Dist: google-search-results (>=2.4.2,<3.0.0)
15
16
  Requires-Dist: litellm (>=1.56.4,<2.0.0)
16
17
  Requires-Dist: loguru (>=0.7.3,<0.8.0)
17
18
  Requires-Dist: markitdown (>=0.0.1a3,<0.0.2)
@@ -19,6 +20,7 @@ Requires-Dist: pathspec (>=0.12.1,<0.13.0)
19
20
  Requires-Dist: prompt-toolkit (>=3.0.48,<4.0.0)
20
21
  Requires-Dist: pydantic (>=2.10.4,<3.0.0)
21
22
  Requires-Dist: rich (>=13.9.4,<14.0.0)
23
+ Requires-Dist: serpapi (>=0.1.5,<0.2.0)
22
24
  Requires-Dist: tenacity (>=9.0.0,<10.0.0)
23
25
  Requires-Dist: toml (>=0.10.2,<0.11.0)
24
26
  Requires-Dist: tree-sitter (>=0.23.2,<0.24.0)
@@ -31,6 +33,7 @@ Requires-Dist: tree-sitter-python (>=0.23.6,<0.24.0)
31
33
  Requires-Dist: tree-sitter-rust (>=0.23.2,<0.24.0)
32
34
  Requires-Dist: tree-sitter-scala (>=0.23.4,<0.24.0)
33
35
  Requires-Dist: tree-sitter-typescript (>=0.23.2,<0.24.0)
36
+ Requires-Dist: types-requests (>=2.32.0.20241016,<3.0.0.0)
34
37
  Requires-Dist: uvicorn (>=0.34.0,<0.35.0)
35
38
  Requires-Dist: websocket (>=0.2.1,<0.3.0)
36
39
  Description-Content-Type: text/markdown
@@ -129,7 +132,7 @@ Options:
129
132
  e.g. "openrouter/A/gpt-4o-mini").
130
133
  --log [info|debug|warning] Set logging level (info/debug/warning).
131
134
  --verbose Enable verbose output.
132
- --mode [code|basic|interpreter|full|code-basic]
135
+ --mode [code|basic|interpreter|full|code-basic|search]
133
136
  Agent mode (code/search/full).
134
137
  --help Show this message and exit.
135
138
 
@@ -140,6 +143,8 @@ Commands:
140
143
  ### Commands
141
144
  task Execute a task with the QuantaLogic AI Assistant
142
145
 
146
+
147
+
143
148
  ### Detailed Usage
144
149
 
145
150
  #### Agent Modes
@@ -379,16 +384,19 @@ By integrating these tools into its architecture, QuantaLogic allows agents to p
379
384
 
380
385
  ### Tools Documentation
381
386
 
387
+
388
+
382
389
  #### Overview of Tools
383
390
 
384
391
  | Category | Tools |
385
392
  |-----------------------|---------------------------------------------------------------------------------------------------|
386
- | Task Automation | Agent Tool, Task Complete Tool, Input Question Tool, Execute Bash Command Tool |
387
- | Script Execution | Python Tool, Node.js Tool, Elixir Tool |
388
- | File Operations | Read File Tool, Write File Tool, Edit Whole Content Tool, Replace In File Tool |
389
- | Code Analysis | Search Definition Names Tool, Ripgrep Tool |
390
- | Content Generation | LLM Tool, LLMVisionTool |
391
- | Utility and Management | Download HTTP File Tool, List Directory Tool, Markitdown Tool, Unified Diff Tool |
393
+ | 1. Search Tools | 1.1 SerpAPI Search Tool, 1.2 Wikipedia Search Tool |
394
+ | 2. Task Automation | Agent Tool, Task Complete Tool, Input Question Tool, Execute Bash Command Tool |
395
+ | 3. Script Execution | Python Tool, Node.js Tool, Elixir Tool |
396
+ | 4. File Operations | Read File Tool, Write File Tool, Edit Whole Content Tool, Replace In File Tool |
397
+ | 5. Code Analysis | Search Definition Names Tool, Ripgrep Tool |
398
+ | 6. Content Generation | LLM Tool, LLMVisionTool |
399
+ | 7. Utility & Management| Download HTTP File Tool, List Directory Tool, Markitdown Tool, Unified Diff Tool |
392
400
 
393
401
  ---
394
402
 
@@ -787,6 +795,51 @@ result = markitdown_tool.execute(markdown_path="./path/to/file.md")
787
795
  print("Processed Markdown Output:", result)
788
796
  ```
789
797
 
798
+ ---
799
+
800
+ ### 19. SerpAPI Search Tool
801
+
802
+ The **SerpAPI Search Tool** allows agents to perform web searches using the SerpAPI service.
803
+
804
+ ##### Parameters
805
+ | Parameter | Type | Description | Example |
806
+ |-----------|--------|---------------------------------|-----------------------------|
807
+ | query | string | The search query to execute | "latest AI research papers" |
808
+ | location | string | Geographic location for results | "United States" |
809
+ | num | int | Number of results to return | 5 |
810
+
811
+ ##### Example Usage
812
+ ```python
813
+ from quantalogic.tools import SerpAPISearchTool
814
+
815
+ search_tool = SerpAPISearchTool()
816
+ results = search_tool.execute(query="latest AI research", location="United States", num=5)
817
+ print(results)
818
+ ```
819
+
820
+ ---
821
+
822
+ ### 20. Wikipedia Search Tool
823
+
824
+ The **Wikipedia Search Tool** enables agents to search and retrieve information from Wikipedia.
825
+
826
+ ##### Parameters
827
+
828
+ | Parameter | Type | Description | Example |
829
+ |-----------|--------|---------------------------------|-----------------------------|
830
+ | query | string | The search query to execute | "Artificial Intelligence" |
831
+ | lang | string | Language code for results | "en" |
832
+ | sentences | int | Number of summary sentences | 3 |
833
+
834
+ ##### Example Usage
835
+ ```python
836
+ from quantalogic.tools import WikipediaSearchTool
837
+
838
+ wiki_tool = WikipediaSearchTool()
839
+ results = wiki_tool.execute(query="Artificial Intelligence", lang="en", sentences=3)
840
+ print(results)
841
+ ```
842
+ ```
790
843
 
791
844
  #### Creating Custom Tools
792
845