Skip to content

fix(phase1b): make CLI backend tests actually run#1532

Merged
MervinPraison merged 3 commits intomainfrom
fix/phase1b-tests
Apr 24, 2026
Merged

fix(phase1b): make CLI backend tests actually run#1532
MervinPraison merged 3 commits intomainfrom
fix/phase1b-tests

Conversation

@MervinPraison
Copy link
Copy Markdown
Owner

@MervinPraison MervinPraison commented Apr 24, 2026

Summary

Follow-up to PR #1531 (Phase 1b). After that PR merged, 19/34 of its shipped unit tests were failing locally because they asserted against fabricated APIs. CI just skipped them so the breakage was silent. This PR makes the tests actually exercise the real code.

Production behaviour: unchanged. Only changes are (a) one tiny helper extraction in agents_generator.py for testability, and (b) rewritten test files.

Before / after

Before (on main at 39f2c79d)

$ pytest src/praisonai/tests/unit/test_cli_backend_flag.py \
         src/praisonai/tests/unit/test_external_agents_backcompat.py \
         src/praisonai/tests/unit/test_yaml_cli_backend.py \
         src/praisonai/tests/unit/test_claude_backend.py
==========================================
19 failed, 15 passed in 0.65s
==========================================

Failures breakdown:

File Failures Root cause
test_yaml_cli_backend.py 6/6 AgentsGenerator(config=...) — kwarg doesn't exist; .create_agents_and_tasks() — method doesn't exist
test_cli_backend_flag.py 8/8 PraisonAI().parse_args() short-circuits to parse_known_args([]) when PYTEST_CURRENT_TEST is in env (see main.py:1137-1138), so patched sys.argv is ignored and --help never raises SystemExit
test_external_agents_backcompat.py 5/7 Same parse_args() short-circuit

After (on this branch)

$ pytest src/praisonai/tests/unit/test_cli_backend_flag.py \
         src/praisonai/tests/unit/test_external_agents_backcompat.py \
         src/praisonai/tests/unit/test_yaml_cli_backend.py \
         src/praisonai/tests/unit/test_claude_backend.py
==========================================
34 passed in 1.18s
==========================================

Plus src/praisonai-agents/tests/unit/test_cli_backend_protocol.py8/8 still pass (no changes).

Evidence that the feature still works (regression proof)

$ python -m praisonai.cli.main backends list
claude-code

$ python -m praisonai.cli.main --help | grep -E '(cli-backend|external-agent)'
  --external-agent {claude,gemini,codex,cursor}
  --cli-backend {claude-code}
  --external-agent-direct

$ python -m praisonai.cli.main --cli-backend claude-code --external-agent claude hi
usage: praisonai ...
praisonai: error: argument --external-agent: not allowed with argument --cli-backend

Changes

1. src/praisonai/praisonai/agents_generator.py — small helper extraction

Moved the 23-line YAML cli_backend resolve block out of generate_crew_and_kickoff into a module-level function _resolve_yaml_cli_backend(cli_backend_config, logger). Zero behaviour change — the PraisonAgent construction still receives cli_backend=cli_backend_resolved. The extraction simply makes the logic unit-testable without spinning up a full generator.

2. test_yaml_cli_backend.py — 8 tests (was 6)

Direct calls to _resolve_yaml_cli_backend(...). Covers:

  • string id → resolve_cli_backend('claude-code')
  • dict with overrides → resolve_cli_backend('claude-code', overrides={...})
  • dict missing idNone + warning (no raise)
  • missing field → None (no warning)
  • ImportError in resolver → None + warning
  • unknown id (ValueError from registry) → None + warning
  • invalid type (e.g. 123) → None + warning
  • end-to-end: real 'claude-code' id resolves without any mocking

3. test_cli_backend_flag.py — 7 tests (was 8)

