Metadata-Version: 2.4
Name: autourgos-core
Version: 1.0.1
Summary: Core tool system for the Autourgos agentic AI framework — Tool class, @tool decorator, and schema generation.
Author-email: Jitin Kumar Sengar <autourgoskit@gmail.com>
Maintainer: Sonia & Om
License: MIT
Project-URL: Homepage, https://github.com/autourgoskit
Project-URL: Repository, https://github.com/autourgoskit
Project-URL: Linkedin, https://www.linkedin.com/in/devxjitin/
Keywords: agents,ai,autourgos,llm
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: pydantic>=2.0.0

<div align="center">

# Tools System

![version](https://img.shields.io/badge/version-1.0.0-c96bff?style=for-the-badge) ![python](https://img.shields.io/badge/python-3.10%2B-1f6feb?style=for-the-badge) ![license](https://img.shields.io/badge/license-MIT-1b7f5a?style=for-the-badge) ![focus](https://img.shields.io/badge/focus-agentic%20AI-111827?style=for-the-badge)

</div>

---

In Autourgos, a **Tool** is a capability that you give to your local agent. Tools let your agent interact with the local filesystem, run terminal scripts, or call APIs.

The Autourgos tool system is fully compatible with standard LangChain tool interfaces. There are three main ways to define tools:
1. **The `@tool` Decorator** (simplest, auto-generates schema from function signature)
2. **Subclassing `BaseTool`** (best for complex or stateful tools)
3. **Using `StructuredTool.from_function`** (best for explicit schema mapping)

---

## The `@tool` Decorator

This is the easiest way to create a tool. You simply write a standard Python function and decorate it with `@tool`.

Autourgos automatically reads the function name, arguments, type hints, and docstrings to create the strict Pydantic argument schemas needed by the local LLM.

```python
from autourgos.core import tool

@tool
def calculate_area(width: float, height: float) -> float:
"""Calculate the area of a rectangle.

Args:
width: The width of the rectangle in meters.
height: The height of the rectangle in meters.
"""
return width * height
```

> [!NOTE]
> Always write clear docstrings and precise Python type hints. The local agent uses your docstrings and type hints to understand when to call the tool and what parameters to pass.

### Parameterized Decorator (`@tool(...)`)

For greater customization, the `@tool` decorator accepts explicit keyword parameters. You can supply custom values for `name` and `description` rather than relying on automatic function signature and docstring parsing.

It also supports advanced parameters:
- **`name`**: An explicit string name exposed to the local LLM.
- **`description`**: An explicit string description explaining the tool's purpose.
- **`return_direct`**: Set to `True` to bypass subsequent cognitive loops and return the tool output directly as the final answer.
- **`requires_approval`**: Set to `True` to pause agent execution and prompt for manual approval prior to execution.
- **`args`**: An explicit dictionary mapping parameters to types (e.g. `{"query": "str"}`).

```python
from autourgos.core import tool

# Decorate with explicit configuration overrides
@tool(
name="rectangle_calculator",
description="Calculate the total area of a rectangular space in square meters.",
requires_approval=True
)
def calculate_area(width: float, height: float) -> float:
return width * height
```

---

## Class-Based Tools (`BaseTool` Subclass)

For complex tools that maintain state, load configurations, or require standard synchronous and asynchronous methods, you subclass `BaseTool`.

To build a class-based tool:
1. Define a Pydantic `BaseModel` representing the arguments schema.
2. Subclass `BaseTool`, specifying `name`, `description`, and your `args_schema`.
3. Implement `_run()` (for synchronous calls) and `_arun()` (for asynchronous calls).

```python
from typing import Type
from pydantic import BaseModel, Field
from autourgos.core import BaseTool

# 1. Define the input parameters schema
class WriteFileArgs(BaseModel):
filepath: str = Field(description="The local path where the file will be written.")
text: str = Field(description="The text content to write into the file.")

# 2. Subclass BaseTool
class WriteFileTool(BaseTool):
name: str = "write_file_tool"
description: str = "Write text content into a local file safely."
args_schema: Type[BaseModel] = WriteFileArgs

def _run(self, filepath: str, text: str) -> str:
"""Synchronous tool execution logic."""
try:
with open(filepath, "w", encoding="utf-8") as f:
f.write(text)
return f"Successfully wrote content to {filepath}"
except Exception as e:
return f"Error writing file: {str(e)}"

async def _arun(self, filepath: str, text: str) -> str:
"""Asynchronous tool execution logic."""
# Standard async wraps can also run in thread pools
return self._run(filepath, text)
```

---

## Structured Tools (`StructuredTool.from_function`)

If you want to quickly convert an existing Python function into an Autourgos tool but need to explicitly specify a custom arguments schema, you can use the `StructuredTool.from_function` factory method.

```python
from pydantic import BaseModel, Field
from autourgos.core import StructuredTool

# 1. Define arguments schema
class DivisionArgs(BaseModel):
numerator: float = Field(description="The number to divide.")
denominator: float = Field(description="The divisor (must not be zero).")

# 2. Write the standard function
def divide(numerator: float, denominator: float) -> float:
if denominator == 0:
raise ValueError("Cannot divide by zero.")
return numerator / denominator

# 3. Build the structured tool
divide_tool = StructuredTool.from_function(
func=divide,
name="division_tool",
description="Divide two floating point numbers.",
args_schema=DivisionArgs
)
```

---

## Integrating Third-Party Tools (e.g., LangChain)

Because the Autourgos tool interfaces are fully LangChain-compatible, you can easily integrate third-party tools from standard ecosystems like LangChain or CrewAI. You can either pass standard LangChain tools directly to your agent, or wrap them inside a standard `@tool` function.

### Direct LangChain Tool Integration
Standard LangChain tools that subclass LangChain's `BaseTool` can be passed directly to your Autourgos agents:

```python
from langchain_community.tools import WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper
from autourgos.llmagentkit.ReActAgent import Create_ReAct_Agent

# 1. Initialize the LangChain community tool
api_wrapper = WikipediaAPIWrapper(top_k_results=2)
wikipedia_lc_tool = WikipediaQueryRun(api_wrapper=api_wrapper)

# 2. Register it directly in your Autourgos agent
agent = Create_ReAct_Agent(
llm=model,
tools=[wikipedia_lc_tool], # Pass the LangChain tool directly!
verbose=True
)
```

### Wrapping via the `@tool` Decorator
If you want to customize arguments, add local safety boundaries, or catch exceptions, you can easily wrap any third-party tool inside an Autourgos `@tool` decorator:

```python
from langchain_community.tools import WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper
from autourgos.core import tool

# Initialize the third-party tool
api_wrapper = WikipediaAPIWrapper(top_k_results=2)
wikipedia_lc_tool = WikipediaQueryRun(api_wrapper=api_wrapper)

# Wrap it inside Autourgos @tool
@tool
def search_wikipedia(query: str) -> str:
"""Search Wikipedia for the given query topic.

Args:
query: The search term or topic to query on Wikipedia.
"""
try:
return wikipedia_lc_tool.run(query)
except Exception as e:
return "Error querying Wikipedia: " + str(e)
```

---

## How to Register Tools

Once you have created your tools, pass them as a list to the `tools` constructor parameter when you create your cognitive loop agent (like `Create_ReAct_Agent`):

```python
from autourgos.llmagentkit.ReActAgent import Create_ReAct_Agent
from local_tools import calculate_area, divide_tool, WriteFileTool

# Instantiate class-based tools
file_writer = WriteFileTool()

# Register all tool types with the agent
agent = Create_ReAct_Agent(
llm=model,
tools=[calculate_area, divide_tool, file_writer],
verbose=True
)
```

---

## FAQs

### Can tools execute asynchronous operations?

Yes. Both decorated function tools and class-based tools fully support standard async routines. Simply write an `async def` decorated function or implement the `async def _arun()` method inside your custom tool class.

### How are tool execution exceptions handled by the agent?

All tool errors are automatically caught by the agent's execution loop. The exception details are formatted as standard strings and fed back into the cognitive loop, prompting the model to dynamically self-correct and try different parameters.

### When should I subclass BaseTool instead of using the @tool decorator?

Use the `@tool` decorator for simple, stateless functions. Subclass `BaseTool` when your tool needs to maintain a persistent state, keep active file or network connection handles, or load local credentials during class instantiation.

### Do I need to manually configure argument schemas for decorated tools?

No. Autourgos automatically parses the Python function's signature, argument type hints, and docstrings to generate strict Pydantic schemas behind the scenes.

### Can local tools access standard physical workspace resources?

Yes. Since Autourgos runs completely locally on your hardware with no sandboxed cloud limits, your tools have native access to all local operating system resources, shell terminals, local files, and directories.
---

## Metadata & Credits

- **Developer / Author**: [Jitin Kumar Sengar](https://www.linkedin.com/in/devxjitin/)
- **Documentation Authors**: Sonia & Om
- **GitHub Repository**: [AutourgosKit](https://github.com/autourgoskit)
- **Contact Email**: autourgoskit@gmail.com
