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

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

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:

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:

{
  "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:

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:

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
  • Three-phase execution: agent creationengine 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.

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.

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 →