Subprocess-driven to avoid the PYTEST_CURRENT_TEST short-circuit. Child env has all PYTEST_* vars stripped. Each subprocess has a bounded timeout so hangs fail fast. Covers:

  • --cli-backend in --help
  • registered backend accepted
  • unknown backend rejected by argparse
  • mutual exclusion with --external-agent
  • backends list subcommand
  • bare backends (defaults to list)
  • unknown backends bogus subcommand

4. test_external_agents_backcompat.py — 6 tests (was 7)

Mix of direct imports and subprocess argparse checks. Covers:

  • ExternalAgentsHandler still importable + list_integrations() preserves original 4
  • ClaudeCodeIntegration still importable + .cli_command == 'claude'
  • --external-agent in --help
  • all 4 choices (claude, gemini, codex, cursor) in --help
  • --external-agent-direct in --help
  • unknown value rejected

Out of scope

  • Fixing the parse_args() PYTEST_CURRENT_TEST short-circuit itself. That's a pre-existing CLI-wide testability issue unrelated to Phase 1b; touching it would balloon this PR.
  • Adding --cli-backend back-compat alias for --external-agent claude. Separate design decision.

Verification

cd /path/to/praisonai-package
git fetch origin pull/<this-pr>/head:fix-phase1b && git checkout fix-phase1b

# Wrapper tests
PYTHONPATH=src/praisonai-agents:src/praisonai python3 -m pytest \
  src/praisonai/tests/unit/test_cli_backend_flag.py \
  src/praisonai/tests/unit/test_external_agents_backcompat.py \
  src/praisonai/tests/unit/test_yaml_cli_backend.py \
  src/praisonai/tests/unit/test_claude_backend.py -v
# 34 passed

# Core tests (unchanged)
PYTHONPATH=src/praisonai-agents:src/praisonai python3 -m pytest \
  src/praisonai-agents/tests/unit/test_cli_backend_protocol.py -v
# 8 passed

# Functional smoke (feature still works)
PYTHONPATH=src/praisonai-agents:src/praisonai python3 -m praisonai.cli.main backends list
# claude-code

Closes the bug silently introduced by #1531. Refs #1530.

Summary by CodeRabbit

  • Refactor

    • Centralized YAML CLI-backend resolution for more consistent validation and tolerant error handling when loading configured backends.
  • Tests

    • Expanded end-to-end CLI tests that run the real CLI to verify help text, acceptance/rejection of backend and external-agent flags, mutual-exclusion behavior, subcommand listing and error reporting, and legacy back-compat.

Problem: After PR #1531 merged, 19/34 shipped unit tests for the Phase 1b
CLI Backend Protocol were failing because they were written against
fabricated APIs that do not exist on this codebase:

  - test_yaml_cli_backend.py: used AgentsGenerator(config=...) and
    .create_agents_and_tasks(); neither the kwarg nor the method exist.
  - test_cli_backend_flag.py, test_external_agents_backcompat.py:
    called PraisonAI().parse_args() which deliberately short-circuits to
    parse_known_args([]) when PYTEST_CURRENT_TEST is in env, so patched
    sys.argv was ignored and --help never raised SystemExit.

The Phase 1b *feature* works end-to-end (verified via manual CLI smoke:
'praisonai backends list' prints claude-code, --cli-backend flag accepts
registered ids, mutual exclusion fires). The tests, however, were dead
weight; CI just skipped them.

Fix:

  1. Extract the YAML cli_backend resolution block (23 lines) from
     agents_generator.py into a new module-level helper
     _resolve_yaml_cli_backend(cli_backend_config, logger). Zero behaviour
     change for existing callers; PraisonAgent(..., cli_backend=...)
     wiring is unchanged.

  2. Rewrite test_yaml_cli_backend.py to call that helper directly (8
     tests). Covers: string id, dict+overrides, missing id, None, import
     error, unknown id, invalid type, plus a real end-to-end resolve
     against the registered claude-code backend.

  3. Rewrite test_cli_backend_flag.py to drive the CLI via subprocess
     (7 tests), stripping PYTEST_* env vars so parse_args does not
     short-circuit. Covers: --cli-backend in --help, registered backend
     accepted, unknown backend rejected, mutual exclusion with
     --external-agent, backends list subcommand (bare and with 'list'),
     and unknown subcommand reporting.

  4. Rewrite test_external_agents_backcompat.py as a mix of direct
     imports (ExternalAgentsHandler, ClaudeCodeIntegration) and
     subprocess argparse checks (6 tests). Guards against regression
     of --external-agent {claude,gemini,codex,cursor} and
     --external-agent-direct.

