# Needle `complete()` Response Contract: Return Value Structure Explained

> Understand the needle.complete() response contract. Learn about the guaranteed 10 fields, performance metrics, and optional error details in its JSON-compatible dictionary return.

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

---

**The `needle.Needle.complete()` method returns a JSON‑compatible Python dictionary with 10 guaranteed fields including `type`, `success`, `function_calls`, performance metrics, and optional error details.**

The **response contract** for `Needle.complete()` defines the exact shape of the data returned after each turn of inference in the Cactus Compute **Needle** engine. This contract is enforced by the C‑extension wrapper implemented in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py) and is designed to be fully serializable for network transport or persistent storage.

## Guaranteed Response Fields

Every successful call to `complete()` returns a dictionary containing these fields:

| Field | Type | Description |
|-------|------|-------------|
| `type` | `str` | Either `"call"` (model emitted a function call) or `"respond"` (turn complete, no calls pending). |
| `success` | `bool` | `True` when the engine produced a syntactically valid call; `False` on runtime error. |
| `error` | `str` or `None` | Human‑readable message when `success` is `False`. |
| `error_code` | `int` or `None` | Numeric code from the native library for debugging. |
| `function_calls` | `list[dict]` | Tool calls, each with `name` (str) and `arguments` (dict). |
| `reasoning` | `str` | Model‑generated trace mapping prompt spans to extracted arguments. |
| `confidence` | `float` or `None` | Calibrated score 0–1; `None` when using fine‑tuned weights. |
| `prefill_tps` | `float` | Tokens‑per‑second for prompt pre‑fill. |
| `decode_tps` | `float` | Tokens‑per‑second for token generation. |
| `peak_ram_mb` | `float` | Peak memory usage in megabytes for this turn. |

The dictionary returned by `complete()` is **always JSON‑serializable**—no custom objects or non‑serializable types appear in the output according to the implementation in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py) lines 111‑126.

## Error Handling vs. Error Fields

The response contract distinguishes between **wrapper‑level failures** and **engine‑level errors**:

- **Runtime failures**: Python exceptions (`RuntimeError`) raised by the wrapper when native bindings fail (lines 115‑122 in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py)).
- **Engine errors**: Returned in‑band via `success=False`, `error`, and `error_code` fields allowing your application to handle model or parsing problems gracefully.

This two‑tier design prevents conflating infrastructure failures with model behavior errors.

## Code Examples: Working with the Response

### Basic Call Inspection

```python
import needle

agent = needle.Needle(tools=[set_lights])
response = agent.complete("dim the living room to 30")

print(response["type"])           # → "call"

print(response["function_calls"]) # → [{'name': 'set_lights', 'arguments': {'room': 'living', 'brightness': 30}}]

print(response["confidence"])     # → 0.94 (or None for fine‑tuned weights)

```

### Building an Agent Loop

```python
import json
import needle

agent = needle.Needle(tools=[search, calendar_add])
user_query = "find meetings tomorrow and block focus time"

while True:
    out = agent.complete(user_query)
    
    if out["type"] == "respond":
        print("Final response:", out["reasoning"])
        break
    
    if not out["success"]:
        print(f"Error {out['error_code']}: {out['error']}")
        break
    
    results = []
    for call in out["function_calls"]:
        tool = agent._functions[call["name"]]
        results.append(tool(**call["arguments"]))
    
    user_query = json.dumps(results)

```

### Extracting Performance Metrics

```python
response = agent.complete("summarize the quarterly report")

print(f"Prefill: {response['prefill_tps']:.1f} tps")
print(f"Decode: {response['decode_tps']:.1f} tps")
print(f"Memory: {response['peak_ram_mb']:.1f} MiB")

```

## Implementation Sources

The contract definition spans three key locations in the **cactus-compute/needle** repository:

- **[`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py)** (lines 111‑126): Core `Needle.complete()` implementation and C‑library wrapper.
- **[`doc/apis.md`](https://github.com/cactus-compute/needle/blob/main/doc/apis.md)** (lines 84‑96): Public API documentation with annotated response examples.
- **[`tests/test_inference.py`](https://github.com/cactus-compute/needle/blob/main/tests/test_inference.py)**: Unit tests validating response shape and field presence.

The reference server at [`needle/playground/server.py`](https://github.com/cactus-compute/needle/blob/main/needle/playground/server.py) demonstrates production usage of this contract in a web service context.

## Summary

- `Needle.complete()` returns a **single dictionary with 10 guaranteed fields**—no tuples, no custom objects.
- The `type` field drives control flow: `"call"` for tool execution, `"respond"` for completion.
- Performance metrics (`prefill_tps`, `decode_tps`, `peak_ram_mb`) enable production monitoring.
- The response is **JSON‑serializable by design** for distributed deployments.
- Errors surface either as `RuntimeError` (wrapper) or in‑band fields `success`/`error`/`error_code` (engine).

## Frequently Asked Questions

### What happens if the native library crashes during `complete()`?

A `RuntimeError` is raised from [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py) lines 115‑122 instead of returning a dictionary. This distinguishes infrastructure failures from model‑level parse errors which return normally with `success=False`.

### Is the `confidence` field always present?

The `confidence` field exists in every response but may be `None`. According to the source, confidence scores are **omitted when using fine‑tuned model weights** rather than the base calibration system.

### Can I rely on `function_calls` being a list even for `"respond"` turns?

Yes—the contract guarantees `function_calls` is always a list. For `"respond"` turns, this list is empty (`[]`), never missing or `None`.

### Do I need to handle serialization myself?

No. The dictionary returned by `complete()` uses only JSON‑native types (str, bool, int, float, list, dict, None). You can pass it directly to `json.dumps()` without custom encoders.