# What Input Types Does the `tools` Parameter Accept in `needle.Needle`?

> Discover what input types the tools parameter accepts in needle.Needle. Learn about JSON-encoded strings, Pydantic models, functions, and JSON-Schema dictionaries for effective tool integration.

- Repository: [Cactus Compute, Inc./needle](https://github.com/cactus-compute/needle)
- Tags: api-reference
- Published: 2026-08-17

---

**The `tools` parameter in `needle.Needle` accepts either a JSON-encoded string or an iterable of Pydantic models, decorated or undecorated functions, and raw JSON-Schema dictionaries, automatically converting each into the required tool schema format.**

The `needle.Needle` class from the `cactus-compute/needle` repository provides a flexible interface for defining agent capabilities through its `tools` parameter. Understanding what input types this parameter accepts is essential for integrating custom functions, structured data models, and external API definitions into your AI agent workflows.

## The Four Accepted Input Types

The `tools` parameter supports four distinct input categories processed sequentially by the internal `_resolve` logic in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py). You can provide these as a heterogeneous list or tuple, or as a pre-serialized JSON string.

### 1. Pydantic Model Classes

**Pydantic model classes** are identified by the `_is_pydantic_model` helper and converted to JSON Schema using the `pydantic_schema` utility. According to the source code in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py) lines 94-100, this conversion extracts the model's field definitions, types, and docstrings to generate a compliant tool schema automatically.

### 2. Functions and Callables

**Callable objects** (functions or methods) are processed based on the presence of a `_needle_tool` attribute. As implemented in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py) lines 101-105, if this attribute exists (added by the `@tool` decorator), its value is used directly as the cached schema. Otherwise, the framework calls `build_schema` from [`needle/agent/tools.py`](https://github.com/cactus-compute/needle/blob/main/needle/agent/tools.py) to introspect the function's type hints and docstring for dynamic schema generation.

### 3. Raw JSON-Schema Dictionaries

**Dictionary objects** are treated as pre-constructed JSON-Schema tool definitions. The code at [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py) lines 105-107 checks for `dict` types and appends them to the tools list without modification, allowing precise control over the schema structure when you need custom parameter definitions.

### 4. JSON-Encoded Strings

When the `tools` argument is a **string**, the framework assumes it contains a JSON-encoded list of tool schemas. The logic in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py) lines 62-64 passes the string through unchanged, enabling external configuration via APIs or configuration files.

## Practical Implementation Examples

The following example demonstrates mixing all supported input types when initializing a `Needle` agent:

```python
import needle
from pydantic import BaseModel

# 1. Pydantic model as tool definition

class WeatherInfo(BaseModel):
    """Returned weather details."""
    city: str
    temperature_c: float
    description: str

# 2. Regular function with auto-generated schema

def set_lights(room: str, brightness: int = 50):
    """Set the brightness of a room."""
    return {"room": room, "brightness": brightness}

# 3. Pre-built JSON-Schema dictionary

custom_tool_schema = {
    "name": "add",
    "description": "Add two numbers.",
    "parameters": {
        "type": "object",
        "properties": {
            "a": {"type": "number"},
            "b": {"type": "number"}
        },
        "required": ["a", "b"]
    }
}

# Initialize agent with mixed tool types

agent = needle.Needle(
    tools=[WeatherInfo, set_lights, custom_tool_schema]
)

# Execute with tool invocation

resp = agent.run("Set the kitchen lights to 20 and tell me the weather in Paris.")
print(resp["results"])

```

## Summary

- **`needle.Needle`** accepts either a JSON string or an iterable (list/tuple) for the `tools` parameter
- **Pydantic models** are auto-converted to JSON Schema via `pydantic_schema` as seen in lines 94-100 of [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py)
- **Functions** support both the `@tool` decorator (using the `_needle_tool` attribute) and automatic introspection via `build_schema`
- **Dictionaries** pass through unchanged as raw JSON-Schema definitions per lines 105-107
- **JSON strings** are parsed directly without transformation, useful for dynamic configurations via lines 62-64

## Frequently Asked Questions

### Can I mix different tool types in the same `tools` list?

Yes. The `tools` parameter accepts a heterogeneous list containing any combination of Pydantic models, functions, and dictionaries. The framework processes each element individually according to its detected type in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py).

### Do I need to use the `@tool` decorator for every function?

No. While the `@tool` decorator caches the schema in a `_needle_tool` attribute for performance optimization, undecorated functions are automatically processed by `build_schema`, which inspects type hints and docstrings to generate the JSON Schema dynamically.

### How does `needle.Needle` handle invalid tool definitions?

The source code does not show explicit validation beyond type checking. Invalid dictionaries or unsupported types will likely raise errors during the schema resolution phase in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py) or when the agent attempts to register the tool with the underlying LLM provider.

### Can I load tools from a JSON configuration file?

Yes. Since the `tools` parameter accepts JSON-encoded strings, you can read a configuration file and pass the raw string content directly to `needle.Needle`, bypassing the Python object conversion entirely and using the string handling logic in lines 62-64 of [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py).