Result: 34/34 tests pass locally (6 backcompat + 7 CLI + 8 YAML + 13
existing claude-backend). No production code behaviour change - only
test suite + a small helper extraction in agents_generator.py.
Copilot AI review requested due to automatic review settings April 24, 2026 04:29
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 24, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9f69d08a-67fe-4181-8118-2bc2a55cb5d7

📥 Commits

Reviewing files that changed from the base of the PR and between 0577ea3 and d9fc858.

📒 Files selected for processing (1)
  • src/praisonai/tests/unit/test_cli_backend_flag.py

📝 Walkthrough

Walkthrough

Extracted inline YAML cli_backend resolution from _run_praisonai into a new module-level helper _resolve_yaml_cli_backend(cli_backend_config, logger). Tests shifted from in-process mocking to subprocess-based CLI assertions and unit tests now directly validate the new resolver behavior.

Changes

Cohort / File(s) Summary
CLI Backend Resolution Refactor
src/praisonai/praisonai/agents_generator.py
Added _resolve_yaml_cli_backend(cli_backend_config, logger) and removed the previous inline YAML cli_backend parsing inside _run_praisonai; helper encapsulates type checks, id validation, overrides extraction, calls praisonai.cli_backends.resolve_cli_backend, logs warnings, and returns None on errors.
CLI/Subprocess Tests
src/praisonai/tests/unit/test_cli_backend_flag.py, src/praisonai/tests/unit/test_external_agents_backcompat.py
Replaced white-box, in-process argparse/mocking tests with subprocess invocations of python -m praisonai.cli.main. Verify help text includes flags/choices, enforce acceptance/rejection of --cli-backend/--external-agent values, mutual-exclusion behavior, and backends subcommand outputs/errors at process level.
Unit Tests for Resolver
src/praisonai/tests/unit/test_yaml_cli_backend.py
Tests now call praisonai.agents_generator._resolve_yaml_cli_backend directly: cover valid resolution including overrides passthrough and integration for claude-code, and error cases (missing/invalid shapes, missing id, ImportError/unknown id) asserting None return plus logger.warning.

Sequence Diagram(s)

(omitted — changes are a localized refactor and test adjustments; no new multi-component sequential flow requiring visualization)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

Suggested labels

Review effort 4/5

Poem

🐰
I hopped through code with nimble feet,
Pulled tangled backend threads to neat;
Tests now shout from outside the den,
CLI truth proven time and again,
A carrot for clean, tidy feat!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'fix(phase1b): make CLI backend tests actually run' directly and specifically describes the main change: fixing failing unit tests by rewriting them to exercise real code rather than mocked APIs.
Docstring Coverage ✅ Passed Docstring coverage is 90.32% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/phase1b-tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@MervinPraison
Copy link
Copy Markdown
Owner Author

@copilot Do a thorough review of this PR. Read ALL existing reviewer comments above from Qodo, Coderabbit, and Gemini first — incorporate their findings.

Review areas:

  1. Bloat check: Are changes minimal and focused? Any unnecessary code or scope creep?
  2. Security: Any hardcoded secrets, unsafe eval/exec, missing input validation?
  3. Performance: Any module-level heavy imports? Hot-path regressions?
  4. Tests: Are tests included? Do they cover the changes adequately?
  5. Backward compat: Any public API changes without deprecation?
  6. Code quality: DRY violations, naming conventions, error handling?
  7. Address reviewer feedback: If Qodo, Coderabbit, or Gemini flagged valid issues, include them in your review
  8. Suggest specific improvements with code examples where possible

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the CLI backend resolution logic by introducing a module-level helper function, _resolve_yaml_cli_backend, which improves testability and code reuse. The test suite has been significantly updated to use subprocess-based integration tests for the CLI surface, ensuring that the --cli-backend and legacy --external-agent flags behave correctly in a real environment. Additionally, the PR maintains backward compatibility for existing external agent integrations. I have no feedback to provide as the changes are well-structured and the test coverage is robust.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/praisonai/tests/unit/test_external_agents_backcompat.py (1)

