How to Access Optional Fields from the Needle.complete() Response
Use the dictionary get() method to safely retrieve optional fields like function_calls, reasoning, and metadata from the dict returned by Needle.complete().
The Needle.complete() method in the cactus-compute/needle repository returns a JSON-decoded Python dictionary containing the model's output. While core fields like type and content are always present, the response may also include optional fields generated dynamically by the underlying engine. Because the library does not enforce a fixed schema on the returned envelope, you must defensively check for these optional keys to avoid KeyError exceptions.
Understanding the Needle.complete() Response Structure
When you call agent.complete(), the library processes a raw C-API string through json.loads() and returns the resulting dictionary directly to the caller. According to the source code in needle/__init__.py, the response handling looks like this:
# https://github.com/cactus-compute/needle/blob/main/needle/__init__.py#L52-L63
raw = self._buffer.value.decode("utf-8")
response = json.loads(raw) # ← JSON envelope from the engine
if self._weights:
response["confidence"] = None
if ground:
_annotate_ungrounded(response, ...) # adds grounding info
return response
Since the envelope is a plain dictionary, any additional keys added by the engine—such as function_calls or reasoning—will simply be present in the returned dict when the model chooses to emit them. The library does not guarantee the presence of these fields for every request.
Optional Fields Available in the Response
The engine may include several optional fields depending on the request configuration and model behavior.
function_calls
The function_calls field contains a list of function-call objects generated by the model when tools are available. This field is defined in relation to the tool schemas in needle/agent/tools.py. When tools are supplied to the agent, the engine can emit this field to request external function execution.
reasoning
The reasoning field stores any chain-of-thought or rationale the model attaches to its response. This appears only when the underlying provider includes reasoning tokens or explanation blocks in the output.
metadata
The metadata field contains provider-specific extra information such as confidence scores, token usage statistics, or latency metrics. The structure varies by backend implementation.
confidence
The confidence field is conditionally added in needle/__init__.py when self._weights is configured. The source explicitly inserts this key only when weights are present:
if self._weights:
response["confidence"] = None
Safely Accessing Optional Fields in Python
Because optional fields may be absent, you should never access them using direct bracket notation. Instead, use dict.get() or in checks to handle missing keys gracefully.
Preferred approaches:
response.get("field_name", default)– Returns the value or a default if the key is missingif "field_name" in response– Boolean check before accessing the value
Direct access like response["function_calls"] will raise a KeyError if the model did not generate tool calls.
Complete Code Example
Here is a robust pattern for accessing optional fields from the Needle.complete() response:
from needle import Needle
# Initialise the agent (optionally with tools or a system prompt)
agent = Needle()
# Simple completion – may or may not include optional fields
resp = agent.complete("Give me the weather forecast for tomorrow")
# Safely access optional fields
function_calls = resp.get("function_calls", [])
if function_calls:
for call in function_calls:
print(f"Tool: {call['name']}, args: {call.get('arguments', {})}")
# Access other optional fields
reasoning = resp.get("reasoning")
if reasoning:
print("Model reasoning:", reasoning)
metadata = resp.get("metadata", {})
print("Metadata:", metadata)
The test suite in tests/test_inference.py demonstrates this pattern when validating function_calls presence in the returned dictionary, confirming that production code should treat these fields as optional.
Summary
Needle.complete()returns a plain Pythondictparsed from JSON inneedle/__init__.py- Optional fields like
function_calls,reasoning, andmetadataappear only when the engine emits them - Always use
.get()orinchecks to access optional fields safely and avoidKeyError - The response envelope is not schema-enforced, so defensive programming is required for robust integrations
Frequently Asked Questions
What optional fields can appear in a Needle.complete() response?
The response may include function_calls (when tools are used), reasoning (when the model provides explanations), metadata (provider-specific data), and confidence (when weights are configured). These fields are not guaranteed and depend entirely on the model output and request parameters.
Why does Needle.complete() return a dictionary instead of a typed object?
The library passes through the raw JSON envelope from the underlying C-API engine without unmarshaling it into a fixed dataclass or Pydantic model. This design, implemented in needle/__init__.py, allows the library to remain agnostic to provider-specific extensions and future fields without requiring schema updates.
How do I handle missing optional fields without raising KeyError?
Use the dictionary get() method with an appropriate default value, such as resp.get("function_calls", []) or resp.get("reasoning"). Alternatively, check for key existence using if "field_name" in resp before accessing the value. Never use direct bracket notation for optional fields.
Where is the response parsing logic implemented in the Needle source code?
The response parsing occurs in needle/__init__.py around lines 52-63, where the raw buffer is decoded from UTF-8 and passed through json.loads(). This file also conditionally enriches the response with additional fields like confidence before returning the final dictionary to the caller.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →