Use Codex with local Qwen served by Eole
This experimental recipe targets the Codex CLI and Linux desktop app through
Eole's stateless /v1/responses endpoint. The answering model is local Qwen,
and Codex executes tools under its normal permissions. A working HTTP response
alone does not establish that Qwen can complete a coding task.
Start Eole and check the protocol
From the repository root, complete the Qwen3.8 conversion setup.
The recommended checkpoint is converted RedHatAI/Qwen3.8-27B-INT4.
export EOLE_MODEL_DIR=/mnt/InternalCrucial4/LLM_work
export QWEN38_MODEL="$EOLE_MODEL_DIR/Qwen3.8-27B-INT4"
export EOLE_TORCH_COMPILE=1
export EOLE_COMPILE_MODE=0
eole serve -c recipes/codex/serve.yaml --host 127.0.0.1 --port 5000
This YAML fixes single-sequence greedy generation, a 28,672-token context, a 4096-token output budget, splits prefill into 256-token chunks, and disables MTP for the initial integration test. Chunking limits temporary prefill workspace for the large instruction/tool prompts sent by the desktop app; it does not reduce the configured context window. Establish correctness before comparing MTP throughput.
In another terminal:
python recipes/codex/smoke_test.py --base-url http://127.0.0.1:5000/v1 \
--model qwen3.8-27B
The smoke test checks JSON text, typed SSE text, typed function arguments, and an add-tool/result round trip. It executes only a synthetic integer addition; it does not run generated shell commands.
Create an isolated Codex configuration
python recipes/codex/configure.py --output-dir /tmp/eole-codex-home
mkdir -p /tmp/eole-codex-demo
printf 'EOLE_SENTINEL_42\n' > /tmp/eole-codex-demo/sentinel.txt
The helper creates config.toml and a matching Qwen model catalog. It refuses
to overwrite existing configuration. Context metadata must match the server;
pass --context-window if you change the YAML. The helper sets both catalog
context fields and the top-level Codex context limit to the same value, with
effective_context_window_percent=90. Its defaults also include:
model_context_window = 28672
model_auto_compact_token_limit = 24576
The compaction threshold reserves 4096 tokens below the context limit; it is
adjusted by the same amount when --context-window changes. Keep these values
aligned with the server, and restart Codex in a new chat after changing them.
For an existing isolated home, edit config.toml at the top level (before any
[section]) and update both context_window and max_context_window in
models.json; the helper deliberately refuses to overwrite existing files.
These settings are described in the
official configuration reference.
The provider uses HTTP Responses
with supports_websockets=false, no OpenAI authentication, and disabled hosted
web search. The model name must match the server YAML ID exactly.
For the CLI, install Codex using its official instructions. Run it with the isolated home:
CODEX_HOME=/tmp/eole-codex-home codex -C /tmp/eole-codex-demo
If your Linux desktop package bundles the CLI without installing a codex
command, use that package's bundled binary instead. For example, the tested
package places it at /usr/lib/chatgpt/resources/codex.
Linux desktop app
Quit the running desktop app before launching it with a different CODEX_HOME;
a second invocation can otherwise reuse the existing process and configuration.
Launch your installed app executable from a terminal:
CODEX_HOME=/tmp/eole-codex-home <your-codex-app-executable>
For the Linux package whose desktop launcher is chatgpt, that is:
CODEX_HOME=/tmp/eole-codex-home chatgpt
Select the local qwen3.8-27B (Eole) model in a new local Codex chat and open
/tmp/eole-codex-demo as the project. The custom provider/catalog configuration
is described in the official gateway guide.
Do not select a cloud work environment for this localhost provider. If the model
is absent, check the app's active host and configuration, then restart it.
An existing chat can retain its previous model selection.
First ask it to read sentinel.txt with a tool and report its exact contents.
Then ask it to create a palindrome function and a unittest file, run the tests,
and report their output. Review the tool calls through the normal permission
flow and independently inspect the files and test results.
Return to the default OpenAI configuration
The setup above keeps Qwen configuration in /tmp/eole-codex-home and leaves
~/.codex/config.toml and your normal sign-in untouched. Switching back means
starting Codex with your normal home directory and selecting an OpenAI model.
You do not need to delete the Qwen files or log out of your OpenAI account.
CLI: exit the Qwen session, then launch without the home override:
unset CODEX_HOME
env -u CODEX_HOME codex
Use the bundled CLI path instead of codex if that is how you normally launch
it. Do not pass --oss, --local-provider, a Qwen --model, or an Eole
--config override. In the new session, use /status to verify that the active
provider/model is OpenAI rather than Eole/Qwen. If needed, use /model to
select your usual OpenAI model. Your normal ChatGPT/API authentication is read
from the normal Codex home; sign in normally only if Codex asks.
Linux desktop app: fully quit the app, including any process left running in the tray. Then launch it normally from the desktop menu, or run:
unset CODEX_HOME
env -u CODEX_HOME chatgpt
Replace chatgpt with your installed app executable if different. A second
launch while the Qwen app process is still running can reuse that process and
its configuration. Start a new local chat and select your usual OpenAI
model in the model picker; an existing Qwen chat can retain its model choice.
You should see the normal OpenAI model catalog instead of the isolated Qwen
catalog. If you previously used a different custom CODEX_HOME for your normal
OpenAI setup, restore that original value instead of unsetting it.
If you exported CODEX_HOME=/tmp/eole-codex-home in a shell startup file or
added it to a desktop launcher, remove that override there too, then restart
the terminal/app. The one-command environment assignments in this recipe do
not persist after the command exits.
If you copied the Qwen settings into your normal config manually: back up
~/.codex/config.toml, then restore its previous settings. Remove the Qwen
model value and the custom model_catalog_json path, and remove
model_provider = "eole" or replace it with model_provider = "openai".
The unused [model_providers.eole] table can also be removed. Restore any
web_search setting you changed for the recipe. Keep your other settings and
authentication files. Quit/restart Codex and select an OpenAI model in a new
chat. See the official configuration guide
for configuration locations and override precedence.
Supported behavior and limits
- Text SSE deltas are emitted during generation. Each tool block is buffered until its complete arguments can be parsed, then emitted as a typed call.
- System/developer instructions are combined into one leading system message
for Qwen. Replayed user, assistant, function-call and function-result items
retain their order and call IDs. Use
store=false; server-side history andprevious_response_idare unsupported. - Function tools, namespaced tools, and custom raw-input tools are translated
for Qwen's chat template. Custom tools such as
apply_patchare represented to Qwen as a function with oneinputstring, then translated back to acustom_tool_call. The backend does not enforce a custom grammar. Codex still validates/executes its tool input; malformed patches can fail. - Hosted web/file search, images, JSON-schema output, background responses, encrypted reasoning replay, and server-side compaction are unsupported. Start a fresh chat before reaching the context limit. Requests for these operations return an error instead of silently enabling them.
- Server generation is capped by the YAML. A budget stop emits
response.incomplete; engine/parsing errors emitresponse.failed. Generated-token usage counts include EOS; input token counts use the server tokenizer or its existing estimate fallback. Cache and reasoning breakdowns are unavailable and reported as zero. - The server disables Qwen thinking through its existing chat-template setting; Codex reasoning-effort settings do not change that policy.
- This endpoint adds no authentication. Keep the server bound to loopback. Advanced desktop features and third-party plugins have not been validated against this model. Use short, isolated coding tasks first.
First-prompt troubleshooting
For CUDA out of memory, stop the desktop request/retries and restart the
server with recipes/codex/serve.yaml, not recipes/qwen38/serve.yaml.
The latter enables MTP and unchunked prefill. A short smoke-test prompt does
not exercise the desktop app's much larger instructions and tool definitions.
The server logs the rendered prompt token count and output budget for each
accepted Responses request. Chunked prefill reduces temporary workspace, but
KV caches and other persistent allocations still grow with the context;
long sessions may require a smaller context or fewer client tools.
The settings above were reported to fit the user's local Qwen INT4 desktop
setup. Memory requirements still depend on the hardware and runtime. The
client must reserve room for generation as history and tool results grow;
server-side compaction remains unsupported, so check whether client history
compaction succeeds and start a fresh chat if it fails. In the same test,
disabling plugins did not reduce the reported 53 tools. Do not assume plugin
disabling alone reduces the prompt: check the server's actual tools and
input_tokens counts.
A Unsupported output format 'json_schema' rejection is a separate protocol
limit. The endpoint supports text output only and does not silently discard a
schema constraint. If a later request gets 200 OK, inspect its completion or
failure separately. Streaming HTTP 200 means the stream opened; a terminal
response.failed event still reports a failed inference. After any allocation
failure, failed-request decoder/MTP state is cleared before the next request.
Validation status
CPU protocol regression tests cover streaming, function/custom/namespaced calls, tool-result replay, tag boundaries, EOS handling, input limits, and error/incomplete responses. Codex CLI 0.162.0-alpha.2, bundled with the Linux app, accepted the generated model catalog and completed a Responses tool-call round trip against a deterministic fake inference engine. Its shell tool hit a sandbox-directory error in the development environment, so that check does not establish successful shell execution or Qwen coding quality.
The installed Linux app code reads CODEX_HOME, and its app-server
initialize/model/list checks exposed the generated local Qwen catalog entry.
The desktop UI and live GPU
Qwen workflow still require validation on the host. Record your app/CLI version
and smoke-test results before treating this as a validated integration.