13-36: Reasonable subprocess harness; path assumptions are coupled to the current layout.

The 4-level REPO_ROOT walk and hard-coded src/praisonai-agents + src/praisonai PYTHONPATH entries will silently break if this test file is moved or if either sibling package is renamed. That's acceptable pragmatism for a phase-1b fix, but a conftest-level fixture (e.g., computing REPO_ROOT via pytest.rootdir and reusing _build_env/_run_cli between this file and test_cli_backend_flag.py) would avoid the duplication you now have across both files. Happy to send a follow-up that lifts these helpers into a shared fixture if useful.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/praisonai/tests/unit/test_external_agents_backcompat.py` around lines 13
- 36, The REPO_ROOT, _build_env, and _run_cli helpers duplicate logic and
hard-code path walks; refactor them into a shared pytest fixture in conftest.py
that computes the repository root via pytest.rootdir (or request.config.rootdir)
and exposes a reusable CLI runner/env builder to tests instead of the local
REPO_ROOT/_build_env/_run_cli functions in test_external_agents_backcompat.py
and test_cli_backend_flag.py; update those tests to use the new fixture to build
PYTHONPATH entries (for praisonai-agents and praisonai) and to run the CLI,
removing the four-level os.path walk and duplicate helper code.
src/praisonai/tests/unit/test_cli_backend_flag.py (1)

58-72: Minor docstring/comment drift vs. actual args.

Lines 60-62 describe passing "an unrealistic prompt that won't trigger LLM work" and relying on the timeout to abort, but the argv here is --cli-backend claude-code --help--help short-circuits argparse and exits 0 before any LLM/prompt path runs, so the try/except TimeoutExpired + pytest.skip are effectively dead branches. Either drop the skip path or switch to a non---help argv that actually exercises the short timeout. Keeping --help is fine; just realign the comment.

📝 Proposed comment tweak
-    # We intentionally pass an unrealistic prompt that won't trigger LLM work and
-    # rely on the default timeout to abort quickly. We only assert that argparse
-    # accepts the flag (no "invalid choice" or "unrecognized" in stderr).
-    try:
-        r = _run_cli(
-            "--cli-backend", "claude-code", "--help",
-            timeout=15,
-        )
-    except subprocess.TimeoutExpired:
-        pytest.skip("CLI startup exceeded timeout; unrelated to flag parsing")
+    # Use --help to short-circuit argparse; we only want to prove the flag+value
+    # is accepted (no "invalid choice" / "unrecognized" in stderr).
+    r = _run_cli("--cli-backend", "claude-code", "--help", timeout=15)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/praisonai/tests/unit/test_cli_backend_flag.py` around lines 58 - 72, The
test test_cli_backend_flag_accepts_registered_backend uses "--help" which
short-circuits argparse, so the try/except TimeoutExpired and pytest.skip are
dead code; update the test by removing the try/except/pytest.skip block and its
timeout argument (used with _run_cli), and adjust the docstring/comment to state
that "--cli-backend claude-code --help" is used to exercise argparse only (no
LLM run), or alternatively replace "--help" with a realistic prompt (and keep
the timeout/skip) if you want to exercise runtime behavior; locate the test
function test_cli_backend_flag_accepts_registered_backend and the _run_cli call
to implement the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/praisonai/praisonai/agents_generator.py`:
- Around line 156-176: Pre-seed the local variable `label` from
`cli_backend_config` before attempting `from praisonai.cli_backends import
resolve_cli_backend` so the `except ImportError` log can show the requested
backend; specifically, set `label = cli_backend_config` when it's a string and
when it's a dict set `label = cli_backend_config.get('id') or "<missing>"` (or
fallback to the type name) before the import, then keep the existing branches
that call `resolve_cli_backend` and the `logger.warning` in the `except` to
reference that pre-populated `label`.

