mpfaffenberger / mpfaffenberger/code_puppy
Core runtime grab-bag: codex client clobbers request.extensions, JWT age guessing, version parser breaks on rc/post releases, unused retry params, pytest check in prod code, blocking fetch in ModelsDevRegistry.__init__
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 814
- Forks
- 278
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 76
Description
Grouped minor findings across the core runtime/model layer (one issue to avoid noise; all are small, independent fixes).
1. chatgpt_codex_client.py — request rebuild clobbers extensions; stream conversion buffers entire response
- Line ~76:
request.extensions = rebuilt.extensionsreplaces caller extensions instead of merging.claude_cache_client.pygot this right ({**rebuilt.extensions, **request.extensions}with a comment explaining why losing flags is dangerous). Codex client should do the same. _convert_stream_to_response()buffers the full SSE stream in memory and returns a fakehttpx.Responsewhose headers still claimcontent-type: text/event-stream/ possiblycontent-encodingfrom the original — copyingresponse.headersverbatim onto a JSON body is fragile; strip transfer-related headers and setcontent-type: application/json.
2. claude_cache_client.py — _get_jwt_age_seconds 'exp' fallback guesses
Lines ~150-160: when only exp is present, age is computed as TOKEN_MAX_AGE_SECONDS - time_until_exp, i.e. assumes all tokens live exactly 3600s. For longer-lived tokens this causes premature refresh storms; for shorter ones it misses expiry. Prefer comparing exp - now < REFRESH_BUFFER directly instead of synthesizing an "age".
3. version_checker.py — _version_tuple cannot parse pre/post-release versions
tuple(int(x) for x in version_str.split('.')) returns None for 1.2.3rc1 or 1.2.3.post1, silently disabling update notification. Use packaging.version.Version (already a transitive dependency).
4. http_utils.py — create_client() ignores its retry_status_codes parameter
Lines ~207-228: parameter accepted, documented by a TODO, never used — misleading API surface. Either implement RetryingClient(httpx.Client) or drop the parameter.
5. config.py — normalize_command_history() checks if \"pytest\" in sys.modules: return
Production code special-casing the test runner is an anti-pattern; tests should patch/inject instead. Same file: import datetime, import os, import configparser re-imported inside multiple function bodies despite top-level imports.
6. reopenable_async_client.py — is_closed race & build_request churn
is_closed reads _is_closed without the asyncio lock (benign but inconsistent with the rest of the class), and build_request() constructs and tears down a full httpx.Client (TLS context and all) per call when closed — expensive; a plain httpx.Request(...) construction would do.
7. models_dev_parser.py — blocking network call in constructor
ModelsDevRegistry.__init__ performs a synchronous 10s-timeout HTTP fetch. Any caller on the event loop (TUI pickers) freezes the UI for up to 10s. Provide an async factory or fetch lazily/cached.
8. callbacks.py — _trigger_callbacks_sync returns None for async callbacks in async contexts
Lines ~243-258: when a sync trigger meets a coroutine while a loop is running, it logs a warning and appends None — the callback silently never runs. Hooks documented as "accept sync or async functions" (CONTRIBUTING table includes sync-triggered hooks like load_models_config) will mysteriously no-op if a plugin makes them async. Consider asyncio.run_coroutine_threadsafe when on a worker thread, or document loudly which hooks must be sync.
Filed by Zen Reviewer A (code-puppy-60635a)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Separate the eight findings into focused changes and inspect the referenced functions in chatgpt_codex_client.py, claude_cache_client.py, version_checker.py, http_utils.py, config.py, reopenable_async_client.py, models_dev_parser.py, and callbacks.py. Compare the Codex request handling with claude_cache_client.py and locate existing pytest coverage before changing behavior. Done means each reported issue has a focused fix or documented decision, with relevant tests passing.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- api, backend, networking, performance, testing-qa
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100