Skip to content

About

Async Swift port of OpenAI's Codex SDK with upstream parity tooling and integration tests

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Codex SDK for Swift

CI Swift 6 License

An async-first Swift port of OpenAI's openai-codex Python SDK. It communicates with the Codex app server over newline-delimited JSON-RPC and is pinned to openai/codex@aea26af.

This is an independent community project, not an official OpenAI Swift package.

Installation

Add the package in Xcode, or declare it in Package.swift:

dependencies: [
    .package(url: "https://github.com/jimmystridh/codex-sdk-swift.git", from: "0.1.0")
]

Then add .product(name: "CodexSDK", package: "codex-sdk-swift") to your target dependencies.

Requirements

  • Swift 6.0 or newer
  • macOS 13 or newer, or a recent Swift toolchain on Linux
  • A compatible codex executable on PATH, or CodexConfiguration.codexBinary

The upstream Python wheel pins Codex CLI 0.144.4. SwiftPM cannot bundle that platform-specific executable, so applications should install and pin it separately.

Quickstart

import CodexSDK

let codex = try await Codex.connect()
let thread = try await codex.threadStart()
let result = try await thread.run("Explain this repository")
print(result.finalResponse ?? "")
await codex.close()

The package also includes a small executable:

swift run codex-quickstart "Reply with one sentence"

Configuration and lifecycle

Codex is an actor and initializes lazily on the first API call. Use Codex.connect when startup should fail immediately:

let configuration = CodexConfiguration(
    codexBinary: URL(fileURLWithPath: "/opt/codex/bin/codex"),
    configOverrides: ["model_reasoning_effort=\"high\""],
    workingDirectory: URL(fileURLWithPath: "/work/project"),
    environment: ["RUST_LOG": "warn"]
)

let codex = try await Codex.connect(configuration: configuration)
defer { Task { await codex.close() } }

Threads and turns

let thread = try await codex.threadStart(options: .init(
    approvalMode: .denyAll,
    model: "gpt-5.4",
    sandbox: .readOnly
))

let input: Input = [
    .text("Describe this image"),
    .localImage("/tmp/example.png"),
]

let result = try await thread.run(input, options: .init(
    effort: .high,
    summary: .concise
))

Start a controllable turn and consume its routed stream:

let turn = try await thread.turn("Draft a plan")

for try await notification in try await turn.stream() {
    if case let .agentMessageDelta(delta) = notification.payload {
        print(delta.delta, terminator: "")
    }
}

A turn stream is single-consumer. Early notifications are buffered, and active turns on one client are routed independently.

Authentication

try await codex.loginAPIKey(apiKey)

let login = try await codex.loginChatGPTDeviceCode()
print("Open \(login.verificationUrl) and enter \(login.userCode)")
let completed = try await login.wait()

Errors and retries

let result = try await retryOnOverload {
    try await thread.run("Continue")
}

do {
    _ = try await codex.models()
} catch let CodexError.jsonRPC(error) {
    print(error.kind, error.message)
}

Unknown enum strings, thread-item variants, and notifications are retained so routine upstream protocol additions do not immediately break decoding.

Verification

make check
make live-smoke
make integration-test  # authenticated real model request

The deterministic suite launches a real child app-server process and exercises the JSON-RPC boundary. Source line coverage is above 90% and enforced by scripts/check_coverage.py.

Maintenance

Agent-assisted updates can invoke the project-local $sync-codex-upstream skill.

About

Async Swift port of OpenAI's Codex SDK with upstream parity tooling and integration tests

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages