Needle Response Object Structure: A Complete Guide to Agent Outputs

A Needle response object is a Python dictionary returned by Needle.complete() or Needle.run() that contains a type field, optional function_calls, validation metadata, and execution results, formatted as JSON and parsed in needle/__init__.py.

The Needle response object forms the core communication protocol between the inference engine and your application code in the cactus-compute/needle library. After every call to Needle.complete() or the higher-level Needle.run(), the engine returns a serialized JSON payload that the library parses into a structured Python dictionary. Understanding this schema is essential for building reliable agent workflows, handling tool execution, and validating structured extractions.

Core Structure of a Needle Response Object

The engine always ships results as JSON, which Needle._complete() parses using json.loads to produce the final dictionary. The parsed object follows a strict schema used to drive tool execution and validation throughout the codebase.

Required Fields

Every response includes these fundamental keys:

  • type (str): The categorical classification of the response. Common values include "call" (tool invocation required), "text" (direct answer), or "refuse" (model declined). The run() loop checks this field at line 189 to determine whether to continue the reasoning cycle.

  • function_calls (list[dict]): A specification list of tools the model wants to invoke. Each dictionary contains:

    • name: The string identifier of the tool
    • arguments: A mapping of parameter names to their values

    The Needle.run() method iterates over this list at lines 88-99 to execute the requested functions.

Optional Fields

Depending on the operation and engine configuration, these fields may be present:

  • validation (dict): Structured extraction validation data containing:

    • ungrounded: A list of JSON-pointer strings indicating which extracted fields the model believes lack grounding in the source text
    • negation: A boolean flag indicating whether the request was negated

    The _validate_extraction() method consumes this data at lines 15-27.

  • confidence (float or None): A confidence score returned by the native engine. This value is set to None when using fine-tuned weight files because the confidence head remains uncalibrated. The assignment occurs in _complete() at lines 79-81.

Runtime-Added Fields

When using the higher-level run() interface, the library augments the response:

  • results (list[object]): Accumulated return values from each tool execution performed during the reasoning loop. Needle.run() appends to this list at line 103 after every iteration, providing a complete trace of the agent's tool usage.

Working with Needle Response Objects in Practice

Retrieving Raw Completions with complete()

Use Needle.complete() to obtain the direct engine output without automatic tool execution. The response contains the raw function_calls and metadata:

from needle import Needle

agent = Needle(tools=[my_tool])
raw = agent.complete("Set the thermostat to 22°C in the office")

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

print(raw["function_calls"])      # → [{'name': 'set_thermostat', 'arguments': {...}}]

print(raw.get("confidence"))      # → 0.87 (or None for fine-tuned weights)

Executing Tools with the run() Loop

When invoking Needle.run(), the library enters a reasoning loop that executes tools automatically. The returned Needle response object includes the additional results key containing the output of each tool call:

agent = Needle(tools=[my_tool])
resp = agent.run("Configure the office temperature")

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

print(resp["results"])             # → [{"status": "ok", "new_temp": 21}]

print(resp.get("validation"))      # → may contain grounding info

Handling Validation and Errors

For structured extraction tasks, inspect the validation field to identify ungrounded claims or negations before processing the data:

from needle import ExtractionValidationError

try:
    data = agent.extract(
        "Invoice due on 2023-04-01", schema=InvoiceSchema
    )
except ExtractionValidationError as err:
    print("Extraction failed:", err)

Source Code Implementation Details

The Needle response object contract is defined and enforced across these key files:

File Implementation Details
needle/__init__.py Core Needle class that parses raw engine JSON in _complete(), adds the confidence field, and implements run() which injects the results list.
needle/agent/tools.py Constructs the JSON schema for available tools; this schema dictates the exact shape of each entry inside function_calls.
needle/_worker.py Low-level worker interface that returns the raw JSON envelope from the native engine, providing the source data for all response fields.
tests/test_inference.py Unit tests asserting the mandatory presence of type and function_calls keys, illustrating expected usage patterns.
tests/test_environments.py Integration tests exercising the response structure when running against built-in environments, confirming field consistency.

Summary

  • A Needle response object is a Python dict parsed from engine JSON via json.loads in Needle._complete().
  • The type field (values like "call", "text", or "refuse") drives execution logic in run() at line 189.
  • Tool specifications reside in function_calls, iterated at lines 88-99 of needle/__init__.py.
  • Optional validation data includes ungrounded pointers and negation flags, processed by _validate_extraction().
  • The confidence score is None for fine-tuned models, set at lines 79-81.
  • The run() method adds a results list at line 103 containing tool execution outputs.

Frequently Asked Questions

What is the data type of a Needle response object?

A Needle response object is a standard Python dict (dictionary) parsed from JSON. The library uses json.loads in the _complete() method to convert the engine's raw JSON output into this dictionary structure, allowing standard Python key-access syntax like response["type"] or response.get("confidence").

How does the type field determine program flow?

The type field categorizes the model's intention. When type equals "call", the Needle.run() loop at line 189 continues execution to invoke the tools listed in function_calls. If type is "text", the loop terminates and returns the final answer. A type of "refuse" indicates the model declined the request, typically triggering an exception or fallback behavior.

Why is the confidence field sometimes None?

The confidence field returns None specifically when you load a fine-tuned weight file. According to the source code at lines 79-81 of needle/__init__.py, the confidence prediction head is not calibrated for fine-tuned models, so the library explicitly sets this value to None rather than returning misleading scores. Native engine weights return a float between 0 and 1.

What happens to extra fields returned by the engine?

Any additional keys present in the engine's JSON payload—such as message, status, or model-specific metadata—are preserved unchanged in the returned dictionary. The parsing logic in _complete() passes these fields through directly without modification, ensuring forward compatibility with future engine updates.

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 →