---

Nitpick comments:
In `@src/praisonai/tests/unit/test_cli_backend_flag.py`:
- Around line 58-72: The test test_cli_backend_flag_accepts_registered_backend
uses "--help" which short-circuits argparse, so the try/except TimeoutExpired
and pytest.skip are dead code; update the test by removing the
try/except/pytest.skip block and its timeout argument (used with _run_cli), and
adjust the docstring/comment to state that "--cli-backend claude-code --help" is
used to exercise argparse only (no LLM run), or alternatively replace "--help"
with a realistic prompt (and keep the timeout/skip) if you want to exercise
runtime behavior; locate the test function
test_cli_backend_flag_accepts_registered_backend and the _run_cli call to
implement the change.

In `@src/praisonai/tests/unit/test_external_agents_backcompat.py`:
- Around line 13-36: The REPO_ROOT, _build_env, and _run_cli helpers duplicate
logic and hard-code path walks; refactor them into a shared pytest fixture in
conftest.py that computes the repository root via pytest.rootdir (or
request.config.rootdir) and exposes a reusable CLI runner/env builder to tests
instead of the local REPO_ROOT/_build_env/_run_cli functions in
test_external_agents_backcompat.py and test_cli_backend_flag.py; update those
tests to use the new fixture to build PYTHONPATH entries (for praisonai-agents
and praisonai) and to run the CLI, removing the four-level os.path walk and
duplicate helper code.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 24e94e28-ac67-47b9-bf30-7ba0aa762ec9

📥 Commits

Reviewing files that changed from the base of the PR and between 39f2c79 and bf2cfc3.

📒 Files selected for processing (4)
  • src/praisonai/praisonai/agents_generator.py
  • src/praisonai/tests/unit/test_cli_backend_flag.py
  • src/praisonai/tests/unit/test_external_agents_backcompat.py
  • src/praisonai/tests/unit/test_yaml_cli_backend.py

Comment thread src/praisonai/praisonai/agents_generator.py Outdated
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 24, 2026

Greptile Summary

This PR fixes 19 silently-skipped unit tests from PR #1531 by (a) extracting a module-level _resolve_yaml_cli_backend helper in agents_generator.py for direct unit testing, and (b) rewriting three test files — replacing mock-based in-process tests (which were broken by the PYTEST_CURRENT_TEST argparse short-circuit) with subprocess-driven CLI tests and direct helper calls. Production behaviour is unchanged.

Confidence Score: 5/5

Safe to merge — production code is unchanged and all remaining findings are P2 style/maintenance suggestions.

All four changed files have clear, correct logic. The one production-code change (_resolve_yaml_cli_backend extraction) is a pure refactor with no behavior change on the hot path. The two P2 findings (helper duplication, one live-registry dependency in a test) do not affect correctness or reliability of the shipped feature.

No files require special attention for merging.

Important Files Changed

