From 9d5e89560cf3d0282e9fcb7d48d32a9db04b1183 Mon Sep 17 00:00:00 2001 From: Pedro Filho Date: Fri, 21 Aug 2026 11:27:39 -0300 Subject: [PATCH] codex keeps its shell and apply_patch tools on the gpt-5.6 models --- CHANGELOG.md | 1 + package.json | 2 +- src/proxy.test.ts | 23 +++++++++++++++++++---- src/proxy.ts | 10 +++++----- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52ee4e4..246de57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,4 @@ +- [2026-08-21] codex keeps its shell and apply_patch tools on the gpt-5.6 models - [2026-08-18] meter clients that hang up early - [2026-08-18] reclaim bare provider tables - [2026-08-18] settings shows pi diff --git a/package.json b/package.json index 04a0258..7ec8ed3 100644 --- a/package.json +++ b/package.json @@ -59,5 +59,5 @@ "post-commit": "bun x @rubriclab/package post-commit" }, "type": "module", - "version": "0.0.65" + "version": "0.0.66" } diff --git a/src/proxy.test.ts b/src/proxy.test.ts index b223a78..2e0d3b6 100644 --- a/src/proxy.test.ts +++ b/src/proxy.test.ts @@ -44,13 +44,11 @@ describe('chatgpt dialect adapter', () => { expect(adapted.max_output_tokens).toBeUndefined() }) - test('merges lifted developer messages after existing instructions', () => { + test('merges lifted system messages after existing instructions', () => { const adapted = JSON.parse( adaptChatGptRequest( JSON.stringify({ - input: [ - { content: [{ text: 'Prefer short replies.', type: 'input_text' }], role: 'developer' } - ], + input: [{ content: [{ text: 'Prefer short replies.', type: 'input_text' }], role: 'system' }], instructions: 'You are a coding agent.' }) ) @@ -59,6 +57,23 @@ describe('chatgpt dialect adapter', () => { expect(adapted.input).toHaveLength(0) }) + test('keeps developer messages in input', () => { + const adapted = JSON.parse( + adaptChatGptRequest( + JSON.stringify({ + input: [ + { content: [{ text: 'You are working inside bb.', type: 'input_text' }], role: 'developer' }, + { content: [{ text: 'Drop this one.', type: 'input_text' }], role: 'system' }, + { content: [{ text: 'hi', type: 'input_text' }], role: 'user' } + ], + instructions: 'You are Codex.' + }) + ) + ) + expect(adapted.instructions).toBe('You are Codex.\n\nDrop this one.') + expect(adapted.input.map((item: { role: string }) => item.role)).toEqual(['developer', 'user']) + }) + test('leaves codex-shaped requests and non-json bodies alone', () => { const codexShaped = JSON.stringify({ input: [{ content: [{ text: 'hi', type: 'input_text' }], role: 'user' }], diff --git a/src/proxy.ts b/src/proxy.ts index 6313f19..50ab7cd 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -239,7 +239,9 @@ function messageText(item: ResponsesInputMessage): string { // The ChatGPT codex backend rejects requests third-party harnesses send to a // standard Responses endpoint: system messages must ride in `instructions` // ("System messages are not allowed") and `max_output_tokens` is unsupported. -// Codex's own requests already have that shape, so this is a no-op for them. +// Developer messages are accepted and must stay in `input`: codex sends its +// tool contract as developer items, and the gpt-5.6 models drop the shell and +// apply_patch tools when those items arrive folded into `instructions`. export function adaptChatGptRequest(raw: string): string { let parsed: { input?: unknown; instructions?: unknown; [key: string]: unknown } try { @@ -250,10 +252,8 @@ export function adaptChatGptRequest(raw: string): string { if (typeof parsed !== 'object' || parsed === null || !Array.isArray(parsed.input)) { return raw } - const isSystem = (item: unknown): item is ResponsesInputMessage => { - const role = (item as ResponsesInputMessage | null)?.role - return role === 'system' || role === 'developer' - } + const isSystem = (item: unknown): item is ResponsesInputMessage => + (item as ResponsesInputMessage | null)?.role === 'system' const lifted = parsed.input.filter(isSystem).map(messageText) const instructions = [ ...(typeof parsed.instructions === 'string' ? [parsed.instructions] : []),