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

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. 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 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 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 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 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 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:

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
  • 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.

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 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →