Skip to main content

Async Codex-backed coding agent SDK.

Project description

kagent

Async Python SDK for running Codex-backed coding-agent tasks with a small, memorable thread API.

The PyPI distribution is codex-python-kagent; the import package is kagent.

import asyncio

from kagent import kagent


async def main() -> None:
    agent = kagent()
    run = await agent.thread("main").run("Create hello.txt with exactly: hello")
    print(run.text)


asyncio.run(main())

Status

kagent is experimental. It wraps the local Codex CLI/app-server flow and currently depends on the experimental OpenAI Codex Python SDK for runner="sdk".

The package itself has no required runtime dependencies so it can be built and published cleanly. The default runner uses the Codex CLI. The experimental Codex Python SDK is kept in a local uv dependency group instead of PyPI metadata.

Install

In a uv project:

uv add codex-python-kagent
kagent login

For API-key auth instead of ChatGPT subscription auth:

export OPENAI_API_KEY="sk-..."
kagent login --api-key-env OPENAI_API_KEY

For a headless server without a browser:

kagent login --device-auth

For local development in this repo:

uv sync --group dev --group codex --group examples

The local machine must also have the Codex CLI installed and authenticated:

codex login status

API

Use kagent(...) when you already authenticated with kagent login or codex login.

from kagent import kagent

agent = kagent(workspace=".", model="gpt-5.5", reasoning_effort="medium")
thread = agent.thread("refactor-auth")
await thread.run("Refactor auth.py without changing behavior.")
await thread.run("Now run the tests and fix any failures.")

Create a fresh Codex-named thread by omitting the id:

thread = agent.thread()
await thread.run("Create hello.txt with exactly: hello")
print(thread.id)

Stream events with async for while still getting the final result:

stream = agent.thread("refactor-auth").stream("Run the tests and fix failures.")

async for event in stream:
    print(event.get("type") or event.get("method"))

print(stream.result.text)
print(stream.events)

Or trigger Codex auth from Python after configuring the agent:

import os

from kagent import kagent

agent = kagent(model="gpt-5.5").login()
api_agent = kagent(model="gpt-5.5").login(api_key=os.environ["OPENAI_API_KEY"])
server_agent = kagent(model="gpt-5.5").login(device=True)

Options:

kagent(
    workspace=".",
    model="gpt-5.5",
    reasoning_effort="medium",
    runner="cli",
    ask_for_approval="never",
    sandbox="danger-full-access",
    skip_git_repo_check=True,
    ignore_user_config=False,
    yolo=True,
    codex_bin=None,
    store_path=None,
    mcp_servers=None,
)

agent.thread(id, ...) accepts a human-readable id. kagent maps that id globally to Codex's generated session id using a local shelve store. If you omit id, kagent starts a new Codex thread and adopts Codex's generated thread id as thread.id after the first run starts. By default, the store lives at ~/.kagent/threads, not inside the workspace. Set KAGENT_HOME to move the whole kagent state directory or KAGENT_STORE_PATH to point directly at a custom thread store.

Thread creation and loading:

agent.thread("billing-main") # create only; raise if saved already
agent.load("billing-main")   # resume only; never create

runner="cli" uses codex exec through an async subprocess. It stores Codex's generated session id in that user-level store, then uses codex exec resume on later runs with the same human-readable Thread id. If you need separate threads for separate projects, choose separate ids such as billing-main and website-main.

reasoning_effort maps to Codex's model_reasoning_effort config. The default is model="gpt-5.5" and reasoning_effort="medium". The examples use model="gpt-5.5" and reasoning_effort="low" for lighter test runs.

CLI runs inherit your Codex user config by default, so your configured MCPs are available. Pass ignore_user_config=True when you want an isolated run that skips $CODEX_HOME/config.toml.

You can also provide MCP servers directly from Python. These are passed as Codex config overrides for the run, without editing your global Codex config:

from kagent import McpServer, kagent

agent = kagent(
    mcp_servers={
        "read_ai": McpServer(
            command="npx",
            args=["-y", "mcp-remote@latest", "https://api.read.ai/mcp"],
        ),
        "internal_api": McpServer(
            url="https://internal.example.com/mcp",
            bearer_token_env_var="INTERNAL_MCP_TOKEN",
        ),
    },
)

Use run(verbose=True) when you want the simple API while still printing readable model activity as it arrives:

run = await agent.thread().run("Create hello.txt with exactly: hello", verbose=True)
print(run.text)

Verbose output is grouped by prefix:

event: turn.started
message: Creating result.txt with the requested content.
action: file_change completed: add /path/to/result.txt
event: turn.completed input_tokens=12 output_tokens=4

run() consumes Codex's JSON event stream internally because that is how kagent gets the generated thread id, final output, tool activity, and structured failures. stream() exposes the same event source when you want to handle events yourself.

runner="sdk" uses the experimental Codex app-server SDK and persistent threads. It requires the local development codex dependency group.

agent = kagent(model="gpt-5.5", runner="cli", yolo=True)

await agent.thread("goal-test").run(
    "Create hello.txt with exactly the text hello.",
    goal=True,
)

There is no native codex exec --goal flag. goal=True translates to a prompt beginning with /goal ..., which is the behavior verified locally. Goal runs use the CLI runner, not app-server SDK thread persistence.

yolo=True maps to Codex's --dangerously-bypass-approvals-and-sandbox flag.

Examples

Already logged in with kagent login or codex login:

uv run python examples/01_already_logged_in.py

Trigger ChatGPT/Codex subscription login from Python:

uv run python examples/02_subscription_login.py

Log in with an OpenAI API key from Python:

export OPENAI_API_KEY="sk-..."
uv run python examples/03_api_key_login.py

Stream events in real time:

uv run python examples/04_stream_events.py

Run the OpenHands comparison example:

uv run --group examples python examples/openhands_thread.py

OpenHands may require interactive ChatGPT subscription login on first run.

Development

uv sync --group dev --group codex --group examples
uv run pytest
uv run ruff check .
uv run mypy
uv build

Publish:

export UV_PUBLISH_TOKEN="pypi-..."
uv build
uv publish

The package uses:

  • src/ layout
  • hatchling build backend
  • MIT license
  • py.typed for typed package consumers
  • uv.lock committed for reproducible local development
  • pytest, ruff, and mypy for validation

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

codex_python_kagent-0.1.15.tar.gz (19.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

codex_python_kagent-0.1.15-py3-none-any.whl (17.0 kB view details)

Uploaded Python 3

File details

Details for the file codex_python_kagent-0.1.15.tar.gz.

File metadata

File hashes

Hashes for codex_python_kagent-0.1.15.tar.gz
Algorithm Hash digest
SHA256 60833b7206d7ba95fab72afa071f66fafa31f5d537690a8001f04b6d6d5583ad
MD5 3153142fde870afae76a289b9eaee7f0
BLAKE2b-256 c1c25b72941cae31eb0e964c2645dcdd5e19d3f028dbd25266c6092dedd91f61

See more details on using hashes here.

File details

Details for the file codex_python_kagent-0.1.15-py3-none-any.whl.

File metadata

File hashes

Hashes for codex_python_kagent-0.1.15-py3-none-any.whl
Algorithm Hash digest
SHA256 a45431d541b3009d8963f7a623f4e5fc05627019c4463af9ea8be7a3b5db95a2
MD5 e3a8c2cbebe88ebadaf6bb0b692f2ed3
BLAKE2b-256 c2fc2f1887298a24be2a233e917a8b3014f66470d62924cbafaf848d78d39a82

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page