Filename Overview
src/praisonai/praisonai/agents_generator.py Extracted 23-line YAML cli_backend resolution block into module-level _resolve_yaml_cli_backend helper; zero behavior change in production path except overrides: null YAML now coerces to {} via or {} (already noted in previous threads).
src/praisonai/tests/unit/test_cli_backend_flag.py Rewritten from mock-based in-process tests to subprocess-driven tests that strip PYTEST_* env vars; helpers _build_env/_run_cli are duplicated from test_external_agents_backcompat.py — candidates for a shared conftest.
src/praisonai/tests/unit/test_external_agents_backcompat.py Rewritten with a mix of direct-import assertions and subprocess argparse checks; _build_env/_run_cli duplicated from test_cli_backend_flag.py.
src/praisonai/tests/unit/test_yaml_cli_backend.py Rewritten to call _resolve_yaml_cli_backend directly; test_yaml_cli_backend_unknown_id relies on live registry raising for unknown IDs rather than mocking the contract explicitly.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["AgentsGenerator.generate_crew_and_kickoff()"] -->|"details.get('cli_backend')"| B["_resolve_yaml_cli_backend(config, logger)"]
    B --> C{config type?}
    C -->|None / falsy| D["return None"]
    C -->|str| E["resolve_cli_backend(id)"]
    C -->|dict| F{has 'id' key?}
    C -->|other| G["raise ValueError"]
    F -->|yes| H["resolve_cli_backend(id, overrides=overrides or {})"]
    F -->|no| I["raise ValueError"]
    E -->|success| J["return backend instance"]
    H -->|success| J
    G -->|caught| K["logger.warning → return None"]
    I -->|caught| K
    E -->|ImportError| L["logger.warning → return None"]
    H -->|ImportError| L
    E -->|Exception| K
    H -->|Exception| K
    J --> M["PraisonAgent(cli_backend=backend)"]
    D --> N["PraisonAgent(cli_backend=None)"]
    K --> N
    L --> N
Loading

Reviews (3): Last reviewed commit: "docs(tests): add inline comments documen..." | Re-trigger Greptile

Comment thread src/praisonai/praisonai/agents_generator.py
@MervinPraison
Copy link
Copy Markdown
Owner Author

@claude You are the FINAL architecture reviewer. If the branch is under MervinPraison/PraisonAI (not a fork), you are able to make modifications to this branch and push directly. SCOPE: Focus ONLY on Python packages (praisonaiagents, praisonai). Do NOT modify praisonai-rust or praisonai-ts. Read ALL comments above from Gemini, Qodo, CodeRabbit, and Copilot carefully before responding.

Phase 1: Review per AGENTS.md

  1. Protocol-driven: check heavy implementations vs core SDK
  2. Backward compatible: ensure zero feature regressions
  3. Performance: no hot-path regressions

Phase 2: FIX Valid Issues
4. For any VALID bugs or architectural flaws found by Gemini, CodeRabbit, Qodo, Copilot, or any other reviewer: implement the fix
5. Push all code fixes directly to THIS branch (do NOT create a new PR)
6. Comment a summary of exact files modified and what you skipped

Phase 3: Final Verdict
7. If all issues are resolved, approve the PR / close the Issue
8. If blocking issues remain, request changes / leave clear action items

@praisonai-triage-agent
Copy link
Copy Markdown
Contributor

praisonai-triage-agent Bot commented Apr 24, 2026

Claude finished @MervinPraison's task —— View job


✅ Final Architecture Review Complete

Conducting comprehensive review per AGENTS.md guidelines and addressing all reviewer feedback.

Review Tasks:

  • Read AGENTS.md architecture guidelines
  • Review all existing reviewer feedback (Gemini, CodeRabbit, Qodo, Copilot, Greptile)
  • Analyze changed files against architecture rules
  • Identify valid issues requiring fixes
  • Implement fixes for valid issues
  • Test changes
  • Final verdict

Phase 1: Architecture Review

  • Protocol-driven: Check heavy implementations vs core SDK ✅ COMPLIANT
  • Backward compatible: Ensure zero feature regressions ✅ COMPLIANT
  • Performance: No hot-path regressions ✅ COMPLIANT

Phase 2: Fix Valid IssuesCOMPLETED

  • Address CodeRabbit feedback
  • Address Greptile feedback
  • Push fixes to branch (commit 0577ea3)

Phase 3: Final VerdictAPPROVED


🏆 Final Architectural Approval

✅ APPROVED FOR MERGE

This PR successfully addresses the silent test failures from PR #1531 while maintaining full compliance with AGENTS.md architecture guidelines.

📋 Architecture Compliance Summary

