OpenAI SDK
Use the official OpenAI SDKs for Python and TypeScript with XField: client setup, chat, responses, streaming, reasoning, tools, timeouts and retries.
XField speaks the OpenAI Chat Completions and Responses APIs, so the official SDKs work once you change two settings: the base URL and the key. Everything below uses the stock openai packages.
Install and configure
pip install openai # Python
npm install openai # TypeScript / Nodeimport os
from openai import OpenAI
client = OpenAI(
base_url="https://xfield.cloud.brutal.ai/api/v1",
api_key=os.environ["XFIELD_API_KEY"],
)The key is sent as Authorization: Bearer. Model ids are exact; see models.
Chat Completions
resp = client.chat.completions.create(
model="deepseek-v4.1-flash-1017-uncensored",
messages=[
{"role": "system", "content": "You are a terse security reviewer."},
{"role": "user", "content": "What does a SameSite=None cookie without Secure do?"},
],
)
print(resp.choices[0].message.content)Responses
resp = client.responses.create(
model="glm-5.3-uncensored",
input="Outline a test plan for a prompt-injection filter.",
reasoning={"effort": "high"},
)
print(resp.output_text)Reasoning comes back as native reasoning items in resp.output, ahead of the message.
Streaming
Set stream: true. Chat Completions sends usage in the last chunk, which has no choices, so guard for that.
stream = client.chat.completions.create(
model="deepseek-v4.1-flash-1017-uncensored",
messages=[{"role": "user", "content": "Write a haiku about log rotation."}],
stream=True,
)
for chunk in stream:
if chunk.choices:
print(chunk.choices[0].delta.content or "", end="", flush=True)
elif chunk.usage:
print("\n", chunk.usage)Reasoning
On Chat Completions, set reasoning_effort (none turns thinking off). The reasoning text is in a reasoning field the SDK types do not declare, so read it loosely: message.reasoning on a full response, delta.reasoning while streaming.
resp = client.chat.completions.create(
model="deepseek-v4.1-flash-1017-uncensored",
messages=[{"role": "user", "content": "Is 2^61 - 1 prime? Show your check."}],
reasoning_effort="xhigh",
)
msg = resp.choices[0].message
print(getattr(msg, "reasoning", None))
print(msg.content)To keep the thinking but drop its text from the response, send "reasoning": {"exclude": true}. In Python that goes through extra_body; in TypeScript, add it to the request object (the SDK forwards it, though the types need a cast). More in reasoning.
Tools
Tool calls use the standard tools and tool_choice fields.
tools = [{
"type": "function",
"function": {
"name": "lookup_cve",
"description": "Fetch the summary for a CVE id from the local mirror.",
"parameters": {
"type": "object",
"properties": {"id": {"type": "string"}},
"required": ["id"],
},
},
}]
resp = client.chat.completions.create(
model="deepseek-v4.1-flash-1017-uncensored",
messages=[{"role": "user", "content": "Summarize CVE-2024-3094."}],
tools=tools,
)
call = resp.choices[0].message.tool_calls[0]
print(call.function.name, call.function.arguments)Append the assistant message and a {"role": "tool", "tool_call_id": call.id, "content": ...} message, then call again for the final answer.
Timeouts and retries
Both SDKs retry connection errors, 429s and 5xx responses with backoff, and respect Retry-After. Long reasoning runs can take minutes, so set a timeout that matches the work, or stream.
client = OpenAI(
base_url="https://xfield.cloud.brutal.ai/api/v1",
api_key=os.environ["XFIELD_API_KEY"],
timeout=300.0,
max_retries=4,
)
slow = client.with_options(timeout=900.0) # per-call overrideErrors surface as the SDK's usual classes: AuthenticationError for 401, RateLimitError for 429, BadRequestError for an unknown model id.