> ## Documentation Index
> Fetch the complete documentation index at: https://simplellmfunc.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# Decorators

> API reference for @llm_function, @llm_chat, and @tool

# Decorators API Reference

## @llm\_function

```python theme={null}
from SimpleLLMFunc import llm_function

@llm_function(
    llm_interface: LLM_Interface,
    toolkit: Optional[List[Tool]] = None,
    max_tool_calls: Optional[int] = None,
    system_prompt_template: Optional[str] = None,
    user_prompt_template: Optional[str] = None,
    **llm_kwargs: Any,
)
```

Transforms an async function into an `LLMFunction` callable instance. `await fn(...)` returns the parsed typed result; `fn.stream(...)` yields `ReactOutput`.

For multimodal input, keep the normal Python-function style: explicitly type image parameters as `ImgUrl`, `ImgPath`, or lists/unions containing those types. `ImgUrl` accepts `http(s)` URLs and `data:` URLs; `ImgPath` is encoded as an image data URL at the provider boundary.

### Parameters

| Parameter | Type | Default | Description |
| - | - | - | - |
| `llm_interface` | `LLM_Interface` | required | Model to call |
| `toolkit` | `List[Tool] \| None` | `None` | Tools available to the model |
| `max_tool_calls` | `int \| None` | `None` | Maximum tool calls before forcing final answer. `None` = unlimited |
| `system_prompt_template` | `str \| None` | `None` | Override the system prompt template |
| `user_prompt_template` | `str \| None` | `None` | Override the user prompt template |
| `**llm_kwargs` | `Any` | — | Forwarded to LLM (temperature, max\_tokens, etc.) |

### Special Call-Time Parameters

| Parameter | Type | Description |
| - | - | - |
| `_template_params` | `Dict[str, Any]` | Template values for docstring `{placeholders}` |
| `_abort_signal` | `AbortSignal` | Cancellation signal |

### Example

```python theme={null}
from pydantic import BaseModel, Field
from SimpleLLMFunc import llm_function, OpenAICompatible

llm = OpenAICompatible.load_from_json_file("provider.json")["openrouter"]["gpt-4o"]

class Sentiment(BaseModel):
    label: str = Field(description="positive, negative, or neutral")
    score: float = Field(description="confidence 0.0–1.0")

@llm_function(llm_interface=llm)
async def classify(text: str) -> Sentiment:
    """Classify the sentiment of the text."""
    pass

# Usage
result = await classify("I love this!")
print(result)  # Sentiment(label="positive", score=0.95)
```

***

## @llm\_chat

```python theme={null}
from SimpleLLMFunc import llm_chat

@llm_chat(
    llm_interface: LLM_Interface,
    toolkit: Optional[List[Tool]] = None,
    max_tool_calls: Optional[int] = DEFAULT_MAX_TOOL_CALLS,
    stream: bool = False,
    strict_signature: bool = False,
    self_reference: Optional[SelfReference] = None,
    self_reference_key: Optional[str] = None,
    **llm_kwargs: Any,
)
```

Creates an `LLMChat` callable instance. Calling it yields `AsyncGenerator[ReactOutput, None]` and gives SelfRef a stable agent identity.

For multimodal chat input, prefer a single explicit `message: UserChatMessage` argument. `UserChatMessage` is OpenAI Chat Completions-compatible and can contain text and `image_url` content parts.

### Parameters

| Parameter | Type | Default | Description |
| - | - | - | - |
| `llm_interface` | `LLM_Interface` | required | Model to call |
| `toolkit` | `List[Tool] \| None` | `None` | Available tools |
| `max_tool_calls` | `int \| None` | framework default | Tool call limit per invocation |
| `stream` | `bool` | `False` | Enable streaming chunks |
| `strict_signature` | `bool` | `False` | Enforce strict parameter validation |
| `self_reference` | `SelfReference \| None` | `None` | Explicit SelfReference backend |
| `self_reference_key` | `str \| None` | `None` | Auto-create SelfReference for this key |
| `**llm_kwargs` | `Any` | — | Forwarded to LLM |

