Skip to content

Extra codex passa a exigir openai-codex 0.162.1 - #239

Merged
bdcdo merged 3 commits into
mainfrom
chore/openai-codex-0162
Oct 14, 2026
Merged

bdcdo merged 3 commits into
mainfrom
chore/openai-codex-0162

Conversation

@bdcdo

@bdcdo bdcdo commented Oct 14, 2026 •

Copy link
Copy Markdown
Owner

O quê

Com openai-codex 0.162.1, a versão mais recente, dois testes de tests/test_codex_runtime.py falham, e por isso o PR do dependabot para essa versão fica vermelho. test_enabled_features_match_reviewed_list acusa cinco flags que o runtime novo liga por padrão e que ninguém revisou (api_key_model_discovery, browser_annotation_api, in_app_voice, instant_interrupt, ultrafast_mode). test_request_to_model_offers_only_reviewed_tools não acha lista de ferramentas no request do gpt-6-astra e para ali.

Este PR sobe o extra codex para openai-codex==0.162.1, revisa as cinco flags no fonte do runtime, tira CODEX_API_KEY do ambiente em que o catálogo de modelos é lido e ajusta o teste do request ao formato novo.

Como

  • Flags. As cinco ficam ligadas e entram em _REVIEWED_ENABLED_FEATURES. browser_annotation_api e in_app_voice são portões dos apps de desktop, sem leitor no runtime; instant_interrupt interrompe a amostragem só quando chega entrada nova ao turno em curso, o que o provider nunca faz, e o prazo usa turn/interrupt, que cancela o turno por outro caminho; ultrafast_mode só libera service_tier="ultrafast" pedido pela config, que o provider não define. As duas últimas ganham comentário no teste.
  • Catálogo e turno com a mesma credencial. api_key_model_discovery faz o codex debug models, que o provider roda para gravar o catálogo de model_catalog_json, baixar o catálogo da API com a CODEX_API_KEY do ambiente. O app-server dos turnos ignora essa variável e usa o auth.json, e o catálogo sairia de uma credencial e os turnos, de outra. _write_model_catalog passa a rodar o debug models sem CODEX_API_KEY. Com um provider falso local, a mesma chamada com a variável exportada fazia um GET /v1/models antes da mudança e não faz nenhum depois. test_catalogo_e_lido_sem_codex_api_key confere o ambiente do subprocesso.
  • Ferramentas no request. O lugar não mudou: nos modelos com use_responses_lite, as ferramentas vão num item additional_tools do input, e no gpt-5.5, na chave tools. O runtime passou a omitir o item additional_tools quando não há ferramenta, e a exigência de achar uma lista deixou de servir de prova. O teste do request passa a exigir só o conjunto vazio e a ausência de spawn_agent, e o novo test_tool_lists_find_tool_offered_by_runtime tira o override de view_image e confere que _tool_lists acha a ferramenta num modelo de cada forma de request.
  • Classificação de erros. O SDK novo aceita código de erro fora do enum e variante desconhecida do codexErrorInfo; o turno que falha com um deles cai no caso dos demais códigos e falha só a linha, sem nova tentativa. Com o SDK 0.160.1, o mesmo turno abortava a execução inteira com ProviderAbortError (TransportClosedError: Turn is no longer streaming) depois de um único turn/start. test_codigo_de_erro_desconhecido_falha_so_a_linha prende o comportamento novo para um código e para uma variante desconhecidos. Os códigos já classificados não mudam.
  • CHANGELOG.md: a entrada do extra codex passa à 0.162.1 e registra o código desconhecido e o catálogo lido sem CODEX_API_KEY.

Testes

  • main com o runtime 0.162.1, Python 3.13: codex-provider com 2 falhas, as da issue (1208 aprovados, 213 pulados); unit com 1278 aprovados e 120 pulados. Ramo, mesmo ambiente: codex-provider com 1214 aprovados e 213 pulados; unit com 1278 aprovados e 123 pulados, os 3 testes novos de test_codex.py pulados sem o extra. Cobertura de ramos combinada dos dois jobs em 3.13: 100%. Codex continua opcional; ruff format, ruff check, ty, vulture e deptry sem achado.
  • Mutações: _tool_lists lendo só o topo reprova o controle novo; o provider sem features.view_image=false reprova o teste do request; CODEX_API_KEY de volta ao ambiente do debug models reprova test_catalogo_e_lido_sem_codex_api_key; código desconhecido classificado como ProviderTransientError ou como ProviderAbortError reprova os dois casos de test_codigo_de_erro_desconhecido_falha_so_a_linha.
  • A suíte do codex com -X dev -W always::ResourceWarning passa sem ResourceWarning.
  • Teste com a conta do Codex: gpt-6-luna, 2 de 2 linhas processadas, 4532 e 4525 tokens de entrada, nenhum aviso.

