0.0
The project is in a healthy, maintained state
A RubyLLM provider that invokes the official Codex CLI, reuses local ChatGPT authentication, and maps RubyLLM structured-output schemas to Codex output schemas.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

Runtime

~> 2.1.1
 Project Readme

RubyLLM Codex provider

Commit messages Gem Version License

This adapter lets RubyLLM invoke the official local Codex CLI as a provider. It supports text completions and structured output through RubyLLM's familiar chat interface.

Authentication is handled by the Codex CLI using the account configured by codex login; the gem does not accept or store an OpenAI API key.

Responses come from the Codex agent harness, not directly from a raw model API. Codex applies its own base instructions and runtime behavior. RubyLLM system messages are passed as Codex developer instructions, which is the closest supported mapping but not an identical wire-level request.

Documentation

This README and the linked repository guides describe the checked-out code. The Ethos Link project page provides the canonical public project guide, overview and resources.

Requirements

  • Ruby 4.0 or newer
  • RubyLLM 2.1.1 or newer, below 2.2
  • Codex CLI 0.162.1 or newer, available as codex
  • Linux or macOS (timeout cleanup relies on POSIX process groups)
  • A completed ChatGPT login: codex login

Install Codex if necessary:

npm install -g @openai/codex
codex login

Check the model list in your installed Codex version before a large run. Model availability depends on the account and currently installed CLI.

For migration steps from RubyLLM 1.x, see UPGRADE.md.

Installation

Add the gem to your application's Gemfile:

gem "ruby_llm-codex", "~> 0.4.0"

Then run bundle install. You can also install it directly:

gem install ruby_llm-codex

Quick start

Set CODEX_MODEL to a model available to the account configured by codex login, then run:

require "ruby_llm-codex"

response = RubyLLM.chat(
  model: ENV.fetch("CODEX_MODEL"), provider: :codex
).ask("Reply with a short greeting.")

puts response.content

Each request starts a local codex exec process. Its output and usage depend on the selected model and account; the gem does not provide its own model list.

Structured output

Require the gem and use Codex as an explicit RubyLLM provider:

require "ruby_llm-codex"

class SummarySchema < Schematist::Schema
  string :summary
end

response = RubyLLM.chat(model: ENV.fetch("CODEX_MODEL"), provider: :codex)
  .with_instructions("Return a concise summary.")
  .with_schema(SummarySchema)
  .with_thinking(effort: :medium)
  .ask("The text to summarize")

pp response.parsed

response.content contains the JSON string. Read response.parsed for the structured Hash, and response.tokens for token counts.

Isolation and reproducibility

By default every request:

  • runs in a fresh empty temporary directory;
  • uses a read-only sandbox;
  • disables interactive approvals;
  • ignores user Codex configuration while retaining authentication;
  • creates an ephemeral Codex session;
  • disables Codex shell snapshots, which are unnecessary because this provider does not support tools;
  • prevents model-generated shell commands from inheriting the parent process environment;
  • passes RubyLLM's system instruction as Codex developer instructions;
  • passes RubyLLM's JSON schema through --output-schema.

These defaults separate the request from the current repository and user configuration. Supplying a working directory, profile or user configuration changes that context deliberately; the adapter still runs the Codex harness. Sandbox behaviour also depends on the installed CLI and host platform.

Configuration

Per request

To deliberately let Codex inspect a repository or use selected configuration:

chat = RubyLLM.chat(model: ENV.fetch("CODEX_MODEL"), provider: :codex)

chat.with_provider_options(
  codex: {
    working_directory: "/path/to/project",
    sandbox: "read-only",
    ignore_user_config: false,
    ephemeral: true,
    timeout: 300,
    shell_environment_inherit: "none"
  }
)

Global

Global configuration is also available:

RubyLLM.configure do |config|
  config.codex_cli_path = "/usr/local/bin/codex"
  config.codex_working_directory = nil
  config.codex_profile = nil
  config.codex_home = nil
  config.codex_ignore_user_config = true
  config.codex_ephemeral = true
  config.codex_timeout = 300
  config.codex_shell_environment_inherit = "none"
end

Only the nested codex namespace is accepted by with_provider_options; unsupported generic provider options raise an error instead of being silently ignored. Use with_thinking for reasoning effort and with_instructions for developer instructions. Those settings, plus features.shell_snapshot and shell_environment_policy.inherit, are reserved from the arbitrary codex.config map so their precedence remains unambiguous.

Deliberate limitations

  • Non-streaming chat only.
  • Text prompts only; attachments are rejected.
  • RubyLLM tools are rejected. Codex remains the generation harness, not a tool execution backend for your application.
  • Temperature is rejected because this Codex path does not expose it.
  • Fresh codex exec process per RubyLLM completion. This prioritizes isolation and predictable behavior over throughput.
  • Multi-turn RubyLLM histories are serialized into a role-labelled transcript. One-shot with_instructions(...).ask(...) requests have the most direct semantic mapping.

Streaming, persistent threads and a long-running app-server client are not implemented by this gem.

Troubleshooting

  • codex is not found: install the Codex CLI, run codex login, or set RubyLLM.config.codex_cli_path to its absolute path.
  • A request times out: increase codex.timeout or CODEX_TIMEOUT for the smoke task. Timed-out process groups are terminated automatically.
  • Codex consumes excessive memory: use the current gem version. The provider explicitly disables Codex shell snapshots, which are unnecessary for its completion-only execution and previously caused runaway Bash processes.
  • Local instructions affect output: keep ignore_user_config: true and do not set a working directory when you need isolated requests.

Contributing

See CONTRIBUTING.md. By participating, you agree to follow the Code of Conduct. Security reports should follow SECURITY.md, not a public issue.

License

MIT License. See LICENSE.

Development and releases

Shared tooling uses published Ethos Gemkit. Keep the exact Gemfile version and workflow commit pins on the same release.

bundle install
bundle exec lefthook install
bundle exec rake verify

Verification uses a fake Codex executable; it makes no live model requests. The optional codex:smoke task requires your Codex account, an available CODEX_MODEL and a bounded process/memory scope.

Release preparation, publication, registry setup and recovery are documented in the Gemkit release guide.

About Ethos Link

Ethos Link is a software company founded by Paulo Fidalgo. This gem is part of the open-source tooling we publish alongside our business products:

  • Reviato: collect private customer feedback and analyse public reviews.
  • Nuntio: prepare, review and schedule social posts.
  • EthosPlaces: find places, opening hours and contact details.

Explore our open-source projects.