### Special Call-Time Parameters

| Parameter | Type | Description |
| - | - | - |
| `_template_params` | `Dict[str, Any]` | Template values |
| `_abort_signal` | `AbortSignal` | Cancellation signal |
| `_too_long_to_file` | `bool` | Truncate long tool results to temp file |

### History Parameter

The function must have a parameter named `history` or `chat_history` (type: `list | None`). The framework uses it to carry conversation state.

### Example

```python theme={null}
from SimpleLLMFunc import llm_chat, tool

@tool
async def search(query: str) -> str:
    """Search for information."""
    return f"Result for: {query}"

@llm_chat(llm_interface=llm, toolkit=[search], stream=True)
async def agent(message: str, history: list | None = None):
    """A helpful research assistant."""
    pass

# Usage
history = []
async for output in agent("What is SimpleLLMFunc?", history):
    if is_response_yield(output):
        print(output.response)
        history = output.messages
```

### Multimodal Chat Example

```python theme={null}
from SimpleLLMFunc import llm_chat
from SimpleLLMFunc.type import UserChatMessage, ImgUrl

@llm_chat(llm_interface=llm)
async def vision_agent(message: UserChatMessage, history: list | None = None):
    """Answer questions about user-provided images."""
    pass

async for output in vision_agent(
    UserChatMessage.multimodal(
        "What is in this image?",
        ImgUrl("https://example.com/cat.jpg", detail="high"),
    ),
    history=[],
):
    ...
```

***

## @tool

```python theme={null}
from SimpleLLMFunc import tool

@tool(
    name: Optional[str] = None,
    description: Optional[str] = None,
    best_practices: Optional[Sequence[str]] = None,
    prompt_injection_builder: Optional[Callable] = None,
    too_long_to_file: bool = False,
)
```

Registers an async function as a tool callable by the LLM. Can be used with or without arguments.

### Parameters

| Parameter | Type | Default | Description |
| - | - | - | - |
| `name` | `str \| None` | function name | Override tool name |
| `description` | `str \| None` | from docstring | Override tool description |
| `best_practices` | `Sequence[str] \| None` | from docstring | Override best practices list |
| `prompt_injection_builder` | `Callable \| None` | `None` | Dynamic system prompt injection |
| `too_long_to_file` | `bool` | `False` | Write results > 20k tokens to temp file |

### Requirements

* Decorated function **must** be `async def`
* Docstring should include `Args`, `Returns`, and `Best Practices` sections
* Parameter types become the tool's JSON schema

### Example

```python theme={null}
from SimpleLLMFunc import tool

@tool
async def calculate(expression: str) -> float:
    """
    Evaluate a math expression.

    Args:
        expression: Python math expression (e.g., "2 ** 10").

    Returns:
        Numeric result.

    Best Practices:
        - Use Python syntax.
        - Keep expressions simple.
    """
    return float(eval(expression))

# Used without parentheses (simple form)
@tool
async def simple_tool(x: str) -> str:
    """Do something."""
    return x.upper()
```

***

## Tool Class

```python theme={null}
from SimpleLLMFunc import Tool

tool_instance = Tool(
    name: str,
    description: str,
    func: Callable[..., Awaitable[Any]],
    best_practices: Optional[Sequence[str]] = None,
    prompt_injection_builder: Optional[Callable] = None,
    too_long_to_file: bool = False,
)
```

For programmatic tool creation without the decorator.

### Methods

| Method | Returns | Description |
| - | - | - |
| `.tool_spec()` | `Dict` | Tool specification dict |
| `.to_openai_tool()` | `Dict` | OpenAI-format tool definition |
| `.serialize_tools(tools)` | `List[Dict]` | Class method: serialize tool list |
| `.build_system_prompt_injection(context)` | `str \| None` | Dynamic prompt injection |

### Properties

| Property | Type | Description |
| - | - | - |
| `.name` | `str` | Tool name |
| `.description` | `str` | Tool description |
| `.parameters` | `List[Parameter]` | Extracted parameters |
| `.func` | `Callable` | The underlying async function |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.