feat: External CLI Integrations Documentation with Registry Pattern & Streaming#157
feat: External CLI Integrations Documentation with Registry Pattern & Streaming#157praisonai-triage-agent[bot] wants to merge 1 commit intomainfrom
Conversation
…ples - Complete guide covering ExternalAgentRegistry pattern - Enhanced CodexCLI integration with approval modes and providers - TypeScript SDK streaming support examples - Practical use cases: code review, development pipeline, QA automation - Custom integration development guide - Configuration, error handling, and best practices - Migration guide for backward compatibility Addresses MervinPraison/PraisonAI#1394 Co-authored-by: Mervin Praison <MervinPraison@users.noreply.github.com>
|
@coderabbitai review |
|
/review |
|
@gemini review this PR |
✅ Actions performedReview triggered.
|
📝 WalkthroughWalkthroughA new documentation file is added providing comprehensive client-facing guidance for the External CLI Integrations feature, including system capabilities, Python and TypeScript usage examples, configuration options, error-handling patterns, and migration guidance from legacy APIs. Changes
Possibly Related Issues
Poem
Estimated Code Review Effort🎯 2 (Simple) | ⏱️ ~15 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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.
Code Review
This pull request introduces a new documentation file, EXTERNAL_CLI_INTEGRATIONS_DOCS.md, which outlines the external CLI integration system. The review feedback identifies several critical issues where the documentation describes features, classes, and parameters that do not currently exist in the codebase, such as the ExternalAgentRegistry and specific arguments for CodexCLIIntegration. Additionally, the feedback points out technical errors in the provided code examples, including missing imports and the incorrect use of await on synchronous properties.
| A singleton registry for managing external CLI integrations with dynamic registration capabilities. | ||
|
|
||
| ```python | ||
| from praisonai.integrations.registry import ExternalAgentRegistry |
|
|
||
| class MyCustomAgent(BaseCLIIntegration): | ||
| def __init__(self, workspace: str = ".", **kwargs): | ||
| super().__init__(workspace=workspace, **kwargs) |
There was a problem hiding this comment.
BaseCLIIntegration.__init__ does not accept **kwargs. Calling super().__init__(workspace=workspace, **kwargs) will raise a TypeError if any unexpected keyword arguments are passed to the subclass constructor. It is safer to pass only the expected arguments.
| super().__init__(workspace=workspace, **kwargs) | |
| super().__init__(workspace=workspace) |
| # Suggest mode (default) | ||
| codex_suggest = CodexCLIIntegration( | ||
| workspace="/path/to/project", | ||
| approval_mode="suggest" |
| ### 2. Multi-Agent Development Pipeline | ||
|
|
||
| ```python | ||
| async def development_pipeline(feature_request: str, project_path: str): |
There was a problem hiding this comment.
This example uses several integration classes (ClaudeCodeIntegration, CodexCLIIntegration, GeminiCLIIntegration, CursorCLIIntegration) that are not imported within this code block. This will lead to a NameError if the code is executed.
| async def development_pipeline(feature_request: str, project_path: str): | |
| from praisonai.integrations import ClaudeCodeIntegration, CodexCLIIntegration, GeminiCLIIntegration, CursorCLIIntegration | |
| async def development_pipeline(feature_request: str, project_path: str): |
|
|
||
| ```python | ||
| from praisonai.integrations import CodexCLIIntegration | ||
| from praisonai.integrations.base import CLIIntegrationError |
|
|
||
| try: | ||
| # Check availability first | ||
| if not await codex.is_available(): |
There was a problem hiding this comment.
| 1. **Always check availability** before executing: | ||
| ```python | ||
| agent = CodexCLIIntegration(workspace="/project") | ||
| if await agent.is_available(): |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@EXTERNAL_CLI_INTEGRATIONS_DOCS.md`:
- Around line 54-127: The docs use non-existent constructor args for
CodexCLIIntegration (approval_mode, provider) but the real constructor uses
full_auto (bool) plus sandbox, json_output, output_schema, and output_file;
update every example (including the migration guide) to replace
approval_mode="suggest"/"auto-edit"/"full-auto" with full_auto=False/False/True
respectively, remove any provider= parameters, and correct the migration guide
to state that full_auto=True is the current supported flag (not deprecated);
ensure examples reference CodexCLIIntegration and its actual parameters
(full_auto, sandbox, json_output, output_schema, output_file) so they match the
implementation.
- Around line 303-311: The docs reference non-existent API functions and module:
implement praisonai.integrations.registry with at least get_registry(),
register_integration(), and create_integration() or update the docs to use the
existing API; specifically either (A) add a new module
praisonai.integrations.registry that exposes get_registry() returning an object
that wraps or delegates to the existing get_available_integrations() from
praisonai.integrations.base and implements register_integration() and
create_integration() with the same signatures described in the docs, or (B)
change the documentation to call get_available_integrations() (and any
appropriate existing functions) instead of get_registry(),
register_integration(), and create_integration(); update all occurrences
referenced in the PR (lines mentioning get_registry(), register_integration(),
create_integration(), and get_available_integrations()) so the docs and codebase
match.
- Around line 506-507: The calls to the synchronous is_available method are
being awaited; remove the await and call is_available() directly for both codex
and agent (e.g., replace await codex.is_available() and await
agent.is_available() with codex.is_available() and agent.is_available()) because
BaseCLIIntegration.is_available is not async; update any conditional checks or
error raises that rely on those results accordingly.
- Around line 17-50: The docs incorrectly reference a non-existent registry API
(ExternalAgentRegistry, registry.register, registry.create, get_registry, and
async await registry.get_available()); remove the entire ExternalAgentRegistry
example block and replace it with a direct subclassing example that demonstrates
extending BaseCLIIntegration and implementing execute(), stream(), and the
cli_command property, and update the later block that references
get_registry()/await registry.get_available() to instead show calling the
synchronous get_available_integrations() function to list integrations.
- Around line 30-40: The examples for BaseCLIIntegration are missing required
abstract methods and thus cannot be instantiated; add minimal implementations of
the abstract methods execute and stream in the shown classes (e.g., implement
execute(self, task: str, **kwargs) -> str and stream(self, task: str, **kwargs)
-> Iterator[str] or async equivalents) inside MyCustomAgent and
CustomAIAssistant so they satisfy the BaseCLIIntegration interface; implement
them as simple stubs that call _build_command/cli_command or raise a clear
NotImplementedError if you intend them as placeholders, ensuring method
signatures match the abstract definitions in BaseCLIIntegration.
🪄 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: 9d21af89-23ea-459e-8949-28aad602a10d
📒 Files selected for processing (1)
EXTERNAL_CLI_INTEGRATIONS_DOCS.md
| ### 1. ExternalAgentRegistry | ||
|
|
||
| A singleton registry for managing external CLI integrations with dynamic registration capabilities. | ||
|
|
||
| ```python | ||
| from praisonai.integrations.registry import ExternalAgentRegistry | ||
|
|
||
| # Get singleton registry | ||
| registry = ExternalAgentRegistry.get_instance() | ||
|
|
||
| # Register custom integration | ||
| from praisonai.integrations import BaseCLIIntegration | ||
|
|
||
| class MyCustomAgent(BaseCLIIntegration): | ||
| def __init__(self, workspace: str = ".", **kwargs): | ||
| super().__init__(workspace=workspace, **kwargs) | ||
|
|
||
| @property | ||
| def cli_command(self) -> str: | ||
| return "my-custom-cli" | ||
|
|
||
| def _build_command(self, task: str, **options) -> list: | ||
| return ["my-custom-cli", task] | ||
|
|
||
| # Register the custom agent | ||
| registry.register('my-agent', MyCustomAgent) | ||
|
|
||
| # Create integration instance | ||
| agent = registry.create('my-agent', workspace="/path/to/project") | ||
|
|
||
| # List all registered integrations | ||
| available_agents = await registry.get_available() | ||
| print(f"Available agents: {available_agents}") | ||
| ``` |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Find integrations-related files
find . -type f -name "*.py" -path "*/integrations/*" | head -20Repository: MervinPraison/PraisonAIDocs
Length of output: 734
🏁 Script executed:
# Locate the documentation file
find . -type f -name "EXTERNAL_CLI_INTEGRATIONS_DOCS.md"Repository: MervinPraison/PraisonAIDocs
Length of output: 106
🏁 Script executed:
# Search for ExternalAgentRegistry class definition
rg "class ExternalAgentRegistry" -A 10Repository: MervinPraison/PraisonAIDocs
Length of output: 53
🏁 Script executed:
# Search for get_available_integrations function
rg "def get_available_integrations" -A 5Repository: MervinPraison/PraisonAIDocs
Length of output: 478
🏁 Script executed:
# Read the doc file to see lines 17-50
head -60 ./EXTERNAL_CLI_INTEGRATIONS_DOCS.md | tail -50Repository: MervinPraison/PraisonAIDocs
Length of output: 1639
🏁 Script executed:
# Read lines 599-603 from the doc
sed -n '595,610p' ./EXTERNAL_CLI_INTEGRATIONS_DOCS.mdRepository: MervinPraison/PraisonAIDocs
Length of output: 522
🏁 Script executed:
# Search for "registry" references anywhere in the codebase (case-insensitive)
rg "registry" -i --type py | grep -v ".pyc" | head -30Repository: MervinPraison/PraisonAIDocs
Length of output: 2483
🏁 Script executed:
# Check base.py for ExternalAgentRegistry or Registry patterns
rg "Registry" ./praisonai/integrations/base.py -A 3Repository: MervinPraison/PraisonAIDocs
Length of output: 53
🏁 Script executed:
# Check what's exported from the integrations module
cat ./praisonai/integrations/__init__.pyRepository: MervinPraison/PraisonAIDocs
Length of output: 2898
🏁 Script executed:
# Read more of base.py to see full BaseCLIIntegration API
head -100 ./praisonai/integrations/base.pyRepository: MervinPraison/PraisonAIDocs
Length of output: 3231
🏁 Script executed:
# Check if there are any async methods or registry patterns in the codebase
rg "async def" ./praisonai/integrations/base.py -A 3Repository: MervinPraison/PraisonAIDocs
Length of output: 1249
🏁 Script executed:
# Search for any mention of "register" in integrations modules
rg "\.register\(" ./praisonai/integrations/ -B 2 -A 2Repository: MervinPraison/PraisonAIDocs
Length of output: 53
Remove non-existent registry API from all examples; the codebase does not provide ExternalAgentRegistry, registry.register(), registry.create(), or async registry methods.
The docs repeatedly describe a registry-based integration pattern that does not exist. The actual API is simpler: users extend BaseCLIIntegration directly (implementing execute(), stream(), and cli_command property), and call the sync function get_available_integrations() to list registered integrations. There is no dynamic registration mechanism or registry singleton.
Both lines 17–50 and lines 599–603 require fixes:
- Lines 17–50: Remove the entire
ExternalAgentRegistryexample and replace with a directBaseCLIIntegrationsubclass pattern. - Lines 599–603: The second code block referencing
get_registry()andawait registry.get_available()must be removed; keep only the syncget_available_integrations()example.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@EXTERNAL_CLI_INTEGRATIONS_DOCS.md` around lines 17 - 50, The docs incorrectly
reference a non-existent registry API (ExternalAgentRegistry, registry.register,
registry.create, get_registry, and async await registry.get_available()); remove
the entire ExternalAgentRegistry example block and replace it with a direct
subclassing example that demonstrates extending BaseCLIIntegration and
implementing execute(), stream(), and the cli_command property, and update the
later block that references get_registry()/await registry.get_available() to
instead show calling the synchronous get_available_integrations() function to
list integrations.
| class MyCustomAgent(BaseCLIIntegration): | ||
| def __init__(self, workspace: str = ".", **kwargs): | ||
| super().__init__(workspace=workspace, **kwargs) | ||
|
|
||
| @property | ||
| def cli_command(self) -> str: | ||
| return "my-custom-cli" | ||
|
|
||
| def _build_command(self, task: str, **options) -> list: | ||
| return ["my-custom-cli", task] | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -name "EXTERNAL_CLI_INTEGRATIONS_DOCS.md" -o -name "*EXTERNAL*" -type f | head -20Repository: MervinPraison/PraisonAIDocs
Length of output: 106
🏁 Script executed:
cat -n ./EXTERNAL_CLI_INTEGRATIONS_DOCS.md | sed -n '25,45p'Repository: MervinPraison/PraisonAIDocs
Length of output: 863
🏁 Script executed:
cat -n ./EXTERNAL_CLI_INTEGRATIONS_DOCS.md | sed -n '395,430p'Repository: MervinPraison/PraisonAIDocs
Length of output: 1500
🏁 Script executed:
cat -n ./EXTERNAL_CLI_INTEGRATIONS_DOCS.md | sed -n '420,450p'Repository: MervinPraison/PraisonAIDocs
Length of output: 1168
🏁 Script executed:
find . -type f -name "*.py" | xargs rg "class BaseCLIIntegration" -A 30Repository: MervinPraison/PraisonAIDocs
Length of output: 2203
🏁 Script executed:
rg "class BaseCLIIntegration|@abstractmethod|async def execute|async def stream" ./praisonai/integrations/base.py -A 2Repository: MervinPraison/PraisonAIDocs
Length of output: 1193
🏁 Script executed:
wc -l ./EXTERNAL_CLI_INTEGRATIONS_DOCS.mdRepository: MervinPraison/PraisonAIDocs
Length of output: 110
🏁 Script executed:
sed -n '399,437p' ./EXTERNAL_CLI_INTEGRATIONS_DOCS.mdRepository: MervinPraison/PraisonAIDocs
Length of output: 1392
Custom BaseCLIIntegration examples are incomplete and cannot be instantiated as shown.
The first example (MyCustomAgent) omits both required abstract methods execute and stream. The second example (CustomAIAssistant) implements execute but omits stream. Copying these examples directly will raise TypeError for missing abstract methods.
Suggested minimal completion for abstract methods
For MyCustomAgent:
class MyCustomAgent(BaseCLIIntegration):
def _build_command(self, task: str, **options) -> list:
return ["my-custom-cli", task]
+
+ async def execute(self, prompt: str, **options) -> str:
+ return await self.execute_async(self._build_command(prompt, **options))
+
+ async def stream(self, prompt: str, **options):
+ async for line in self.stream_async(self._build_command(prompt, **options)):
+ yield {"type": "text", "content": line}For CustomAIAssistant, add stream method after execute:
async def execute(self, prompt: str, **options) -> str:
"""Execute the custom AI assistant"""
cmd = self._build_command(prompt, **options)
return await self.execute_async(cmd)
+
+ async def stream(self, prompt: str, **options):
+ """Stream output from the custom AI assistant"""
+ cmd = self._build_command(prompt, **options)
+ async for line in self.stream_async(cmd):
+ yield {"type": "text", "content": line}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| class MyCustomAgent(BaseCLIIntegration): | |
| def __init__(self, workspace: str = ".", **kwargs): | |
| super().__init__(workspace=workspace, **kwargs) | |
| @property | |
| def cli_command(self) -> str: | |
| return "my-custom-cli" | |
| def _build_command(self, task: str, **options) -> list: | |
| return ["my-custom-cli", task] | |
| class MyCustomAgent(BaseCLIIntegration): | |
| def __init__(self, workspace: str = ".", **kwargs): | |
| super().__init__(workspace=workspace, **kwargs) | |
| `@property` | |
| def cli_command(self) -> str: | |
| return "my-custom-cli" | |
| def _build_command(self, task: str, **options) -> list: | |
| return ["my-custom-cli", task] | |
| async def execute(self, prompt: str, **options) -> str: | |
| return await self.execute_async(self._build_command(prompt, **options)) | |
| async def stream(self, prompt: str, **options): | |
| async for line in self.stream_async(self._build_command(prompt, **options)): | |
| yield {"type": "text", "content": line} |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@EXTERNAL_CLI_INTEGRATIONS_DOCS.md` around lines 30 - 40, The examples for
BaseCLIIntegration are missing required abstract methods and thus cannot be
instantiated; add minimal implementations of the abstract methods execute and
stream in the shown classes (e.g., implement execute(self, task: str, **kwargs)
-> str and stream(self, task: str, **kwargs) -> Iterator[str] or async
equivalents) inside MyCustomAgent and CustomAIAssistant so they satisfy the
BaseCLIIntegration interface; implement them as simple stubs that call
_build_command/cli_command or raise a clear NotImplementedError if you intend
them as placeholders, ensuring method signatures match the abstract definitions
in BaseCLIIntegration.
| The CodexCLI integration now supports multiple approval modes and providers. | ||
|
|
||
| #### Approval Modes | ||
|
|
||
| - **suggest**: Default mode, suggests changes without applying them | ||
| - **auto-edit**: Automatically applies safe edits | ||
| - **full-auto**: Full autonomous mode with file modifications | ||
|
|
||
| ```python | ||
| from praisonai.integrations import CodexCLIIntegration | ||
|
|
||
| # Suggest mode (default) | ||
| codex_suggest = CodexCLIIntegration( | ||
| workspace="/path/to/project", | ||
| approval_mode="suggest" | ||
| ) | ||
|
|
||
| # Auto-edit mode for safe changes | ||
| codex_auto_edit = CodexCLIIntegration( | ||
| workspace="/path/to/project", | ||
| approval_mode="auto-edit" | ||
| ) | ||
|
|
||
| # Full autonomous mode | ||
| codex_full_auto = CodexCLIIntegration( | ||
| workspace="/path/to/project", | ||
| approval_mode="full-auto", | ||
| provider="openai" # Optional provider selection | ||
| ) | ||
|
|
||
| # Execute with different modes | ||
| result = await codex_suggest.execute("Review this code for potential bugs") | ||
| print(f"Suggestions: {result}") | ||
|
|
||
| result = await codex_auto_edit.execute("Fix obvious syntax errors") | ||
| print(f"Applied fixes: {result}") | ||
|
|
||
| result = await codex_full_auto.execute("Refactor the authentication module") | ||
| print(f"Refactoring result: {result}") | ||
| ``` | ||
|
|
||
| #### Multi-Provider Support | ||
|
|
||
| ```python | ||
| # OpenAI Codex | ||
| codex_openai = CodexCLIIntegration( | ||
| provider="openai", | ||
| approval_mode="suggest" | ||
| ) | ||
|
|
||
| # OpenRouter | ||
| codex_openrouter = CodexCLIIntegration( | ||
| provider="openrouter", | ||
| approval_mode="auto-edit" | ||
| ) | ||
|
|
||
| # Azure OpenAI | ||
| codex_azure = CodexCLIIntegration( | ||
| provider="azure", | ||
| approval_mode="full-auto" | ||
| ) | ||
|
|
||
| # Gemini | ||
| codex_gemini = CodexCLIIntegration( | ||
| provider="gemini", | ||
| approval_mode="suggest" | ||
| ) | ||
|
|
||
| # Ollama (local) | ||
| codex_ollama = CodexCLIIntegration( | ||
| provider="ollama", | ||
| approval_mode="suggest" | ||
| ) | ||
| ``` |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Search for CodexCLIIntegration class definition
find . -type f -name "*.py" | head -20Repository: MervinPraison/PraisonAIDocs
Length of output: 803
🏁 Script executed:
# Find the documentation file
find . -name "*EXTERNAL_CLI_INTEGRATIONS*"Repository: MervinPraison/PraisonAIDocs
Length of output: 106
🏁 Script executed:
# Search for CodexCLIIntegration class using ripgrep
rg "class CodexCLIIntegration" -A 30Repository: MervinPraison/PraisonAIDocs
Length of output: 2320
🏁 Script executed:
# Read the documentation file to check what's documented
cat EXTERNAL_CLI_INTEGRATIONS_DOCS.mdRepository: MervinPraison/PraisonAIDocs
Length of output: 18354
CodexCLIIntegration constructor parameters in docs do not match the implementation.
The examples throughout this documentation use approval_mode= (with string values like "suggest", "auto-edit", "full-auto") and provider= parameters. However, the actual CodexCLIIntegration implementation has no such parameters. Instead, it uses full_auto (boolean), sandbox, json_output, output_schema, and output_file.
The migration guide (lines 637–643) compounds this by incorrectly claiming full_auto=True is deprecated in favor of the new approval_mode="full-auto" parameter—the opposite is true: full_auto is the current supported parameter.
Required fixes:
- Replace all
approval_mode="suggest"/"auto-edit"/"full-auto"withfull_auto=False/False/True - Remove all
provider=parameters (not supported in the constructor) - Correct the migration guide to show
full_auto=Trueas current, not deprecated
Affected locations
Lines 54–127, 227–230, 268–272, 502–503, 574–575, 623–624, 637–643
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@EXTERNAL_CLI_INTEGRATIONS_DOCS.md` around lines 54 - 127, The docs use
non-existent constructor args for CodexCLIIntegration (approval_mode, provider)
but the real constructor uses full_auto (bool) plus sandbox, json_output,
output_schema, and output_file; update every example (including the migration
guide) to replace approval_mode="suggest"/"auto-edit"/"full-auto" with
full_auto=False/False/True respectively, remove any provider= parameters, and
correct the migration guide to state that full_auto=True is the current
supported flag (not deprecated); ensure examples reference CodexCLIIntegration
and its actual parameters (full_auto, sandbox, json_output, output_schema,
output_file) so they match the implementation.
| from praisonai.integrations.registry import get_registry | ||
|
|
||
| async def interactive_coding_session(): | ||
| """ | ||
| Interactive session with multiple agents | ||
| """ | ||
| registry = get_registry() | ||
| available_agents = await registry.get_available_names() | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Read-only verification of documented registry/API symbols.
rg -n -C2 '\bExternalAgentRegistry\b|\bget_registry\s*\(|\bregister_integration\s*\(|\bcreate_integration\s*\(|\bget_available_integrations\s*\('Repository: MervinPraison/PraisonAIDocs
Length of output: 16046
🏁 Script executed:
# Check if praisonai/integrations/registry.py exists and what's in it
fd "registry.py" praisonai/integrations/Repository: MervinPraison/PraisonAIDocs
Length of output: 53
🏁 Script executed:
# Search for register_integration and create_integration definitions
rg -n "def register_integration|def create_integration" praisonai/Repository: MervinPraison/PraisonAIDocs
Length of output: 53
🏁 Script executed:
# List all files in praisonai/integrations
ls -la praisonai/integrations/Repository: MervinPraison/PraisonAIDocs
Length of output: 838
🏁 Script executed:
# Check what's exported from praisonai/integrations
cat praisonai/integrations/__init__.pyRepository: MervinPraison/PraisonAIDocs
Length of output: 2898
Documented registry API functions do not exist in the codebase.
The docs reference get_registry(), register_integration(), and create_integration() from praisonai.integrations.registry, but this module does not exist. Only get_available_integrations() from praisonai/integrations/base.py is available. These functions must be implemented in the codebase or the documentation must be corrected before release.
Applies to lines 303-311, 397-398, 431-433, and 654-657.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@EXTERNAL_CLI_INTEGRATIONS_DOCS.md` around lines 303 - 311, The docs reference
non-existent API functions and module: implement praisonai.integrations.registry
with at least get_registry(), register_integration(), and create_integration()
or update the docs to use the existing API; specifically either (A) add a new
module praisonai.integrations.registry that exposes get_registry() returning an
object that wraps or delegates to the existing get_available_integrations() from
praisonai.integrations.base and implements register_integration() and
create_integration() with the same signatures described in the docs, or (B)
change the documentation to call get_available_integrations() (and any
appropriate existing functions) instead of get_registry(),
register_integration(), and create_integration(); update all occurrences
referenced in the PR (lines mentioning get_registry(), register_integration(),
create_integration(), and get_available_integrations()) so the docs and codebase
match.
| if not await codex.is_available(): | ||
| raise CLIIntegrationError("Codex CLI is not available") |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Find the documentation file
find . -name "*EXTERNAL_CLI_INTEGRATIONS_DOCS*" -type fRepository: MervinPraison/PraisonAIDocs
Length of output: 106
🏁 Script executed:
# Once found, check the specific lines mentioned
git ls-files | grep -E "(EXTERNAL|CLI|INTEGRATION)" | head -20Repository: MervinPraison/PraisonAIDocs
Length of output: 104
🏁 Script executed:
# Search for BaseCLIIntegration class
rg "class BaseCLIIntegration" -A 50Repository: MervinPraison/PraisonAIDocs
Length of output: 3364
🏁 Script executed:
# Get the full definition of is_available in BaseCLIIntegration
rg "def is_available|async.*is_available" praisonai/integrations/base.py -A 10Repository: MervinPraison/PraisonAIDocs
Length of output: 518
🏁 Script executed:
# Check lines 506-507 and 536-537 from the documentation file
sed -n '500,540p' ./EXTERNAL_CLI_INTEGRATIONS_DOCS.mdRepository: MervinPraison/PraisonAIDocs
Length of output: 1190
Remove await from is_available() calls—it's a synchronous method, not async.
At lines 506-507 and 536-537, await codex.is_available() and await agent.is_available() will fail because is_available is a synchronous method (defined in BaseCLIIntegration without the async keyword). It must be called without await.
Correct fix
-if not await codex.is_available():
+if not codex.is_available():
@@
-if await agent.is_available():
+if agent.is_available():🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@EXTERNAL_CLI_INTEGRATIONS_DOCS.md` around lines 506 - 507, The calls to the
synchronous is_available method are being awaited; remove the await and call
is_available() directly for both codex and agent (e.g., replace await
codex.is_available() and await agent.is_available() with codex.is_available()
and agent.is_available()) because BaseCLIIntegration.is_available is not async;
update any conditional checks or error raises that rely on those results
accordingly.
Implements comprehensive documentation for External CLI Integrations feature from MervinPraison/PraisonAI#1394
What's Included
Core Documentation
5 Detailed Use Cases
Client-Focused Examples
Best Practices & Troubleshooting
Files Added
Related Issue
Addresses #156
Related PR
Documents features from MervinPraison/PraisonAI#1394
Generated with Claude Code
Summary by CodeRabbit