Skip to content

fix: make call feature guard detect missing optional deps#3169

Open
praisonai-triage-agent[bot] wants to merge 1 commit into
mainfrom
claude/issue-3168-20260718-1616
Open

fix: make call feature guard detect missing optional deps#3169
praisonai-triage-agent[bot] wants to merge 1 commit into
mainfrom
claude/issue-3168-20260718-1616

Conversation

@praisonai-triage-agent

@praisonai-triage-agent praisonai-triage-agent Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Fixes #3168

Summary

The call feature's availability guard used importlib.util.find_spec("praisonai.api.call"), which succeeds whenever the wrapper submodule file exists on disk. It did not detect the missing third-party dependencies (fastapi, twilio, websockets, pyngrok) that praisonai/api/call.py imports at module top, so the friendly hint never fired and users saw a raw ImportError: No module named 'fastapi'.

Change

Replaced the ineffective find_spec check in get_call_module (praisonai/cli/legacy/inbuilt_tools.py) with a try/except ImportError around the real import, re-raising the existing friendly install message. This mirrors the correct pattern already used in api/agent_invoke.py.

Notes

  • Feature logic and the praisonai[call] optional-dependency set are unchanged.
  • Off the base-import hot path (call.py loads only on demand) β€” correctness/UX fix, not an import-time regression.

Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling when the optional call feature is unavailable.
    • Displays a clearer installation hint while preserving the original error details for troubleshooting.

Co-authored-by: MervinPraison <MervinPraison@users.noreply.github.com>
@MervinPraison

Copy link
Copy Markdown
Owner

@coderabbitai review

@MervinPraison

Copy link
Copy Markdown
Owner

/review

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more β†’

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account β†’

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us β†’

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor
βœ… Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@MervinPraison MervinPraison added pipeline/blocked:ci Blocked: CI not green on HEAD pipeline/blocked:no-final Blocked: no FINAL @claude trigger yet pipeline/final-claude-pending Reviews done; waiting for FINAL @claude labels Jul 18, 2026
@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

πŸ“ Walkthrough

Walkthrough

The call feature loader now imports praisonai.api.call inside a try/except ImportError block and raises the existing optional-installation hint with the original exception chained when dependencies are unavailable.

Changes

Call feature import guard

Layer / File(s) Summary
Guard call module import
src/praisonai/praisonai/cli/legacy/inbuilt_tools.py
get_call_module() replaces the ineffective find_spec check with guarded importing and chained error reporting.

Estimated code review effort: 1 (Trivial) | ~3 minutes

πŸš₯ 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 title clearly summarizes the main change: fixing the call-feature guard to handle missing optional dependencies.
Linked Issues check βœ… Passed The change matches issue #3168 by replacing the ineffective find_spec guard with a real import wrapped in ImportError handling.
Out of Scope Changes check βœ… Passed The PR is narrowly scoped to the optional-dependency guard fix and adds no unrelated changes.
Docstring Coverage βœ… Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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 claude/issue-3168-20260718-1616

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.

@greptile-apps

greptile-apps Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR changes how the optional call feature is loaded.

  • Replaces the find_spec() check with a real module import.
  • Converts import failures into the existing installation hint.
  • Preserves the original exception as the cause.

Confidence Score: 4/5

The intended CLI error handling remains inactive on the production call paths.

  • The changed helper correctly detects failures while importing the call module.
  • The active CLI loaders retain the old module-presence check.
  • Missing optional dependencies can still produce the original raw import error.

src/praisonai/praisonai/cli/legacy/inbuilt_tools.py and the active call loaders in praisonai-code.

Important Files Changed

Filename Overview
src/praisonai/praisonai/cli/legacy/inbuilt_tools.py The helper now catches dependency import failures, but the active CLI call paths do not use it.

Reviews (1): Last reviewed commit: "fix: make call feature guard detect miss..." | Re-trigger Greptile

Comment on lines 26 to +28
def get_call_module():
import importlib.util

if not importlib.util.find_spec("praisonai.api.call"):
try:
from praisonai.api import call as call_module

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Updated Guard Is Not Reached

The active call command paths use separate _get_call_module() implementations in praisonai-code/cli/main.py and praisonai-code/cli/legacy/praison_ai.py, both of which retain the old find_spec() guard. A normal CLI invocation with a missing call dependency therefore never reaches this handler and still exposes the raw import failure this change is intended to replace.

