Guia de Integração com o OpenAI SDK¶
A API do Nodexa é wire-compatible com a Responses API da OpenAI. Você pode usar o SDK oficial da OpenAI para Node.js ou Python sem nenhum código customizado — basta apontá-lo para sua instância Nodexa.
Configuração¶
O sufixo de path /v1 é obrigatório
O baseURL deve terminar com /v1. Esse é o erro de configuração mais comum.
# Correto
baseURL: 'https://app.nodexa.cloud/v1'
# Errado — as requests não vão chegar à API
baseURL: 'https://app.nodexa.cloud'
Sem /v1, as requests caem em um middleware que retorna uma página de redirecionamento em vez de uma resposta da API, gerando erros confusos que não parecem erros de API.
Instale o OpenAI SDK:
Configure o cliente:
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://app.nodexa.cloud/v1',
apiKey: process.env.NODEXA_API_KEY,
});
Com CommonJS:
Enviando Headers Adicionais¶
Algumas funcionalidades do Nodexa precisam de headers customizados (x-user-id, x-user-tokens). Você pode passar headers extras usando a opção defaultHeaders do SDK ou via headers por request.
Requests Sem Streaming¶
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://your-admin.example.com/v1',
apiKey: process.env.NODEXA_API_KEY,
});
async function ask(question) {
const response = await client.responses.create({
model: process.env.NODEXA_ASSISTANT_ID,
input: question,
});
return {
id: response.id,
text: response.output_text,
status: response.status,
};
}
const result = await ask('What is the difference between TCP and UDP?');
console.log(result.text);
from openai import OpenAI
import os
client = OpenAI(
base_url="https://your-admin.example.com/v1",
api_key=os.environ["NODEXA_API_KEY"],
)
def ask(question: str) -> dict:
response = client.responses.create(
model=os.environ["NODEXA_ASSISTANT_ID"],
input=question,
)
return {
"id": response.id,
"text": response.output_text,
"status": response.status,
}
result = ask("What is the difference between TCP and UDP?")
print(result["text"])
Requests com Streaming¶
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://your-admin.example.com/v1',
apiKey: process.env.NODEXA_API_KEY,
});
async function streamAnswer(question) {
const stream = await client.responses.create({
model: process.env.NODEXA_ASSISTANT_ID,
input: question,
stream: true,
});
let fullText = '';
let responseId = null;
for await (const event of stream) {
switch (event.type) {
case 'response.output_text.delta':
process.stdout.write(event.delta);
fullText += event.delta;
break;
case 'response.completed':
responseId = event.response.id;
break;
}
}
console.log('\n');
return { text: fullText, id: responseId };
}
const { text, id } = await streamAnswer('Explain how async/await works in JavaScript.');
console.log('Response ID for threading:', id);
from openai import OpenAI
import os
client = OpenAI(
base_url="https://your-admin.example.com/v1",
api_key=os.environ["NODEXA_API_KEY"],
)
def stream_answer(question: str) -> tuple[str, str]:
full_text = ""
response_id = None
with client.responses.stream(
model=os.environ["NODEXA_ASSISTANT_ID"],
input=question,
) as stream:
for event in stream:
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True)
full_text += event.delta
elif event.type == "response.completed":
response_id = event.response.id
print()
return full_text, response_id
text, response_id = stream_answer("Explain how async/await works in Python.")
print(f"Response ID: {response_id}")
Conversas com Múltiplos Turnos¶
import OpenAI from 'openai';
import * as readline from 'readline';
const client = new OpenAI({
baseURL: 'https://your-admin.example.com/v1',
apiKey: process.env.NODEXA_API_KEY,
});
async function interactiveChat() {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
let lastResponseId = null;
const prompt = (question) =>
new Promise((resolve) => rl.question(question, resolve));
console.log('Chat with Nodexa (type "exit" to quit)\n');
while (true) {
const userInput = await prompt('You: ');
if (userInput.toLowerCase() === 'exit') break;
const response = await client.responses.create({
model: process.env.NODEXA_ASSISTANT_ID,
input: userInput,
...(lastResponseId ? { previous_response_id: lastResponseId } : {}),
});
lastResponseId = response.id;
console.log(`Assistant: ${response.output_text}\n`);
}
rl.close();
}
interactiveChat();
from openai import OpenAI
import os
client = OpenAI(
base_url="https://your-admin.example.com/v1",
api_key=os.environ["NODEXA_API_KEY"],
)
def interactive_chat():
last_response_id = None
print("Chat with Nodexa (type 'exit' to quit)\n")
while True:
user_input = input("You: ")
if user_input.lower() == "exit":
break
kwargs = {
"model": os.environ["NODEXA_ASSISTANT_ID"],
"input": user_input,
}
if last_response_id:
kwargs["previous_response_id"] = last_response_id
response = client.responses.create(**kwargs)
last_response_id = response.id
print(f"Assistant: {response.output_text}\n")
interactive_chat()
Function Calling com o SDK¶
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://your-admin.example.com/v1',
apiKey: process.env.NODEXA_API_KEY,
});
const tools = [
{
type: 'function',
name: 'lookup_order',
description: 'Look up an order by its order number',
parameters: {
type: 'object',
properties: {
orderNumber: {
type: 'string',
description: 'The order number, e.g. ORD-2024-00123',
},
},
required: ['orderNumber'],
},
},
];
async function lookupOrder(orderNumber) {
// Substitua pela sua lógica real de consulta de pedidos
return {
orderNumber,
status: 'shipped',
estimatedDelivery: '2024-11-20',
items: [{ name: 'Widget Pro', quantity: 2, price: 49.99 }],
};
}
async function chatWithOrderLookup(userMessage) {
let response = await client.responses.create({
model: process.env.NODEXA_ASSISTANT_ID,
input: userMessage,
tools,
});
while (response.status === 'requires_action') {
const results = [];
for (const item of response.output) {
if (item.type !== 'function_call') continue;
const args = JSON.parse(item.arguments);
let result;
if (item.name === 'lookup_order') {
result = await lookupOrder(args.orderNumber);
} else {
result = { error: `Unknown function: ${item.name}` };
}
results.push({
type: 'function_call_output',
call_id: item.call_id,
output: JSON.stringify(result),
});
}
response = await client.responses.create({
model: process.env.NODEXA_ASSISTANT_ID,
previous_response_id: response.id,
input: results,
});
}
return response.output_text;
}
const answer = await chatWithOrderLookup('Where is my order ORD-2024-00123?');
console.log(answer);
import json
from openai import OpenAI
import os
client = OpenAI(
base_url="https://your-admin.example.com/v1",
api_key=os.environ["NODEXA_API_KEY"],
)
tools = [
{
"type": "function",
"name": "lookup_order",
"description": "Look up an order by its order number",
"parameters": {
"type": "object",
"properties": {
"orderNumber": {
"type": "string",
"description": "The order number, e.g. ORD-2024-00123",
}
},
"required": ["orderNumber"],
},
}
]
def lookup_order(order_number: str) -> dict:
# Substitua pela lógica real de consulta
return {
"orderNumber": order_number,
"status": "shipped",
"estimatedDelivery": "2024-11-20",
}
def chat_with_order_lookup(user_message: str) -> str:
response = client.responses.create(
model=os.environ["NODEXA_ASSISTANT_ID"],
input=user_message,
tools=tools,
)
while response.status == "requires_action":
results = []
for item in response.output:
if item.type != "function_call":
continue
args = json.loads(item.arguments)
if item.name == "lookup_order":
result = lookup_order(args["orderNumber"])
else:
result = {"error": f"Unknown function: {item.name}"}
results.append({
"type": "function_call_output",
"call_id": item.call_id,
"output": json.dumps(result),
})
response = client.responses.create(
model=os.environ["NODEXA_ASSISTANT_ID"],
previous_response_id=response.id,
input=results,
)
return response.output_text
print(chat_with_order_lookup("Where is my order ORD-2024-00123?"))
Tratamento de Erros¶
import OpenAI, { APIError } from 'openai';
try {
const response = await client.responses.create({
model: process.env.NODEXA_ASSISTANT_ID,
input: 'Hello',
});
console.log(response.output_text);
} catch (err) {
if (err instanceof APIError) {
console.error(`Status: ${err.status}`);
console.error(`Error type: ${err.error?.type}`);
console.error(`Message: ${err.message}`);
} else {
throw err;
}
}
from openai import OpenAI, APIError, APIStatusError
try:
response = client.responses.create(
model=os.environ["NODEXA_ASSISTANT_ID"],
input="Hello",
)
print(response.output_text)
except APIStatusError as e:
print(f"Status: {e.status_code}")
print(f"Message: {e.message}")
except APIError as e:
print(f"API Error: {e}")
Tipos TypeScript¶
O OpenAI SDK fornece tipos TypeScript completos para a Responses API:
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: process.env.NODEXA_BASE_URL + '/v1',
apiKey: process.env.NODEXA_API_KEY!,
});
// Resposta tipada
const response: OpenAI.Responses.Response = await client.responses.create({
model: process.env.NODEXA_ASSISTANT_ID!,
input: 'Hello',
});
// Definições de tools tipadas
const tools: OpenAI.Responses.Tool[] = [
{
type: 'function',
name: 'my_function',
parameters: {
type: 'object',
properties: {
query: { type: 'string' },
},
required: ['query'],
},
},
];
Compatibilidade de Versão do SDK¶
O Nodexa é compatível com a Responses API da OpenAI introduzida no SDK openai v4.x. Use uma versão recente: