@yadimon/codex-to-llm
v1.1.1
Published
Run stateless Codex text and image prompts using local Codex authentication
Readme
@yadimon/codex-to-llm
Run a stateless text or image prompt through your local Codex sign-in from Node.js or the command line.
The package is useful when you need model output inside a script without starting an interactive coding-agent session. It keeps the interface deliberately small: prompt in, text and usage out.
Community package; not an official OpenAI SDK. Node.js
>=20is required.
Install
npm install @yadimon/codex-to-llmThe default mode also requires:
- an installed
codexCLI inPATH(orCODEX_TO_LLM_CLI_PATH) - a valid Codex login at
~/.codex/auth.json(orCODEX_TO_LLM_AUTH_PATH)
Quick start
SDK
import { runPrompt } from "@yadimon/codex-to-llm";
const result = await runPrompt("Classify this as positive or negative: I love it.", {
model: "gpt-5.3-codex-spark",
reasoningEffort: "low",
maxTokens: 32
});
console.log(result.content);
console.log(result.usage);Attach local files, HTTPS URLs, or base64 images through the recommended codex exec backend:
const result = await runPrompt("What is visible in this image?", {
images: [{ type: "file", path: "./screenshot.png" }]
});runPrompt() returns:
{
id: string;
model: string;
prompt: string;
createdAt: number;
content: string;
usage: {
inputTokens: number;
cachedInputTokens: number;
outputTokens: number;
totalTokens: number;
};
raw: { stderr: string; events: unknown[] };
}CLI
npx @yadimon/codex-to-llm --prompt "Return only the word OK."
npx @yadimon/codex-to-llm --input-file ./prompt.txt --json
npx @yadimon/codex-to-llm --input-file ./prompt.txt --stream --json
npx @yadimon/codex-to-llm --prompt "Describe this image." --image ./screenshot.pngRun npx @yadimon/codex-to-llm --help for the full option list.
SDK patterns
Streaming
import { streamPrompt } from "@yadimon/codex-to-llm";
for await (const event of streamPrompt("Explain closures in two sentences.")) {
if (event.type === "response.output_text.delta") {
process.stdout.write(event.delta);
}
}In the default codex exec mode, a delta corresponds to a Codex agent_message, not necessarily one token. Short answers may therefore arrive as one large delta.
Reuse defaults
import { createRunner } from "@yadimon/codex-to-llm";
const fastReadOnly = createRunner({
model: "gpt-5.3-codex-spark",
reasoningEffort: "low",
maxTokens: 128,
timeout: 60_000
});
const result = await fastReadOnly.runPrompt("Summarize this release note: ...");Call options override the defaults passed to createRunner().
Small parallel evaluation
import { runPrompt } from "@yadimon/codex-to-llm";
const cases = [
"Return the sentiment of: Great work.",
"Return the sentiment of: This is broken.",
"Return the sentiment of: It is acceptable."
];
const results = await Promise.all(
cases.map(prompt => runPrompt(prompt, { maxTokens: 16 }))
);
console.log(results.map(result => result.content));Every default-mode call starts its own Codex process and isolated temporary home. The package does not add concurrency limits, retries, or a job queue; add those in the caller for larger batches.
Default mode: codex exec
This is the recommended mode. For each call the package:
- copies the selected Codex auth file into an isolated per-run
CODEX_HOME; - creates a temporary workspace unless
cwdis supplied; - validates and materializes any image inputs, then runs
codex exec --ephemeral --image <file>with JSON output; - disables history persistence, shell/tool surfaces, plugins, multi-agent, and web search by default;
- parses text, usage, and raw events, then removes package-owned temporary directories.
Useful options:
| Option | Default | Purpose |
|---|---|---|
| model | gpt-5.3-codex-spark | Codex model name. |
| reasoningEffort | low | Reasoning effort passed to Codex. |
| maxTokens | 64 | Requested maximum output tokens. |
| timeout | 300000 | Process timeout in milliseconds. |
| sandbox | read-only | Codex sandbox mode. |
| webSearch | disabled | disabled, cached, or live. |
| cwd | temporary directory | Workspace passed to Codex. Supplied directories are not deleted. |
| configHome | temporary directory | Explicit Codex home. Supplied directories are not deleted. |
| signal | - | Abort a running call with an AbortSignal. |
| images | [] | Local files, HTTPS URLs, or base64 PNG/JPEG/GIF/WebP images. |
Each image is limited to 10 MiB, all images together to 20 MiB, and each call to 20 images. HTTPS downloads reject credentials, private/reserved network destinations, unsafe redirects, oversized responses, and unsupported file signatures. Package-owned image files are removed after success, failure, timeout, or abort. The CLI exposes the same input through repeatable --image <path|url|data-url> flags.
Codex CLI controls image fidelity in default mode; the SDK does not expose a separate detail setting for codex exec.
Select a model that supports image input, such as gpt-5.6-sol; a text-only model produces an explicit package error instead of a misleading successful result.
--search is CLI shorthand for --web-search live.
ignoreUserConfig / --ignore-user-config tells Codex to skip the generated per-run config.toml. That file is what disables web search, tools, plugins, and other agent features, so use the option only when you explicitly want raw Codex behavior.
Experimental direct API mode
Direct mode skips the codex process and sends one user message to the ChatGPT/Codex Responses backend using the OAuth token in auth.json.
Use it only for trusted, local, short-lived automation. It is not the public OpenAI API-key endpoint, it can change without notice, and it must not be exposed as a public or shared proxy.
Two explicit inputs are required:
- risk confirmation:
--confirm-direct-api-riskorCODEX_TO_LLM_CONFIRM_DIRECT_API_RISK=1 - caller-owned instructions:
--instructions/directApiInstructions
CLI:
npx @yadimon/codex-to-llm \
--direct-api-call \
--confirm-direct-api-risk \
--model gpt-5.3-codex-spark \
--instructions "Translate to German. Return only the translation." \
--prompt "The package is ready."SDK:
import { runPrompt } from "@yadimon/codex-to-llm";
const result = await runPrompt("The package is ready.", {
directApiCall: true,
confirmDirectApiRisk: true,
directApiInstructions: "Translate to German. Return only the translation.",
model: "gpt-5.3-codex-spark",
reasoningEffort: "low",
signal: AbortSignal.timeout(30_000)
});
console.log(result.content);Direct-mode differences:
- no temporary workspace, generated Codex config, repository instructions, or tool definitions;
- upstream is always requested with
stream: trueandstore: false;runPrompt()aggregates the SSE events locally; maxTokensandtimeoutare not sent by this direct client; use anAbortSignalfor a deadline;- one user message containing the supplied text and image blocks is constructed by the core package;
- no OAuth refresh, retries, rate limiting, or stability guarantee is provided.
For recurring or production batch workloads, prefer the official OpenAI API or Batch API when available for the model and account.
The local-only boundary also follows OpenAI's Services Agreement restrictions around account access, credentials, limits, and resale, and the API authentication guidance to keep credentials secret.
Direct-mode smoke test (repository checkout)
PowerShell:
$env:CODEX_TO_LLM_CONFIRM_DIRECT_API_RISK = "1"
npm run smoke:direct-apimacOS/Linux:
CODEX_TO_LLM_CONFIRM_DIRECT_API_RISK=1 npm run smoke:direct-apiThe script exits before any network request if the confirmation variable is missing.
Environment variables
| Variable | Default | Description |
|---|---|---|
| CODEX_TO_LLM_AUTH_PATH | ~/.codex/auth.json | Codex auth file. |
| CODEX_TO_LLM_CLI_PATH | codex | Codex CLI command or path. |
| CODEX_TO_LLM_WEB_SEARCH | disabled | Default web-search mode. |
| CODEX_TO_LLM_IGNORE_RULES | false | Pass --ignore-rules to Codex. |
| CODEX_TO_LLM_IGNORE_USER_CONFIG | false | Skip the package-generated Codex config. |
| CODEX_TO_LLM_ENV_PASSTHROUGH | - | Comma-separated extra environment names passed to the Codex child. |
| CODEX_TO_LLM_HOME_BASE | platform data directory | Base for generated per-run Codex homes. |
| CODEX_TO_LLM_CONFIRM_DIRECT_API_RISK | - | Set to 1 to confirm direct-mode risk. |
| CODEX_TO_LLM_DIRECT_API_ENDPOINT | ChatGPT/Codex backend | Direct-mode endpoint override for testing. |
| CODEX_TO_LLM_CODEX_CLIENT_VERSION | 0.144.1 | Direct-mode Version header. |
| CODEX_TO_LLM_CODEX_USER_AGENT | codex-cli/0.144.1 | Direct-mode User-Agent header. |
Troubleshooting
Codex CLI not foundorENOENT: install the Codex CLI, checkcodex --version, or setCODEX_TO_LLM_CLI_PATH/cliPathto the executable.Codex auth not found: sign in with Codex or pointCODEX_TO_LLM_AUTH_PATH/authPathat the correctauth.json. Never commit that file.- The response is cut short: increase
maxTokensabove its intentionally small default of64. In direct mode this option is not forwarded upstream. - A call hangs or must follow a client disconnect: default mode has a five-minute timeout. Set
timeoutand/or pass anAbortSignal. Direct mode uses the signal but not thetimeoutoption. - Web search or agent behavior is missing: those capabilities are disabled intentionally. Opt into web search explicitly.
ignoreUserConfigenables broader raw Codex behavior and also bypasses the package's hardening. - An image is rejected before Codex starts: verify that it is PNG, JPEG, GIF, or WebP, within the documented size limits, and supplied as a local file, HTTPS URL, or valid base64 data URL. Private-network image URLs are intentionally blocked.
Development
npm run build --workspace @yadimon/codex-to-llm
npm run lint --workspace @yadimon/codex-to-llm
npm run typecheck --workspace @yadimon/codex-to-llm
npm test --workspace @yadimon/codex-to-llm