@MervinPraison

Copy link
Copy Markdown
Owner

@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
  4. SDK value: review in depth whether the change genuinely adds value to the SDK β€” never add features for the sake of adding them. It must strengthen the SDK (simpler, more user-friendly, robust, world-class, secure). If it does not clearly add value, request changes or recommend rejecting/closing rather than merging scope creep
  5. Do not bloat the Agent class with additional params β€” only if absolutely required; we already support many params.
  6. Repo routing: agent-callable tools β†’ PraisonAI-Tools; lifecycle plugins β†’ PraisonAI-Plugins; optional sandbox backends β†’ PraisonAI-Plugins (praisonai.sandbox entry point) β€” request changes if wrongly added to praisonaiagents/

Phase 2: FIX Valid Issues
7. For any VALID bugs or architectural flaws found by Gemini, CodeRabbit, Qodo, Copilot, or any other reviewer: implement the fix
8. Also independently identify and fix any gaps or issues you find in the changed code β€” do not rely only on prior reviewer feedback
9. Push all code fixes directly to THIS branch (do NOT create a new PR)
10. Comment a summary of exact files modified and what you skipped

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

@MervinPraison MervinPraison added pipeline/awaiting-merge-gate FINAL done; waiting for merge gate / CI pipeline/blocked:cooldown Blocked: post-push or @claude cooldown and removed pipeline/final-claude-pending Reviews done; waiting for FINAL @claude pipeline/blocked:no-final Blocked: no FINAL @claude trigger yet labels Jul 18, 2026
@praisonai-triage-agent

praisonai-triage-agent Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor Author

Claude finished @MervinPraison's task β€”β€” View job


Claude Architecture Review β€” PR #3169 βœ… Approve

  • Read AGENTS.md & understand architecture rules
  • Review the changed file (inbuilt_tools.py)
  • Investigate Greptile/Copilot P1 finding
  • Fix valid issues in Python packages only
  • Test
  • Final verdict

Phase 1 β€” Architecture Review (per AGENTS.md)

Check Verdict
Protocol-driven βœ… Fix lives in wrapper (praisonai/), not core SDK. Correct routing.
Backward compatible βœ… Same public signature get_call_module(), same friendly message, zero regressions.
Performance / hot path βœ… Off the base-import path β€” call.py loads only on demand. No import-time cost.
SDK value βœ… Genuine UX/correctness fix. No new params, modules, or exports. Not scope creep.
Agent class bloat βœ… N/A β€” no agent.py change.

Phase 2 β€” Verification of the fix

The change replaces the ineffective find_spec("praisonai.api.call") (which only checks the wrapper file exists on disk) with a real try/except ImportError:

def get_call_module():
    try:
        from praisonai.api import call as call_module
    except ImportError as exc:
        raise ImportError(
            'Call feature is not installed. Install with: pip install "praisonai[call]"'
        ) from exc
    return call_module

I confirmed call.py imports websockets, fastapi, twilio, pyngrok, uvicorn at module top, so the real import now surfaces the missing optional deps. This correctly mirrors the established pattern in api/agent_invoke.py. Runtime test passed:

RESULT: ImportError raised with friendly message:
   Call feature is not installed. Install with: pip install "praisonai[call]"
   cause: ModuleNotFoundError   ← original error preserved via `from exc`

I also grepped the entire in-scope praisonai package: get_call_module() is the only call-feature guard here β€” no stray find_spec("praisonai.api.call") checks remain to bypass it.

On the Greptile P1 finding ("Updated Guard Is Not Reached")

Greptile is technically correct that _get_call_module() in src/praisonai-code/praisonai_code/cli/{main.py,legacy/praison_ai.py} still uses the old find_spec guard. However, that is a separate distribution package (praisonai-code), which is explicitly out of scope for this PR (scope: praisonaiagents, praisonai only). This PR's issue #3168 concerns the praisonai package guard, which is fully fixed. The praisonai-code guards are a distinct, pre-existing item best handled in their own PR under that package's ownership. Flagging for tracking, not blocking here.

Phase 3 β€” Final Verdict

