quantalogic 0.51.0__py3-none-any.whl → 0.52.1__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 +1 -1
- quantalogic/flow/__init__.py +17 -0
- quantalogic/flow/flow_extractor.py +32 -103
- quantalogic/flow/flow_generator.py +6 -2
- quantalogic/flow/flow_manager.py +33 -24
- quantalogic/flow/flow_manager_schema.py +2 -3
- quantalogic/flow/flow_mermaid.py +240 -0
- quantalogic/flow/flow_validator.py +335 -0
- quantalogic/flow/flow_yaml.md +313 -329
- quantalogic/tools/__init__.py +3 -2
- quantalogic/tools/tool.py +129 -3
- {quantalogic-0.51.0.dist-info → quantalogic-0.52.1.dist-info}/METADATA +89 -2
- {quantalogic-0.51.0.dist-info → quantalogic-0.52.1.dist-info}/RECORD +16 -14
- {quantalogic-0.51.0.dist-info → quantalogic-0.52.1.dist-info}/LICENSE +0 -0
- {quantalogic-0.51.0.dist-info → quantalogic-0.52.1.dist-info}/WHEEL +0 -0
- {quantalogic-0.51.0.dist-info → quantalogic-0.52.1.dist-info}/entry_points.txt +0 -0
quantalogic/tools/__init__.py
CHANGED
@@ -28,7 +28,7 @@ from .sequence_tool import SequenceTool
|
|
28
28
|
from .serpapi_search_tool import SerpApiSearchTool
|
29
29
|
from .sql_query_tool import SQLQueryTool
|
30
30
|
from .task_complete_tool import TaskCompleteTool
|
31
|
-
from .tool import Tool, ToolArgument
|
31
|
+
from .tool import Tool, ToolArgument, create_tool
|
32
32
|
from .unified_diff_tool import UnifiedDiffTool
|
33
33
|
from .wikipedia_search_tool import WikipediaSearchTool
|
34
34
|
from .write_file_tool import WriteFileTool
|
@@ -65,5 +65,6 @@ __all__ = [
|
|
65
65
|
'ToolArgument',
|
66
66
|
'UnifiedDiffTool',
|
67
67
|
'WikipediaSearchTool',
|
68
|
-
'WriteFileTool'
|
68
|
+
'WriteFileTool',
|
69
|
+
"create_tool"
|
69
70
|
]
|
quantalogic/tools/tool.py
CHANGED
@@ -4,11 +4,16 @@ This module provides base classes and data models for creating configurable tool
|
|
4
4
|
with type-validated arguments and execution methods.
|
5
5
|
"""
|
6
6
|
|
7
|
+
import ast
|
7
8
|
import asyncio # Added for asynchronous support
|
8
|
-
|
9
|
+
import inspect
|
10
|
+
from typing import Any, Callable, Literal, TypeVar
|
9
11
|
|
12
|
+
from docstring_parser import parse as parse_docstring
|
10
13
|
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
11
14
|
|
15
|
+
# Type variable for create_tool to preserve function signature
|
16
|
+
F = TypeVar('F', bound=Callable[..., Any])
|
12
17
|
|
13
18
|
class ToolArgument(BaseModel):
|
14
19
|
"""Represents an argument for a tool with validation and description.
|
@@ -204,7 +209,7 @@ class Tool(ToolDefinition):
|
|
204
209
|
]
|
205
210
|
return []
|
206
211
|
|
207
|
-
def execute(self, **kwargs) -> str:
|
212
|
+
def execute(self, **kwargs: Any) -> str:
|
208
213
|
"""Execute the tool with provided arguments.
|
209
214
|
|
210
215
|
If not implemented by a subclass, falls back to the asynchronous execute_async method.
|
@@ -221,7 +226,7 @@ class Tool(ToolDefinition):
|
|
221
226
|
return asyncio.run(self.async_execute(**kwargs))
|
222
227
|
raise NotImplementedError("This method should be implemented by subclasses.")
|
223
228
|
|
224
|
-
async def async_execute(self, **kwargs) -> str:
|
229
|
+
async def async_execute(self, **kwargs: Any) -> str:
|
225
230
|
"""Asynchronous version of execute.
|
226
231
|
|
227
232
|
By default, runs the synchronous execute method in a separate thread using asyncio.to_thread.
|
@@ -253,6 +258,96 @@ class Tool(ToolDefinition):
|
|
253
258
|
return {name: value for name, value in properties.items() if value is not None and name in argument_names}
|
254
259
|
|
255
260
|
|
261
|
+
def create_tool(func: F) -> Tool:
|
262
|
+
"""Create a Tool instance from a Python function using AST analysis.
|
263
|
+
|
264
|
+
Analyzes the function's source code to extract its name, docstring, and arguments,
|
265
|
+
then constructs a Tool subclass with appropriate execution logic.
|
266
|
+
|
267
|
+
Args:
|
268
|
+
func: The Python function (sync or async) to convert into a Tool.
|
269
|
+
|
270
|
+
Returns:
|
271
|
+
A Tool subclass instance configured based on the function.
|
272
|
+
|
273
|
+
Raises:
|
274
|
+
ValueError: If the input is not a valid function or lacks a function definition.
|
275
|
+
"""
|
276
|
+
if not callable(func):
|
277
|
+
raise ValueError("Input must be a callable function")
|
278
|
+
|
279
|
+
# Get source code and parse with AST
|
280
|
+
try:
|
281
|
+
source = inspect.getsource(func).strip()
|
282
|
+
tree = ast.parse(source)
|
283
|
+
except (OSError, TypeError, SyntaxError) as e:
|
284
|
+
raise ValueError(f"Failed to parse function source: {e}")
|
285
|
+
|
286
|
+
# Ensure root node is a function definition
|
287
|
+
if not tree.body or not isinstance(tree.body[0], (ast.FunctionDef, ast.AsyncFunctionDef)):
|
288
|
+
raise ValueError("Source must define a single function")
|
289
|
+
func_def = tree.body[0]
|
290
|
+
|
291
|
+
# Extract metadata
|
292
|
+
name = func_def.name
|
293
|
+
docstring = ast.get_docstring(func_def) or ""
|
294
|
+
parsed_doc = parse_docstring(docstring)
|
295
|
+
description = parsed_doc.short_description or f"Tool generated from {name}"
|
296
|
+
param_docs = {p.arg_name: p.description for p in parsed_doc.params}
|
297
|
+
is_async = isinstance(func_def, ast.AsyncFunctionDef)
|
298
|
+
|
299
|
+
# Get type hints using typing module
|
300
|
+
from typing import get_type_hints
|
301
|
+
type_hints = get_type_hints(func)
|
302
|
+
type_map = {int: "int", str: "string", float: "float", bool: "boolean"}
|
303
|
+
|
304
|
+
# Process arguments
|
305
|
+
args = func_def.args
|
306
|
+
defaults = [None] * (len(args.args) - len(args.defaults)) + [
|
307
|
+
ast.unparse(d) if isinstance(d, ast.AST) else str(d) for d in args.defaults
|
308
|
+
]
|
309
|
+
arguments: list[ToolArgument] = []
|
310
|
+
|
311
|
+
for i, arg in enumerate(args.args):
|
312
|
+
arg_name = arg.arg
|
313
|
+
default = defaults[i]
|
314
|
+
required = default is None
|
315
|
+
|
316
|
+
# Determine argument type
|
317
|
+
hint = type_hints.get(arg_name, str) # Default to str if no hint
|
318
|
+
arg_type = type_map.get(hint, "string") # Fallback to string for unmapped types
|
319
|
+
|
320
|
+
# Use docstring or default description
|
321
|
+
description = param_docs.get(arg_name, f"Argument {arg_name}")
|
322
|
+
|
323
|
+
# Create ToolArgument
|
324
|
+
arguments.append(ToolArgument(
|
325
|
+
name=arg_name,
|
326
|
+
arg_type=arg_type,
|
327
|
+
description=description,
|
328
|
+
required=required,
|
329
|
+
default=default,
|
330
|
+
example=default if default else None
|
331
|
+
))
|
332
|
+
|
333
|
+
# Define Tool subclass
|
334
|
+
class GeneratedTool(Tool):
|
335
|
+
def __init__(self, *args: Any, **kwargs: Any):
|
336
|
+
super().__init__(*args, name=name, description=description, arguments=arguments, **kwargs)
|
337
|
+
self._func = func
|
338
|
+
|
339
|
+
if is_async:
|
340
|
+
async def async_execute(self, **kwargs: Any) -> str:
|
341
|
+
result = await self._func(**kwargs)
|
342
|
+
return str(result)
|
343
|
+
else:
|
344
|
+
def execute(self, **kwargs: Any) -> str:
|
345
|
+
result = self._func(**kwargs)
|
346
|
+
return str(result)
|
347
|
+
|
348
|
+
return GeneratedTool()
|
349
|
+
|
350
|
+
|
256
351
|
if __name__ == "__main__":
|
257
352
|
tool = Tool(name="my_tool", description="A simple tool", arguments=[ToolArgument(name="arg1", arg_type="string")])
|
258
353
|
print(tool.to_markdown())
|
@@ -274,3 +369,34 @@ if __name__ == "__main__":
|
|
274
369
|
)
|
275
370
|
print(tool_with_fields_defined.to_markdown())
|
276
371
|
print(tool_with_fields_defined.get_injectable_properties_in_execution())
|
372
|
+
|
373
|
+
# Test create_tool with synchronous function
|
374
|
+
def add(a: int, b: int = 0) -> int:
|
375
|
+
"""Add two numbers.
|
376
|
+
|
377
|
+
Args:
|
378
|
+
a: First number.
|
379
|
+
b: Second number (optional).
|
380
|
+
"""
|
381
|
+
return a + b
|
382
|
+
|
383
|
+
# Test create_tool with asynchronous function
|
384
|
+
async def greet(name: str) -> str:
|
385
|
+
"""Greet a person.
|
386
|
+
|
387
|
+
Args:
|
388
|
+
name: Name of the person.
|
389
|
+
"""
|
390
|
+
await asyncio.sleep(0.1) # Simulate async work
|
391
|
+
return f"Hello, {name}"
|
392
|
+
|
393
|
+
# Create and test tools
|
394
|
+
sync_tool = create_tool(add)
|
395
|
+
print("\nSynchronous Tool:")
|
396
|
+
print(sync_tool.to_markdown())
|
397
|
+
print("Execution result:", sync_tool.execute(a=5, b=3))
|
398
|
+
|
399
|
+
async_tool = create_tool(greet)
|
400
|
+
print("\nAsynchronous Tool:")
|
401
|
+
print(async_tool.to_markdown())
|
402
|
+
print("Execution result:", asyncio.run(async_tool.async_execute(name="Alice")))
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: quantalogic
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.52.1
|
4
4
|
Summary: QuantaLogic ReAct Agents
|
5
5
|
Author: Raphaël MANSUY
|
6
6
|
Author-email: raphael.mansuy@gmail.com
|
@@ -88,6 +88,8 @@ At [QuantaLogic](https://www.quantalogic.app), we spotted a black hole: amazing
|
|
88
88
|
- [Quick Start](#quick-start)
|
89
89
|
- [ReAct Framework: Dynamic Agents](#react-framework-dynamic-agents)
|
90
90
|
- [Flow Module: Structured Workflows](#flow-module-structured-workflows)
|
91
|
+
- 📘 **[Workflow YAML DSL Specification](./quantalogic/flow/flow_yaml.md)**: Comprehensive guide to defining powerful, structured workflows using our Domain-Specific Language
|
92
|
+
- 📚 **[Flow YAML Documentation](https://quantalogic.github.io/quantalogic/flow/flow_yaml)**: Dive into the official documentation for a deeper understanding of Flow YAML and its applications
|
91
93
|
- [ReAct vs. Flow: Pick Your Power](#react-vs-flow-pick-your-power)
|
92
94
|
- [Using the CLI](#using-the-cli)
|
93
95
|
- [Examples That Spark Joy](#examples-that-spark-joy)
|
@@ -357,7 +359,15 @@ Perfect for coding, debugging, or answering wild questions on the fly.
|
|
357
359
|
|
358
360
|
## Flow Module: Structured Workflows
|
359
361
|
|
360
|
-
The **Flow module** is your architect—building workflows that hum with precision. It
|
362
|
+
The **Flow module** is your architect—building workflows that hum with precision. It's all about nodes, transitions, and a steady rhythm, ideal for repeatable missions.
|
363
|
+
|
364
|
+
🔍 **Want to dive deeper?** Check out our comprehensive [Workflow YAML DSL Specification](./quantalogic/flow/flow_yaml.md), a detailed guide that walks you through defining powerful, structured workflows. From basic node configurations to complex transition logic, this documentation is your roadmap to mastering workflow design with QuantaLogic.
|
365
|
+
|
366
|
+
📚 **For a deeper understanding of Flow YAML and its applications, please refer to the official [Flow YAML Documentation](https://quantalogic.github.io/quantalogic/flow/flow_yaml).**
|
367
|
+
|
368
|
+
The Flow YAML documentation provides a comprehensive overview of the Flow YAML language, including its syntax, features, and best practices. It's a valuable resource for anyone looking to create complex workflows with QuantaLogic.
|
369
|
+
|
370
|
+
Additionally, the Flow YAML documentation includes a number of examples and tutorials to help you get started with creating your own workflows. These examples cover a range of topics, from simple workflows to more complex scenarios, and are designed to help you understand how to use Flow YAML to create powerful and flexible workflows.
|
361
371
|
|
362
372
|
### The Building Blocks
|
363
373
|
- **Nodes**: Tasks like functions or LLM calls.
|
@@ -629,6 +639,83 @@ mypy quantalogic # Check types
|
|
629
639
|
ruff check quantalogic # Lint it
|
630
640
|
```
|
631
641
|
|
642
|
+
### Create Custom Tools
|
643
|
+
The `create_tool()` function transforms any Python function into a reusable Tool:
|
644
|
+
|
645
|
+
```python
|
646
|
+
from quantalogic.tools import create_tool
|
647
|
+
|
648
|
+
def weather_lookup(city: str, country: str = "US") -> dict:
|
649
|
+
"""Retrieve current weather for a given location.
|
650
|
+
|
651
|
+
Args:
|
652
|
+
city: Name of the city to look up
|
653
|
+
country: Two-letter country code (default: US)
|
654
|
+
|
655
|
+
Returns:
|
656
|
+
Dictionary with weather information
|
657
|
+
"""
|
658
|
+
# Implement weather lookup logic here
|
659
|
+
return {"temperature": 22, "condition": "Sunny"}
|
660
|
+
|
661
|
+
# Convert the function to a Tool
|
662
|
+
weather_tool = create_tool(weather_lookup)
|
663
|
+
|
664
|
+
# Now you can use it as a Tool
|
665
|
+
print(weather_tool.to_markdown()) # Generate tool documentation
|
666
|
+
result = weather_tool.execute(city="New York") # Execute as a tool
|
667
|
+
```
|
668
|
+
|
669
|
+
#### Using Custom Tools with ReAct Agent
|
670
|
+
|
671
|
+
Here's how to integrate custom tools with a ReAct Agent:
|
672
|
+
|
673
|
+
```python
|
674
|
+
from quantalogic import Agent
|
675
|
+
from quantalogic.tools import create_tool, PythonTool
|
676
|
+
|
677
|
+
# Create a custom stock price lookup tool
|
678
|
+
def get_stock_price(symbol: str) -> str:
|
679
|
+
"""Get the current price of a stock by its ticker symbol.
|
680
|
+
|
681
|
+
Args:
|
682
|
+
symbol: Stock ticker symbol (e.g., AAPL, MSFT)
|
683
|
+
|
684
|
+
Returns:
|
685
|
+
Current stock price information
|
686
|
+
"""
|
687
|
+
# In a real implementation, you would fetch from an API
|
688
|
+
prices = {"AAPL": 185.92, "MSFT": 425.27, "GOOGL": 175.43}
|
689
|
+
if symbol in prices:
|
690
|
+
return f"{symbol} is currently trading at ${prices[symbol]}"
|
691
|
+
return f"Could not find price for {symbol}"
|
692
|
+
|
693
|
+
# Create an agent with standard and custom tools
|
694
|
+
agent = Agent(
|
695
|
+
model_name="gpt-4o",
|
696
|
+
tools=[
|
697
|
+
PythonTool(), # Standard Python execution tool
|
698
|
+
create_tool(get_stock_price) # Custom stock price tool
|
699
|
+
]
|
700
|
+
)
|
701
|
+
|
702
|
+
# The agent can now use both tools to solve tasks
|
703
|
+
result = agent.solve_task(
|
704
|
+
"Write a Python function to calculate investment growth, "
|
705
|
+
"then analyze Apple stock's current price"
|
706
|
+
)
|
707
|
+
|
708
|
+
print(result)
|
709
|
+
```
|
710
|
+
|
711
|
+
In this example, the agent can seamlessly use both the standard `PythonTool` and your custom stock price lookup tool to complete the task.
|
712
|
+
|
713
|
+
Key features of `create_tool()`:
|
714
|
+
- 🔧 Automatically converts functions to Tools
|
715
|
+
- 📝 Extracts metadata from function signature and docstring
|
716
|
+
- 🔍 Supports both synchronous and asynchronous functions
|
717
|
+
- 🛠️ Generates tool documentation and validation
|
718
|
+
|
632
719
|
---
|
633
720
|
|
634
721
|
## Contributing
|
@@ -1,5 +1,5 @@
|
|
1
1
|
quantalogic/__init__.py,sha256=BcM0DKB86DijMFtht9YTBdWyzh81zU7E5fhNLFiP260,869
|
2
|
-
quantalogic/agent.py,sha256=
|
2
|
+
quantalogic/agent.py,sha256=8Zz0kzFcOVdZSQ2FraoWirk8dWrBCKILNGbF9oPXMpY,41163
|
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
|
@@ -9,13 +9,15 @@ quantalogic/console_print_token.py,sha256=5IRVoPhwWZtSc4LpNoAsCQhCB_RnAW9chycGgy
|
|
9
9
|
quantalogic/create_custom_agent.py,sha256=1ZMsbpQGHFueJJpfJIuYCWvR3LUsEtDYqDbr6OcwlWw,20850
|
10
10
|
quantalogic/docs_cli.py,sha256=Ie6NwKQuxLKwVQ-cjhFMCttXeiHDjGhNY4hSmMtc0Qg,1664
|
11
11
|
quantalogic/event_emitter.py,sha256=e_1r6hvx5GmW84iuRkoqcjpjRiYHBk4hzujd5ZoUC6U,16777
|
12
|
-
quantalogic/flow/__init__.py,sha256=
|
12
|
+
quantalogic/flow/__init__.py,sha256=MD5FAdD6jnVnTPMIOmToKjFxHBQvLmOCT0VeaWhASBc,1295
|
13
13
|
quantalogic/flow/flow.py,sha256=P4T6N6IDOHA5OKqoNjLIZ9BQ9Vk8LwhrqcYjz3wjMB8,25297
|
14
|
-
quantalogic/flow/flow_extractor.py,sha256=
|
15
|
-
quantalogic/flow/flow_generator.py,sha256=
|
16
|
-
quantalogic/flow/flow_manager.py,sha256=
|
17
|
-
quantalogic/flow/flow_manager_schema.py,sha256=
|
18
|
-
quantalogic/flow/
|
14
|
+
quantalogic/flow/flow_extractor.py,sha256=tkhisbnEhXXGk996tVU9_QNgB1rAW7z7yKtWxXG_G5Y,26804
|
15
|
+
quantalogic/flow/flow_generator.py,sha256=FMEVVXOt3Q6PpTjcA3zO87IGgtvGIWaQEDfEZKMQ_xw,4219
|
16
|
+
quantalogic/flow/flow_manager.py,sha256=2-HzQCzNGbrP4aMRCg3c1kvT9KBLfU470G-WhYfKWeo,20976
|
17
|
+
quantalogic/flow/flow_manager_schema.py,sha256=07lAiefER0aWEA2tkBkWT7iEX9EOLRwP81m5UMahiQk,7249
|
18
|
+
quantalogic/flow/flow_mermaid.py,sha256=iehCtKYP7mrVDjKewD2f_XUzxJK7xfan1ynSpuMrexw,10305
|
19
|
+
quantalogic/flow/flow_validator.py,sha256=rawAfus7WMKt9Jfw1OD3qsB1CkCXDHU2cJl_gvSUgPs,15561
|
20
|
+
quantalogic/flow/flow_yaml.md,sha256=J779AkqI2cfn0cb2rNmICnSW38RtK5UcpOnn6AAeOMY,15195
|
19
21
|
quantalogic/generative_model.py,sha256=os30wdVRq3OsSf8M7TjoaGqJweL99UINQtSGCwoE91k,15913
|
20
22
|
quantalogic/get_model_info.py,sha256=RgblwjjP7G97v_AzoGbXxXBIO082jVCRmvRwxnEpW_s,2991
|
21
23
|
quantalogic/interactive_text_editor.py,sha256=CzefvRiLscFfOKBS4gmrI10Gn3SF_eS5zbiLVQ9Gugw,16334
|
@@ -47,7 +49,7 @@ quantalogic/server/templates/index.html,sha256=nDnXJoQEm1vXbhXtgaYk0G5VXj0wwzE6K
|
|
47
49
|
quantalogic/task_file_reader.py,sha256=oPcB4vTxJ__Y8o7VVABIPOkVw3tGDMdQYwdK27PERlE,1440
|
48
50
|
quantalogic/task_runner.py,sha256=c2QVGKZfHA0wZIBUvehpjMvtRaKZuhuYQerjIiCC9iY,10053
|
49
51
|
quantalogic/tool_manager.py,sha256=vNA7aBKgdU3wpw_goom6i9rg_64pNZapNxvg4cUhhCI,6983
|
50
|
-
quantalogic/tools/__init__.py,sha256=
|
52
|
+
quantalogic/tools/__init__.py,sha256=lpfUu6S61dr4WYW4izUkpob7s5NLhkmmR5Zdi9iYrIc,2274
|
51
53
|
quantalogic/tools/agent_tool.py,sha256=MXCXxWHRch7VK4UWhtRP1jeI8Np9Ne2CUGo8vm1oZiM,3064
|
52
54
|
quantalogic/tools/composio/__init__.py,sha256=Yo9ygNx0qQILVhIfRgqpO8fgnCgp5WoZMd3Hm5D20GY,429
|
53
55
|
quantalogic/tools/composio/composio.py,sha256=icVHA_Scr1pViBhahGGBGBRBl9JSB3hGSqpgQzAIUH8,17627
|
@@ -130,7 +132,7 @@ quantalogic/tools/sequence_tool.py,sha256=Hb2FSjWWACvXZX7rmJXPk5lnnnqaDeRTbhQQRt
|
|
130
132
|
quantalogic/tools/serpapi_search_tool.py,sha256=sX-Noch77kGP2XiwislPNFyy3_4TH6TwMK6C81L3q9Y,5316
|
131
133
|
quantalogic/tools/sql_query_tool.py,sha256=jEDZLlxOsB2bzsWlEqsqvTKiyovnRuk0XvgtwW7-WSQ,6055
|
132
134
|
quantalogic/tools/task_complete_tool.py,sha256=L8tuyVoN07Q2hOsxx17JTW0C5Jd_N-C0i_0PtCUQUKU,929
|
133
|
-
quantalogic/tools/tool.py,sha256=
|
135
|
+
quantalogic/tools/tool.py,sha256=FLF4Y1nqjArVUYakD0w3WcDxkRJkbSBQzTG6Sp72Z4Q,15592
|
134
136
|
quantalogic/tools/unified_diff_tool.py,sha256=o7OiYnCM5MjbPlQTpB2OmkMQRI9zjdToQmgVkhiTvOI,14148
|
135
137
|
quantalogic/tools/utilities/__init__.py,sha256=M54fNYmXlTzG-nTnBVQamxSCuu8X4WzRM4bQQ-NvIC4,606
|
136
138
|
quantalogic/tools/utilities/csv_processor_tool.py,sha256=Mu_EPVj6iYAclNaVX_vbkekxcNwPYwy7dW1SCY22EwY,9023
|
@@ -161,8 +163,8 @@ quantalogic/version_check.py,sha256=JyQFTNMDWtpHCLnN-BiakzB2cyXf6kUFsTjvmSruZi4,
|
|
161
163
|
quantalogic/welcome_message.py,sha256=o4tHdgabNuIV9kbIDPgS3_2yzJhayK30oKad2UouYDc,3020
|
162
164
|
quantalogic/xml_parser.py,sha256=AKuMdJC3QAX3Z_tErHVlZ-msjPemWaZUFiTwkHz76jg,11614
|
163
165
|
quantalogic/xml_tool_parser.py,sha256=Vz4LEgDbelJynD1siLOVkJ3gLlfHsUk65_gCwbYJyGc,3784
|
164
|
-
quantalogic-0.
|
165
|
-
quantalogic-0.
|
166
|
-
quantalogic-0.
|
167
|
-
quantalogic-0.
|
168
|
-
quantalogic-0.
|
166
|
+
quantalogic-0.52.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
167
|
+
quantalogic-0.52.1.dist-info/METADATA,sha256=XHeG9nuaPvNZ92KXj83W05hKR-62MKZIs88JiHqtx5E,28120
|
168
|
+
quantalogic-0.52.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
169
|
+
quantalogic-0.52.1.dist-info/entry_points.txt,sha256=h74O_Q3qBRCrDR99qvwB4BpBGzASPUIjCfxHq6Qnups,183
|
170
|
+
quantalogic-0.52.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|