Closes #226

bdcdo added 2 commits October 14, 2026 17:23
O runtime 0.162.1 liga cinco flags novas por padrão. Lidas no fonte do
runtime, nenhuma oferece ferramenta ao modelo nem muda o turno de uma linha,
e as cinco entram na lista revisada: api_key_model_discovery só age no
catálogo baixado com chave de API, e o app-server do provider usa o catálogo
estático de model_catalog_json; browser_annotation_api e in_app_voice são
portões dos apps de desktop, sem leitor no runtime; instant_interrupt só
interrompe a amostragem quando chega entrada nova ao turno em curso, o que o
provider não faz; ultrafast_mode só libera service_tier="ultrafast" pedido
pela config, que o provider não define.

O runtime passou a omitir o item additional_tools do input quando não há
ferramenta, e o request dos modelos com use_responses_lite deixou de trazer
lista de ferramentas. O teste do request deixa de exigir uma lista, e um
teste novo liga view_image e confere que _tool_lists acha a ferramenta nas
duas formas de request, o item additional_tools do input e a chave tools do
topo.

Closes #226
@bdcdo

bdcdo commented Oct 14, 2026 •

Copy link
Copy Markdown
Owner Author

Evidência

Versão escolhida: openai-codex==0.162.1, a mais recente estável no PyPI em 14/10/2026 (a mesma do openai-codex-cli-bin); o binário empacotado responde codex-cli 0.162.1. Fonte do runtime lido: codex-rs da tag rust-v0.162.1 do repositório openai/codex (commit 7a078f6), comparado com a tag rust-v0.160.1.

Os dois testes, antes e depois

Mesmo ambiente (Python 3.13, --extra dev --extra codex, openai-codex 0.162.1 instalado), árvore da main (cab65678) e árvore do ramo:

# main, com o runtime 0.162.1
$ python -m pytest
FAILED tests/test_codex_runtime.py::test_enabled_features_match_reviewed_list
  Extra items in the left set:
  'instant_interrupt' 'ultrafast_mode' 'api_key_model_discovery' 'in_app_voice' 'browser_annotation_api'
FAILED tests/test_codex_runtime.py::test_request_to_model_offers_only_reviewed_tools
  AssertionError: gpt-6-astra
  assert []
2 failed, 1190 passed, 213 skipped

# ramo
$ python -m pytest
1193 passed, 213 skipped

Flags novas ligadas pelo runtime

As cinco aparecem em codex features list com os overrides do provider aplicados. Todas ficam ligadas e entram em _REVIEWED_ENABLED_FEATURES; nenhuma vai para _CODEX_CONFIG_OVERRIDES.

Flag O que faz no runtime Onde foi lido Decisão
api_key_model_discovery Com autenticação por chave de API, o gerenciador de modelos baixa o catálogo do endpoint /models do provider em vez de usar o embutido. Na 0.160.1 existia, desligada por padrão. features/src/lib.rs; core/src/thread_manager.rs (build_models_manager); models-manager/src/manager.rs (supports_api_key_discovery); model-provider/src/provider.rs (create_models_manager) Fica. Com model_catalog_json, que o provider sempre passa, o app-server usa StaticModelsManager, cujo set_api_key_model_discovery_enabled não faz nada. O efeito fica no codex debug models de _write_model_catalog, que, com chave de API, passa a ler o catálogo da conta no mesmo provider do modelo, como já acontece com a conta do ChatGPT. Nenhuma ferramenta, nenhum efeito no turno.
browser_annotation_api Portão dos apps de desktop para sites abrirem ferramentas de anotação; "requirements-only". features/src/lib.rs; nenhum leitor fora de features, do schema de config e dos testes Fica. Não há código do runtime que o leia no caminho do turno.
in_app_voice Portão da voz nos apps de desktop; "requirements-only". features/src/lib.rs; nenhum leitor fora de features, do schema de config e dos testes Fica, pelo mesmo motivo.
instant_interrupt Cria o token preempt do passo; ele é cancelado quando chega entrada do usuário ao turno em curso (TurnInput::UserInput na fila, vinda de turn/start ou turn/steer com o turno ativo), e então a amostragem para e o turno segue com a entrada nova. Também faz o code mode ceder em primeiro plano. Na 0.160.1 existia, desligada por padrão. core/src/session/mod.rs (montagem do StepContext); core/src/session/turn.rs (run_sampling_request, try_run_sampling_request); core/src/session/input_queue.rs (watch_user_input, has_user_input); core/src/session/turn_input.rs (steer_input) Fica. O provider abre uma thread efêmera por tentativa, manda um turno e não manda entrada depois dele; o code mode está fora pelo catálogo (tool_mode nulo). O prazo fecha a assinatura do turno e pede turn/interrupt, que passa por interrupt_task e abort_all_tasks (token de cancelamento do turno), não pelo preempt. Comentário no teste registra isso.
ultrafast_mode Deixa passar service_tier="ultrafast" quando a config ou o override o pede, como fast_mode faz com fast. features/src/lib.rs (service_tier_enabled); core/src/config/mod.rs; core/src/agent/role.rs; core/src/session/mod.rs (get_service_tier) Fica. get_service_tier sai cedo sem service_tier configurado, e o provider não o define nem herda config do usuário (o CODEX_HOME é isolado). Nenhum dos requests capturados traz service_tier. Comentário no teste registra isso.

