# How to Perform One-Shot Completion with `needle.agent.complete()`: A Complete Guide

> Learn to perform one-shot completion with needle.agent.complete(). Get JSON responses for text generation and structured extraction without function call iterations. A complete guide.

- Repository: [Cactus Compute, Inc./needle](https://github.com/cactus-compute/needle)
- Tags: how-to-guide
- Published: 2026-08-31

---

**Use `needle.agent.complete()` to send a single prompt and receive a JSON-encoded response without iterating over function calls, ideal for straightforward text generation and structured extraction tasks.**

The `needle.agent.complete()` method provides the simplest entry point to the **Cactus-Needle** inference engine. This guide walks through the internal implementation, practical usage patterns, and when to choose one-shot completion over multi-turn alternatives.

## How `needle.agent.complete()` Works Under the Hood

The `complete()` method is implemented in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py) as a thin orchestration layer around the native **Cactus-Needle** engine. The execution flow follows three distinct phases:

### Agent Initialization

Creating a `Needle` instance sets up the shared engine context. The constructor accepts:
- `system`: Optional system prompt string
- `tools`: List of Pydantic models or callable schemas
- `weights`: Path to fine-tuned checkpoint files (`.cact` format)

Implementation: `class Needle` in **[`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py)**.

### Engine Binding

Before inference, the private `_bind()` method ensures:
- The native shared library is loaded
- Weights are loaded into memory (if specified)
- The system prompt and tool schemas are registered with the engine

This binding occurs automatically at the start of `_complete()` (lines 24–28 in the source).

### Native Execution

The public `complete()` method (lines 119–124) records telemetry delegates to `_complete()` (lines 123–138), which:
1. Calls the C function `needle_complete` via ctypes
2. Receives a JSON envelope in a pre-allocated buffer
3. Decodes the response into a Python dictionary
4. Adds a `confidence` field when tuned weights are present

## Basic One-Shot Completion Example

For pure text generation without tool usage:

```python
import needle

# Create an agent with a custom system prompt

agent = needle.Needle(system="You are a helpful assistant.")

# Perform a single completion

response = agent.complete("Write a short haiku about sunrise.", max_new_tokens=64)
print(response["completion"])

```

Typical response structure:

```json
{
  "type": "completion",
  "completion": "Golden light ascends,\nShadows flee from waking hills—\nDay breaks, soft and sure.",
  "model": "cactus-needle-vX",
  "usage": { "prompt_tokens": 12, "completion_tokens": 18 }
}

```

## One-Shot Completion with Tuned Weights

Fine-tuned checkpoints enhance output quality for domain-specific tasks:

```python
import needle

# Load a custom-tuned checkpoint

agent = needle.Needle(
    weights="path/to/my_model.cact",
    system="You are a medical summarization assistant."
)

result = agent.complete(
    "Summarize the key findings of this patient report...",
    max_new_tokens=512
)

print(result["completion"])
print("Confidence score:", result.get("confidence"))  # Populated for tuned weights

```

The `confidence` field appears only when `weights` is provided, reflecting the model's calibrated uncertainty.

## Structured One-Shot Extraction

For **JSON-structured output**, register a Pydantic model as a tool. The engine returns a function call that you can parse directly:

```python
from pydantic import BaseModel
import needle

class WeatherReport(BaseModel):
    location: str
    temperature_c: float
    condition: str

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

resp = agent.complete("Give me the weather for Paris right now.")
extracted = resp["function_calls"][0]["arguments"]
report = WeatherReport(**extracted)

print(f"{report.location}: {report.temperature_c}°C, {report.condition}")

```

While `Needle.extract()` provides a convenience wrapper, `complete()` offers direct control over the raw response format.

## Key Method Signatures and Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `text` | `str` | *required* | The user prompt to complete |
| `max_new_tokens` | `int` | `256` | Hard limit on generated tokens |

Return type: `dict` containing `type`, `completion` or `function_calls`, `model`, and `usage` fields.

## When to Use `complete()` vs. Multi-Turn Alternatives

Choose **one-shot completion** when:
- No tool chaining or iterative reasoning is required
- Latency is critical (single round-trip to the engine)
- Output is either freeform text or a single structured object

Avoid `complete()` for multi-step workflows requiring sequential tool calls—use `Needle.run()` or streaming interfaces instead.

## Summary

- **`needle.agent.complete()`** is a lightweight wrapper around the native Cactus-Needle engine defined in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py)
- Three-phase execution: **agent creation** → **engine binding** (`_bind()`) → **native inference** (`_complete()`)
- Returns a **JSON-decoded dictionary** with completion text, usage statistics, and optional confidence scores
- Supports **tuned weights** via the `weights` parameter and **structured output** via Pydantic tool schemas
- Ideal for **low-latency, single-response** use cases without function-call iteration

## Frequently Asked Questions

### What is the difference between `complete()` and `extract()`?

`extract()` is a convenience wrapper around `complete()` that automatically parses the first function call into your Pydantic model and returns the instantiated object. `complete()` returns the raw dictionary response, giving you full control over error handling and multi-call scenarios. Both methods use identical underlying machinery in [`needle/__init__.py`](https://github.com/cactus-compute/needle/blob/main/needle/__init__.py).

### Why is `confidence` sometimes `None` in the response?

The `confidence` field is populated only when the `weights` parameter points to a fine-tuned checkpoint (`.cact` file). Base model completions do not include calibrated confidence scores. Check `result.get("confidence")` rather than direct key access for safe handling.

### Can I use `complete()` with multiple tools registered?

Yes, but the engine returns only the **first matching function call** in the response array. For multi-tool orchestration where several tools may be invoked in sequence, use `Needle.run()` instead. The `complete()` method is explicitly designed for one-shot scenarios per the implementation in lines 119–138.

### How do I adjust generation parameters like temperature or top-p?

As of the current implementation, sampling parameters are fixed at engine initialization or configured via the `weights` checkpoint metadata. The `complete()` method signature exposes only `max_new_tokens` for per-call control. Modify system-level sampling settings through the `system` prompt engineering or custom weight configurations.