fix(optimizer): honor CLAUDE_SMART_CLI_PATH#127
Conversation
When CLAUDE_SMART_HOST=opencode (or codex), backend-service.sh sets
CLAUDE_SMART_CLI_PATH to the host-specific compatibility bridge
(opencode-claude-compat or codex-claude-compat) so the reflexio
claude-code provider generates via the same bridge.
optimizer_assistant.py was previously hardcoded to spawn the real
"claude" CLI via shutil.which. With CLAUDE_SMART_HOST=opencode this
bypassed the bridge on the very next optimizer rollout and consumed CC
quota even after the user had switched reflexio's auto-detected model
to MiniMax-M3 via MINIMAX_API_KEY.
Extracted _resolve_claude_cli_path() that honours CLAUDE_SMART_CLI_PATH
and falls back to shutil.which("claude") when unset, so non-bridge
hosts (vanilla Claude Code, any environment that doesn't set the
override) continue to behave unchanged.
Also expand the CLAUDE_SMART_USE_LOCAL_CLI default comment so future
installs write a description that explains both the 1 and 0 semantics
(previously the wording implied it always routes through Claude Code
regardless of value, which made the .env confusing to scan).
Tests added: bridge override preferred, fallback when unset,
resolver handles empty override.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds ChangesHost CLI Path Override
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 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 |
Code reviewFound 1 issue:
On an OpenCode host, claude-smart/plugin/src/claude_smart/optimizer_assistant.py Lines 172 to 191 in f272e13 Bridge allow-list for reference: claude-smart/plugin/scripts/opencode-claude-compat.js Lines 55 to 77 in f272e13 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
|
Addressed in What changed:
Verified:
|
What's broken / annoying
When claude-smart runs under OpenCode, the backend already knows which local bridge should handle Claude-style AI calls:
opencode-claude-compatclaudeCLIcodex execpath, not the Claude-compat bridgeMost Reflexio calls already follow their host-specific path. But the optimizer assistant had one old path that still looked up
claudedirectly on non-Codex hosts.The first version of this PR fixed that lookup, but it sent full Claude Code safety flags to the OpenCode compatibility bridge. That bridge intentionally accepts only a small Claude-provider argument surface, so the optimizer would fail on OpenCode instead of routing correctly.
What's changing
CLAUDE_SMART_CLI_PATHbefore falling back to the normalclaudeCLI._run_codex()and ignoresCLAUDE_SMART_CLI_PATHfor optimizer rollouts.flowchart TD A[Optimizer needs an AI response] --> B{Which host is running?} B -->|Claude Code| C[Resolve normal claude CLI] C --> D[Use guarded Claude flags] D --> E[Same Claude Code behavior as before] B -->|OpenCode before fix| F[Resolve opencode-claude-compat] F --> G[Send unsupported Claude Code flags] G --> H[Bridge rejects the call] B -->|OpenCode after fix| I[Resolve opencode-claude-compat] I --> J[Send bridge-supported args only] J --> K[Request runs through OpenCode bridge] B -->|Codex| L[Use native codex exec optimizer path] L --> M[Same Codex behavior as before] classDef broken fill:#ffe5e5,stroke:#c62828,color:#111; classDef changed fill:#e8f5e9,stroke:#2e7d32,color:#111; classDef same fill:#eef3ff,stroke:#315fbd,color:#111; class F,G,H broken; class I,J,K changed; class C,D,E,L,M same;How the product behaves afterwards
claude, because silent fallback would recreate the quota/routing bug.Validation
uvx ruff check plugin/src/claude_smart/optimizer_assistant.py plugin/src/claude_smart/env_config.py tests/test_optimizer_assistant.py-> passeduv run --project plugin pytest tests/test_optimizer_assistant.py tests/test_opencode_support.py::test_opencode_backend_service_uses_bridge_without_opencode_path_probe tests/test_codex_support.py::test_codex_hooks_use_expected_events_and_marketplace_fallback-> 14 passednpm ci-> installed locked Node dev dependencies needed by packaging/TypeScript checksuv run --project plugin pytest-> 642 passedCLAUDE_SMART_HOST=opencodewith realopencode-claude-compatand localopencode 1.17.12returned{"content":"OK"}CLAUDE_SMART_HOST=codexwith localcodex-cli 0.142.5returned{"content":"OK"}Risks / follow-ups
Why this is needed
This closes the gap where OpenCode optimizer rollouts could either bypass the host bridge or, after the initial PR version, fail because the bridge received unsupported Claude Code-only flags.
Why this is net-positive
Developers get predictable local routing and clearer failure behavior. OpenCode gets the bridge path it expects, Claude Code keeps its guarded CLI behavior, and Codex keeps its existing native optimizer path.
Summary by CodeRabbit
New Features
Bug Fixes