Onde as ferramentas foram parar

Não mudaram de lugar. Nos modelos com use_responses_lite (todos do catálogo embutido menos o gpt-5.5), as ferramentas vão num item additional_tools do input; no gpt-5.5, na chave tools do topo. O que mudou é que o runtime 0.162.1 só põe o item additional_tools quando há ferramenta (core/src/client.rs, build_responses_request: if !prompt.tools.is_empty()); a 0.160.1 o punha sempre, com a lista vazia.

Requests capturados pelo servidor falso do teste, um por modelo do catálogo embutido:

Runtime Modelos com use_responses_lite (10) gpt-5.5
0.160.1, overrides do provider item additional_tools com lista vazia; ferramentas oferecidas: nenhuma tools: []
0.162.1, overrides do provider nenhum item additional_tools, nenhuma lista; ferramentas oferecidas: nenhuma tools: []
0.162.1, sem features.view_image=false item additional_tools com o namespace functions, que contém view_image tools: [view_image]

O teste deixa de exigir uma lista (assert tool_lists), que só provava o lugar quando o runtime mandava a lista vazia. No lugar, test_tool_lists_find_tool_offered_by_runtime tira o override de view_image e confere que _tool_lists acha a ferramenta num modelo de cada forma de request. O teste principal continua exigindo, para os 11 modelos, conjunto de ferramentas oferecidas vazio e nenhum spawn_agent no corpo.

Mutações, com o ramo verde antes e restaurado depois:

Mutação Esperado Obtido
_tool_lists lê só a chave tools do topo o controle reprova no modelo com Responses Lite test_tool_lists_find_tool_offered_by_runtime falha em gpt-6-astra; os outros dois passam
provider sem features.view_image=false o teste principal reprova test_request_to_model_offers_only_reviewed_tools falha em gpt-6-astra com {'functions', 'view_image'} == frozenset()

Classificação de erros do turno

Do SDK 0.160.1 para o 0.162.1 mudaram só generated/v2_all.py e generated/notification_registry.py. A mudança que toca a classificação: CodexErrorInfoValue passou a str, Enum com _missing_, e o codexErrorInfo ganhou dict[str, Any] como última variante. Os códigos conhecidos continuam virando os membros canônicos. Um turn/completed validado com TurnCompletedNotification.model_validate e passado a _raise_turn_error:

codexErrorInfo SDK 0.160.1 SDK 0.162.1
usageLimitExceeded ProviderUsageLimitError ProviderUsageLimitError
serverOverloaded ProviderOverloadedError ProviderOverloadedError
internalServerError ProviderTransientError ProviderTransientError
codigoNovo (texto fora do enum) validação falha ProviderError
{"variantNova": {...}} validação falha ProviderError

Com a validação falhando, o SDK entrega a notificação como UnknownNotification, e o stream do turno, que só para num TurnCompletedNotification, segue até o prazo da tentativa (leitura do código do SDK, não executado de ponta a ponta). Com o 0.162.1, o código desconhecido cai no caso "demais códigos" e falha só a linha, como os códigos já classificados assim. O CHANGELOG registra isso.

