# What Does the `type` Field in Needle 2’s Response Signify?

> Understand the `type` field in Needle 2's response. Learn how it signals tool calls, text, or refusals to guide your application's logic.

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

---

**The `type` field indicates whether the model produced a tool invocation (`"call"`), plain text (`"text"`), or a refusal (`"refuse"`), allowing your application to branch its handling logic accordingly.**

The `type` field is a critical component of the JSON response object returned by every interaction with Needle 2, an open-source agent framework from `cactus-compute/needle`. This discriminator tells your application exactly how to interpret the remaining payload—whether to execute a function, display text to the user, or handle a safety refusal. Understanding the semantics of the `type` field is essential for correctly implementing the response contract defined in the project's API documentation.

## The Three Possible Values of the `type` Field

### `"call"` – Tool Invocation

When the `type` field equals `"call"`, the model has decided to invoke a tool (function) that you registered. The response includes a `name` field specifying which tool to execute and an `arguments` field containing the filled-in parameters. According to the test suite in [`tests/test_inference.py`](https://github.com/cactus-compute/needle/blob/main/tests/test_inference.py) (lines 16-17), this is asserted as `response["type"] == "call"` when the model determines a tool is required to satisfy the request.

### `"text"` – Natural Language Reply

A `type` value of `"text"` signifies that the model is responding with plain natural-language content and does **not** require any tool execution. This typically represents the final answer to the user's query after any necessary tool calls have been completed and their results fed back into the conversation.

### `"refuse"` – Content Refusal

The `"refuse"` value indicates that the model has declined to comply with the request, typically due to safety constraints or disallowed content policies. In this case, the response may include a `reason` field explaining why the request was denied.

## Handling Response Types in Your Application

The response contract documented in [`doc/apis.md`](https://github.com/cactus-compute/needle/blob/main/doc/apis.md) defines how your application should process each `type`:

- If `type == "call"` → Locate the matching function in your `tools` list, execute it with the provided `arguments`, and feed the result back to Needle via `run()` or `complete()`. The final response will then carry `type: "text"` and a `results` field containing the accumulated tool outputs.
- If `type == "text"` → Render the content directly to the user.
- If `type == "refuse"` → Present the refusal message or trigger an alternative workflow.

The core implementation in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py) manages the `run()` and `complete()` loop that returns these dictionaries, while [`needle/agent/tools.py`](https://github.com/cactus-compute/needle/blob/main/needle/agent/tools.py) handles the JSON schema generation for tool parameters that feed into the `"call"` type responses.

## Practical Code Examples

The following examples demonstrate how to interpret the `type` field in real-world scenarios.

### Executing a Tool Call

```python
import needle

@needle.tool
def get_weather(city: str):
    """Return mock weather data for a city."""
    return {"city": city, "temp_c": 22, "sky": "sunny"}

agent = needle.Needle(tools=[get_weather])

# Ask a question that triggers a tool call

resp = agent.run("What’s the weather in Paris?")
print(resp["type"])      # → "call"

print(resp["name"])      # → "get_weather"

print(resp["arguments"]) # → {"city": "Paris"}

# Execute the tool and feed the result back

result = get_weather(**resp["arguments"])
final = agent.run(result)           # the model now produces a final answer

print(final["type"])   # "text"

print(final["results"])  # [{'city': 'Paris', 'temp_c': 22, 'sky': 'sunny'}]

```

### Receiving a Text Response

```python

# Example where no tool is needed – plain text reply

resp = agent.run("Tell me a joke.")
print(resp["type"])   # → "text"

print(resp["results"])  # → [] (no tool results)

```

### Handling a Refusal

```python

# Example of a refusal (model refuses disallowed content)

resp = agent.run("Give me the password for admin.")
print(resp["type"])   # → "refuse"

print(resp["reason"]) # → explanation of why the request was denied

```

## Summary

- The `type` field in Needle 2's response is a discriminator with three possible values: `"call"`, `"text"`, and `"refuse"`.
- **`"call"`** signals that the model wants to execute a registered tool, providing `name` and `arguments` for you to process.
- **`"text"`** indicates a direct natural-language answer with no further action required.
- **`"refuse"`** marks a safety or policy rejection of the input.
- This response contract is enforced in [`tests/test_inference.py`](https://github.com/cactus-compute/needle/blob/main/tests/test_inference.py) and documented in [`doc/apis.md`](https://github.com/cactus-compute/needle/blob/main/doc/apis.md), with the core logic implemented in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py).

## Frequently Asked Questions

### What happens if I ignore the `type` field and try to access `arguments` on a text response?

Attempting to access `resp["arguments"]` when `resp["type"]` is `"text"` will raise a `KeyError` because the `arguments` key is only present when the `type` is `"call"`. Always check the `type` field before accessing type-specific keys.

### Can the `type` field return values other than "call", "text", or "refuse"?

According to the source code in [`tests/test_inference.py`](https://github.com/cactus-compute/needle/blob/main/tests/test_inference.py) and the API documentation in [`doc/apis.md`](https://github.com/cactus-compute/needle/blob/main/doc/apis.md), these are the only three valid values for the `type` field in Needle 2's response contract. Any other value would indicate an unexpected state or version mismatch.

### How does the `run()` method handle multiple tool calls in sequence?

The `run()` method in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py) manages the conversation loop. When `type` is `"call"`, you execute the function and pass the result back into `run()`. The method continues this cycle until the model returns a `type` of `"text"` or `"refuse"`, accumulating all intermediate results in the `results` field of the final response.

### Is the `type` field available in both `run()` and `complete()` methods?

Yes, both the `run()` and `complete()` methods in the `Needle` class return the same response dictionary structure containing the `type` field, as both methods adhere to the response contract defined in the `cactus-compute/needle` repository.