Repository navigation
fix(openai-shim): recover stalled provider streams - #1817
Conversation
Bound SSE reader waits with an idle timeout so non-streaming fallback can recover before the parent query is force-aborted. Preserve parent-abort cancellation semantics and cover fallback, disabled-fallback, and slow-active stream cases.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (4)
📜 Recent review details🧰 Additional context used📓 Path-based instructions (13)src/**/*.{ts,tsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
{src/commands/**/*.ts,src/services/**/*.ts,src/entrypoints/**/*.ts}📄 CodeRabbit inference engine (AGENTS.md)
Files:
{src/services/**/*.ts,src/utils/**/*.ts}📄 CodeRabbit inference engine (AGENTS.md)
Files:
{src/integrations/**/*.ts,src/services/**/*.ts}📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.{ts,tsx,js,jsx,py,json,md}📄 CodeRabbit inference engine (CONTRIBUTING.md)
Files:
**/*.test.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (CONTRIBUTING.md)
Files:
**/*.test.{ts,tsx,js}📄 CodeRabbit inference engine (CONTRIBUTING.md)
Files:
**/*.{ts,tsx,js,jsx,py}📄 CodeRabbit inference engine (CONTRIBUTING.md)
Files:
**/*.{ts,tsx}📄 CodeRabbit inference engine (CONTRIBUTING.md)
Files:
**⚙️ CodeRabbit configuration file
Files:
**/*⚙️ CodeRabbit configuration file
Files:
{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}⚙️ CodeRabbit configuration file
Files:
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}⚙️ CodeRabbit configuration file
Files:
🔇 Additional comments (5)
📝 WalkthroughWalkthroughAdds shared idle-timeout handling for SSE streaming, routes Claude streaming to the shared timeout source, adjusts abort propagation, and expands unit and lifecycle tests for stalled streams and fallback behavior. ChangesStream idle timeout watchdog unification
Estimated code review effort: 4 (Complex) | ~50 minutes Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 6 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (6 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/services/api/claude.ts`:
- Around line 1962-1973: The stream idle-timeout parsing in claude.ts duplicates
the shared logic already used by openaiShim. Replace the local
CLAUDE_STREAM_IDLE_TIMEOUT_MS parsing block in claude.ts with a call to
getStreamIdleTimeoutMs() from src/services/api/openaiShim so the default value
and upper cap are maintained in one place. Update the STREAM_IDLE_TIMEOUT_MS
setup to use the shared helper and keep the surrounding reader/timeout usage
unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 4b793e25-0ccb-47c5-bd21-8ee0d007e1b5
📒 Files selected for processing (5)
src/__tests__/bugfixes.test.tssrc/services/api/claude.lifecycle.test.tssrc/services/api/claude.tssrc/services/api/openaiShim.test.tssrc/services/api/openaiShim.ts
💤 Files with no reviewable changes (1)
- src/tests/bugfixes.test.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (13)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript with strict mode and ESM imports
Files:
src/services/api/claude.tssrc/services/api/openaiShim.test.tssrc/services/api/claude.lifecycle.test.tssrc/services/api/openaiShim.ts
{src/commands/**/*.ts,src/services/**/*.ts,src/entrypoints/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
chalkfor terminal color in CLI code
Files:
src/services/api/claude.tssrc/services/api/openaiShim.test.tssrc/services/api/claude.lifecycle.test.tssrc/services/api/openaiShim.ts
{src/services/**/*.ts,src/utils/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
execafor child processes
Files:
src/services/api/claude.tssrc/services/api/openaiShim.test.tssrc/services/api/claude.lifecycle.test.tssrc/services/api/openaiShim.ts
{src/integrations/**/*.ts,src/services/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Test the exact provider/model path you changed when possible for provider modifications
Files:
src/services/api/claude.tssrc/services/api/openaiShim.test.tssrc/services/api/claude.lifecycle.test.tssrc/services/api/openaiShim.ts
**/*.{ts,tsx,js,jsx,py,json,md}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow the existing code style in the touched files
Files:
src/services/api/claude.tssrc/services/api/openaiShim.test.tssrc/services/api/claude.lifecycle.test.tssrc/services/api/openaiShim.ts
**/*.{ts,tsx,js,jsx,py}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Keep comments useful and concise
Files:
src/services/api/claude.tssrc/services/api/openaiShim.test.tssrc/services/api/claude.lifecycle.test.tssrc/services/api/openaiShim.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow TypeScript strict mode and type safety practices by running typecheck before submitting
Files:
src/services/api/claude.tssrc/services/api/openaiShim.test.tssrc/services/api/claude.lifecycle.test.tssrc/services/api/openaiShim.ts
**
⚙️ CodeRabbit configuration file
**: # AGENTS.md - AI Agent Coding GuideThis guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.
Project Snapshot
OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.
The installed CLI runs on Node.js
>=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.Work Style
- Keep changes focused on one problem.
- Prefer existing patterns in the file or nearby module.
- Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
- Add or update tests when behavior changes.
- Update docs when setup, commands, provider behavior, or user-facing behavior changes.
- For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.
Stack And Conventions
- TypeScript with strict mode and ESM imports.
- React + Ink for terminal UI.
- Bun lockfile and Bun scripts for development workflows.
- Node runtime for the built CLI.
- Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.
Common libraries and patterns:
chalkfor terminal color.commanderfor CLI argument parsing.execafor child processes.- Existing service, provider, settings, permission, and UI patterns over new abstractions.
Repository Map
src/commands/- slash and CLI command implementations.src/components/- React/Ink UI components.src/services/- API, MCP, OAuth, wiki, voice, and other service integrations.src/tools/- tool implementations.src/utils/- shared utilities.- `src/integration...
Files:
src/services/api/claude.tssrc/services/api/openaiShim.test.tssrc/services/api/claude.lifecycle.test.tssrc/services/api/openaiShim.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.
Files:
src/services/api/claude.tssrc/services/api/openaiShim.test.tssrc/services/api/claude.lifecycle.test.tssrc/services/api/openaiShim.ts
{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}
⚙️ CodeRabbit configuration file
{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}: Review provider routing, model selection, env precedence, auth/token handling, OpenAI-compatible shims, retries, proxy behavior, and outbound HTTP behavior with high scrutiny. Block on silent default changes, hidden fallback expansion, credential reuse mistakes, hardcoded provider assumptions, or new network reach that is not intentional and documented.
Files:
src/services/api/claude.tssrc/services/api/openaiShim.test.tssrc/services/api/claude.lifecycle.test.tssrc/services/api/openaiShim.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Add or update tests when the change affects behavior
Files:
src/services/api/openaiShim.test.tssrc/services/api/claude.lifecycle.test.ts
**/*.test.{ts,tsx,js}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Test the exact provider/model path you changed when possible
Files:
src/services/api/openaiShim.test.tssrc/services/api/claude.lifecycle.test.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}
⚙️ CodeRabbit configuration file
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.
Files:
src/services/api/openaiShim.test.tssrc/services/api/claude.lifecycle.test.ts
🔇 Additional comments (11)
src/services/api/openaiShim.ts (3)
134-218: LGTM!
147-155: 🎯 Functional CorrectnessNo change needed. The idle-timeout parser already matches the outer watchdog’s digits-only, safe-int, and clamp rules.
1859-2248: 🩺 Stability & AvailabilityNo change needed. The idle-timeout path already falls through to the non-streaming fallback, while parent aborts rethrow as
APIUserAbortError; the 90s default also stays below the 5-minute query idle timeout.src/services/api/openaiShim.test.ts (2)
53-53: LGTM!Also applies to: 238-238, 281-281
1270-1587: LGTM!src/services/api/claude.ts (1)
2561-2566: LGTM!src/services/api/claude.lifecycle.test.ts (5)
39-40: LGTM!
124-214: LGTM!
460-519: LGTM!
521-682: LGTM!
446-459: 🩺 Stability & AvailabilityNo issue:
globalThis.fetchis restored inafterEach.> Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/services/api/claude.lifecycle.test.ts`:
- Around line 56-57: The idle-timeout lifecycle tests are using the same 1_000ms
value for both the stream watchdog and the assertion budget, which makes
`waitForPromise()` and the `Date.now()` checks race `readWithIdleTimeout()`
itself. Update the `claude.lifecycle.test.ts` helpers/constants so the test idle
timeout is smaller or the assertion window is larger than the timeout, and apply
the same decoupled budget to the idle-timeout cases around the
`readWithIdleTimeout()` coverage and the elapsed-time checks in the affected
tests. Keep the regression coverage focused on `CLAUDE_STREAM_IDLE_TIMEOUT_MS`,
`STREAM_IDLE_RECOVERY_ASSERTION_MS`, and `STALLING_STREAM_CLEANUP_MS` so the
fallback behavior is validated without relying on scheduler speed.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 3643467a-421d-461d-8415-fee92a1e57b1
📒 Files selected for processing (1)
src/services/api/claude.lifecycle.test.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (13)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript with strict mode and ESM imports
Files:
src/services/api/claude.lifecycle.test.ts
{src/commands/**/*.ts,src/services/**/*.ts,src/entrypoints/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
chalkfor terminal color in CLI code
Files:
src/services/api/claude.lifecycle.test.ts
{src/services/**/*.ts,src/utils/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
execafor child processes
Files:
src/services/api/claude.lifecycle.test.ts
{src/integrations/**/*.ts,src/services/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Test the exact provider/model path you changed when possible for provider modifications
Files:
src/services/api/claude.lifecycle.test.ts
**/*.{ts,tsx,js,jsx,py,json,md}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow the existing code style in the touched files
Files:
src/services/api/claude.lifecycle.test.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Add or update tests when the change affects behavior
Files:
src/services/api/claude.lifecycle.test.ts
**/*.test.{ts,tsx,js}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Test the exact provider/model path you changed when possible
Files:
src/services/api/claude.lifecycle.test.ts
**/*.{ts,tsx,js,jsx,py}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Keep comments useful and concise
Files:
src/services/api/claude.lifecycle.test.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow TypeScript strict mode and type safety practices by running typecheck before submitting
Files:
src/services/api/claude.lifecycle.test.ts
**
⚙️ CodeRabbit configuration file
**: # AGENTS.md - AI Agent Coding GuideThis guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.
Project Snapshot
OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.
The installed CLI runs on Node.js
>=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.Work Style
- Keep changes focused on one problem.
- Prefer existing patterns in the file or nearby module.
- Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
- Add or update tests when behavior changes.
- Update docs when setup, commands, provider behavior, or user-facing behavior changes.
- For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.
Stack And Conventions
- TypeScript with strict mode and ESM imports.
- React + Ink for terminal UI.
- Bun lockfile and Bun scripts for development workflows.
- Node runtime for the built CLI.
- Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.
Common libraries and patterns:
chalkfor terminal color.commanderfor CLI argument parsing.execafor child processes.- Existing service, provider, settings, permission, and UI patterns over new abstractions.
Repository Map
src/commands/- slash and CLI command implementations.src/components/- React/Ink UI components.src/services/- API, MCP, OAuth, wiki, voice, and other service integrations.src/tools/- tool implementations.src/utils/- shared utilities.- `src/integration...
Files:
src/services/api/claude.lifecycle.test.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.
Files:
src/services/api/claude.lifecycle.test.ts
{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}
⚙️ CodeRabbit configuration file
{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}: Review provider routing, model selection, env precedence, auth/token handling, OpenAI-compatible shims, retries, proxy behavior, and outbound HTTP behavior with high scrutiny. Block on silent default changes, hidden fallback expansion, credential reuse mistakes, hardcoded provider assumptions, or new network reach that is not intentional and documented.
Files:
src/services/api/claude.lifecycle.test.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}
⚙️ CodeRabbit configuration file
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.
Files:
src/services/api/claude.lifecycle.test.ts
🪛 GitHub Actions: PR Checks / 0_smoke-and-tests.txt
src/services/api/claude.lifecycle.test.ts
[error] 246-246: Test failed: non-streaming fallback did not start promptly after stream idle timeout. Error at claude.lifecycle.test.ts:246:22.
🪛 GitHub Actions: PR Checks / smoke-and-tests
src/services/api/claude.lifecycle.test.ts
[error] 246-246: non-streaming fallback did not start promptly after stream idle timeout. Test failure at claude.lifecycle.test.ts:246.
🪛 GitHub Check: smoke-and-tests
src/services/api/claude.lifecycle.test.ts
[failure] 246-246: error: non-streaming fallback did not start promptly after stream idle timeout
at <anonymous> (/home/runner/work/openclaude/openclaude/src/services/api/claude.lifecycle.test.ts:246:22)
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/services/api/claude.lifecycle.test.ts`:
- Line 23: The Claude lifecycle test is injecting the internal
StreamIdleTimeoutError instead of exercising the real stalled-stream behavior.
Update the test around makeIdleTimeoutOpenAIStreamResponse and the relevant
claude.lifecycle.test setup to keep the stream open after a valid chunk, set
CLAUDE_STREAM_IDLE_TIMEOUT_MS to a small value before starting the request, and
let readWithIdleTimeout() trigger the timeout naturally. Remove the
openAIShimTest.StreamIdleTimeoutError import/use so the assertions cover the
user-visible timeout path rather than an implementation detail.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: cbb81ef4-eef7-4635-81bc-9b2a72e2aeff
📒 Files selected for processing (3)
src/services/api/claude.lifecycle.test.tssrc/services/api/claude.tssrc/services/api/openaiShim.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (13)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript with strict mode and ESM imports
Files:
src/services/api/claude.tssrc/services/api/claude.lifecycle.test.tssrc/services/api/openaiShim.ts
{src/commands/**/*.ts,src/services/**/*.ts,src/entrypoints/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
chalkfor terminal color in CLI code
Files:
src/services/api/claude.tssrc/services/api/claude.lifecycle.test.tssrc/services/api/openaiShim.ts
{src/services/**/*.ts,src/utils/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
execafor child processes
Files:
src/services/api/claude.tssrc/services/api/claude.lifecycle.test.tssrc/services/api/openaiShim.ts
{src/integrations/**/*.ts,src/services/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Test the exact provider/model path you changed when possible for provider modifications
Files:
src/services/api/claude.tssrc/services/api/claude.lifecycle.test.tssrc/services/api/openaiShim.ts
**/*.{ts,tsx,js,jsx,py,json,md}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow the existing code style in the touched files
Files:
src/services/api/claude.tssrc/services/api/claude.lifecycle.test.tssrc/services/api/openaiShim.ts
**/*.{ts,tsx,js,jsx,py}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Keep comments useful and concise
Files:
src/services/api/claude.tssrc/services/api/claude.lifecycle.test.tssrc/services/api/openaiShim.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow TypeScript strict mode and type safety practices by running typecheck before submitting
Files:
src/services/api/claude.tssrc/services/api/claude.lifecycle.test.tssrc/services/api/openaiShim.ts
**
⚙️ CodeRabbit configuration file
**: # AGENTS.md - AI Agent Coding GuideThis guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.
Project Snapshot
OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.
The installed CLI runs on Node.js
>=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.Work Style
- Keep changes focused on one problem.
- Prefer existing patterns in the file or nearby module.
- Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
- Add or update tests when behavior changes.
- Update docs when setup, commands, provider behavior, or user-facing behavior changes.
- For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.
Stack And Conventions
- TypeScript with strict mode and ESM imports.
- React + Ink for terminal UI.
- Bun lockfile and Bun scripts for development workflows.
- Node runtime for the built CLI.
- Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.
Common libraries and patterns:
chalkfor terminal color.commanderfor CLI argument parsing.execafor child processes.- Existing service, provider, settings, permission, and UI patterns over new abstractions.
Repository Map
src/commands/- slash and CLI command implementations.src/components/- React/Ink UI components.src/services/- API, MCP, OAuth, wiki, voice, and other service integrations.src/tools/- tool implementations.src/utils/- shared utilities.- `src/integration...
Files:
src/services/api/claude.tssrc/services/api/claude.lifecycle.test.tssrc/services/api/openaiShim.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.
Files:
src/services/api/claude.tssrc/services/api/claude.lifecycle.test.tssrc/services/api/openaiShim.ts
{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}
⚙️ CodeRabbit configuration file
{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}: Review provider routing, model selection, env precedence, auth/token handling, OpenAI-compatible shims, retries, proxy behavior, and outbound HTTP behavior with high scrutiny. Block on silent default changes, hidden fallback expansion, credential reuse mistakes, hardcoded provider assumptions, or new network reach that is not intentional and documented.
Files:
src/services/api/claude.tssrc/services/api/claude.lifecycle.test.tssrc/services/api/openaiShim.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Add or update tests when the change affects behavior
Files:
src/services/api/claude.lifecycle.test.ts
**/*.test.{ts,tsx,js}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Test the exact provider/model path you changed when possible
Files:
src/services/api/claude.lifecycle.test.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}
⚙️ CodeRabbit configuration file
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.
Files:
src/services/api/claude.lifecycle.test.ts
🪛 GitHub Actions: PR Checks / 1_smoke-and-tests.txt
src/services/api/claude.lifecycle.test.ts
[error] 558-558: Test failed: stream completed before non-streaming fallback started (error thrown at claude.lifecycle.test.ts:558).
🪛 GitHub Actions: PR Checks / smoke-and-tests
src/services/api/claude.lifecycle.test.ts
[error] 558-558: Test failed: Error thrown because 'stream completed before non-streaming fallback started'. (Claude API lifecycle tracking)
🪛 GitHub Check: smoke-and-tests
src/services/api/claude.lifecycle.test.ts
[failure] 558-558: error: stream completed before non-streaming fallback started
at <anonymous> (/home/runner/work/openclaude/openclaude/src/services/api/claude.lifecycle.test.ts:558:19)
🔇 Additional comments (3)
src/services/api/openaiShim.ts (1)
134-217: LGTM!src/services/api/claude.ts (1)
105-105: LGTM!Also applies to: 1963-1963, 2551-2556
src/services/api/claude.lifecycle.test.ts (1)
630-677: LGTM!
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/services/api/claude.lifecycle.test.ts (1)
179-184: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winExercise the real stalled-stream path, not the internal error type.
pull()immediately throwingStreamIdleTimeoutErrorbypasses the watchdog behavior this lifecycle test is meant to cover. Keep the SSE stream open after a valid event and set a smallCLAUDE_STREAM_IDLE_TIMEOUT_MSso productionreadWithIdleTimeout()produces the timeout naturally.As per path instructions, “Review tests for meaningful coverage of the changed behavior” and block when tests “assert implementation details while missing the user-visible behavior.”
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/services/api/claude.lifecycle.test.ts` around lines 179 - 184, The stalled-stream test currently triggers the internal StreamIdleTimeoutError directly from makeIdleTimeoutOpenAIStreamResponse, which bypasses the real watchdog path. Update the claude.lifecycle test to keep the SSE stream open after emitting a valid event and configure a small CLAUDE_STREAM_IDLE_TIMEOUT_MS so readWithIdleTimeout() times out naturally; use the existing makeIdleTimeoutOpenAIStreamResponse and related lifecycle test setup to exercise the user-visible stalled-stream behavior instead of asserting the internal error type.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@src/services/api/claude.lifecycle.test.ts`:
- Around line 179-184: The stalled-stream test currently triggers the internal
StreamIdleTimeoutError directly from makeIdleTimeoutOpenAIStreamResponse, which
bypasses the real watchdog path. Update the claude.lifecycle test to keep the
SSE stream open after emitting a valid event and configure a small
CLAUDE_STREAM_IDLE_TIMEOUT_MS so readWithIdleTimeout() times out naturally; use
the existing makeIdleTimeoutOpenAIStreamResponse and related lifecycle test
setup to exercise the user-visible stalled-stream behavior instead of asserting
the internal error type.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 0f54265d-1e66-4781-a64e-1b9e19052be7
📒 Files selected for processing (1)
src/services/api/claude.lifecycle.test.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (13)
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript with strict mode and ESM imports
Files:
src/services/api/claude.lifecycle.test.ts
{src/commands/**/*.ts,src/services/**/*.ts,src/entrypoints/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
chalkfor terminal color in CLI code
Files:
src/services/api/claude.lifecycle.test.ts
{src/services/**/*.ts,src/utils/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use
execafor child processes
Files:
src/services/api/claude.lifecycle.test.ts
{src/integrations/**/*.ts,src/services/**/*.ts}
📄 CodeRabbit inference engine (AGENTS.md)
Test the exact provider/model path you changed when possible for provider modifications
Files:
src/services/api/claude.lifecycle.test.ts
**/*.{ts,tsx,js,jsx,py,json,md}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow the existing code style in the touched files
Files:
src/services/api/claude.lifecycle.test.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Add or update tests when the change affects behavior
Files:
src/services/api/claude.lifecycle.test.ts
**/*.test.{ts,tsx,js}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Test the exact provider/model path you changed when possible
Files:
src/services/api/claude.lifecycle.test.ts
**/*.{ts,tsx,js,jsx,py}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Keep comments useful and concise
Files:
src/services/api/claude.lifecycle.test.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Follow TypeScript strict mode and type safety practices by running typecheck before submitting
Files:
src/services/api/claude.lifecycle.test.ts
**
⚙️ CodeRabbit configuration file
**: # AGENTS.md - AI Agent Coding GuideThis guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.
Project Snapshot
OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.
The installed CLI runs on Node.js
>=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.Work Style
- Keep changes focused on one problem.
- Prefer existing patterns in the file or nearby module.
- Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
- Add or update tests when behavior changes.
- Update docs when setup, commands, provider behavior, or user-facing behavior changes.
- For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.
Stack And Conventions
- TypeScript with strict mode and ESM imports.
- React + Ink for terminal UI.
- Bun lockfile and Bun scripts for development workflows.
- Node runtime for the built CLI.
- Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.
Common libraries and patterns:
chalkfor terminal color.commanderfor CLI argument parsing.execafor child processes.- Existing service, provider, settings, permission, and UI patterns over new abstractions.
Repository Map
src/commands/- slash and CLI command implementations.src/components/- React/Ink UI components.src/services/- API, MCP, OAuth, wiki, voice, and other service integrations.src/tools/- tool implementations.src/utils/- shared utilities.- `src/integration...
Files:
src/services/api/claude.lifecycle.test.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.
Files:
src/services/api/claude.lifecycle.test.ts
{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}
⚙️ CodeRabbit configuration file
{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}: Review provider routing, model selection, env precedence, auth/token handling, OpenAI-compatible shims, retries, proxy behavior, and outbound HTTP behavior with high scrutiny. Block on silent default changes, hidden fallback expansion, credential reuse mistakes, hardcoded provider assumptions, or new network reach that is not intentional and documented.
Files:
src/services/api/claude.lifecycle.test.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}
⚙️ CodeRabbit configuration file
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.
Files:
src/services/api/claude.lifecycle.test.ts
🪛 GitHub Actions: PR Checks / 1_smoke-and-tests.txt
src/services/api/claude.lifecycle.test.ts
[error] 549-549: Test failed (Claude API lifecycle tracking): stream completed before non-streaming fallback started. Error thrown at /home/runner/work/openclaude/openclaude/src/services/api/claude.lifecycle.test.ts:549:19.
🪛 GitHub Actions: PR Checks / smoke-and-tests
src/services/api/claude.lifecycle.test.ts
[error] 547-549: Test failed: stream completed before non-streaming fallback started. Error thrown at line 549.
jatmn
left a comment
There was a problem hiding this comment.
Thanks for the contribution. I do not see any actionable issues from my review.
@kevincodex1 LGTM
# Conflicts: # src/services/api/openaiShim.test.ts # src/services/api/openaiShim.ts
…f upstream Twigpine#1817) # OpenCC: functional-sync of upstream 67227cf (3 files). # Adaptations: kept HEAD's streamWatchdog* logic in claude.ts intact; folded # upstream's readWithIdleTimeout as superset of HEAD's readWithAbort (abort # via signal). Skipped: codex-specific paths (provider policy) and # claude.lifecycle.test.ts new file (would require new test fixtures # makeStallingResponse/makeOpenAIStreamFrame which don't exist in OpenCC's # current test surface). Rebranded test fixtures N/A (no openclaude strings). # Bugfixes.test.ts upstream diff is a no-op (Session timeout block absent).
3 main-opencc commits since 0.19.2: - 02fee76 fix(openai-shim): recover stalled provider streams (functional-sync Twigpine#1817) - dbf3529 fix(openai-shim): wire stream controller abort (functional-sync Twigpine#1828) - 31a9ee0 refactor(tests): migrate openaiShim test imports to modular barrel
Summary
Impact
Testing
bun test src/services/api/openaiShim.test.tsbun test src/services/api/claude.lifecycle.test.tsbun test src/__tests__/bugfixes.test.tsbun run test:providerbun test src/query/autoCompactCooldown.test.ts src/query/stopHooks.goal.test.ts src/query/goalContinuation.test.ts src/query/stopHooks.test.ts src/query/providerMaxTokensCapRetry.test.ts src/query/toolFailureLoopGuard.test.ts src/queryEngine.goal.test.tsbun run typecheckbun run security:pr-scangit diff --checkNotes
CLAUDE_STREAM_IDLE_TIMEOUT_MS.Summary by CodeRabbit