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.
@@ -4,18 +4,20 @@ This tool provides a sophisticated interface to fetch, analyze, and format news
4
4
  from Google News using multiple sources and advanced filtering capabilities.
5
5
  """
6
6
 
7
+ from datetime import datetime, timedelta
8
+ from typing import List, Optional, Dict, Any
9
+ import json
10
+ from urllib.parse import quote_plus
7
11
  import asyncio
8
- from typing import Any, Dict, List
9
-
10
12
  import aiohttp
11
- import html2text
12
13
  from bs4 import BeautifulSoup
13
14
  from gnews import GNews
14
15
  from loguru import logger
16
+ from pydantic import Field, validator, ConfigDict
17
+ import html2text
15
18
 
19
+ from quantalogic.tools.tool import Tool, ToolArgument
16
20
  from quantalogic.event_emitter import EventEmitter
17
- from quantalogic.tools.llm_tool import LLMTool
18
- from quantalogic.tools.tool import Tool, ToolArgument
19
21
 
20
22
 
21
23
  class NewsArticle:
@@ -155,151 +157,19 @@ class GoogleNewsTool(Tool):
155
157
  ),
156
158
  ]
157
159
 
158
- def __init__(
159
- self,
160
- model_name: str | None = None,
161
- on_token: Any | None = None,
162
- event_emitter: EventEmitter | None = None,
163
- ):
160
+ def __init__(self, name: str | None = None):
164
161
  """Initialize the GoogleNewsTool.
165
162
 
166
163
  Args:
