Brutal AI

Brutal AIModelsDocsOpenAI SDK

SDKs and frameworks

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

Shell
pip install openai        # Python
npm install openai        # TypeScript / Node
client.py
Python
import 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

Python
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

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

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

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

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

Python
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 override

Errors surface as the SDK's usual classes: AuthenticationError for 401, RateLimitError for 429, BadRequestError for an unknown model id.