✅ Protocol-Driven Core

  • No heavy implementations added to core SDK
  • Only test infrastructure and minimal helper extraction
  • Maintains clean separation between core/wrapper layers

✅ Backward Compatible

  • Zero production behavior changes confirmed
  • Legacy API surface fully preserved
  • All existing functionality maintained

✅ Performance

  • No module-level imports added
  • No hot-path changes
  • Lazy import pattern preserved in helper function

✅ Agent-Centric Design

  • Changes are test-focused, don't affect agent functionality
  • CLI backend integration remains lightweight

🔧 Issues Fixed

Applied fixes for all valid reviewer feedback:

  1. ImportError logging - Backend ID now preserved in error logs
  2. Dead code removal - Cleaned up try/except TimeoutExpired in --help test
  3. PYTHONPATH fix - Removed trailing separator to avoid implicit CWD inclusion
  4. Test assertions - Added missing returncode check for error cases

🎯 What This PR Achieves

🚀 Recommendation

APPROVE AND MERGE - This PR represents excellent engineering:

  • Focused scope (test fixes only)
  • Architecture compliant
  • Backward compatible
  • Addresses all reviewer concerns
  • Zero production risk

The Phase 1b CLI backend feature is now properly tested and ready for production use.

- Fix ImportError path to preserve requested backend ID in log messages
- Remove dead try/except code in --help test
- Fix trailing PYTHONPATH separator issue in test environments
- Add missing returncode assertion for error cases

Co-authored-by: Mervin Praison <MervinPraison@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/praisonai/tests/unit/test_external_agents_backcompat.py (2)

13-39: Optional: hoist REPO_ROOT, _build_env, and _run_cli into a shared conftest.py.

The identical helpers live in src/praisonai/tests/unit/test_cli_backend_flag.py. Extracting them to a conftest.py (or a small _cli_subprocess.py helper module) eliminates the duplication and keeps PYTHONPATH/PYTEST_* handling consistent if future tests join the subprocess pattern. Not a blocker.

♻️ Proposed conftest extraction
# src/praisonai/tests/unit/conftest.py
import os
import subprocess
import sys
import pytest

REPO_ROOT = os.path.abspath(
    os.path.join(os.path.dirname(__file__), "..", "..", "..", "..")
)

def _build_env():
    env = {k: v for k, v in os.environ.items() if not k.startswith("PYTEST_")}
    parts = [
        os.path.join(REPO_ROOT, "src", "praisonai-agents"),
        os.path.join(REPO_ROOT, "src", "praisonai"),
    ]
    if env.get("PYTHONPATH"):
        parts.append(env["PYTHONPATH"])
    env["PYTHONPATH"] = os.pathsep.join(parts)
    return env

`@pytest.fixture`
def run_cli():
    def _run(*args, timeout=30):
        return subprocess.run(
            [sys.executable, "-m", "praisonai.cli.main", *args],
            capture_output=True, text=True,
            timeout=timeout, cwd=REPO_ROOT, env=_build_env(),
        )
    return _run
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/praisonai/tests/unit/test_external_agents_backcompat.py` around lines 13
- 39, Move the duplicated test helpers into a shared test fixture/module: hoist
REPO_ROOT, _build_env, and _run_cli into a new
src/praisonai/tests/unit/conftest.py (or a small helper module) and export a
pytest fixture (e.g., run_cli) that wraps the existing _run_cli behavior;
replace direct uses of _build_env/_run_cli in test_external_agents_backcompat.py
and test_cli_backend_flag.py with the new fixture to remove duplication and
ensure consistent PYTHONPATH/PYTEST_* handling across tests.

86-90: Minor: consider asserting the expected argparse error text explicitly.

assert "invalid choice" in r.stderr or "notreal" in r.stderr will also pass on unrelated failures that happen to echo notreal (e.g., a crash before argparse). Tightening to require "invalid choice" (and optionally the value) makes the test strictly validate argparse rejection rather than generic failure modes. Same pattern applies to test_cli_backend_flag_rejects_unknown_backend in the sibling file.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/praisonai/tests/unit/test_external_agents_backcompat.py` around lines 86
- 90, The test test_external_agent_rejects_unknown_value currently uses a loose
assertion that may pass for unrelated failures; change its assertion to
explicitly require argparse's rejection text by asserting that "invalid choice"
is in r.stderr (optionally also assert "notreal" appears) instead of the
disjunction. Apply the same tightening to the sibling
test_cli_backend_flag_rejects_unknown_backend so both tests explicitly check for
the argparse "invalid choice" error message.
src/praisonai/tests/unit/test_cli_backend_flag.py (1)