167
- model_name (str | None): Name of the LLM model to use for summarization
168
- on_token (Any | None): Token callback for streaming
169
- event_emitter (EventEmitter | None): Event emitter for the tool
164
+ name (str | None): Optional name override for the tool
170
165
  """
171
166
  super().__init__()
172
- self.model_name = model_name
173
- self.on_token = on_token
174
- self.event_emitter = event_emitter
175
- if model_name:
176
- self.llm_tool = LLMTool(
177
- model_name=model_name,
178
- on_token=on_token,
179
- event_emitter=event_emitter,
180
- )
181
-
182
- def _summarize_article(self, article: Dict[str, Any]) -> str:
183
- """Summarize a news article using LLM.
184
-
185
- Args:
186
- article (Dict[str, Any]): Article data including title and description
187
-
188
- Returns:
189
- str: Summarized article content
190
- """
191
- if not hasattr(self, 'llm_tool'):
192
- return article.get('description', '')
193
-
194
- prompt = f"""
195
- Summarize this news article concisely and professionally:
196
-
197
- Title: {article.get('title', '')}
198
- Description: {article.get('description', '')}
199
-
200
- Provide a 2-3 sentence summary that captures the key points.
201
- """
202
-
203
- try:
204
- summary = self.llm_tool.execute(
205
- system_prompt="You are a professional news summarizer. Create clear, accurate, and concise summaries.",
206
- prompt=prompt,
207
- temperature="0.3"
208
- )
209
- return summary
210
- except Exception as e:
211
- logger.error(f"Error summarizing article: {e}")
212
- return article.get('description', '')
167
+ if name:
168
+ self.name = name
213
169
 
214
170
  def _format_html_output(self, articles: List[Dict[str, Any]], query: str) -> str:
215
171
  """Format articles as HTML with a modern, clean design."""
216
- css_styles = """
217
- body {
218
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
219
- line-height: 1.6;
220
- max-width: 1200px;
221
- margin: 0 auto;
222
- padding: 20px;
223
- background-color: #f5f5f5;
224
- }
225
- .header {
226
- background-color: #2c3e50;
227
- color: white;
228
- padding: 20px;
229
- border-radius: 8px;
230
- margin-bottom: 20px;
231
- }
232
- .article {
233
- background-color: white;
234
- padding: 20px;
235
- margin-bottom: 20px;
236
- border-radius: 8px;
237
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
238
- }
239
- .article h2 {
240
- color: #2c3e50;
241
- margin-top: 0;
242
- }
243
- .article-meta {
244
- color: #666;
245
- font-size: 0.9em;
246
- margin-bottom: 10px;
247
- }
248
- .summary {
249
- border-left: 4px solid #2c3e50;
250
- padding-left: 15px;
251
- margin: 15px 0;
252
- }
253
- .source-link {
254
- display: inline-block;
255
- margin-top: 10px;
256
- color: #3498db;
257
- text-decoration: none;
258
- }
259
- .source-link:hover {
260
- text-decoration: underline;
261
- }
262
- """
263
-
264
- articles_html = []
265
- for article in articles:
266
- article_html = f"""
267
- <div class="article">
268
- <h2>{article.get('title', 'No Title')}</h2>
269
- <div class="article-meta">
270
- <span>Source: {article.get('source', {}).get('title', 'Unknown')}</span>
271
- <span> • </span>
272
- <span>Published: {article.get('published_date', 'Unknown date')}</span>
273
- </div>
274
- <div class="summary">
275
- {article.get('summary', 'No summary available')}
276
- </div>
277
- <a href="{article.get('link', '#')}" class="source-link" target="_blank">Read full article →</a>
278
- </div>
279
- """
280
- articles_html.append(article_html)
281
-
282
- html_content = f"""
283
- <!DOCTYPE html>
284
- <html>
285
- <head>
286
- <meta charset="UTF-8">
287
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
288
- <style>
289
- {css_styles}
290
- </style>
291
- </head>
292
- <body>
293
- <div class="header">
294
- <h1>News Results for: {query}</h1>
295
- <p>Found {len(articles)} articles</p>
296
- </div>
297
- {''.join(articles_html)}
298
- </body>
299
- </html>
300
- """
301
-
302
- return html_content.strip()
172
+ return json.dumps(articles, indent=2)
303
173
 
304
174
  def _fetch_article_data(self, articles: List[NewsArticle]) -> List[NewsArticle]:
305
175
  """Fetch detailed data for multiple articles."""
@@ -319,38 +189,6 @@ class GoogleNewsTool(Tool):
319
189
 
320
190
  return loop.run_until_complete(fetch_all())
321
191
 
322
- def _format_results(self, articles: List[NewsArticle], analyze: bool) -> str:
323
- """Format news results with optional analysis data."""
324
- results = ["=== Advanced Google News Results ===\n"]
325
-
326
- for i, article in enumerate(articles, 1):
327
- results.extend([
328
- f"{i}. {article.title}",
329
- f" Source: {article.source} | Date: {article.date}",
330
- f" URL: {article.url}",
331
- ""
332
- ])
333
-
334
- if analyze and article.summary:
335
- results.extend([
336
- " Summary:",
337
- f" {article.summary}",
338
- "",
339
- " Key Topics:",
340
- f" {', '.join(article.keywords[:5])}",
341
- "",
342
- " Sentiment Analysis:",
343
- " Overall tone: " + self._interpret_sentiment(article.sentiment),
344
- f" - Positive: {article.sentiment.get('pos', 0)*100:.1f}% ({self._get_sentiment_level(article.sentiment.get('pos', 0))})",
345
- f" - Negative: {article.sentiment.get('neg', 0)*100:.1f}% ({self._get_sentiment_level(article.sentiment.get('neg', 0))})",
346
- f" - Neutral: {article.sentiment.get('neu', 0)*100:.1f}% ({self._get_sentiment_level(article.sentiment.get('neu', 0))})",
347
- ""
348
- ])
349
-
350
- results.append("")
351
-
352
- return "\n".join(results)
353
-
354
192
  def _get_sentiment_level(self, score: float) -> str:
355
193
  """Convert sentiment score to descriptive level."""
356
194
  if score >= 0.6:
@@ -388,7 +226,7 @@ class GoogleNewsTool(Tool):
388
226
  sort_by: str = "relevance",
389
227
  analyze: bool = True,
390
228
  ) -> str:
391
- """Execute the Google News search with summarization and HTML formatting.
229
+ """Execute the Google News search and return full articles in JSON format.
392
230
 
393
231
  Args:
394
232
  query (str): Search query
@@ -400,7 +238,7 @@ class GoogleNewsTool(Tool):
400
238
  analyze (bool, optional): Whether to analyze results. Defaults to True.
401
239
 
402
240
  Returns:
403
- str: HTML formatted news results with summaries
241
+ str: JSON-formatted string containing list of article dictionaries with full content
404
242
  """
