[codex] fix: address follow-up promotion bugs#207
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
📜 Recent review details🧰 Additional context used📓 Path-based instructions (1)tywrap_ir/**/*.py📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🧠 Learnings (3)📓 Common learnings📚 Learning: 2026-03-17T05:27:14.946ZApplied to files:
📚 Learning: 2026-03-17T05:27:08.277ZApplied to files:
🔇 Additional comments (1)
📝 WalkthroughWalkthroughAdds late-response filtering for timed-out IPC requests, skips cache reads in check-mode, shifts docs toward TypeScript NodeBridge examples, configures Python 3.11 in the release workflow, and adds tests and IR improvements for async-generator classification and optimized extractor behavior. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant ProcessIO
participant Transport
participant TimedOutTracker
Client->>ProcessIO: send request (messageId)
ProcessIO->>Transport: write(message)
Transport-->>ProcessIO: response(messageId) Note right of Transport: response arrives before timeout
ProcessIO->>Client: resolve response
alt request times out/aborted
ProcessIO->>TimedOutTracker: mark(messageId)
end
Transport-->>ProcessIO: late response(messageId)
ProcessIO->>TimedOutTracker: consume(messageId)
alt TimedOutTracker had entry
ProcessIO--xClient: ignore late response
else
ProcessIO->>Client: treat as protocol error
end
ProcessIO->>TimedOutTracker: clear() upon transport disposal
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 434233588e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return; | ||
| } | ||
| // Unknown IDs while requests are pending indicate protocol desync. | ||
| this.handleProtocolError(`Unexpected response id ${messageId}`, line); |
There was a problem hiding this comment.
Ignore evicted late-response IDs before raising protocol errors
When a response arrives for a request that already timed out/cancelled, this branch now treats any tracker miss as a protocol desync and rejects all pending requests. That is unsafe once TimedOutRequestTracker has pruned old IDs (TTL/max-size): under sustained timeouts/cancellations, a legitimate late response for an older timed-out request will miss the tracker and trigger handleProtocolError, aborting unrelated in-flight calls. This turns expected late traffic into cross-request failures in long-running/high-timeout workloads.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@test/integration.test.ts`:
- Around line 126-127: The finally block currently restores PYTHONPATH by
assigning process.env.PYTHONPATH = originalPythonPath which can set the string
"undefined"; change it to conditionally restore or remove the env var: if
originalPythonPath is strictly undefined (or null) then delete
process.env.PYTHONPATH, otherwise set process.env.PYTHONPATH =
originalPythonPath; reference the variables process.env.PYTHONPATH and
originalPythonPath and update the finally cleanup in the test to perform this
conditional delete/restore.
In `@test/transport.test.ts`:
- Around line 641-660: Add a companion unit test that verifies a response
arriving after its request has already timed out is ignored (i.e., does not
reject the original promise with Unexpected response id). Use the same setup as
the existing test: instantiate ProcessIO, cast to ProcessIOInternals, set _state
= 'ready', processExited = false and provide a mock stdin.write, then call
transport.send(...) with a short timeout to produce a pending promise; after the
send times out (await the rejection or wait past the timeout), call
internals.handleResponseLine(...) with the original message id (the late
response) and assert that it does not cause an additional rejection or throw
BridgeProtocolError for that id—use the same identifiers ProcessIO,
ProcessIOInternals, send, handleResponseLine, and BridgeProtocolError to locate
code.
In `@tywrap_ir/tests/test_ir_async_generator_flags.py`:
- Around line 19-26: Replace the redundant assertIsNotNone plus explicit
None-check in test_async_generator_is_marked_as_generator with a single assert
result is not None to both simplify the test and provide type-narrowing for the
remainder of the test; locate the assertion around the call to
_extract_function(sample_async_generator, "tests.sample_async_generator") and
remove the subsequent if result is None: self.fail(...) block so the test
continues to assert result.is_async and result.is_generator.
- Around line 6-16: Add explicit return type annotations to the sample
functions: annotate sample_async_generator as returning AsyncIterator[int],
sample_async_coroutine as returning int (i.e., -> int for the async coroutine),
and sample_sync_generator as returning Iterator[int]; also add the required
imports from typing (AsyncIterator, Iterator) at the top of the file so the
annotations resolve. Ensure the async generator and sync generator signatures
use the AsyncIterator/Iterator types respectively and the async coroutine uses a
plain int return type annotation.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 8a224a05-8b7c-4279-ac54-9ccac141b67d
📒 Files selected for processing (15)
.github/workflows/release.ymldocs/guide/configuration.mddocs/guide/runtimes/node.mddocs/index.mddocs/public/llms-full.txtdocs/troubleshooting/index.mdsrc/runtime/process-io.tssrc/tywrap.tstest/integration.test.tstest/transport.test.tstywrap_ir/tests/test_ir_async_generator_flags.pytywrap_ir/tests/test_optimized_ir_options.pytywrap_ir/tests/test_optimized_ir_parallel_warnings.pytywrap_ir/tywrap_ir/ir.pytywrap_ir/tywrap_ir/optimized_ir.py
📜 Review details
🧰 Additional context used
📓 Path-based instructions (5)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
TypeScript strict mode; avoid
any— useunknownand type guards instead
Files:
src/runtime/process-io.tssrc/tywrap.ts
src/runtime/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Runtime bridges code should be located in
src/runtime/with corresponding tests intest/runtime_*.test.ts
Files:
src/runtime/process-io.ts
src/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript strict mode and avoid
any— useunknownand type guards instead
Files:
src/runtime/process-io.tssrc/tywrap.ts
test/**/*.test.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Use
NODE_OPTIONS=--expose-gcenvironment variable for GC-sensitive tests
Files:
test/integration.test.tstest/transport.test.ts
tywrap_ir/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
Python code must follow PEP 8 and use type hints
Follow PEP 8 and use type hints in Python code
Files:
tywrap_ir/tywrap_ir/ir.pytywrap_ir/tests/test_optimized_ir_parallel_warnings.pytywrap_ir/tests/test_optimized_ir_options.pytywrap_ir/tests/test_ir_async_generator_flags.pytywrap_ir/tywrap_ir/optimized_ir.py
🧠 Learnings (26)
📓 Common learnings
Learnt from: bbopen
Repo: bbopen/tywrap PR: 136
File: src/runtime/node.ts:238-249
Timestamp: 2026-01-20T01:33:12.841Z
Learning: In the tywrap repository, when reviewing init/startup patterns, prioritize cases that break core functionality over edge cases with diagnostic-only impact (e.g., missing bridgeInfo metadata). If workers are healthy and operational, defer low-impact defensive checks to follow-up PRs.
📚 Learning: 2026-01-19T21:14:40.872Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:260-263
Timestamp: 2026-01-19T21:14:40.872Z
Learning: In `src/runtime/bridge-core.ts` and similar hot request/response loop implementations in the tywrap repository, avoid adding extra defensive validation (e.g., runtime shape checks on error payloads) in tight loops unless the protocol boundary is untrusted or there's a concrete bug report. The Python bridge protocol is controlled and validated via tests, so defensive checks would add unnecessary branching overhead without meaningful benefit.
Applied to files:
docs/guide/runtimes/node.mddocs/troubleshooting/index.mddocs/guide/configuration.mddocs/public/llms-full.txttest/transport.test.ts
📚 Learning: 2026-03-17T05:27:14.946Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-17T05:27:14.946Z
Learning: Place runtime bridge implementations in `src/runtime/` with corresponding tests in `test/runtime_*.test.ts`
Applied to files:
docs/guide/runtimes/node.mddocs/troubleshooting/index.mddocs/public/llms-full.txt
📚 Learning: 2026-03-17T05:27:08.277Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T05:27:08.277Z
Learning: Applies to src/runtime/**/*.ts : Runtime bridges code should be located in `src/runtime/` with corresponding tests in `test/runtime_*.test.ts`
Applied to files:
docs/guide/runtimes/node.mddocs/troubleshooting/index.md
📚 Learning: 2026-03-17T05:27:08.277Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T05:27:08.277Z
Learning: Applies to test/runtime_*.test.ts : Include tests for new runtime behavior following the `test/runtime_*.test.ts` patterns
Applied to files:
docs/guide/runtimes/node.mdsrc/tywrap.tstest/integration.test.ts
📚 Learning: 2026-01-19T21:14:37.032Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:375-385
Timestamp: 2026-01-19T21:14:37.032Z
Learning: In tywrap (src/runtime/bridge-core.ts and similar), environment variable parsing follows a tolerant/best-effort policy. For example, `TYWRAP_CODEC_MAX_BYTES=1024abc` should be accepted as 1024. Only reject clearly invalid values (non-numeric start or <=0). This avoids surprising failures from minor typos.
Applied to files:
docs/guide/runtimes/node.mddocs/troubleshooting/index.mddocs/guide/configuration.mddocs/public/llms-full.txt
📚 Learning: 2026-03-17T05:27:14.946Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-17T05:27:14.946Z
Learning: Applies to test/runtime_*.test.ts : Include tests for new runtime behavior following patterns in `test/runtime_*.test.ts`
Applied to files:
docs/guide/runtimes/node.mdsrc/tywrap.tstest/integration.test.ts
📚 Learning: 2026-01-20T16:01:14.323Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: docs/adr/002-bridge-protocol.md:599-602
Timestamp: 2026-01-20T16:01:14.323Z
Learning: In `src/runtime/node-bridge.ts` (NodeBridge), a test message is sent to the Python subprocess to confirm the bridge is responsive before marking it as ready.
Applied to files:
docs/guide/runtimes/node.mddocs/troubleshooting/index.mddocs/public/llms-full.txttest/transport.test.ts
📚 Learning: 2026-01-19T21:48:45.693Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:260-298
Timestamp: 2026-01-19T21:48:45.693Z
Learning: In `src/runtime/bridge-core.ts`, keep `normalizeErrorPayload` to validate error payloads from the Python subprocess. The subprocess boundary is effectively untrusted, and normalizing error responses prevents `undefined: undefined` errors on malformed payloads. Error responses are not the hot path, so the small validation overhead is acceptable for the added resilience.
Applied to files:
docs/guide/runtimes/node.mddocs/troubleshooting/index.mddocs/public/llms-full.txttest/transport.test.ts
📚 Learning: 2026-01-20T16:01:14.323Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: docs/adr/002-bridge-protocol.md:599-602
Timestamp: 2026-01-20T16:01:14.323Z
Learning: In the tywrap repository, bridges currently use implicit ready detection: the first successful response from the Python subprocess proves the bridge is ready to handle requests.
Applied to files:
docs/guide/runtimes/node.mddocs/troubleshooting/index.mddocs/public/llms-full.txttest/transport.test.ts
📚 Learning: 2026-03-17T05:27:14.946Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-17T05:27:14.946Z
Learning: Set `NODE_OPTIONS=--expose-gc` for running GC-sensitive tests
Applied to files:
docs/guide/runtimes/node.mddocs/public/llms-full.txt
📚 Learning: 2026-01-19T21:49:05.612Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: runtime/python_bridge.py:99-123
Timestamp: 2026-01-19T21:49:05.612Z
Learning: In the tywrap repository, TYWRAP_REQUEST_MAX_BYTES uses strict integer parsing that rejects values with trailing characters (e.g., "1024abc"). This differs from TYWRAP_CODEC_MAX_BYTES, which uses tolerant/best-effort parsing that accepts numeric prefixes. The strict policy for REQUEST_MAX_BYTES ensures explicit integer values and consistent parse behavior across Node/Python implementations.
Applied to files:
docs/guide/runtimes/node.mddocs/troubleshooting/index.mddocs/guide/configuration.mddocs/public/llms-full.txt
📚 Learning: 2026-03-17T05:27:14.946Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-17T05:27:14.946Z
Learning: Set `TYWRAP_PERF_BUDGETS=1` to enable performance budget assertions in tests
Applied to files:
docs/guide/runtimes/node.mddocs/troubleshooting/index.mddocs/public/llms-full.txt
📚 Learning: 2026-01-20T16:01:29.276Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: docs/adr/002-bridge-protocol.md:636-637
Timestamp: 2026-01-20T16:01:29.276Z
Learning: In the tywrap BridgeProtocol ProcessIO transport (ADR-002), when implementing `restartAfterRequests` functionality, use drain-before-restart as the default: wait for `pendingRequests.size === 0` before killing and restarting the process. This prevents rejecting in-flight requests during restart. Alternative graceful restart (spawn new process, drain old) adds complexity with two concurrent processes.
Applied to files:
src/runtime/process-io.tstest/transport.test.ts
📚 Learning: 2026-01-19T21:14:29.869Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:375-385
Timestamp: 2026-01-19T21:14:29.869Z
Learning: In the runtime env-var parsing (e.g., in src/runtime/bridge-core.ts and similar modules), adopt a tolerant, best-effort policy: numeric env values should parse by taking the leading numeric portion (e.g., TYWRAP_CODEC_MAX_BYTES=1024abc -> 1024). Only reject clearly invalid values (non-numeric start or <= 0). This reduces surprising failures from minor typos. Add tests to cover partial numeric prefixes, and ensure downstream logic documents the trusted range; consider a small helper to extract a positive integer from a string with a safe fallback.
Applied to files:
src/runtime/process-io.ts
📚 Learning: 2026-01-19T21:14:35.390Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:260-263
Timestamp: 2026-01-19T21:14:35.390Z
Learning: In src/runtime/bridge-core.ts and similar hot request/response loop implementations in the tywrap repository, avoid adding extra defensive validation (such as runtime, shape, or error-payload checks) inside tight loops unless the protocol boundary is untrusted or there is a concrete bug report. The Python bridge protocol is controlled via tests, so these checks add unnecessary branching overhead without meaningful benefit. Apply this guidance to other hot-path runtime loops in src/runtime/**/*.ts, and re-enable additional validations only when a documented risk or failure scenario is identified. Ensure tests cover protocol validation where applicable.
Applied to files:
src/runtime/process-io.ts
📚 Learning: 2026-01-20T01:34:07.064Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 136
File: src/runtime/node.ts:444-458
Timestamp: 2026-01-20T01:34:07.064Z
Learning: When reviewing promise-based polling patterns (e.g., recursive setTimeout in waitForAvailableWorker functions), ensure that any recursive timer is tracked and cleared on timeout or promise resolution to prevent timer leaks. Do not rely on no-op checks after settlement; verify clearTimeout is invoked in all paths and consider using an explicit cancellation (e.g., AbortController) or a guard to cancel pending timers when the promise settles.
Applied to files:
src/runtime/process-io.tssrc/tywrap.tstest/integration.test.tstest/transport.test.ts
📚 Learning: 2026-01-20T18:37:05.670Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: src/runtime/process-io.ts:37-40
Timestamp: 2026-01-20T18:37:05.670Z
Learning: In the tywrap repo, ESLint is used for linting (not Biome). Do not flag regex literals that contain control characters (e.g., \u001b, \u0000-\u001F) as lint errors, since the current ESLint configuration allows them. When reviewing TypeScript files (e.g., src/**/*.ts), rely on ESLint results and avoid raising issues about these specific control-character regex literals unless there is a competing config change or a policy requiring explicit escaping.
Applied to files:
src/runtime/process-io.tssrc/tywrap.tstest/integration.test.tstest/transport.test.ts
📚 Learning: 2026-01-20T16:00:49.829Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: docs/adr/002-bridge-protocol.md:203-211
Timestamp: 2026-01-20T16:00:49.829Z
Learning: In the BridgeProtocol implementation (tywrap), reject Map and Set explicitly before serialization (e.g., in safeStringify or the serialization entrypoint) with a clear error like "Bridge protocol does not support Map/Set values". Do not rely on post-hoc checks of non-string keys at the point of JSON.stringify, since Maps/Sets cannot round-trip. This should be enforced at the boundary where data is prepared for serialization to ensure deterministic errors and prevent invalid data from propagating.
Applied to files:
src/runtime/process-io.tssrc/tywrap.tstest/integration.test.tstest/transport.test.ts
📚 Learning: 2026-01-19T21:48:27.823Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: test/runtime_bridge_fixtures.test.ts:59-66
Timestamp: 2026-01-19T21:48:27.823Z
Learning: In fixture-based tests (e.g., test/runtime_bridge_fixtures.test.ts) and similar tests in the tywrap repository, prefer early returns when Python or fixture files are unavailable. Do not rely on Vitest dynamic skip APIs; a silent pass is intentional for environments lacking Python/fixtures. Treat missing fixtures as optional soft-guards and ensure the test remains non-disruptive in non-availability scenarios.
Applied to files:
test/integration.test.tstest/transport.test.ts
📚 Learning: 2026-03-17T05:27:08.277Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T05:27:08.277Z
Learning: Applies to test/**/*.test.ts : Use `NODE_OPTIONS=--expose-gc` environment variable for GC-sensitive tests
Applied to files:
test/integration.test.ts
📚 Learning: 2026-03-17T05:27:08.277Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T05:27:08.277Z
Learning: Applies to tywrap_ir/**/*.py : Python code must follow PEP 8 and use type hints
Applied to files:
docs/troubleshooting/index.mddocs/public/llms-full.txt
📚 Learning: 2026-03-17T05:27:14.946Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-17T05:27:14.946Z
Learning: Applies to tywrap_ir/**/*.py : Follow PEP 8 and use type hints in Python code
Applied to files:
docs/troubleshooting/index.mddocs/public/llms-full.txt
📚 Learning: 2026-01-19T21:48:35.351Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: test/runtime_bridge_fixtures.test.ts:59-66
Timestamp: 2026-01-19T21:48:35.351Z
Learning: In test/runtime_bridge_fixtures.test.ts and similar fixture-based tests in the tywrap repository, early returns are preferred over explicit test skips when Python or fixture files are unavailable. These fixture tests are intentionally optional soft-guards, and the project does not currently rely on Vitest dynamic skip APIs. The silent pass behavior is deliberate for environments without Python/fixtures.
Applied to files:
docs/guide/configuration.mddocs/public/llms-full.txt
📚 Learning: 2026-01-19T21:00:30.825Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: test/adversarial_playground.test.ts:339-360
Timestamp: 2026-01-19T21:00:30.825Z
Learning: In adversarial tests for the bridge (test/adversarial_playground.test.ts), recovery assertions should be kept in the finally block adjacent to cleanup to verify resilience under stress, even if that means post-timeout checks might mask the original error. The goal is to surface recovery failures as legitimate test failures.
Applied to files:
test/transport.test.ts
📚 Learning: 2026-01-19T21:00:52.689Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: test/fixtures/out_of_order_bridge.py:29-48
Timestamp: 2026-01-19T21:00:52.689Z
Learning: In `test/fixtures/out_of_order_bridge.py`, the fixture intentionally leaves a pending request unanswered at EOF to simulate missing/out-of-order responses and validate bridge behavior when requests never complete; this is the exact failure mode being tested and must be preserved.
Applied to files:
test/transport.test.ts
🪛 Ruff (0.15.6)
tywrap_ir/tests/test_optimized_ir_parallel_warnings.py
[warning] 19-19: Boolean positional value in function call
(FBT003)
[warning] 21-21: Use a regular assert instead of unittest-style assertEqual
Replace assertEqual(...) with assert ...
(PT009)
[warning] 22-22: Use a regular assert instead of unittest-style assertIn
Replace assertIn(...) with assert ...
(PT009)
[warning] 23-23: Use a regular assert instead of unittest-style assertTrue
Replace assertTrue(...) with assert ...
(PT009)
tywrap_ir/tests/test_optimized_ir_options.py
[warning] 26-26: Use a regular assert instead of unittest-style assertTrue
Replace assertTrue(...) with assert ...
(PT009)
[warning] 27-27: Use a regular assert instead of unittest-style assertTrue
Replace assertTrue(...) with assert ...
(PT009)
[warning] 28-28: Use a regular assert instead of unittest-style assertIs
Replace assertIs(...) with assert ...
(PT009)
[warning] 37-37: Use a regular assert instead of unittest-style assertGreaterEqual
Replace assertGreaterEqual(...) with assert ...
(PT009)
tywrap_ir/tests/test_ir_async_generator_flags.py
[warning] 21-21: Use a regular assert instead of unittest-style assertIsNotNone
Replace assertIsNotNone(...) with assert ...
(PT009)
[warning] 24-24: Use a regular assert instead of unittest-style assertTrue
Replace assertTrue(...) with assert ...
(PT009)
[warning] 25-25: Use a regular assert instead of unittest-style assertTrue
Replace assertTrue(...) with assert ...
(PT009)
[warning] 29-29: Use a regular assert instead of unittest-style assertIsNotNone
Replace assertIsNotNone(...) with assert ...
(PT009)
[warning] 32-32: Use a regular assert instead of unittest-style assertTrue
Replace assertTrue(...) with assert ...
(PT009)
[warning] 33-33: Use a regular assert instead of unittest-style assertFalse
Replace assertFalse(...) with assert ...
(PT009)
[warning] 37-37: Use a regular assert instead of unittest-style assertIsNotNone
Replace assertIsNotNone(...) with assert ...
(PT009)
[warning] 40-40: Use a regular assert instead of unittest-style assertFalse
Replace assertFalse(...) with assert ...
(PT009)
[warning] 41-41: Use a regular assert instead of unittest-style assertTrue
Replace assertTrue(...) with assert ...
(PT009)
tywrap_ir/tywrap_ir/optimized_ir.py
[warning] 230-230: Do not catch blind exception: Exception
(BLE001)
🔇 Additional comments (16)
docs/index.md (1)
49-49: Looks good — release link now points to the right source for breaking changes.tywrap_ir/tywrap_ir/ir.py (1)
235-237: Good fix for async-generator classification.Marking async generators as generators here is the correct IR behavior.
docs/guide/configuration.md (1)
331-365: Nice clarification of config precedence and env-var scope.This makes runtime setup expectations much clearer for users.
.github/workflows/release.yml (1)
44-47: CI hardening looks correct.Bootstrapping Python +
tywrap_irin the release job removes implicit environment assumptions.Also applies to: 50-54
src/tywrap.ts (1)
150-150: Correct check-mode cache bypass.This closes the stale-IR path for
checkruns while preserving normal caching behavior.test/integration.test.ts (1)
3-3: Good cross-platform setup for the cache-bypass integration test.Using
path.delimiterand isolating cache state via temp cwd is the right approach.Also applies to: 83-125
src/runtime/process-io.ts (1)
24-24: Strong transport fix: late timed-out responses are ignored, true unknown IDs still fail fast.The tracker wiring and disposal cleanup are consistent, and the unmatched-ID handling now cleanly separates expected late arrivals from protocol desync.
Also applies to: 40-42, 186-188, 270-271, 284-285, 371-371, 609-615
docs/public/llms-full.txt (1)
55-55: Documentation updates align well with the bridge-centric configuration approach.The shift from environment-variable-driven configuration to programmatic
NodeBridgeconstruction is consistently applied throughout the documentation. The updated experimental note correctly references the Releases page, and the environment variables section now appropriately emphasizes that Python path and virtual environment selection are configured via code or config files rather than env vars.Also applies to: 772-806
docs/troubleshooting/index.md (1)
249-260: Consistent TypeScript bridge patterns in troubleshooting guidance.The updated examples properly demonstrate
NodeBridgeinstantiation withenvoptions for thread tuning (OMP_NUM_THREADS,MKL_NUM_THREADS). This aligns with the bridge-centric configuration approach and provides actionable guidance for common runtime issues.Also applies to: 296-306
docs/guide/runtimes/node.md (1)
293-317: Clear distinction between generation-time and runtime debugging.The updated debugging section properly separates:
- CLI's
--debugflag for wrapper generation diagnosticsTYWRAP_LOG_LEVELandTYWRAP_LOG_JSONfor subprocess diagnostics- Bridge instance options (
timeoutMs: 0,env) for debugging-specific configurationsThis provides a clear mental model for users troubleshooting different parts of the system.
tywrap_ir/tywrap_ir/optimized_ir.py (2)
208-246: Per-task warning collection and propagation implemented correctly.The warning collection logic properly:
- Initializes a local
warningslist per extraction- Captures both timeout and general extraction errors
- Emits structured stderr output with emoji prefixes
- Passes warnings to
IRModuleconstructionThe broad
Exceptioncatch at line 230 is appropriate here since extraction failures should degrade gracefully to warnings rather than crashing the entire extraction process.
431-447: Global state preservation logic is well-designed.The branching logic correctly:
- Reuses
_global_extractorfor the default fast path (both caching and parallel enabled)- Creates a new local
OptimizedIRExtractorfor non-default options to avoid mutating global stateThis ensures that calling
extract_module_ir_optimized(..., enable_caching=False, ...)doesn't affect subsequent calls that rely on the default behavior.tywrap_ir/tests/test_optimized_ir_parallel_warnings.py (2)
12-14: Clever error injection technique.The generator throw pattern
(_ for _ in ()).throw(RuntimeError("boom"))effectively creates a callable that raises when evaluated. This is a valid approach for injecting failures into the extraction pipeline.
19-23: Test correctly validates warning propagation.The test verifies that:
- The result contains the expected module name
- A
warningskey exists in the result- The warning message includes the expected error format
The warning string
"Error extracting functions from math: boom"matches the format defined in_extract_parallelat line 231 ofoptimized_ir.py.tywrap_ir/tests/test_optimized_ir_options.py (2)
11-21: Proper test isolation with setUp/tearDown.The explicit restoration of global extractor state in both
setUpandtearDownensures test isolation. This is important since the tests verify behavior that depends on global state (_global_extractorand_global_cache).
23-37: Tests correctly validate global state preservation and cache behavior.The tests verify the two key behaviors from the implementation:
- Non-default options (
enable_caching=False, enable_parallel=False) don't mutate the global extractor- Default options use the shared cache, evidenced by cache hits increasing between extractions
Both tests align with the branching logic in
extract_module_ir_optimizedat lines 434-441 ofoptimized_ir.py.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@tywrap_ir/tests/test_ir_async_generator_flags.py`:
- Line 2: Replace the typing-based iterator imports with the modern
collections.abc imports to satisfy Ruff UP035: change the import line that
currently reads using AsyncIterator and Iterator from the typing module to
import AsyncIterator and Iterator from collections.abc (look for the import
statement in test_ir_async_generator_flags.py that imports AsyncIterator,
Iterator).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: fb1c0fef-0cb1-43f2-a32d-5f6fc175608d
📒 Files selected for processing (3)
test/integration.test.tstest/transport.test.tstywrap_ir/tests/test_ir_async_generator_flags.py
📜 Review details
🧰 Additional context used
📓 Path-based instructions (2)
test/**/*.test.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Use
NODE_OPTIONS=--expose-gcenvironment variable for GC-sensitive tests
Files:
test/integration.test.tstest/transport.test.ts
tywrap_ir/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
Python code must follow PEP 8 and use type hints
Follow PEP 8 and use type hints in Python code
Files:
tywrap_ir/tests/test_ir_async_generator_flags.py
🧠 Learnings (18)
📓 Common learnings
Learnt from: bbopen
Repo: bbopen/tywrap PR: 136
File: src/runtime/node.ts:238-249
Timestamp: 2026-01-20T01:33:12.841Z
Learning: In the tywrap repository, when reviewing init/startup patterns, prioritize cases that break core functionality over edge cases with diagnostic-only impact (e.g., missing bridgeInfo metadata). If workers are healthy and operational, defer low-impact defensive checks to follow-up PRs.
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:260-298
Timestamp: 2026-01-19T21:48:45.693Z
Learning: In `src/runtime/bridge-core.ts`, keep `normalizeErrorPayload` to validate error payloads from the Python subprocess. The subprocess boundary is effectively untrusted, and normalizing error responses prevents `undefined: undefined` errors on malformed payloads. Error responses are not the hot path, so the small validation overhead is acceptable for the added resilience.
📚 Learning: 2026-03-17T05:27:08.277Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T05:27:08.277Z
Learning: Applies to test/runtime_*.test.ts : Include tests for new runtime behavior following the `test/runtime_*.test.ts` patterns
Applied to files:
test/integration.test.tstest/transport.test.ts
📚 Learning: 2026-03-17T05:27:14.946Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-17T05:27:14.946Z
Learning: Applies to test/runtime_*.test.ts : Include tests for new runtime behavior following patterns in `test/runtime_*.test.ts`
Applied to files:
test/integration.test.tstest/transport.test.ts
📚 Learning: 2026-01-19T21:00:30.825Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: test/adversarial_playground.test.ts:339-360
Timestamp: 2026-01-19T21:00:30.825Z
Learning: In adversarial tests for the bridge (test/adversarial_playground.test.ts), recovery assertions should be kept in the finally block adjacent to cleanup to verify resilience under stress, even if that means post-timeout checks might mask the original error. The goal is to surface recovery failures as legitimate test failures.
Applied to files:
test/integration.test.tstest/transport.test.ts
📚 Learning: 2026-01-19T21:48:27.823Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: test/runtime_bridge_fixtures.test.ts:59-66
Timestamp: 2026-01-19T21:48:27.823Z
Learning: In fixture-based tests (e.g., test/runtime_bridge_fixtures.test.ts) and similar tests in the tywrap repository, prefer early returns when Python or fixture files are unavailable. Do not rely on Vitest dynamic skip APIs; a silent pass is intentional for environments lacking Python/fixtures. Treat missing fixtures as optional soft-guards and ensure the test remains non-disruptive in non-availability scenarios.
Applied to files:
test/integration.test.tstest/transport.test.ts
📚 Learning: 2026-03-17T05:27:08.277Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T05:27:08.277Z
Learning: Applies to test/**/*.test.ts : Use `NODE_OPTIONS=--expose-gc` environment variable for GC-sensitive tests
Applied to files:
test/integration.test.ts
📚 Learning: 2026-01-20T01:34:07.064Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 136
File: src/runtime/node.ts:444-458
Timestamp: 2026-01-20T01:34:07.064Z
Learning: When reviewing promise-based polling patterns (e.g., recursive setTimeout in waitForAvailableWorker functions), ensure that any recursive timer is tracked and cleared on timeout or promise resolution to prevent timer leaks. Do not rely on no-op checks after settlement; verify clearTimeout is invoked in all paths and consider using an explicit cancellation (e.g., AbortController) or a guard to cancel pending timers when the promise settles.
Applied to files:
test/integration.test.tstest/transport.test.ts
📚 Learning: 2026-01-20T18:37:05.670Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: src/runtime/process-io.ts:37-40
Timestamp: 2026-01-20T18:37:05.670Z
Learning: In the tywrap repo, ESLint is used for linting (not Biome). Do not flag regex literals that contain control characters (e.g., \u001b, \u0000-\u001F) as lint errors, since the current ESLint configuration allows them. When reviewing TypeScript files (e.g., src/**/*.ts), rely on ESLint results and avoid raising issues about these specific control-character regex literals unless there is a competing config change or a policy requiring explicit escaping.
Applied to files:
test/integration.test.tstest/transport.test.ts
📚 Learning: 2026-01-20T16:00:49.829Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: docs/adr/002-bridge-protocol.md:203-211
Timestamp: 2026-01-20T16:00:49.829Z
Learning: In the BridgeProtocol implementation (tywrap), reject Map and Set explicitly before serialization (e.g., in safeStringify or the serialization entrypoint) with a clear error like "Bridge protocol does not support Map/Set values". Do not rely on post-hoc checks of non-string keys at the point of JSON.stringify, since Maps/Sets cannot round-trip. This should be enforced at the boundary where data is prepared for serialization to ensure deterministic errors and prevent invalid data from propagating.
Applied to files:
test/integration.test.tstest/transport.test.ts
📚 Learning: 2026-01-20T16:01:29.276Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: docs/adr/002-bridge-protocol.md:636-637
Timestamp: 2026-01-20T16:01:29.276Z
Learning: In the tywrap BridgeProtocol ProcessIO transport (ADR-002), when implementing `restartAfterRequests` functionality, use drain-before-restart as the default: wait for `pendingRequests.size === 0` before killing and restarting the process. This prevents rejecting in-flight requests during restart. Alternative graceful restart (spawn new process, drain old) adds complexity with two concurrent processes.
Applied to files:
test/transport.test.ts
📚 Learning: 2026-01-20T16:01:14.323Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: docs/adr/002-bridge-protocol.md:599-602
Timestamp: 2026-01-20T16:01:14.323Z
Learning: In `src/runtime/node-bridge.ts` (NodeBridge), a test message is sent to the Python subprocess to confirm the bridge is responsive before marking it as ready.
Applied to files:
test/transport.test.ts
📚 Learning: 2026-01-19T21:00:52.689Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: test/fixtures/out_of_order_bridge.py:29-48
Timestamp: 2026-01-19T21:00:52.689Z
Learning: In `test/fixtures/out_of_order_bridge.py`, the fixture intentionally leaves a pending request unanswered at EOF to simulate missing/out-of-order responses and validate bridge behavior when requests never complete; this is the exact failure mode being tested and must be preserved.
Applied to files:
test/transport.test.ts
📚 Learning: 2026-01-19T21:14:40.872Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:260-263
Timestamp: 2026-01-19T21:14:40.872Z
Learning: In `src/runtime/bridge-core.ts` and similar hot request/response loop implementations in the tywrap repository, avoid adding extra defensive validation (e.g., runtime shape checks on error payloads) in tight loops unless the protocol boundary is untrusted or there's a concrete bug report. The Python bridge protocol is controlled and validated via tests, so defensive checks would add unnecessary branching overhead without meaningful benefit.
Applied to files:
test/transport.test.ts
📚 Learning: 2026-01-19T21:48:45.693Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 127
File: src/runtime/bridge-core.ts:260-298
Timestamp: 2026-01-19T21:48:45.693Z
Learning: In `src/runtime/bridge-core.ts`, keep `normalizeErrorPayload` to validate error payloads from the Python subprocess. The subprocess boundary is effectively untrusted, and normalizing error responses prevents `undefined: undefined` errors on malformed payloads. Error responses are not the hot path, so the small validation overhead is acceptable for the added resilience.
Applied to files:
test/transport.test.ts
📚 Learning: 2026-01-20T01:36:14.701Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 136
File: src/runtime/node.ts:743-759
Timestamp: 2026-01-20T01:36:14.701Z
Learning: In the tywrap repository, when reviewing concurrent request handling patterns (especially with BridgeCore request multiplexing), flag uses of boolean `busy` flags that should be request counters instead. A boolean flag creates a race condition: when request A completes and sets `busy = false`, request B (still in flight via multiplexing) is incorrectly treated as idle. The fix is to use an `inFlightRequests: number` counter that increments on request start and decrements on completion, then check `worker.inFlightRequests === 0` before cleanup/termination.
Applied to files:
test/transport.test.ts
📚 Learning: 2026-01-20T16:01:14.323Z
Learnt from: bbopen
Repo: bbopen/tywrap PR: 152
File: docs/adr/002-bridge-protocol.md:599-602
Timestamp: 2026-01-20T16:01:14.323Z
Learning: In the tywrap repository, bridges currently use implicit ready detection: the first successful response from the Python subprocess proves the bridge is ready to handle requests.
Applied to files:
test/transport.test.ts
📚 Learning: 2026-03-17T05:27:14.946Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-17T05:27:14.946Z
Learning: Applies to tywrap_ir/**/*.py : Follow PEP 8 and use type hints in Python code
Applied to files:
tywrap_ir/tests/test_ir_async_generator_flags.py
📚 Learning: 2026-03-17T05:27:08.277Z
Learnt from: CR
Repo: bbopen/tywrap PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T05:27:08.277Z
Learning: Applies to tywrap_ir/**/*.py : Python code must follow PEP 8 and use type hints
Applied to files:
tywrap_ir/tests/test_ir_async_generator_flags.py
🪛 Ruff (0.15.6)
tywrap_ir/tests/test_ir_async_generator_flags.py
[warning] 2-2: Import from collections.abc instead: AsyncIterator, Iterator
Import from collections.abc
(UP035)
🔇 Additional comments (5)
test/integration.test.ts (2)
3-3: LGTM!The
delimiterimport is correctly added to support cross-platform PATH separator handling used in line 96 for constructingPYTHONPATH.
83-135: Well-structured test for cache bypass behavior.The test correctly validates that
check: truebypasses the IR cache:
- First run with
caching: truepopulates the cache- Python module is modified to introduce staleness
- Second run with
check: truedetects the stale file despite cached IRThe
PYTHONPATHrestoration in thefinallyblock (lines 126-130) now correctly handles theundefinedcase by usingdeleteinstead of assignment, which prevents the Node.js coercion to the string"undefined".test/transport.test.ts (2)
641-660: LGTM!The test correctly validates the unexpected-response-ID failure path. The setup pattern is consistent with other ProcessIO tests, and the assertions properly verify both the error type and message content.
662-681: LGTM — addresses the late-response coverage gap.This test validates the
timedOutRequests.consume()path fromprocess-io.ts: when a response arrives for an already-timed-out request, it's silently ignored instead of triggering a protocol error.The sequence (await timeout → feed late response → assert no throw) correctly exercises the intended behavior.
tywrap_ir/tests/test_ir_async_generator_flags.py (1)
7-36: Good coverage of IR async/generator flag behavior.The three tests validate the expected flag matrix clearly and directly.
|
@CodeRabbit incremental review A small follow-up fix just landed in |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 897
-from typing import AsyncIterator, Iterator
+from collections.abc import AsyncIterator, IteratorThis correctly resolves the Ruff UP035 violation — 🧠 Learnings used |
Summary
This follow-up PR addresses the post-promotion issues found during review and two additional bug-hunting passes.
It fixes the docs and AI discovery files so they match the current runtime and configuration surface, hardens the npm release workflow so it can run the full test suite on a fresh GitHub runner, and closes several correctness bugs in runtime generation and Python IR extraction.
Root Cause And User Impact
The docs migration left several stale runtime examples and environment variable references in published pages and llms-full.txt, which could send users toward unsupported config keys and nonexistent debug flags.
The npm release job ran npm test without setting up Python or installing tywrap_ir, so releases depended on undeclared runner state.
At runtime and during generation, ProcessIO could ignore unexpected response IDs, check mode could trust stale cached IR, async generators were misclassified in the Python IR, and optimized extraction could both leak option state across calls and drop warnings from failed parallel extraction.
Fixes
Validation