Files
paseo/CODEX_SDK_BINARY_INVESTIGATION.md
T

300 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Codex SDK Binary Investigation Report
**Date:** 2025-12-20
**SDK Version:** @openai/codex-sdk@0.76.0
**Status:** ✅ System binary usage is fully supported
---
## Executive Summary
The `@openai/codex-sdk` library **DOES support using a system-installed Codex binary** instead of the embedded one. This is accomplished via the `codexPathOverride` configuration option in the `CodexOptions` interface.
---
## How the SDK Currently Locates the Codex Binary
### Default Behavior (Embedded Binary)
When no override is provided, the SDK uses the `findCodexPath()` function to locate the embedded binary:
**Source:** `dist/index.js:278-330`
```typescript
function findCodexPath() {
const { platform, arch } = process;
let targetTriple = null;
// Determines platform-specific binary path
// e.g., "aarch64-apple-darwin" for Apple Silicon Macs
const vendorRoot = path2.join(scriptDirName, "..", "vendor");
const archRoot = path2.join(vendorRoot, targetTriple);
const codexBinaryName = process.platform === "win32" ? "codex.exe" : "codex";
const binaryPath = path2.join(archRoot, "codex", codexBinaryName);
return binaryPath;
}
```
### Binary Location Structure
The SDK ships with pre-compiled binaries in the `vendor/` directory:
```
node_modules/@openai/codex-sdk/
├── vendor/
│ ├── aarch64-apple-darwin/codex/codex (40MB - Apple Silicon)
│ ├── x86_64-apple-darwin/codex/codex (Intel Mac)
│ ├── aarch64-unknown-linux-musl/codex/codex (ARM Linux)
│ ├── x86_64-unknown-linux-musl/codex/codex (x86_64 Linux)
│ ├── aarch64-pc-windows-msvc/codex/codex.exe (ARM Windows)
│ └── x86_64-pc-windows-msvc/codex/codex.exe (x86_64 Windows)
```
---
## Configuration Options Available
### `codexPathOverride` Option
**Type Definition:** `dist/index.d.ts:209-218`
```typescript
type CodexOptions = {
codexPathOverride?: string; // ← THIS IS THE KEY OPTION
baseUrl?: string;
apiKey?: string;
env?: Record<string, string>;
};
```
**Implementation:** `dist/index.js:336-338`
```typescript
constructor(options = {}) {
this.exec = new CodexExec(options.codexPathOverride, options.env);
this.options = options;
}
```
**How it works:** `dist/index.js:145-147`
```typescript
constructor(executablePath = null, env) {
this.executablePath = executablePath || findCodexPath();
this.envOverride = env;
}
```
The `codexPathOverride` is passed as `executablePath`. If provided, it bypasses the `findCodexPath()` function entirely.
---
## How to Use a System Codex Binary
### Method 1: Direct Path Specification
```typescript
import { Codex } from '@openai/codex-sdk';
const codex = new Codex({
codexPathOverride: '/Users/moboudra/.asdf/installs/nodejs/22.20.0/bin/codex'
});
```
### Method 2: Dynamic PATH Resolution
```typescript
import { Codex } from '@openai/codex-sdk';
import { execSync } from 'child_process';
const systemCodexPath = execSync('which codex', { encoding: 'utf8' }).trim();
const codex = new Codex({
codexPathOverride: systemCodexPath
});
```
### Method 3: Environment Variable Based (Custom Implementation)
```typescript
import { Codex } from '@openai/codex-sdk';
const codex = new Codex({
codexPathOverride: process.env.CODEX_BINARY_PATH || undefined
});
```
**Note:** The SDK does NOT have a built-in environment variable for this purpose. The `CODEX_BINARY_PATH` above is a custom convention you'd need to implement in your application.
---
## Verification Test Results
### Test Configuration
- **System Codex:** `/Users/moboudra/.asdf/installs/nodejs/22.20.0/bin/codex`
- **Embedded Codex:** `node_modules/@openai/codex-sdk/vendor/aarch64-apple-darwin/codex/codex`
- **Versions:** Both are `codex-cli 0.76.0`
### Test Results
```bash
$ node test-codex-path-override.mjs
Testing codexPathOverride option...
Test 1: Using default embedded binary
✓ Created Codex instance with default settings
Test 2: Using system binary via codexPathOverride
✓ Created Codex instance with codexPathOverride
Test 3: Using which codex result
System codex location: /Users/moboudra/.asdf/installs/nodejs/22.20.0/bin/codex
✓ Created Codex instance with system codex from PATH
✅ All tests passed!
```
---
## Benefits of Using System Codex
### 1. **Version Control**
- Update codex independently via package manager (npm, brew, asdf, etc.)
- No need to wait for SDK release to get latest codex features
- Easier to test beta/development versions
### 2. **Disk Space Savings**
- Embedded binary: ~40MB per architecture
- In a monorepo with multiple node_modules: Saves 40MB × number of installations
- System binary: Single installation regardless of projects
### 3. **Consistency**
- Same codex version across all tools and SDKs
- Easier debugging when CLI and SDK use identical binaries
- Simplified version management
### 4. **Development Workflow**
- Test local codex builds without reinstalling SDK
- Point to custom-compiled binaries for debugging
- A/B test different codex versions easily
---
## Potential Considerations
### 1. **Version Compatibility**
- SDK expects specific codex CLI behavior
- Using mismatched versions might cause issues
- SDK is at v0.76.0, ensure system codex matches or is compatible
### 2. **PATH Availability**
- System binary must be accessible when Node.js process runs
- Consider environment differences (development vs production)
- Absolute paths are safer than relying on PATH resolution
### 3. **No Fallback**
- If codexPathOverride points to invalid/missing binary, execution will fail
- SDK doesn't automatically fall back to embedded binary
- Implement error handling if using dynamic resolution
---
## Environment Variables (Built-in)
The SDK does NOT provide a built-in environment variable for binary path override, but it does use these:
### Used by SDK
1. **`CODEX_INTERNAL_ORIGINATOR_OVERRIDE`** (Internal)
- Source: `dist/index.js:140-141`
- Set to `"codex_sdk_ts"` to identify SDK usage
- Not for user configuration
2. **`OPENAI_BASE_URL`** (Configurable)
- Override via `CodexOptions.baseUrl`
- Also injectable via env
3. **`CODEX_API_KEY`** (Configurable)
- Override via `CodexOptions.apiKey`
- Also injectable via env
### NOT Provided
- ❌ `CODEX_BINARY_PATH` - Not a built-in feature
- ❌ `CODEX_PATH` - Not a built-in feature
- ❌ Auto-discovery via system PATH - Not implemented
---
## Recommended Implementation Pattern
For maximum flexibility, consider this pattern:
```typescript
import { Codex } from '@openai/codex-sdk';
import { execSync } from 'child_process';
import { existsSync } from 'fs';
function createCodexInstance(options = {}) {
// Priority order:
// 1. Explicit override in options
// 2. Environment variable
// 3. System PATH
// 4. Embedded binary (SDK default)
let codexPath = options.codexPathOverride;
if (!codexPath && process.env.CODEX_BINARY_PATH) {
codexPath = process.env.CODEX_BINARY_PATH;
}
if (!codexPath) {
try {
codexPath = execSync('which codex', { encoding: 'utf8' }).trim();
if (!existsSync(codexPath)) {
codexPath = undefined;
}
} catch {
// Fall back to embedded binary
codexPath = undefined;
}
}
return new Codex({
...options,
codexPathOverride: codexPath
});
}
// Usage
const codex = createCodexInstance();
```
---
## Summary
| Question | Answer |
|----------|--------|
| **Can SDK use system codex?** | ✅ Yes, via `codexPathOverride` |
| **Is configuration option available?** | ✅ Yes, in `CodexOptions` interface |
| **Built-in env variable support?** | ❌ No, must implement custom logic |
| **Automatic PATH resolution?** | ❌ No, must provide explicit path |
| **Fallback to embedded?** | ❌ No, fails if override is invalid |
| **Version tested** | 0.76.0 (both system and embedded) |
---
## Conclusion
The `@openai/codex-sdk` library provides full support for using a system-installed Codex binary through the `codexPathOverride` configuration option. This feature is well-designed and allows developers to choose between the convenience of embedded binaries and the flexibility of system-managed installations.
To use a system binary:
1. Install codex globally (via npm, brew, asdf, etc.)
2. Pass the path via `codexPathOverride` when instantiating `Codex`
3. Optionally implement PATH resolution logic for automatic discovery
The embedded binary remains the default, ensuring the SDK works out-of-the-box without requiring system-wide codex installation.