fix(captain): always include instructions in Codex responses body

Codex endpoint retorna HTTP 400 "Instructions are required" quando o
campo vem ausente. Agora sempre incluímos o campo — string com espaço
quando não há system message no request.

Validado end-to-end: curl → /codex/v1/chat/completions → proxy traduz
→ Codex devolve streaming SSE → proxy agrega → JSON Chat Completions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Rodribm10 2026-04-22 15:27:37 -03:00
parent 928b1ec6b9
commit d53c86df94
2 changed files with 17 additions and 1 deletions

View File

@ -15,10 +15,12 @@ class Captain::Codex::Translator
body = {
model: chat_body['model'] || chat_body[:model],
input: input,
# Codex exige o campo instructions sempre. Se não vier system message,
# usamos uma string com um espaço pra satisfazer o endpoint sem influenciar o comportamento.
instructions: instructions.presence || ' ',
store: false,
stream: true # Codex exige streaming sempre — o Client agrega.
}
body[:instructions] = instructions if instructions
body[:max_output_tokens] = chat_body['max_tokens'] if chat_body['max_tokens']
tools = chat_body['tools'] || chat_body[:tools]

View File

@ -130,6 +130,20 @@ RSpec.describe Captain::Codex::Translator do
expect(result.keys).not_to include(:temperature, :top_p, :frequency_penalty)
end
it 'always includes instructions (empty placeholder when no system message)' do
chat = {
'model' => 'gpt-5.4',
'messages' => [{ 'role' => 'user', 'content' => 'Oi' }]
}
result = described_class.chat_to_responses(chat)
# Codex exige o campo instructions mesmo sem system message.
expect(result).to have_key(:instructions)
expect(result[:instructions]).not_to be_nil
expect(result[:instructions]).not_to eq('')
end
end
describe '.responses_to_chat' do