405
243
  try:
406
244
  # Input validation
@@ -442,22 +280,23 @@ class GoogleNewsTool(Tool):
442
280
  if sort_by == "date":
443
281
  articles.sort(key=lambda x: x.date if x.date else "", reverse=True)
444
282
 
445
- # Process and summarize each article
283
+ # Process and return full article data
446
284
  processed_articles = []
447
285
  for article in articles:
448
- article_copy = {
286
+ processed_article = {
449
287
  'title': article.title,
450
- 'link': article.url,
451
- 'source': {'title': article.source},
452
- 'published_date': article.date,
453
- 'description': article.full_text if hasattr(article, 'full_text') else '',
288
+ 'url': article.url,
289
+ 'source': article.source,
290
+ 'date': article.date,
291
+ 'full_text': article.full_text if hasattr(article, 'full_text') else '',
292
+ 'keywords': article.keywords if hasattr(article, 'keywords') else [],
293
+ 'sentiment': article.sentiment if hasattr(article, 'sentiment') else {},
294
+ 'summary': article.summary if hasattr(article, 'summary') else ''
454
295
  }
455
- article_copy['summary'] = self._summarize_article(article_copy)
456
- processed_articles.append(article_copy)
296
+ processed_articles.append(processed_article)
457
297
 
458
- # Format results as HTML
459
- html_output = self._format_html_output(processed_articles, query)
460
- return html_output
298
+ # Return pretty-printed JSON string, matching DuckDuckGo tool format
299
+ return json.dumps(processed_articles, indent=4, ensure_ascii=False)
461
300
 
462
301
  except Exception as e:
463
302
  logger.error(f"Error in GoogleNewsTool: {e}")
@@ -10,12 +10,14 @@ from loguru import logger
10
10
  from .csv_processor_tool import CSVProcessorTool
11
11
  from .download_file_tool import PrepareDownloadTool
12
12
  from .mermaid_validator_tool import MermaidValidatorTool
13
+ from .vscode_tool import VSCodeServerTool
13
14
 
14
15
  # Define __all__ to control what is imported with `from ... import *`
15
16
  __all__ = [
16
17
  'CSVProcessorTool',
17
18
  'PrepareDownloadTool',
18
19
  'MermaidValidatorTool',
20
+ 'VSCodeServerTool',
19
21
  ]
20
22
 
21
23
  # Optional: Add logging for import confirmation
@@ -45,14 +45,16 @@ class PrepareDownloadTool(Tool):
45
45
  ),
46
46
  ]
47
47
 
48
- def __init__(self, upload_dir: str = "/tmp/data", base_url: str = "http://localhost:8082"):
48
+ def __init__(self, upload_dir: str = "/tmp/data", base_url: str = "http://localhost:8082", name: str = None):
49
49
  """Initialize the tool with upload directory path.
50
50
 
51
51
  Args:
52
52
  upload_dir: Directory where files are served from. Defaults to /tmp/data.
53
53
  base_url: Base URL of the server. Defaults to http://localhost:8082.
54
54
  """
55
- super().__init__()
55
+ super().__init__()
56
+ if name:
57
+ self.name = name
56
58
  self.upload_dir = upload_dir
57
59
  self.base_url = base_url.rstrip('/')
58
60
  # Ensure upload directory exists