Testes executados

Cada job rodado com uv sync exato nos extras do job; a main rodada no mesmo ambiente, com openai-codex 0.162.1 instalado.

Job Ramo main no mesmo ambiente
codex-provider, Python 3.13 1193 passed, 213 skipped 2 failed, 1190 passed, 213 skipped
codex-provider, Python 3.11 1193 passed, 213 skipped 2 failed, 1190 passed, 213 skipped
unit, Python 3.13 1267 passed, 113 skipped 1267 passed, 113 skipped
unit, Python 3.11 1267 passed, 113 skipped não rodado
suíte do codex com -X dev -W always::ResourceWarning (3.13) 263 passed, nenhum ResourceWarning 2 failed, 260 passed
tests/test_codex.py inteiro (3.13, extra codex) 224 passed
cobertura de ramos combinada (unit 3.11 e 3.13, codex 3.11 e 3.13) 100% (3096 linhas, 1220 ramos)
lowest-direct, extras vazios, Python 3.11 1053 passed, 327 skipped
Verify Codex remains optional, 3.11 e 3.13 base e --extra dev sem openai-codex nem openai-codex-cli-bin
quality: ruff format --check, ruff check, ty check, vulture, deptry src todos sem achado

O ramo tem um teste a mais que a main (test_tool_lists_find_tool_offered_by_runtime); nenhum teste removido, pulado ou enfraquecido além da troca de assert tool_lists pelo controle positivo. A contagem de pulados (213 e 113) é a mesma nas duas árvores; os pulados vêm de extras ausentes do job.

Não executados: codex-windows, lowest-direct com all excel polars search-all e o build da documentação.

O teste com a conta do Codex foi feito depois do commit, pela sessão principal; o resultado está abaixo.

Teste com a conta

Feito pela sessão principal depois do commit, com openai-codex 0.162.1 e runtime 0.162.1: duas linhas no gpt-6-luna, as duas processadas, com 4532 e 4525 tokens de entrada, praticamente iguais aos da 0.160.1. Nenhum aviso na execução, inclusive nenhum ResourceWarning, depois do #234.

A main com o #203 foi integrada em fad9677e; o CHANGELOG ficou com a versão nova.

SHA revisado: de6d1f1

…sconhecido

Com CODEX_API_KEY no ambiente, a flag api_key_model_discovery do runtime
0.162.1 faz o `codex debug models` baixar o catálogo da API com essa
chave, enquanto o app-server dos turnos a ignora e usa o auth.json. A
variável sai do ambiente do `debug models`, e o catálogo passa a vir da
mesma credencial dos turnos.

Novo teste prende a classificação do turno que falha com código ou
variante de CodexErrorInfo que o SDK não declara: ProviderError, uma
única thread, sem nova tentativa nem abort.
@bdcdo

bdcdo commented Oct 14, 2026

Copy link
Copy Markdown
Owner Author

Evidência após a revisão

A revisão por subagente novo não trouxe achado que bloqueie o PR. Trouxe quatro pontos, todos tratados no commit f974cf2d:

  1. Catálogo e turno com credenciais diferentes. Com CODEX_API_KEY no ambiente, a flag api_key_model_discovery do runtime 0.162.1 faz o codex debug models de _write_model_catalog baixar o catálogo da API com essa chave, enquanto o app-server dos turnos ignora a variável e usa o auth.json. A variável sai do ambiente do debug models, e test_catalogo_e_lido_sem_codex_api_key confere que o subprocesso roda sem ela, com o resto do ambiente do usuário e o CODEX_HOME isolado.
  2. Código de erro desconhecido sem teste. O SDK 0.162.1 aceita código fora do enum, que vira membro novo de CodexErrorInfoValue, e variante desconhecida, que fica como dict. test_codigo_de_erro_desconhecido_falha_so_a_linha cobre os dois ("codigoNovo" e {"variantNova": {}}) e exige ProviderError que não seja transitório nem abort, com um único thread_start.
  3. CHANGELOG. A entrada da openai-codex 0.162.1: cinco flags novas do runtime e a lista de ferramentas ausente do request quebram dois testes #226 ganha uma frase sobre o catálogo lido com a credencial do auth.json quando CODEX_API_KEY está no ambiente.
  4. Comportamento do código desconhecido com o SDK 0.160.1. A evidência anterior dizia que o turno ficava esperando até o prazo. Não fica: a execução inteira aborta com ProviderAbortError depois de um único turn/start. O corpo do PR foi corrigido.