βœ… Approve. The fix is correct, minimal, lightweight, backward-compatible, and properly routed. No code changes required β€” the diff already resolves issue #3168 for the praisonai package.

Files modified by me: none (fix is already correct).
Skipped (out of scope): praisonai-code call guards β€” recommend a follow-up in that package if the same UX is desired there.
β€’ Branch: claude/issue-3168-20260718-1616

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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/praisonai/praisonai/cli/legacy/inbuilt_tools.py`:
- Around line 27-32: Update the import handling around call_module in the legacy
inbuilt-tools initialization to use the existing find_spec("praisonai.api.call")
guard, or otherwise only translate a confirmed missing optional module into the
installation message. Let ImportError exceptions raised within
praisonai.api.call propagate unchanged instead of masking them as a missing
extra.
πŸͺ„ 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: c6904878-ae2d-4e5f-ae81-5ce6d570462e

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 882143d and a531d43.

πŸ“’ Files selected for processing (1)
  • src/praisonai/praisonai/cli/legacy/inbuilt_tools.py

Comment on lines +27 to +32
try:
from praisonai.api import call as call_module
except ImportError as exc:
raise ImportError(
'Call feature is not installed. Install with: pip install "praisonai[call]"'
)
from praisonai.api import call as call_module
) from exc

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟑 Minor | ⚑ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect the call module's import graph and callers before narrowing the exception.
rg -n -C3 '^(from|import) ' src/praisonai src/praisonai-code --glob '*call*.py'
rg -n -C4 'get_call_module|from praisonai\.api import call' src/praisonai src/praisonai-code

Repository: MervinPraison/PraisonAI

Length of output: 9247


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== inbuilt_tools ==\n'
sed -n '1,120p' src/praisonai/praisonai/cli/legacy/inbuilt_tools.py

printf '\n== praisonai_code cli main around _get_call_module ==\n'
sed -n '70,120p' src/praisonai-code/praisonai_code/cli/main.py

printf '\n== praisonai_code legacy praison_ai around _get_call_module ==\n'
sed -n '60,100p' src/praisonai-code/praisonai_code/cli/legacy/praison_ai.py

Repository: MervinPraison/PraisonAI

Length of output: 4608


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import importlib.util
spec = importlib.util.find_spec("praisonai.api.call")
print("spec:", spec)
PY

Repository: MervinPraison/PraisonAI

Length of output: 339


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== full inbuilt_tools with line numbers ==\n'
cat -n src/praisonai/praisonai/cli/legacy/inbuilt_tools.py

printf '\n== search for similar import guards ==\n'
rg -n 'find_spec\("praisonai\.api\.call"\)|except ImportError as exc|Call feature is not installed' src/praisonai src/praisonai-code

Repository: MervinPraison/PraisonAI

Length of output: 5763


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== callers of get_call_module in wrapper package ==\n'
rg -n -C4 'get_call_module\(' src/praisonai src/praisonai-code

Repository: MervinPraison/PraisonAI

Length of output: 4340


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C3 'import_wrapper_module\("praisonai\.cli\.legacy\.inbuilt_tools"\)|from praisonai\.cli\.legacy\.inbuilt_tools import|get_call_module\(' src/praisonai src/praisonai-code

Repository: MervinPraison/PraisonAI

Length of output: 7100


Avoid masking unrelated import failures here β€” use the same find_spec("praisonai.api.call") guard used elsewhere, or let other ImportErrors bubble up. Right now any import problem inside praisonai.api.call is reported as a missing praisonai[call] extra.

πŸ€– 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/praisonai/praisonai/cli/legacy/inbuilt_tools.py` around lines 27 - 32,
Update the import handling around call_module in the legacy inbuilt-tools
initialization to use the existing find_spec("praisonai.api.call") guard, or
otherwise only translate a confirmed missing optional module into the
installation message. Let ImportError exceptions raised within
praisonai.api.call propagate unchanged instead of masking them as a missing
extra.

@praisonai-triage-agent praisonai-triage-agent Bot removed the pipeline/blocked:cooldown Blocked: post-push or @claude cooldown label Jul 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pipeline/awaiting-merge-gate FINAL done; waiting for merge gate / CI pipeline/blocked:ci Blocked: CI not green on HEAD

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ineffective optional-dependency guard for the call feature: find_spec check never fires the friendly install hint

1 participant