@@ -0,0 +1,123 @@
1
+ """Tool for launching VS Code Server instances."""
2
+
3
+ import os
4
+ import subprocess
5
+ import urllib.parse
6
+ from typing import Dict, Optional, Union
7
+
8
+ from loguru import logger
9
+
10
+ from quantalogic.tools.tool import Tool, ToolArgument
11
+
12
+
13
+ class VSCodeServerTool(Tool):
14
+ """Tool for launching VS Code Server instances with configurable settings."""
15
+
16
+ name: str = "vscode_tool"
17
+ description: str = "Launches a VS Code Server instance for remote development."
18
+ need_validation: bool = True
19
+ arguments: list = [
20
+ ToolArgument(
21
+ name="workspace_path",
22
+ arg_type="string",
23
+ description="The path to the workspace directory to open in VS Code.",
24
+ required=True,
25
+ example="/path/to/workspace",
26
+ ),
27
+ ToolArgument(
28
+ name="auth",
29
+ arg_type="string",
30
+ description="Authentication mode for VS Code Server ('none' or 'password').",
31
+ required=False,
32
+ example="none",
33
+ default="none",
34
+ ),
35
+ ToolArgument(
36
+ name="port",
37
+ arg_type="int",
38
+ description="Port number for the VS Code Server.",
39
+ required=False,
40
+ example="8080",
41
+ default="8080",
42
+ ),
43
+ ]
44
+
45
+ def execute(
46
+ self,
47
+ workspace_path: str,
48
+ auth: str = "none",
49
+ port: Union[int, str] = 8080,
50
+ ) -> str:
51
+ """Launch a VS Code Server instance with the specified configuration.
52
+
53
+ Args:
54
+ workspace_path: Directory to open in VS Code
55
+ auth: Authentication mode ('none' or 'password')
56
+ port: Port number for the server
57
+
58
+ Returns:
59
+ Formatted string containing command output and status
60
+ """
61
+ try:
62
+ # Validate workspace path
63
+ workspace_path = os.path.abspath(workspace_path)
64
+ if not os.path.exists(workspace_path):
65
+ return f"Error: Workspace path does not exist: {workspace_path}"
66
+
67
+ # Build the command
68
+ command = [
69
+ "code-server",
70
+ f"--auth={auth}",
71
+ f"--port={port}",
72
+ workspace_path
73
+ ]
74
+
75
+ # Launch the server
76
+ process = subprocess.Popen(
77
+ command,
78
+ stdout=subprocess.PIPE,
79
+ stderr=subprocess.PIPE,
80
+ text=True,
81
+ encoding="utf-8"
82
+ )
83
+
84
+ # Wait briefly to check for immediate startup errors
85
+ try:
86
+ stdout, stderr = process.communicate(timeout=2)
87
+ if process.returncode is not None and process.returncode != 0:
88
+ return f"Failed to start VS Code Server: {stderr}"
89
+ except subprocess.TimeoutExpired:
90
+ # Process is still running (expected behavior)
91
+ pass
92
+
93
+ # Create URL with folder parameter
94
+ encoded_path = urllib.parse.quote(workspace_path)
95
+ url = f"http://localhost:{port}/?folder={encoded_path}"
96
+
97
+ # Return success message with connection details
98
+ return (
99
+ "<command_output>"
100
+ "<div style='background: #1e1e1e; border-radius: 8px; padding: 20px; margin: 10px 0; font-family: Arial, sans-serif;'>"
101
+ "<div style='color: #3fb950; margin-bottom: 15px;'>"
102
+ "✓ VS Code Server started successfully"
103
+ "</div>"
104
+ "<div style='background: #2d2d2d; padding: 15px; border-radius: 6px; border-left: 4px solid #58a6ff;'>"
105
+ "<div style='color: #8b949e; margin-bottom: 8px;'>Server URL:</div>"
106
+ f"<a href='{url}' style='color: #58a6ff; text-decoration: none; display: block; word-break: break-all;'>"
107
+ f"Display App builder"
108
+ "</a>"
109
+ "</div>"
110
+ "<div style='color: #8b949e; font-size: 0.9em; margin-top: 15px;'>"
111
+ "Click the link above to open VS Code in your browser"
112
+ "</div>"
113
+ "</div>"
114
+ "</command_output>"
115
+ )
116
+
117
+ except Exception as e:
118
+ logger.error(f"Error launching VS Code Server: {str(e)}")
119
+ return f"Unexpected error: {str(e)}"
120
+
121
+
122
+ if __name__ == "__main__":
123
+ tool = VSCodeServerTool()
@@ -1,12 +1,32 @@
1
- def console_ask_for_user_validation(question: str = "Do you want to continue?") -> bool:
2
- """Prompt the user for validation using Rich.
1
+ import asyncio
2
+
3
+ from rich.prompt import Confirm
3
4
 
4
- Args:
5
- question (str): The validation question.
6
5
 
6
+ async def console_ask_for_user_validation(question="Do you want to continue?", validation_id=None) -> bool:
7
+ """Prompt the user for validation using Rich (async version).
8
+
9
+ Args:
10
+ question: The validation question to ask
11
+ validation_id: Optional ID for tracking validation requests (not used in this implementation)
12
+
7
13
  Returns:
