codexapi 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
codexapi-0.1.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 yieldthought
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,78 @@
1
+ Metadata-Version: 2.1
2
+ Name: codexapi
3
+ Version: 0.1.1
4
+ Summary: Minimal Python API for running the Codex CLI.
5
+ License: MIT
6
+ Keywords: codex,agent,cli,openai
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Operating System :: OS Independent
9
+ Requires-Python: >=3.8
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+
13
+ # CodexAPI
14
+
15
+ Use codex from python as easily as calling a function with your codex credits instead of the API.
16
+
17
+ ## Requirements
18
+
19
+ - Codex CLI installed and authenticated (`codex` must be on your PATH).
20
+ - Python 3.8+.
21
+
22
+ ## Install
23
+
24
+ ```bash
25
+ pip install codexapi
26
+ ```
27
+
28
+ ## Quickstart
29
+
30
+ ```python
31
+ from codexapi import agent, Agent
32
+
33
+ # Run one-shot tasks as a function call
34
+ print(agent("Say hello"))
35
+
36
+ # Run a multi-turn conversation as a session
37
+ session = Agent(cwd="/path/to/project")
38
+ print(session("Summarize this repo."))
39
+ print(session("Now list any risks."))
40
+ ```
41
+
42
+ ## API
43
+
44
+ ### `agent(prompt, cwd=None, *, yolo=False, agent="codex") -> str`
45
+
46
+ Runs a single Codex turn and returns only the agent's message. Any reasoning
47
+ items are filtered out.
48
+
49
+ - `prompt` (str): prompt to send to Codex.
50
+ - `cwd` (str | PathLike | None): working directory for the Codex session.
51
+ - `yolo` (bool): pass `--yolo` to Codex when true.
52
+ - `agent` (str): agent backend to use (only `"codex"` is supported).
53
+
54
+ ### `Agent(cwd=None, *, yolo=False, agent="codex", trace_id=None)`
55
+
56
+ Creates a stateful session wrapper. Calling the instance sends the prompt into
57
+ the same conversation and returns only the agent's message.
58
+
59
+ - `__call__(prompt) -> str`: send a prompt to Codex and return the message.
60
+ - `thread_id -> str | None`: expose the underlying session id once created.
61
+ - `trace_id` (str | None): Codex thread id to resume from the first call.
62
+ - `yolo` (bool): pass `--yolo` to Codex when true.
63
+ - `agent` (str): agent backend to use (only `"codex"` is supported).
64
+
65
+ ## Behavior notes
66
+
67
+ - Uses `codex exec --json` and parses JSONL events for `agent_message` items.
68
+ - Automatically passes `--skip-git-repo-check` so it can run outside a git repo.
69
+ - Passes `--yolo` when enabled (use with care).
70
+ - Raises `RuntimeError` if Codex exits non-zero or returns no agent message.
71
+
72
+ ## Configuration
73
+
74
+ Set `CODEX_BIN` to point at a non-default Codex binary:
75
+
76
+ ```bash
77
+ export CODEX_BIN=/path/to/codex
78
+ ```
@@ -0,0 +1,66 @@
1
+ # CodexAPI
2
+
3
+ Use codex from python as easily as calling a function with your codex credits instead of the API.
4
+
5
+ ## Requirements
6
+
7
+ - Codex CLI installed and authenticated (`codex` must be on your PATH).
8
+ - Python 3.8+.
9
+
10
+ ## Install
11
+
12
+ ```bash
13
+ pip install codexapi
14
+ ```
15
+
16
+ ## Quickstart
17
+
18
+ ```python
19
+ from codexapi import agent, Agent
20
+
21
+ # Run one-shot tasks as a function call
22
+ print(agent("Say hello"))
23
+
24
+ # Run a multi-turn conversation as a session
25
+ session = Agent(cwd="/path/to/project")
26
+ print(session("Summarize this repo."))
27
+ print(session("Now list any risks."))
28
+ ```
29
+
30
+ ## API
31
+
32
+ ### `agent(prompt, cwd=None, *, yolo=False, agent="codex") -> str`
33
+
34
+ Runs a single Codex turn and returns only the agent's message. Any reasoning
35
+ items are filtered out.
36
+
37
+ - `prompt` (str): prompt to send to Codex.
38
+ - `cwd` (str | PathLike | None): working directory for the Codex session.
39
+ - `yolo` (bool): pass `--yolo` to Codex when true.
40
+ - `agent` (str): agent backend to use (only `"codex"` is supported).
41
+
42
+ ### `Agent(cwd=None, *, yolo=False, agent="codex", trace_id=None)`
43
+
44
+ Creates a stateful session wrapper. Calling the instance sends the prompt into
45
+ the same conversation and returns only the agent's message.
46
+
47
+ - `__call__(prompt) -> str`: send a prompt to Codex and return the message.
48
+ - `thread_id -> str | None`: expose the underlying session id once created.
49
+ - `trace_id` (str | None): Codex thread id to resume from the first call.
50
+ - `yolo` (bool): pass `--yolo` to Codex when true.
51
+ - `agent` (str): agent backend to use (only `"codex"` is supported).
52
+
53
+ ## Behavior notes
54
+
55
+ - Uses `codex exec --json` and parses JSONL events for `agent_message` items.
56
+ - Automatically passes `--skip-git-repo-check` so it can run outside a git repo.
57
+ - Passes `--yolo` when enabled (use with care).
58
+ - Raises `RuntimeError` if Codex exits non-zero or returns no agent message.
59
+
60
+ ## Configuration
61
+
62
+ Set `CODEX_BIN` to point at a non-default Codex binary:
63
+
64
+ ```bash
65
+ export CODEX_BIN=/path/to/codex
66
+ ```
@@ -0,0 +1,24 @@
1
+ [build-system]
2
+ requires = ["setuptools>=65,<69", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "codexapi"
7
+ version = "0.1.1"
8
+ description = "Minimal Python API for running the Codex CLI."
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ license = { text = "MIT" }
12
+ keywords = ["codex", "agent", "cli", "openai"]
13
+ classifiers = [
14
+ "Programming Language :: Python :: 3",
15
+ "Operating System :: OS Independent",
16
+ ]
17
+
18
+ dependencies = []
19
+
20
+ [tool.setuptools]
21
+ package-dir = {"" = "src"}
22
+
23
+ [tool.setuptools.packages.find]
24
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,6 @@
1
+ """Minimal Python API for running the Codex CLI."""
2
+
3
+ from .client import Agent, agent
4
+
5
+ __all__ = ["Agent", "agent"]
6
+ __version__ = "0.1.1"
@@ -0,0 +1,172 @@
1
+ """Codex CLI wrapper used by the codexapi public interface."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import os
7
+ import subprocess
8
+ from typing import Optional, Tuple, Union
9
+
10
+ Pathish = Union[str, os.PathLike]
11
+
12
+ _CODEX_BIN = os.environ.get("CODEX_BIN", "codex")
13
+
14
+
15
+ def agent(
16
+ prompt: str,
17
+ cwd: Optional[Pathish] = None,
18
+ *,
19
+ yolo: bool = False,
20
+ agent: str = "codex",
21
+ ) -> str:
22
+ """Run a single Codex turn and return only the agent's message.
23
+
24
+ Args:
25
+ prompt: The user prompt to send to Codex.
26
+ cwd: Optional working directory for the Codex session.
27
+ yolo: Whether to pass --yolo to Codex.
28
+ agent: Agent backend to use (only "codex" is supported).
29
+
30
+ Returns:
31
+ The agent's visible response text with reasoning traces removed.
32
+ """
33
+ _require_codex_agent(agent)
34
+ message, _thread_id = _run_codex(
35
+ prompt=prompt,
36
+ cwd=cwd,
37
+ thread_id=None,
38
+ yolo=yolo,
39
+ )
40
+ return message
41
+
42
+
43
+ class Agent:
44
+ """Stateful Codex session wrapper that resumes the same conversation.
45
+
46
+ Example:
47
+ session = Agent()
48
+ first = session("Say hi")
49
+ follow_up = session("What did you just say?")
50
+ """
51
+
52
+ def __init__(
53
+ self,
54
+ cwd: Optional[Pathish] = None,
55
+ *,
56
+ yolo: bool = False,
57
+ agent: str = "codex",
58
+ trace_id: Optional[str] = None,
59
+ ) -> None:
60
+ """Create a new session wrapper.
61
+
62
+ Args:
63
+ cwd: Optional working directory for the Codex session.
64
+ yolo: Whether to pass --yolo to Codex.
65
+ agent: Agent backend to use (only "codex" is supported).
66
+ trace_id: Optional Codex thread id to resume from the first call.
67
+ """
68
+ _require_codex_agent(agent)
69
+ self._cwd = cwd
70
+ self._yolo = yolo
71
+ self._thread_id: Optional[str] = trace_id
72
+
73
+ def __call__(self, prompt: str) -> str:
74
+ """Send a prompt to Codex and return only the agent's message."""
75
+ message, thread_id = _run_codex(
76
+ prompt=prompt,
77
+ cwd=self._cwd,
78
+ thread_id=self._thread_id,
79
+ yolo=self._yolo,
80
+ )
81
+ if thread_id:
82
+ self._thread_id = thread_id
83
+ return message
84
+
85
+ @property
86
+ def thread_id(self) -> Optional[str]:
87
+ """Return the current Codex session id, if any."""
88
+ return self._thread_id
89
+
90
+
91
+ def _run_codex(
92
+ *,
93
+ prompt: str,
94
+ cwd: Optional[Pathish],
95
+ thread_id: Optional[str],
96
+ yolo: bool,
97
+ ) -> Tuple[str, Optional[str]]:
98
+ """Invoke the Codex CLI and return the message plus thread id (if any)."""
99
+ cmd = [
100
+ _CODEX_BIN,
101
+ "exec",
102
+ "--json",
103
+ "--color",
104
+ "never",
105
+ "--skip-git-repo-check",
106
+ ]
107
+ if yolo:
108
+ cmd.append("--yolo")
109
+ if cwd is not None:
110
+ cmd.extend(["--cd", os.fspath(cwd)])
111
+ if thread_id:
112
+ cmd.extend(["resume", thread_id, "-"])
113
+ else:
114
+ cmd.append("-")
115
+
116
+ result = subprocess.run(
117
+ cmd,
118
+ input=prompt,
119
+ text=True,
120
+ capture_output=True,
121
+ cwd=os.fspath(cwd) if cwd is not None else None,
122
+ )
123
+ if result.returncode != 0:
124
+ stderr = result.stderr.strip()
125
+ msg = f"Codex failed with exit code {result.returncode}."
126
+ if stderr:
127
+ msg = f"{msg}\n{stderr}"
128
+ raise RuntimeError(msg)
129
+
130
+ return _parse_jsonl(result.stdout)
131
+
132
+
133
+ def _require_codex_agent(agent_name: str) -> None:
134
+ if agent_name != "codex":
135
+ raise ValueError('Only agent="codex" is supported right now.')
136
+
137
+
138
+ def _parse_jsonl(output: str) -> Tuple[str, Optional[str]]:
139
+ """Extract agent messages and the latest thread id from Codex JSONL output."""
140
+ thread_id: Optional[str] = None
141
+ messages: list[str] = []
142
+ raw_lines: list[str] = []
143
+
144
+ for line in output.splitlines():
145
+ line = line.strip()
146
+ if not line:
147
+ continue
148
+ try:
149
+ event = json.loads(line)
150
+ except json.JSONDecodeError:
151
+ raw_lines.append(line)
152
+ continue
153
+
154
+ if event.get("type") == "thread.started":
155
+ maybe_thread = event.get("thread_id")
156
+ if isinstance(maybe_thread, str):
157
+ thread_id = maybe_thread
158
+
159
+ if event.get("type") == "item.completed":
160
+ item = event.get("item") or {}
161
+ if item.get("type") == "agent_message":
162
+ text = item.get("text")
163
+ if isinstance(text, str):
164
+ messages.append(text)
165
+
166
+ if not messages:
167
+ fallback = "\n".join(raw_lines) if raw_lines else output.strip()
168
+ raise RuntimeError(
169
+ "Codex returned no agent message. Raw output:\n" + fallback
170
+ )
171
+
172
+ return "\n\n".join(messages), thread_id
@@ -0,0 +1,78 @@
1
+ Metadata-Version: 2.1
2
+ Name: codexapi
3
+ Version: 0.1.1
4
+ Summary: Minimal Python API for running the Codex CLI.
5
+ License: MIT
6
+ Keywords: codex,agent,cli,openai
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Operating System :: OS Independent
9
+ Requires-Python: >=3.8
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+
13
+ # CodexAPI
14
+
15
+ Use codex from python as easily as calling a function with your codex credits instead of the API.
16
+
17
+ ## Requirements
18
+
19
+ - Codex CLI installed and authenticated (`codex` must be on your PATH).
20
+ - Python 3.8+.
21
+
22
+ ## Install
23
+
24
+ ```bash
25
+ pip install codexapi
26
+ ```
27
+
28
+ ## Quickstart
29
+
30
+ ```python
31
+ from codexapi import agent, Agent
32
+
33
+ # Run one-shot tasks as a function call
34
+ print(agent("Say hello"))
35
+
36
+ # Run a multi-turn conversation as a session
37
+ session = Agent(cwd="/path/to/project")
38
+ print(session("Summarize this repo."))
39
+ print(session("Now list any risks."))
40
+ ```
41
+
42
+ ## API
43
+
44
+ ### `agent(prompt, cwd=None, *, yolo=False, agent="codex") -> str`
45
+
46
+ Runs a single Codex turn and returns only the agent's message. Any reasoning
47
+ items are filtered out.
48
+
49
+ - `prompt` (str): prompt to send to Codex.
50
+ - `cwd` (str | PathLike | None): working directory for the Codex session.
51
+ - `yolo` (bool): pass `--yolo` to Codex when true.
52
+ - `agent` (str): agent backend to use (only `"codex"` is supported).
53
+
54
+ ### `Agent(cwd=None, *, yolo=False, agent="codex", trace_id=None)`
55
+
56
+ Creates a stateful session wrapper. Calling the instance sends the prompt into
57
+ the same conversation and returns only the agent's message.
58
+
59
+ - `__call__(prompt) -> str`: send a prompt to Codex and return the message.
60
+ - `thread_id -> str | None`: expose the underlying session id once created.
61
+ - `trace_id` (str | None): Codex thread id to resume from the first call.
62
+ - `yolo` (bool): pass `--yolo` to Codex when true.
63
+ - `agent` (str): agent backend to use (only `"codex"` is supported).
64
+
65
+ ## Behavior notes
66
+
67
+ - Uses `codex exec --json` and parses JSONL events for `agent_message` items.
68
+ - Automatically passes `--skip-git-repo-check` so it can run outside a git repo.
69
+ - Passes `--yolo` when enabled (use with care).
70
+ - Raises `RuntimeError` if Codex exits non-zero or returns no agent message.
71
+
72
+ ## Configuration
73
+
74
+ Set `CODEX_BIN` to point at a non-default Codex binary:
75
+
76
+ ```bash
77
+ export CODEX_BIN=/path/to/codex
78
+ ```
@@ -0,0 +1,9 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ src/codexapi/__init__.py
5
+ src/codexapi/client.py
6
+ src/codexapi.egg-info/PKG-INFO
7
+ src/codexapi.egg-info/SOURCES.txt
8
+ src/codexapi.egg-info/dependency_links.txt
9
+ src/codexapi.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ codexapi