Catálogo com CODEX_API_KEY exportada

O script chama _write_model_catalog do próprio pacote, com os overrides do provider acrescidos de um provider falso local, e conta os GET que chegam ao servidor falso. Cada rodada exporta uma chave falsa numa variável.

Antes (fad9677e):

exportada: (nenhuma)        modelos no catálogo:   0  GET: []
exportada: CODEX_API_KEY    modelos no catálogo:   0  GET: [('/v1/models?client_version=0.162.1', '')]
exportada: OPENAI_API_KEY   modelos no catálogo:   0  GET: []

Depois (f974cf2d):

exportada: (nenhuma)        modelos no catálogo:   0  GET: []
exportada: CODEX_API_KEY    modelos no catálogo:   0  GET: []
exportada: OPENAI_API_KEY   modelos no catálogo:   0  GET: []

OPENAI_API_KEY não dispara a busca nos dois casos. O catálogo sai vazio porque o provider falso não é o da OpenAI; o que a medida separa é a presença do GET.

Código desconhecido, ponta a ponta

SDK real e backend real contra um app-server falso por stdio, que responde ao turn/start com um turno failed trazendo o codexErrorInfo indicado.

SDK e fonte codexErrorInfo Resultado turn/start
0.160.1, main "codigoNovo" ProviderAbortError: O app-server do Codex encerrou: TransportClosedError: Turn is no longer streaming 1
0.160.1, main {"variantNova": {}} idem 1
0.162.1, ramo "codigoNovo" ProviderError: Turno Codex falhou: falhou no falso, aviso de erro não recuperável 1
0.162.1, ramo {"variantNova": {}} idem 1

Mutações

Cópia de src e tests do commit, PYTHONDONTWRITEBYTECODE=1, -p no:cacheprovider, -o pythonpath=<cópia>/src, import conferido na cópia antes de cada rodada. Suíte: tests/test_codex.py e tests/test_codex_runtime.py, Python 3.13, openai-codex 0.162.1.

Mutação Resultado Teste que reprova
nenhuma 247 aprovados
CODEX_API_KEY de volta ao ambiente do debug models 1 falha, 246 aprovados test_catalogo_e_lido_sem_codex_api_key
código ou variante desconhecidos levantam ProviderTransientError 2 falhas, 245 aprovados test_codigo_de_erro_desconhecido_falha_so_a_linha[codigo] e [variante]: a linha é repetida
código ou variante desconhecidos levantam ProviderAbortError 2 falhas, 245 aprovados test_codigo_de_erro_desconhecido_falha_so_a_linha[codigo] e [variante]

Suítes, ramo ao lado da main no mesmo ambiente

Python 3.13. O ambiente do codex-provider tem openai-codex 0.162.1 nos dois lados.

Job main (92f8086c) Ramo (f974cf2d)
codex-provider 2 falhas (test_enabled_features_match_reviewed_list, test_request_to_model_offers_only_reviewed_tools), 1208 aprovados, 213 pulados 1214 aprovados, 213 pulados
unit 1278 aprovados, 120 pulados 1278 aprovados, 123 pulados

Os quatro testes a mais no ramo são test_catalogo_e_lido_sem_codex_api_key, os dois casos de test_codigo_de_erro_desconhecido_falha_so_a_linha e test_tool_lists_find_tool_offered_by_runtime. No job unit, sem o extra codex, os três de test_codex.py aparecem como pulados.

  • Cobertura de ramos combinada de codex-provider e unit em 3.13: 100% (3111 linhas, 1222 ramos).
  • Codex continua opcional: a instalação base não traz filelock, openai-codex nem openai-codex-cli-bin, e o extra dev não traz os dois últimos.
  • Job quality, com os extras dele: ruff format --check src tests, ruff check src tests, ty check, vulture e deptry src sem achado.
  • tests/test_codex.py e tests/test_codex_runtime.py com -X dev -W always::ResourceWarning: 247 aprovados, nenhum ResourceWarning.
  • Não executados neste commit: os jobs em Python 3.11, lowest-direct e codex-windows, que ficam com o CI.

SHA revisado: f974cf2

@bdcdo
bdcdo merged commit 0527430 into main Oct 14, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

openai-codex 0.162.1: cinco flags novas do runtime e a lista de ferramentas ausente do request quebram dois testes

1 participant