8
- bool: User's confirmation.
14
+ bool: True if the user validates, False otherwise.
9
15
  """
10
- from rich.prompt import Confirm
16
+ # Run the synchronous Rich prompt in a thread pool to avoid blocking
17
+ return await asyncio.to_thread(Confirm.ask, question, default=True)
18
+
11
19
 
20
+ def sync_console_ask_for_user_validation(question="Do you want to continue?", validation_id=None) -> bool:
21
+ """Synchronous wrapper for console_ask_for_user_validation.
22
+
23
+ This function allows for backward compatibility with code that isn't using async/await.
24
+
25
+ Args:
26
+ question: The validation question to ask
27
+ validation_id: Optional ID for tracking validation requests (not used in this implementation)
28
+
29
+ Returns:
30
+ bool: User's confirmation
31
+ """
12
32
  return Confirm.ask(question, default=True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quantalogic
3
- Version: 0.56.0
3
+ Version: 0.58.0
4
4
  Summary: QuantaLogic ReAct Agents
5
5
  Author: Raphaël MANSUY
6
6
  Author-email: raphael.mansuy@gmail.com
@@ -1,23 +1,26 @@
1
1
  quantalogic/__init__.py,sha256=qFbvfHOd_chAu536pH816E3uo6CdyAgXCpQOwMXXVnY,1076
2
- quantalogic/agent.py,sha256=8Zz0kzFcOVdZSQ2FraoWirk8dWrBCKILNGbF9oPXMpY,41163
2
+ quantalogic/agent.py,sha256=Jpi4sK9Lj0miMo51zoocCh0OW2bd_IzHgY-bWW5Ka5w,42062
3
3
  quantalogic/agent_config.py,sha256=fPyMfm77BzimyfyFkTzb2ZdyZtGlr2fq5aTRETu77Vs,8202
4
4
  quantalogic/agent_factory.py,sha256=LO0qsFtHxU7lcEi8dn-nDHhkh6Dl8Is6sP_3f1ap_Vg,6251
5
5
  quantalogic/coding_agent.py,sha256=A-firiPWQjMC56B329Ne606_v2GsoF5-nxcuz3rVbYM,5496
6
6
  quantalogic/config.py,sha256=lsJxfWFWEMqS2Asus8z4A3W7X8JWoMi3-VHxfltvSfA,423
7
7
  quantalogic/console_print_events.py,sha256=yDtfOr7s5r_gLTgwkl_XoKSkUqNRZhqqq4hwR_oJsUw,2050
8
8
  quantalogic/console_print_token.py,sha256=5IRVoPhwWZtSc4LpNoAsCQhCB_RnAW9chycGgyD3_5U,437
9
- quantalogic/create_custom_agent.py,sha256=1ZMsbpQGHFueJJpfJIuYCWvR3LUsEtDYqDbr6OcwlWw,20850
9
+ quantalogic/create_custom_agent.py,sha256=e-InULqXFFUOfgZ9TqgsVkDTZTpVCGOPS-5wx5VQedY,21474
10
10
  quantalogic/docs_cli.py,sha256=Ie6NwKQuxLKwVQ-cjhFMCttXeiHDjGhNY4hSmMtc0Qg,1664
11
11
  quantalogic/event_emitter.py,sha256=e_1r6hvx5GmW84iuRkoqcjpjRiYHBk4hzujd5ZoUC6U,16777
12
12
  quantalogic/flow/__init__.py,sha256=MD5FAdD6jnVnTPMIOmToKjFxHBQvLmOCT0VeaWhASBc,1295
13
- quantalogic/flow/flow.py,sha256=QC6U0MRjaAdViSfSGGOwcjYnsPB5FLzJfh7MfPGBrT4,37881
14
- quantalogic/flow/flow_extractor.py,sha256=GNmGOZH8zs4USHxCOURF0wiZtYqchZcscBX137DZuac,34275
15
- quantalogic/flow/flow_generator.py,sha256=6vBsl9wceJfCRKpib_SMl-QrMty3hYoH-IKpLgOEvO8,16041
16
- quantalogic/flow/flow_manager.py,sha256=WpwfpwkWDVr4KNDzG19gBveaqK2VQQjlqgEhnqOxGk0,28531
17
- quantalogic/flow/flow_manager_schema.py,sha256=MR-dw51NEGCDctGZDeJcH49Dpl4Ym0DCw7E7-t6qk10,9240
18
- quantalogic/flow/flow_mermaid.py,sha256=sl5ioOHop8AW5NZsOHLKb7juvieqXU_ZkdzSBSO_INs,16296
13
+ quantalogic/flow/flow.py,sha256=W2t30c0w939EqcMaJM473tL4ou1UtegiYcv7vdnkECA,42240
14
+ quantalogic/flow/flow_extractor.py,sha256=7v5orkfnuAmD_Xu8TeyfB1QM5I_IIXooWokHlCyLY-8,33925
15
+ quantalogic/flow/flow_generator.py,sha256=T0F90VX7B0wRoW3fUPCB8tdl3l7-Ph3Fg0SFNUIQ-ec,15812
16
+ quantalogic/flow/flow_manager.py,sha256=dWwf1X-GgHTtUYQ-mtE41ct-if7sOJck5vmTkkm5JyA,29402
17
+ quantalogic/flow/flow_manager_schema.py,sha256=5JjtNXK-j-QKdvKE2qCjPOgDssGH0cqGDZRoQ9xn8NY,10363
18
+ quantalogic/flow/flow_mermaid.py,sha256=TvQyobLK6Idg5q0rQH1Vr_XmuovwxbFKsdZaIxEJqwY,16242
19
19
  quantalogic/flow/flow_validator.py,sha256=6T4XUPjiHX_oKQVY_dXmRK8aICHnvQCKcyXAaomXtWY,23581
20
- quantalogic/flow/flow_yaml.md,sha256=9Oe5ZPlME4Gf-WZB8Vy5i_s7E5YCrU-zFhOdupBjTSM,25304
20
+ quantalogic/flow/flow_yaml.linkedin.md,sha256=OH1Hoij5ijRZqDju7aaP2GbbTvOcPotBlkaBMajc4UM,1040
21
+ quantalogic/flow/flow_yaml.md,sha256=NIf2MWsmfckVqCQmTLfyo__B_lHg7NcSRQEjCxf7Xg0,27321
22
+ quantalogic/flow/templates/prompt_check_inventory.j2,sha256=ecIZE9rpSubhKxSubQGVaQkQNsM9oMPW-WSkkn4q9VY,119
23
+ quantalogic/flow/templates/system_check_inventory.j2,sha256=FaLO9_MgoKmaVmvaK9pzHSLkrLPWtPQO_ISreSwgRg8,124
21
24
  quantalogic/generative_model.py,sha256=os30wdVRq3OsSf8M7TjoaGqJweL99UINQtSGCwoE91k,15913
22
25
  quantalogic/get_model_info.py,sha256=RgblwjjP7G97v_AzoGbXxXBIO082jVCRmvRwxnEpW_s,2991
23
26
  quantalogic/interactive_text_editor.py,sha256=CzefvRiLscFfOKBS4gmrI10Gn3SF_eS5zbiLVQ9Gugw,16334
@@ -39,7 +42,7 @@ quantalogic/prompts.py,sha256=bSaODtMUhPeIMt4BsOdjA6-9Efadu8LH6msdGnbLvxE,1112
39
42
  quantalogic/quantlitellm.py,sha256=nf-awyOxP0ANoAPGHNvHfdLu8gNn65L39gl7x4saIQc,5550
40
43
  quantalogic/search_agent.py,sha256=tr0cwscJ4wu_G1aumjFyvGHQ0eQv5OL5sxj17s6Ocls,2470
41
44
  quantalogic/server/__init__.py,sha256=8sz_PYAUCrkM6JM5EAUeIzNM4NPW6j6UT72JVkc21WQ,91
42
- quantalogic/server/agent_server.py,sha256=VXaaWqReUSZOCX7CaKS14jria8yZn1kLEc52E2hV7ZA,22510
45
+ quantalogic/server/agent_server.py,sha256=1u5rpiCNAssi7_9KMBlBlyHz7abHodcyt2seGTtyNDo,22949
43
46
  quantalogic/server/models.py,sha256=_j6dAx3L_w0kiP55vcC5uykJJRfChV2K3uL_xAPnsms,1447
44
47
  quantalogic/server/routes.py,sha256=00nFe6s0T4Gv8vCp0wQFjWGo1tC8FViH8h0koAJdWs4,4216
45
48
  quantalogic/server/state.py,sha256=TwtL0BTp_LT-fynF1IR4k8WVXuxXWtSv3NgWG9fuUME,7369
@@ -84,7 +87,7 @@ quantalogic/tools/git/bitbucket_operations_tool.py,sha256=6Vdelau1VSTYREtuQgHlV-
84
87
  quantalogic/tools/git/clone_repo_tool.py,sha256=FA_29pmEsy_71YSrt94M0rAUNt_rEo4TDvq2Y7-uinU,7565
85
88
  quantalogic/tools/git/git_operations_tool.py,sha256=tZqY7fXXfiLkArV_18pEmqreqF6n6BALo0jFy4Hjzfs,20610
86
89
  quantalogic/tools/google_packages/__init__.py,sha256=BIf2t1oJQTCfbh7qZZAzQGIHVQyWiZQ559OwmYrG1A0,452
87
- quantalogic/tools/google_packages/google_news_tool.py,sha256=BdrSlBxCZ1PfWIKzl7_aqvkoV2wVkBH3T2g3X2VBvVQ,17443
90
+ quantalogic/tools/google_packages/google_news_tool.py,sha256=q9ztwUdF2phcSMAceoIIBJXMjVxwCvbFdxNF3xjkAxM,11730
88
91
  quantalogic/tools/grep_app_tool.py,sha256=qAKgqMTtoH82bEZkiNlIk5oDSgVckFgxVXhU7ieTJwc,18672
89
92
  quantalogic/tools/image_generation/__init__.py,sha256=7_ckDTy0ZHW34S9ZIQJqeRCZisdBbAtH-1CLO-8_yUI,455
90
93
  quantalogic/tools/image_generation/dalle_e.py,sha256=SYvKZ1VbdslIKUKBy3nC0jD680-ujabBQr6iK5IFAXY,10968
@@ -134,17 +137,18 @@ quantalogic/tools/sql_query_tool.py,sha256=jEDZLlxOsB2bzsWlEqsqvTKiyovnRuk0Xvgtw
134
137
  quantalogic/tools/task_complete_tool.py,sha256=L8tuyVoN07Q2hOsxx17JTW0C5Jd_N-C0i_0PtCUQUKU,929
135
138
  quantalogic/tools/tool.py,sha256=FLF4Y1nqjArVUYakD0w3WcDxkRJkbSBQzTG6Sp72Z4Q,15592
136
139
  quantalogic/tools/unified_diff_tool.py,sha256=o7OiYnCM5MjbPlQTpB2OmkMQRI9zjdToQmgVkhiTvOI,14148
137
- quantalogic/tools/utilities/__init__.py,sha256=M54fNYmXlTzG-nTnBVQamxSCuu8X4WzRM4bQQ-NvIC4,606
140
+ quantalogic/tools/utilities/__init__.py,sha256=Ra61ITv4SNmMFcj5CLEkAZW9Vl9uv8Mi2qI_kr2psfo,672
138
141
  quantalogic/tools/utilities/csv_processor_tool.py,sha256=Mu_EPVj6iYAclNaVX_vbkekxcNwPYwy7dW1SCY22EwY,9023
139
- quantalogic/tools/utilities/download_file_tool.py,sha256=hw_tO6RD0tA_LH46Tathf-LzSxRl7kgEiiP76rTGdds,6616
142
+ quantalogic/tools/utilities/download_file_tool.py,sha256=x60wpFeMMHmcipgrMnS04l7OnQd3C8MPNyB9Oar7h8Y,6681
140
143
  quantalogic/tools/utilities/mermaid_validator_tool.py,sha256=Brd6pt8OxpUgf8dm6kHqJJs_IU8V4Kc-8VDP-n1eCUM,25886
144
+ quantalogic/tools/utilities/vscode_tool.py,sha256=RNDUtWxutlJ_cATgFM-oMSsGKipwhQ-PJDluJ1yxggs,4362
141
145
  quantalogic/tools/utils/__init__.py,sha256=-NtMSwxRt_G79Oo_DcDaCdLU2vLvuXIoCd34TOYEUmI,334
142
146
  quantalogic/tools/utils/create_sample_database.py,sha256=h5c_uxv3eztQvHlloTZxzWt5gEzai8zfnR8-_QrUqxU,3724
143
147
  quantalogic/tools/utils/generate_database_report.py,sha256=3PT34ClMvZ2O62-24cp_5lOyZHY_pBjVObMHpfyVi-s,10140
144
148
  quantalogic/tools/wikipedia_search_tool.py,sha256=LXQSPH8961Efw2QNxKe-cD5ZiIYD3ufEgrxH4y5uB74,5180
145
149
  quantalogic/tools/write_file_tool.py,sha256=_mx9_Zjg2oMAAVzlcHEKjZVZUxQVgbRfcoMKgWnoZcg,3764
146
150
  quantalogic/utils/__init__.py,sha256=hsS3hXH5lsBQcZh2QBANY1Af2Zs1jtrgxA7kXJEWi58,680
147
- quantalogic/utils/ask_user_validation.py,sha256=gG6iv5996KRJK16JUQiEsY5JgSnLoZ7vmi6f5DXI7Ho,339
151
+ quantalogic/utils/ask_user_validation.py,sha256=kSr7TXPTpsLR9zgwpGWgvffx8-cKAC_rdFRdLqwC22A,1176
148
152
  quantalogic/utils/async_utils.py,sha256=FOizWRbHdsZwoD36dNErzunfwPlE7zDprS6RXcWuWSo,963
149
153
  quantalogic/utils/check_version.py,sha256=aDTEvIn5XNNBIQ0tVOqcY3hcoznRmpsnNuwES6je1MQ,1133
150
154
  quantalogic/utils/download_http_file.py,sha256=FTN3brq9WvCFvuBX-lYAhjsdYTzQT4m9m2vqlcyjkNk,3472
@@ -163,8 +167,8 @@ quantalogic/version_check.py,sha256=JyQFTNMDWtpHCLnN-BiakzB2cyXf6kUFsTjvmSruZi4,
163
167
  quantalogic/welcome_message.py,sha256=o4tHdgabNuIV9kbIDPgS3_2yzJhayK30oKad2UouYDc,3020
164
168
  quantalogic/xml_parser.py,sha256=bLLwIwO-VEHWF3heNS7nuPC8wgdYw9F_fVZZNW1figY,11728
165
169
  quantalogic/xml_tool_parser.py,sha256=hGHA1q20JUoTNTbZYmi4FTdA5I25-AGEIP8DwZgQCNA,3897
166
- quantalogic-0.56.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
167
- quantalogic-0.56.0.dist-info/METADATA,sha256=N1WD5PThI7ECEe0p8sxzj4n5nK0G7dFhsCxRnptflXo,28783
168
- quantalogic-0.56.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
169
- quantalogic-0.56.0.dist-info/entry_points.txt,sha256=h74O_Q3qBRCrDR99qvwB4BpBGzASPUIjCfxHq6Qnups,183
170
- quantalogic-0.56.0.dist-info/RECORD,,
170
+ quantalogic-0.58.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
171
+ quantalogic-0.58.0.dist-info/METADATA,sha256=A4AY49m3p5CSFQEBxmV57Spp1EsTsyno9zTQOL5Yqd8,28783
172
+ quantalogic-0.58.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
173
+ quantalogic-0.58.0.dist-info/entry_points.txt,sha256=h74O_Q3qBRCrDR99qvwB4BpBGzASPUIjCfxHq6Qnups,183
174
+ quantalogic-0.58.0.dist-info/RECORD,,