codexed 0.0.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.
codexed-0.0.1/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024, Philipp Temminghoff
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.
22
+
codexed-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,60 @@
1
+ Metadata-Version: 2.4
2
+ Name: codexed
3
+ Version: 0.0.1
4
+ Summary: Alternative codex app-server client
5
+ Keywords:
6
+ Author: Philipp Temminghoff
7
+ Author-email: Philipp Temminghoff <philipptemminghoff@googlemail.com>
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Framework :: Pydantic
12
+ Classifier: Framework :: Pydantic :: 2
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Documentation
21
+ Classifier: Topic :: Software Development
22
+ Classifier: Topic :: Utilities
23
+ Classifier: Typing :: Typed
24
+ Requires-Dist: anyenv>=2.0.15
25
+ Requires-Dist: pydantic
26
+ Requires-Dist: schemez
27
+ Requires-Python: >=3.13
28
+ Project-URL: Code coverage, https://app.codecov.io/gh/phil65/codexed
29
+ Project-URL: Discussions, https://github.com/phil65/codexed/discussions
30
+ Project-URL: Documentation, https://phil65.github.io/codexed/
31
+ Project-URL: Issues, https://github.com/phil65/codexed/issues
32
+ Project-URL: Source, https://github.com/phil65/codexed
33
+ Description-Content-Type: text/markdown
34
+
35
+ # Codexed
36
+
37
+ [![PyPI License](https://img.shields.io/pypi/l/codexed.svg)](https://pypi.org/project/codexed/)
38
+ [![Package status](https://img.shields.io/pypi/status/codexed.svg)](https://pypi.org/project/codexed/)
39
+ [![Monthly downloads](https://img.shields.io/pypi/dm/codexed.svg)](https://pypi.org/project/codexed/)
40
+ [![Distribution format](https://img.shields.io/pypi/format/codexed.svg)](https://pypi.org/project/codexed/)
41
+ [![Wheel availability](https://img.shields.io/pypi/wheel/codexed.svg)](https://pypi.org/project/codexed/)
42
+ [![Python version](https://img.shields.io/pypi/pyversions/codexed.svg)](https://pypi.org/project/codexed/)
43
+ [![Implementation](https://img.shields.io/pypi/implementation/codexed.svg)](https://pypi.org/project/codexed/)
44
+ [![Releases](https://img.shields.io/github/downloads/phil65/codexed/total.svg)](https://github.com/phil65/codexed/releases)
45
+ [![Github Contributors](https://img.shields.io/github/contributors/phil65/codexed)](https://github.com/phil65/codexed/graphs/contributors)
46
+ [![Github Discussions](https://img.shields.io/github/discussions/phil65/codexed)](https://github.com/phil65/codexed/discussions)
47
+ [![Github Forks](https://img.shields.io/github/forks/phil65/codexed)](https://github.com/phil65/codexed/forks)
48
+ [![Github Issues](https://img.shields.io/github/issues/phil65/codexed)](https://github.com/phil65/codexed/issues)
49
+ [![Github Issues](https://img.shields.io/github/issues-pr/phil65/codexed)](https://github.com/phil65/codexed/pulls)
50
+ [![Github Watchers](https://img.shields.io/github/watchers/phil65/codexed)](https://github.com/phil65/codexed/watchers)
51
+ [![Github Stars](https://img.shields.io/github/stars/phil65/codexed)](https://github.com/phil65/codexed/stars)
52
+ [![Github Repository size](https://img.shields.io/github/repo-size/phil65/codexed)](https://github.com/phil65/codexed)
53
+ [![Github last commit](https://img.shields.io/github/last-commit/phil65/codexed)](https://github.com/phil65/codexed/commits)
54
+ [![Github release date](https://img.shields.io/github/release-date/phil65/codexed)](https://github.com/phil65/codexed/releases)
55
+ [![Github language count](https://img.shields.io/github/languages/count/phil65/codexed)](https://github.com/phil65/codexed)
56
+ [![Github commits this month](https://img.shields.io/github/commit-activity/m/phil65/codexed)](https://github.com/phil65/codexed)
57
+ [![Package status](https://codecov.io/gh/phil65/codexed/branch/main/graph/badge.svg)](https://codecov.io/gh/phil65/codexed/)
58
+ [![PyUp](https://pyup.io/repos/github/phil65/codexed/shield.svg)](https://pyup.io/repos/github/phil65/codexed/)
59
+
60
+ [Read the documentation!](https://phil65.github.io/codexed/)
@@ -0,0 +1,26 @@
1
+ # Codexed
2
+
3
+ [![PyPI License](https://img.shields.io/pypi/l/codexed.svg)](https://pypi.org/project/codexed/)
4
+ [![Package status](https://img.shields.io/pypi/status/codexed.svg)](https://pypi.org/project/codexed/)
5
+ [![Monthly downloads](https://img.shields.io/pypi/dm/codexed.svg)](https://pypi.org/project/codexed/)
6
+ [![Distribution format](https://img.shields.io/pypi/format/codexed.svg)](https://pypi.org/project/codexed/)
7
+ [![Wheel availability](https://img.shields.io/pypi/wheel/codexed.svg)](https://pypi.org/project/codexed/)
8
+ [![Python version](https://img.shields.io/pypi/pyversions/codexed.svg)](https://pypi.org/project/codexed/)
9
+ [![Implementation](https://img.shields.io/pypi/implementation/codexed.svg)](https://pypi.org/project/codexed/)
10
+ [![Releases](https://img.shields.io/github/downloads/phil65/codexed/total.svg)](https://github.com/phil65/codexed/releases)
11
+ [![Github Contributors](https://img.shields.io/github/contributors/phil65/codexed)](https://github.com/phil65/codexed/graphs/contributors)
12
+ [![Github Discussions](https://img.shields.io/github/discussions/phil65/codexed)](https://github.com/phil65/codexed/discussions)
13
+ [![Github Forks](https://img.shields.io/github/forks/phil65/codexed)](https://github.com/phil65/codexed/forks)
14
+ [![Github Issues](https://img.shields.io/github/issues/phil65/codexed)](https://github.com/phil65/codexed/issues)
15
+ [![Github Issues](https://img.shields.io/github/issues-pr/phil65/codexed)](https://github.com/phil65/codexed/pulls)
16
+ [![Github Watchers](https://img.shields.io/github/watchers/phil65/codexed)](https://github.com/phil65/codexed/watchers)
17
+ [![Github Stars](https://img.shields.io/github/stars/phil65/codexed)](https://github.com/phil65/codexed/stars)
18
+ [![Github Repository size](https://img.shields.io/github/repo-size/phil65/codexed)](https://github.com/phil65/codexed)
19
+ [![Github last commit](https://img.shields.io/github/last-commit/phil65/codexed)](https://github.com/phil65/codexed/commits)
20
+ [![Github release date](https://img.shields.io/github/release-date/phil65/codexed)](https://github.com/phil65/codexed/releases)
21
+ [![Github language count](https://img.shields.io/github/languages/count/phil65/codexed)](https://github.com/phil65/codexed)
22
+ [![Github commits this month](https://img.shields.io/github/commit-activity/m/phil65/codexed)](https://github.com/phil65/codexed)
23
+ [![Package status](https://codecov.io/gh/phil65/codexed/branch/main/graph/badge.svg)](https://codecov.io/gh/phil65/codexed/)
24
+ [![PyUp](https://pyup.io/repos/github/phil65/codexed/shield.svg)](https://pyup.io/repos/github/phil65/codexed/)
25
+
26
+ [Read the documentation!](https://phil65.github.io/codexed/)
@@ -0,0 +1,295 @@
1
+ #:tombi schema.strict = false
2
+
3
+ [project]
4
+ name = "codexed"
5
+ version = "0.0.1"
6
+ description = "Alternative codex app-server client"
7
+ readme = "README.md"
8
+ requires-python = ">=3.13"
9
+ license = "MIT"
10
+ license-files = ["LICENSE"]
11
+ authors = [
12
+ { name = "Philipp Temminghoff", email = "philipptemminghoff@googlemail.com" },
13
+ ]
14
+ keywords = []
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Framework :: Pydantic",
18
+ "Framework :: Pydantic :: 2",
19
+ "Intended Audience :: Developers",
20
+ "Operating System :: OS Independent",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3 :: Only",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Programming Language :: Python :: 3.14",
26
+ "Topic :: Documentation",
27
+ "Topic :: Software Development",
28
+ "Topic :: Utilities",
29
+ "Typing :: Typed",
30
+ ]
31
+ dependencies = [
32
+ "anyenv>=2.0.15",
33
+ "pydantic",
34
+ "schemez",
35
+ # Only add below (Copier)
36
+ ]
37
+
38
+ [project.urls]
39
+ "Code coverage" = "https://app.codecov.io/gh/phil65/codexed"
40
+ Discussions = "https://github.com/phil65/codexed/discussions"
41
+ Documentation = "https://phil65.github.io/codexed/"
42
+ Issues = "https://github.com/phil65/codexed/issues"
43
+ Source = "https://github.com/phil65/codexed"
44
+
45
+ [dependency-groups]
46
+ dev = [
47
+ "devtools",
48
+ "pyreadline3",
49
+ "pytest",
50
+ "pytest-cov",
51
+ # Only add below (Copier)
52
+ ]
53
+ benchmark = ["pyinstrument"]
54
+ docs = [
55
+ "mkdocs-material",
56
+ "mkdocs-mknodes",
57
+ # Only add below (Copier)
58
+ ]
59
+ lint = [
60
+ "mypy; python_version >= '3.14'",
61
+ "mypy[faster-cache]; python_version < '3.14'",
62
+ "ruff",
63
+ # Only add below (Copier)
64
+ ]
65
+
66
+ [build-system]
67
+ requires = ["uv_build>=0.8.22"]
68
+ build-backend = "uv_build"
69
+
70
+ [tool.coverage.report]
71
+ exclude_lines = [
72
+ "pragma: no cover",
73
+ "if TYPE_CHECKING:",
74
+ "@overload",
75
+ "except ImportError",
76
+ 'if __name__ == "__main__":',
77
+ ]
78
+
79
+ [tool.mknodes]
80
+ allowed-commit-types = [
81
+ "fix",
82
+ "feat",
83
+ "refactor",
84
+ "docs",
85
+ "test",
86
+ "build",
87
+ "chore",
88
+ ]
89
+ docstring-style = "google"
90
+
91
+ [tool.mypy]
92
+ python_version = "3.13"
93
+ disable_error_code = ["misc", "import"]
94
+ pretty = true
95
+ check_untyped_defs = true
96
+ exclude = ["venv/", ".venv/", "reference/"]
97
+ plugins = ["pydantic.mypy"]
98
+
99
+ [tool.pyright]
100
+ venvPath = "."
101
+ venv = ".venv"
102
+ pythonVersion = "3.13"
103
+ pythonPlatform = "All"
104
+ typeCheckingMode = "basic"
105
+ deprecateTypingAliases = true
106
+ reportMissingTypeStubs = false
107
+ reportUnusedCallResult = false
108
+ reportUnknownVariableType = false
109
+ reportAny = false
110
+ reportImplicitOverride = false
111
+ reportUnusedFunction = false
112
+ reportImplicitStringConcatenation = false
113
+ reportIgnoreCommentWithoutRule = false
114
+ reportUnannotatedClassAttribute = false
115
+ reportSelfClsParameterName = false
116
+ reportPrivateImportUsage = false
117
+
118
+ [tool.pytest]
119
+ log_cli = true
120
+ log_date_format = "%Y-%m-%d %H:%M:%S"
121
+ log_format = "%(asctime)s %(levelname)s %(message)s"
122
+ minversion = "9.0"
123
+ testpaths = ["tests/"]
124
+ asyncio_mode = "auto"
125
+
126
+ [tool.ruff]
127
+ line-length = 100
128
+ extend-exclude = ["docs", "reference"]
129
+ target-version = "py313"
130
+
131
+ [tool.ruff.lint]
132
+ future-annotations = true
133
+ select = [
134
+ "A", # Flake8-builtins
135
+ # "ANN", # Flake8-Annotations
136
+ # "ASYNC", # Flake8-Async
137
+ # "ARG", # # Flake8-Unused-Arguments
138
+ "B", # flake8-bugbear
139
+ "BLE", # Flake8-blind-except
140
+ "C",
141
+ "C4", # flake8-comprehensions
142
+ # "C90", # MCCabe
143
+ "COM", # Flake8-commas
144
+ # "CPY", # Copyright-related rules
145
+ "D", # PyDocStyle
146
+ # "DTZ", # Flake8- Datetimez
147
+ "E", # PyCodeStyle Error
148
+ "EM", # flake8-errmsg
149
+ # "ERA", # Eradicate
150
+ "EXE", # flake8-executable
151
+ "F", # PyFlakes
152
+ "FA", # flake8-future-annotations
153
+ # "FBT", # flake8-boolean-trap
154
+ # "FIX", # flake8-fixme
155
+ "FLY", # flynt
156
+ "G", # flake8-logging-format
157
+ "I", # ISort
158
+ "ICN", # Flake8-import-conventions
159
+ "INP", # flake8-no-pep420
160
+ "INT", # flake8-gettext
161
+ "ISC", # flake8-implicit-str-concat
162
+ "N", # pep8-naming
163
+ # "NPY", # numpy-specific rules
164
+ # "PD", # pandas-vet
165
+ "PERF", # perflint
166
+ # "PGH", # pygrep-hooks
167
+ "PIE", # flake8-pie
168
+ "PLE", # PyLint Error
169
+ "PLC", # PyLint convention
170
+ # "PLW", # PyLint Warning
171
+ "PLR", # PyLint refactor
172
+ "PT", # flake8-pytest-style
173
+ "PTH", # flake8-use-pathlib
174
+ "PYI", # flake8-pyi
175
+ "Q", # flake8-quotes
176
+ "RET", # flake8-return
177
+ "RSE", # flake8-raise
178
+ "RUF", # ruff-specific rules
179
+ # "S", # flake8-bandit
180
+ "SIM", # flake8-simplify
181
+ "SLF", # flake8-self
182
+ "SLOT", # flake8-slots
183
+ # "T",
184
+ # "TD", # flake8-todos
185
+ "T10", # flake8-debugger
186
+ # "T20", # flake8-print
187
+ "TC", # flake8-type-checking
188
+ "TID", # flake8-tidy-imports
189
+ "TRY", # tryceratops
190
+ "UP", # PyUpgrade
191
+ "W", # PyCodeStyle warning
192
+ "YTT", # flake8-2020
193
+ ]
194
+ ignore = [
195
+ "C408", # Unnecessary {obj_type} call (rewrite as a literal)
196
+ "B905", # zip() without an explicit strict= parameter
197
+ "C901", # {name} is too complex ({complexity} > {max_complexity})
198
+ "COM812",
199
+ # "CPY001", # Missing copyright notice at top of file
200
+ "D100", # Missing docstring in public module
201
+ "D101", # Missing docstring in public class
202
+ "D102", # Missing docstring in public method
203
+ "D103", # Missing docstring in public function
204
+ "D104", # Missing docstring in public package
205
+ "D105", # Missing docstring in magic method
206
+ "D106", # Missing docstring in public nested class
207
+ "D107", # Missing docstring in __init__
208
+ "D203", # 1 blank line required before class docstring
209
+ "D204", # 1 blank line required after class docstring
210
+ "D213", # Multi-line docstring summary should start at the second line
211
+ "D215", # Section underline is over-indented ("{name}")
212
+ "D400", # First line should end with a period
213
+ "D401", # First line of docstring should be in imperative mood: "{first_line}"
214
+ "D404", # First word of the docstring should not be "This"
215
+ "D406", # Section name should end with a newline ("{name}")
216
+ "D407", # Missing dashed underline after section ("{name}")
217
+ "D408", # Section underline should be in the line following the section's name ("{name}")
218
+ "D409", # Section underline should match the length of its name ("{name}")
219
+ "D413", # Missing blank line after last section ("{name}")
220
+ "EM101", # Exception must not use a string literal, assign to variable first
221
+ "EM102", # Exception must not use an f-string literal, assign to variable first
222
+ "ISC001",
223
+ "PLC0415",
224
+ "PLR0912", # Too many branches
225
+ "PLR0913", # Too many arguments to function call
226
+ "PLR0915", # Too many statements
227
+ # "PLR2004", # Magic values instead of named consts
228
+ "SLF001", # Private member accessed
229
+ "TRY003", # Avoid specifying long messages outside the exception class
230
+ "TC006", # runtime-cast-value
231
+ ]
232
+
233
+ [tool.ruff.lint.flake8-quotes]
234
+ docstring-quotes = "double"
235
+
236
+ [tool.ruff.lint.flake8-type-checking]
237
+ runtime-evaluated-base-classes = [
238
+ "pydantic.BaseModel",
239
+ "sqlalchemy.orm.DeclarativeBase",
240
+ "schemez.Schema",
241
+ "sqlmodel.SQLModel",
242
+ ]
243
+ runtime-evaluated-decorators = [
244
+ "pydantic.validate_call",
245
+ "fastapi.FastAPI.get",
246
+ "fastapi.FastAPI.post",
247
+ "fastmcp.FastMCP.tool",
248
+ "typer.Typer.command",
249
+ ]
250
+
251
+ [tool.ruff.lint.isort]
252
+ lines-after-imports = 2
253
+ # lines-between-types = 1
254
+ # atomic = true
255
+ force-sort-within-sections = true
256
+ combine-as-imports = true
257
+
258
+ [tool.ruff.lint.mccabe]
259
+ max-complexity = 15
260
+
261
+ [tool.ruff.lint.per-file-ignores]
262
+ "__init__.py" = ["E402", "I001"]
263
+ "scripts/*" = ["INP001"]
264
+ "*tests/*" = ["D100"]
265
+
266
+ [tool.ruff.format]
267
+ preview = true
268
+
269
+ [tool.ty.src]
270
+ exclude = ["reference"]
271
+
272
+ [tool.ty.environment]
273
+ python-version = "3.13"
274
+ python-platform = "all"
275
+
276
+ [tool.uv]
277
+ default-groups = ["dev", "lint", "docs"]
278
+
279
+ [tool.uv.build-backend]
280
+ wheel-exclude = [
281
+ ".mypy_cache/**",
282
+ "__pycache__/**",
283
+ "*.pyc",
284
+ "*.pyo",
285
+ ".pytest_cache/**",
286
+ ".ruff_cache/**",
287
+ ]
288
+ source-exclude = [
289
+ ".mypy_cache/**",
290
+ "__pycache__/**",
291
+ "*.pyc",
292
+ "*.pyo",
293
+ ".pytest_cache/**",
294
+ ".ruff_cache/**",
295
+ ]
@@ -0,0 +1,70 @@
1
+ # Codex Adapter
2
+
3
+ Python adapter for the [Codex](https://github.com/openai/codex) app-server JSON-RPC protocol.
4
+
5
+ ## Quick Start
6
+
7
+ ```python
8
+ import asyncio
9
+ from codexed import CodexClient
10
+ from codexed.models.events import AgentMessageDeltaEvent, TurnCompletedEvent, get_text_delta
11
+
12
+ async def main():
13
+ async with CodexClient() as client:
14
+ session = await client.thread_start(cwd="/path/to/project")
15
+
16
+ async for event in session.turn_stream("Help me refactor this code"):
17
+ match event:
18
+ case AgentMessageDeltaEvent():
19
+ print(get_text_delta(event), end="", flush=True)
20
+ case TurnCompletedEvent():
21
+ break
22
+
23
+ asyncio.run(main())
24
+ ```
25
+
26
+ ## Structured Responses
27
+
28
+ ```python
29
+ from pydantic import BaseModel
30
+
31
+ class FileList(BaseModel):
32
+ files: list[str]
33
+ total: int
34
+
35
+ async with CodexClient() as client:
36
+ session = await client.thread_start(cwd=".")
37
+ result = await session.turn_stream_structured(
38
+ "List Python files",
39
+ FileList,
40
+ )
41
+ print(result.files) # Typed result
42
+ ```
43
+
44
+ ## Events
45
+
46
+ Events are a discriminated union. Use pattern matching or helper functions:
47
+
48
+ ```python
49
+ from codexed.models.events import (
50
+ AgentMessageDeltaEvent,
51
+ CommandExecutionOutputDeltaEvent,
52
+ TurnCompletedEvent,
53
+ TurnErrorEvent,
54
+ get_text_delta,
55
+ is_delta_event,
56
+ )
57
+
58
+ async for event in client.turn_stream(thread_id, message):
59
+ match event:
60
+ case AgentMessageDeltaEvent() | CommandExecutionOutputDeltaEvent():
61
+ print(get_text_delta(event), end="")
62
+ case TurnCompletedEvent():
63
+ break
64
+ case TurnErrorEvent(data=data):
65
+ print(f"Error: {data.error}")
66
+ ```
67
+
68
+ ## See Also
69
+
70
+ - [Codex app-server docs](https://github.com/openai/codex/blob/main/codex-rs/app-server/README.md)