13-13: Nit: pytest appears unused in this module.

No fixtures, markers, or pytest.raises are referenced — the import can be dropped unless you plan to add parametrization/fixtures soon. Leaving it in is harmless.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/praisonai/tests/unit/test_cli_backend_flag.py` at line 13, The import
statement "import pytest" in the test module is unused; remove the top-level
"import pytest" line from test_cli_backend_flag.py (or the module containing the
import) so there are no unused imports left, unless you intend to add
fixtures/parametrization that will use pytest later.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/praisonai/tests/unit/test_cli_backend_flag.py`:
- Around line 97-101: Add a brief inline comment on the second line of the
test_backends_bare_subcommand_lists test (just above the _run_cli call)
documenting that this test depends on the CLI "backends" handler treating
subcommand None as equivalent to "list" (see the backends handler in cli.main);
mention that if the handler changes to require an explicit "list" the test will
fail. This makes the coupling discoverable for future maintainers.

---

Nitpick comments:
In `@src/praisonai/tests/unit/test_cli_backend_flag.py`:
- Line 13: The import statement "import pytest" in the test module is unused;
remove the top-level "import pytest" line from test_cli_backend_flag.py (or the
module containing the import) so there are no unused imports left, unless you
intend to add fixtures/parametrization that will use pytest later.

In `@src/praisonai/tests/unit/test_external_agents_backcompat.py`:
- Around line 13-39: Move the duplicated test helpers into a shared test
fixture/module: hoist REPO_ROOT, _build_env, and _run_cli into a new
src/praisonai/tests/unit/conftest.py (or a small helper module) and export a
pytest fixture (e.g., run_cli) that wraps the existing _run_cli behavior;
replace direct uses of _build_env/_run_cli in test_external_agents_backcompat.py
and test_cli_backend_flag.py with the new fixture to remove duplication and
ensure consistent PYTHONPATH/PYTEST_* handling across tests.
- Around line 86-90: The test test_external_agent_rejects_unknown_value
currently uses a loose assertion that may pass for unrelated failures; change
its assertion to explicitly require argparse's rejection text by asserting that
"invalid choice" is in r.stderr (optionally also assert "notreal" appears)
instead of the disjunction. Apply the same tightening to the sibling
test_cli_backend_flag_rejects_unknown_backend so both tests explicitly check for
the argparse "invalid choice" error message.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 22a4117b-e562-456a-a13c-a641c45ca173

📥 Commits

Reviewing files that changed from the base of the PR and between bf2cfc3 and 0577ea3.

📒 Files selected for processing (3)
  • src/praisonai/praisonai/agents_generator.py
  • src/praisonai/tests/unit/test_cli_backend_flag.py
  • src/praisonai/tests/unit/test_external_agents_backcompat.py

Comment thread src/praisonai/tests/unit/test_cli_backend_flag.py
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

…dler

Addresses remaining CodeRabbit nit on test_cli_backend_flag.py. No test
logic change; only docstring additions that document the coupling
between the subprocess tests and the 'backends' subcommand handler in
praisonai.cli.main (default-to-list behaviour and '[red]Unknown
backends subcommand: ...[/red]' error wording).
@MervinPraison MervinPraison merged commit 914a1a2 into main Apr 24, 2026
2 of 3 checks passed
@MervinPraison MervinPraison deleted the fix/phase1b-tests branch April 24, 2026 06:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants