Skip to content

fix(examples): merge validation fixes phases 2-4 into main (stacked on #1855)#1893

Open
Dhivya-Bharathy wants to merge 10 commits into
MervinPraison:mainfrom
Dhivya-Bharathy:phase4-api-fixes
Open

fix(examples): merge validation fixes phases 2-4 into main (stacked on #1855)#1893
Dhivya-Bharathy wants to merge 10 commits into
MervinPraison:mainfrom
Dhivya-Bharathy:phase4-api-fixes

Conversation

@Dhivya-Bharathy

@Dhivya-Bharathy Dhivya-Bharathy commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Final merge PR to land all example validation fixes (phases 2–4) onto main.

Phases 1–4 were previously merged as stacked PRs (#1855#1859#1864#1865). Phase 1 (#1855) is already on main. This PR brings the remaining work from phase4-api-fixes into main.

What's included

Phase PR Scope On main already?
1 #1855 49 files — syntax + consolidated-params Yes (squash merge)
2 #1859 13 files — memory/knowledge/metrics This PR
3 #1864 22 files — session/output/execution This PR
4 #1865 40 files — persistence/workflows/web/CLI This PR
+ maintainer RouterAgent kwargs + __main__ guards This PR

Validation baseline: 796 examples → 503 PASS / 197 FAIL / 96 BLOCKED (Windows, v4.6.52).

Why 113 files vs main

This compares the full validation branch to main. Phase 1 overlap with #1855 may appear in the diff; phases 2–4 (~64 unique example fixes) plus 1 SDK fix are the net new changes not yet on main.

Test plan

  • Windows CI (test-windows) passes
  • python -m py_compile on changed examples
  • No audit scripts / results.jsonl in diff

Summary by CodeRabbit

  • New Features

    • Added observability helper for provider-agnostic span attribute management
  • Configuration Changes

    • Consolidated persistence and session settings under a single memory object
    • Unified knowledge/vector-store and output/metrics formatting into consolidated configs
    • Simplified web/search modes to explicit mode strings
  • Examples & Documentation

    • Added runtime guards to prevent examples executing on import
    • Improved result extraction, error handling, and defensive response checks
    • Example approval flow now demonstrates a dedicated reviewer agent for command gating

Dhivya-Bharathy and others added 6 commits June 4, 2026 16:30
…ames

- Fix MemoryConfig(memory=...) → user_id=... in agent_centric_api.py
- Fix Session(memory=...) → user_id=... in session-example.py
- Fix build_context_for_task(memory=...) → user_id=... in memory-quality-example.py

Co-authored-by: Mervin Praison <MervinPraison@users.noreply.github.com>
…ame__ guards

- Fixed TypeError in RouterAgent._build_system_prompt() by removing **kwargs from super() call
- Added if __name__ == '__main__' guards to 6 example files to prevent auto-execution on import
- Addresses Gemini Code Assist review feedback

Co-authored-by: Mervin Praison <MervinPraison@users.noreply.github.com>
@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 Jun 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR updates many example scripts to use consolidated constructor shapes (memory/knowledge/output), adds main guards and env/capability checks, normalizes result shapes, and updates RouterAgent._build_system_prompt to accept tools/kwargs.

Changes

Examples and API alignment

Layer / File(s) Summary
Core API contracts and method signatures
examples/approval/agent_approval.py, examples/policy/basic_policy.py, src/praisonai-agents/praisonaiagents/agent/router_agent.py
Approval wiring moves to an explicit reviewer_agent and approver_agent=..., policy is attached after Agent construction, and RouterAgent._build_system_prompt now accepts tools and **kwargs forwarded to super.
Output, web, and LLM consolidation
examples/consolidated_params/advanced_workflow_full_features.py, examples/consolidated_params/basic_web.py, examples/middleware/configurable_model.py, examples/python/token-metrics/*, examples/python/tools/exa-tool/rag_examples/agentic_rag/rag_agent.py, examples/python/models/googlegemini/any-llm-agents-advanced.py, examples/web/*
Examples consolidate formatting/verbosity/markdown/metrics/web/llm options into unified output or single-argument objects, replacing dispersed booleans and separate config args.
Agent memory, session, and DB argument migration
examples/managed-agents/persistence/*, examples/persistence/*, examples/python/session/session_persistence_example.py, examples/persistence/sqlite_local.py
Agent constructor examples move session_id and db into a memory dictionary and adjust imports where needed.
Knowledge and retrieval payload restructuring
examples/persistence/knowledge_qdrant.py, examples/retrieval/basic_retrieval.py, examples/python/models/deepseek/deepseek-rag-agents.py
Knowledge and retrieval configs are nested under knowledge with vector_store and config to standardize provider payloads.
Memory backend and provider structure updates
examples/python/general/memory_example.py, examples/python/memory/*, examples/python/mongodb/mongodb_memory_example.py
Memory provider declarations are nested under config blocks (e.g., config: {"provider": ...}) instead of top-level provider fields.
Runtime entrypoint guards and environment checks
many examples/python/* scripts
Multiple examples now run only under if __name__ == "__main__":, and several add env or backend capability checks to avoid import-time side effects.
Defensive result handling and validation checks
examples/knowledge/context_required_example.py, examples/python/camera/*, examples/python/general/multimodal.py, examples/python/usecases/analysis/*, examples/skills/*, examples/storage/storage_backends_example.py, examples/terminal_bench/test_integration.py
Normalize task_results shapes (dict/list/scalar), safe-string conversions (str(response or "")), and add explicit validation/extraction helpers for structured payloads.
Workflow task and hooks configuration
examples/python/workflows/task_callbacks.py, examples/python/save_output/03_workflow_output_file.py, examples/python/workflows/*
Move lifecycle callbacks into hooks config objects, add task name/description fields, and programmatically construct workflow steps (e.g., Task with output_file).
Handler methods and small API updates
examples/observability/multi_agent_tracing.py, examples/python/cli/*, examples/python/custom_tools/example_latency_tracking.py, examples/python/failover_example.py
Add set_span_attr helper for spans, update handler method calls (print_summary), adapt slash command constructor to new parameter names, remove explicit request_id in one tracked agent, and rename rate_limitrate_limit_rpm.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

Review effort 4/5

Poem

"🐰 I hopped through examples, tidying the lawn,
Memory in baskets, configs neatly drawn.
Guards at the door keep surprises at bay,
Prompts and spans now behave and play.
A tiny rabbit cheers — tidy examples today!"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main objective: merging validation fixes from phases 2-4 into the main branch, with a clear reference to the stacking context (#1855).
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 unit tests (beta)
  • Create PR with unit 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

@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

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request refactors numerous example scripts to align with consolidated configuration parameters, particularly updating memory, web search, and output options, while also wrapping execution blocks with standard __main__ guards. The code review identified two key issues: a missing import of AgentTeam in self-reflection-optimization-patterns.py that will cause a NameError at runtime, and a recommendation in router_agent.py to forward **kwargs to super()._build_system_prompt when overriding the method to ensure robust parameter propagation.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +356 to +358
def _build_system_prompt(self, tools=None, **kwargs) -> str:
"""Build system prompt (inherited from parent but can be customized)."""
base_prompt = super()._build_system_prompt()
base_prompt = super()._build_system_prompt(tools=tools)

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.

medium

When overriding _build_system_prompt, it is highly recommended to forward **kwargs to super()._build_system_prompt to ensure any other keyword arguments are correctly passed to the parent class's method and prevent potential bugs if other mixins or future updates add more parameters.

Suggested change
def _build_system_prompt(self, tools=None, **kwargs) -> str:
"""Build system prompt (inherited from parent but can be customized)."""
base_prompt = super()._build_system_prompt()
base_prompt = super()._build_system_prompt(tools=tools)
def _build_system_prompt(self, tools=None, **kwargs) -> str:
"""Build system prompt (inherited from parent but can be customized)."""
base_prompt = super()._build_system_prompt(tools=tools, **kwargs)

Comment on lines +36 to +44
if __name__ == "__main__":
print("Starting self-reflection optimization demonstration...")
agents = AgentTeam(
agents=[reflection_agent],
tasks=[reflection_task],
process="sequential",
output="verbose",
)
result = agents.start()

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.

medium

The AgentTeam class is used here but it is not imported in this file, which will cause a NameError at runtime. Please import AgentTeam from praisonaiagents.

Suggested change
if __name__ == "__main__":
print("Starting self-reflection optimization demonstration...")
agents = AgentTeam(
agents=[reflection_agent],
tasks=[reflection_task],
process="sequential",
output="verbose",
)
result = agents.start()
if __name__ == "__main__":
from praisonaiagents import AgentTeam
print("Starting self-reflection optimization demonstration...")
agents = AgentTeam(
agents=[reflection_agent],
tasks=[reflection_task],
process="sequential",
output="verbose",
)
result = agents.start()

@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

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

praisonai-triage-agent Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Claude finished @MervinPraison's task —— View job


Final Architecture Review ✅

Todo List:

  • Read AGENTS.md guidelines
  • Review critical issues identified by other reviewers
  • Fix missing AgentTeam import in self-reflection-optimization-patterns.py
  • Fix RouterAgent kwargs forwarding issue
  • Validate syntax of changed files
  • Push fixes to branch
  • Conduct architectural review per AGENTS.md
  • Provide final architectural verdict

Phase 1: Architecture Review per AGENTS.md

Protocol-driven: Changes maintain proper separation between core SDK (praisonaiagents) and wrapper (praisonai). The fixes are minimal and focused.

Backward compatible: No breaking changes. All fixes are internal improvements that maintain API compatibility.

Performance: No hot-path regressions. Changes are focused on import structure and method parameter forwarding.

Phase 2: Critical Issues Fixed

Fixed Issues:

  1. Missing AgentTeam import in examples/python/concepts/self-reflection-optimization-patterns.py:8-9

    • Problem: AgentTeam was used but not imported, causing NameError at runtime
    • Fix: Added proper import from praisonaiagents.agents import AgentTeam
  2. RouterAgent kwargs forwarding in src/praisonai-agents/praisonaiagents/agent/router_agent.py:358

    • Problem: _build_system_prompt override didn't forward **kwargs to super()
    • Fix: Added **kwargs forwarding to ensure robust parameter propagation

Files Modified:

  • examples/python/concepts/self-reflection-optimization-patterns.py
  • src/praisonai-agents/praisonaiagents/agent/router_agent.py

What I Skipped:

  • No other valid bugs or architectural flaws were found in the reviewer comments
  • All other feedback was informational (Qodo paused, CodeRabbit processing)

Phase 3: Final Verdict

✅ APPROVE - All critical issues have been resolved:

  1. Code Quality: Both fixes follow AGENTS.md principles

    • Proper import structure maintained
    • Method signature consistency preserved
    • No new dependencies introduced
  2. Architecture Compliance:

    • Core SDK remains lightweight (RouterAgent fix in praisonaiagents)
    • Examples properly demonstrate API usage
    • Protocol-driven design maintained
  3. Safety:

    • All syntax validated successfully
    • No regressions introduced
    • Backward compatibility preserved

Recommendation: This PR is ready to merge. The validation fixes align examples with the current API while maintaining architectural principles. The two critical runtime issues have been resolved.


Commit: 763f7c8d |

Dhivya-Bharathy and others added 2 commits June 11, 2026 15:07
- Fix missing AgentTeam import in self-reflection-optimization-patterns.py
- Forward kwargs properly in RouterAgent._build_system_prompt to super()
- Addresses critical issues identified by Gemini code reviewer

Co-authored-by: Mervin Praison <MervinPraison@users.noreply.github.com>
@greptile-apps

greptile-apps Bot commented Jun 11, 2026

Copy link
Copy Markdown

Greptile Summary

This PR lands example validation fixes from phases 2–4 (memory/knowledge/metrics, session/output/execution, persistence/workflows/web/CLI) onto main, plus a one-line SDK fix in RouterAgent._build_system_prompt. The bulk of the changes are API alignment across ~73 example files: migrating db=/session_id= kwargs to memory={...}, metrics=True to output={\"metrics\": True}, max_iter= to execution={...}, and adding if __name__ == \"__main__\": guards.

  • SDK fix (router_agent.py): _build_system_prompt now accepts tools=None, **kwargs and forwards tools to the parent class, fixing a TypeError when the parent API added the tools parameter.
  • Two files contain bare merge-conflict residueexamples/persistence/knowledge_qdrant.py and examples/python/stateful/session-example.py each have a stray main token inside a dict/call expression, causing SyntaxError at import time.

Confidence Score: 3/5

Two example files are syntactically broken due to merge-conflict residue and must be fixed before merging.

The SDK change in router_agent.py is correct and isolated. The ~71 example migrations are well-structured. However, knowledge_qdrant.py and session-example.py each contain a bare main token (merge-conflict debris) inside a dict literal and a constructor call respectively — both files are syntactically invalid Python and will fail immediately on import or compile.

examples/persistence/knowledge_qdrant.py and examples/python/stateful/session-example.py both require removal of the stray main token before merging.

Important Files Changed

Filename Overview
src/praisonai-agents/praisonaiagents/agent/router_agent.py Adds tools=None, **kwargs to _build_system_prompt and forwards tools to parent, fixing TypeError from parent API change.
examples/persistence/knowledge_qdrant.py Contains a bare main token inside a dict literal (merge-conflict residue) — causes SyntaxError on import.
examples/python/stateful/session-example.py Contains a bare main token inside Session(...) constructor (merge-conflict residue) — causes SyntaxError on import.
examples/persistence/minimal_agent_db.py Migrates db= and session_id= Agent kwargs to memory={...} dict; updates import to from praisonaiagents.db import db.
examples/python/workflows/task_callbacks.py Replaces flat on_task_start/on_task_complete kwargs with hooks=MultiAgentHooksConfig(...) to match current API.
examples/python/guardrails/production-guardrails-patterns.py Wraps guardrails= + max_retries= into guardrails=GuardrailConfig(validator=..., max_retries=...) for updated Agent API.
examples/python/telemetry/production-telemetry-example.py Reduces 284→55 lines: strips broken OpenTelemetry scaffolding, replaces with minimal TelemetryCollector + nullcontext pattern.
examples/python/mcp/streamable-http-mcp.py Moves Agent construction inside main guard to prevent import-time side effects.
examples/python/mcp/websocket-mcp.py Same main guard refactor as streamable-http-mcp.py.
examples/retrieval/basic_retrieval.py Migrates flat knowledge=[...]+retrieval_config={...} into unified knowledge={sources:[...],config:{...}} dict.
examples/python/token-metrics/01_basic_token_tracking.py Replaces metrics=True with output={'metrics': True} across all three token-metrics examples.
examples/python/save_output/03_workflow_output_file.py Rewrites to construct Agent+Task objects from config dict and call workflow.start() replacing removed workflow.run().

Reviews (1): Last reviewed commit: "Merge branch 'main' into phase4-api-fixe..." | Re-trigger Greptile

Comment thread examples/persistence/knowledge_qdrant.py
Comment thread examples/python/stateful/session-example.py
Comment thread examples/python/usecases/analysis/code-analysis-agents.py

@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: 11

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (8)
examples/knowledge/context_required_example.py (1)

95-96: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Defensive response normalization is still missing in one verification path.

Line 95 still assumes response is a string. If agent.chat() returns None/non-string, this path can raise at runtime. Normalize here the same way as Line 83 and Line 107 (e.g., normalized = str(response or "")).

🤖 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 `@examples/knowledge/context_required_example.py` around lines 95 - 96, The
verification branch that checks for "47.50" currently assumes response is a
string and can raise if agent.chat() returned None or a non-string; normalize
the value the same way as the other checks by creating a normalized =
str(response or "") before using it in the if condition and then check
normalized for "47.50" or "$47.50" (use the existing response normalization
pattern seen around the other agent.chat() checks).
examples/python/tools/langchain/google-serper-search.py (1)

2-2: ⚠️ Potential issue | 🟠 Major

Lazy-load GoogleSerperAPIWrapper to avoid crashing when langchain_community is missing
examples/python/tools/langchain/google-serper-search.py imports GoogleSerperAPIWrapper at module import time (line 2), so an ImportError occurs before the SERPER_API_KEY guard in if __name__ == "__main__": (lines 13-21) can skip the example. Move the import inside the guarded block and handle ImportError with a clear pip install langchain-community hint.

Same module-level langchain_community.utilities import pattern exists in other examples (e.g., serp-search.py, serp-api.py, searchapi-search.py, wikipedia-search.py).

🤖 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 `@examples/python/tools/langchain/google-serper-search.py` at line 2, The
module-level import of GoogleSerperAPIWrapper causes ImportError before the
SERPER_API_KEY guard runs; move the import of
langchain_community.utilities.GoogleSerperAPIWrapper inside the if __name__ ==
"__main__": block (after checking SERPER_API_KEY) and wrap it in a try/except
ImportError that prints a clear message advising to pip install
langchain-community (or skips running the example), so the example doesn’t crash
when langchain_community is not installed; apply the same lazy-import pattern to
other example files that import langchain_community.utilities (e.g.,
serp-search.py, serp-api.py, searchapi-search.py, wikipedia-search.py).
examples/python/concepts/self-reflection-optimization-patterns.py (1)

11-11: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Move banner print under the main guard.

Line 11 still executes on import, so this module still has import-time side effects. Put that print inside the if __name__ == "__main__": flow.

🤖 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 `@examples/python/concepts/self-reflection-optimization-patterns.py` at line
11, The top-level print("=== Self-Reflection Optimization Patterns Example
===\n") causes import-time side effects; move this banner into the module's
entry point by placing the print inside an if __name__ == "__main__": block (and
ensure any demo/run logic in this file is also executed only under that guard),
referencing the module's top-level print statement and the main guard to locate
where to move it.
examples/python/managed-agents/19_manage_environments.py (1)

5-16: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Guard runtime demo code behind if __name__ == "__main__":.

This file still creates agents and calls agent.start(...) at import time, which causes network side effects during import. Wrap the demo setup/execution in a main guard.

🤖 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 `@examples/python/managed-agents/19_manage_environments.py` around lines 5 -
16, The demo currently instantiates ManagedAgent/ManagedConfig and calls
agent.start("Say hello briefly") at import time; wrap the demo setup and
execution (the ManagedAgent(...), Agent(...), and agent.start(...) lines) inside
a main guard by moving them under if __name__ == "__main__": so importing this
module has no network side effects while still allowing the script to run when
executed directly.
examples/python/token-metrics/01_basic_token_tracking.py (1)

2-5: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Root cause: token-metrics example prose was not migrated with the API.
Both files now correctly use output={"metrics": True} in code, but user-facing text/comments still instruct metrics=True. Update both docs/comments together to keep onboarding and copy-paste paths accurate.

🤖 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 `@examples/python/token-metrics/01_basic_token_tracking.py` around lines 2 - 5,
The example prose still instructs using the old Agent(metrics=True) API; update
all user-facing text and comments to reflect the current API by replacing
references to "metrics=True" or "Agent(metrics=True)" with the new usage
"output={\"metrics\": True}" (and mention Agent(output={\"metrics\": True})
where applicable) so copy-paste snippets and onboarding text match the actual
code; change this in the token-metrics example and its companion doc/comments to
keep them consistent.
examples/python/mongodb/mongodb_memory_example.py (1)

30-39: ⚠️ Potential issue | 🟠 Major

Fix MongoDB memory config shape (provider must be top-level)

examples/python/mongodb/mongodb_memory_example.py currently nests "provider": "mongodb" under "config" (creating {"config": {"provider": ...}}). The Memory config shape expects {"provider": "...", "config": {...}} (with connection/database settings inside config), so move "provider" to the top level and keep only MongoDB connection options under "config".

🤖 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 `@examples/python/mongodb/mongodb_memory_example.py` around lines 30 - 39, The
mongodb_memory_config object has provider nested under "config" but the Memory
config expects provider at the top level; update mongodb_memory_config so
"provider": "mongodb" is a top-level key and leave only
connection/database/vector/search options (connection_string, database,
use_vector_search, max_pool_size, min_pool_size, server_selection_timeout)
inside the "config" dict to match the expected shape used by Memory.

Source: Coding guidelines

examples/python/token-metrics/03_cost_estimation.py (1)

4-4: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update the docstring to reflect the new consolidated API.

The comment references Agent(metrics=True), but the code now uses output={"metrics": True}. Update line 4 to match the current API.

📝 Suggested documentation fix
 """
 Cost Estimation Example - SIMPLIFIED VERSION
-This example demonstrates automatic token metrics and cost tracking 
-using just Agent(metrics=True). All tracking and display is automatic!
+This example demonstrates automatic token metrics and cost tracking 
+using just Agent(output={"metrics": True}). All tracking and display is automatic!
 For custom cost calculations, you can still access the detailed reports.
 """
🤖 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 `@examples/python/token-metrics/03_cost_estimation.py` at line 4, Update the
docstring sentence that currently mentions "Agent(metrics=True)" to reference
the new consolidated API by mentioning the actual parameter used in the code:
"output={\"metrics\": True}" (or say using Agent(..., output={\"metrics\": True}
if you want to show context). Locate the docstring near the top where Agent is
described and replace the old API text so the docstring matches the runtime
usage of output={"metrics": True}.
examples/web/01_agent_web_config.py (1)

1-5: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update the example to match its stated purpose or revise the docstring.

The docstring claims "fine-grained control" using WebConfig, but WebConfig has been removed and both agents now use the identical web="search_only" preset (lines 15 and 21). This example no longer demonstrates differentiated configuration.

Consider either:

  1. Updating the docstring to describe the simplified preset-based API, or
  2. Demonstrating different presets/configurations if the goal is to show fine-grained control
📝 Suggested docstring fix
 """
-WebConfig Example
+Web Preset Configuration Example
 
-Demonstrates using WebConfig for fine-grained control.
+Demonstrates using web presets for search capabilities.
 """
🤖 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 `@examples/web/01_agent_web_config.py` around lines 1 - 5, The example's
docstring wrongly promises "fine-grained control" via WebConfig but WebConfig
was removed and both agents use the same web="search_only" preset; either update
the docstring to explain the new preset-based, simplified API (mentioning
web="search_only" preset) or modify the example to demonstrate different
presets/configurations (e.g., use two different web presets or agent configs
instead of WebConfig) so the code actually shows differentiated behavior; locate
references to WebConfig and the web="search_only" usage in this file and apply
the chosen change.
🧹 Nitpick comments (8)
examples/python/telemetry/production-telemetry-example.py (2)

41-49: ⚡ Quick win

Consider adding error handling to demonstrate production-grade patterns.

The script is labeled "Production Telemetry Example" but lacks exception handling around task execution. If agents.start() raises an error, the entire loop will terminate. For an example demonstrating production telemetry patterns, wrapping the task execution in a try/except block would better showcase robust error handling and telemetry under failure conditions.

♻️ Proposed enhancement to add error handling
         with trace_cm:
+            try:
                 task = Task(
                     name=f"customer_request_{idx}",
                     description=description,
                     expected_output="Professional customer service response with solution",
                     agent=customer_service_agent,
                 )
                 agents = AgentTeam(agents=[customer_service_agent], tasks=[task], output="minimal")
                 result = agents.start()
                 print(f"✅ Request {idx} completed, response length={len(str(result))}")
+            except Exception as e:
+                print(f"❌ Request {idx} failed: {e}")
+                # In production, you might want to log this to your telemetry collector
+                continue
🤖 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 `@examples/python/telemetry/production-telemetry-example.py` around lines 41 -
49, The loop around Task/AgentTeam execution lacks exception handling so a
failure in agents.start() will abort the script; wrap the call to
AgentTeam.start() (reference: AgentTeam and its agents.start()) in a try/except
that catches Exception, logs the error (include context like task
name/customer_request_{idx}) and records/flushes telemetry before continuing to
the next iteration, ensuring the Task creation/print remains outside or in the
finally block as appropriate.

38-40: 💤 Low value

Consider adding a comment to explain the trace context fallback pattern.

The dynamic trace context retrieval with getattr/callable check is correct and defensive, but the pattern may not be immediately clear to readers. A brief comment explaining that this falls back to nullcontext() when the collector doesn't support tracing would improve readability.

📝 Suggested clarifying comment
     for idx, description in enumerate(requests, start=1):
+        # Use collector.trace() if available, otherwise no-op context
         trace_ctx = getattr(collector, "trace", None)
         trace_cm = trace_ctx(f"customer_request_{idx}") if callable(trace_ctx) else nullcontext()
🤖 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 `@examples/python/telemetry/production-telemetry-example.py` around lines 38 -
40, Add a brief inline comment above the trace context setup (the
trace_ctx/trace_cm assignments) explaining the fallback pattern: we use
getattr(collector, "trace", None) to safely obtain a trace context factory,
check callable(trace_ctx) to ensure it can be used as a context manager, and
fall back to nullcontext() when the collector does not support tracing so the
with trace_cm: block remains safe. Include reference to the variables trace_ctx,
trace_cm, collector, and nullcontext so readers understand the defensive
behavior.
examples/python/mcp/websocket-mcp.py (1)

29-33: ⚡ Quick win

Avoid inline auth token literals in example code.

Line 31 and Line 40 embed token strings directly. Even as placeholders, prefer environment-backed values to avoid copy/paste secret leakage patterns.

Also applies to: 38-42

🤖 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 `@examples/python/mcp/websocket-mcp.py` around lines 29 - 33, Replace the
inline auth token literals passed to the MCP constructor with environment-backed
values: read the token via os.environ.get or os.getenv (e.g., token =
os.getenv("MCP_AUTH_TOKEN")) and pass that variable into MCP(...,
auth_token=token, ...), using a safe default or raising a clear error when
missing; update both occurrences around the MCP(...) instantiation and any other
examples that currently use "Bearer your-secret-token" so examples illustrate
secure env-backed patterns.

Source: Linters/SAST tools

examples/skills/basic_skill_usage.py (1)

55-63: ⚡ Quick win

Update comment to match the code.

The comment on line 56 references skills_dirs, but the code now uses the skills parameter. This inconsistency may confuse users reading the example.

📝 Suggested fix
 # Example 3: Discovering skills from multiple directories
 print("\n" + "=" * 50)
-print("Example 3: Using skills_dirs for discovery")
+print("Example 3: Using skills for directory discovery")
 print("=" * 50)
🤖 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 `@examples/skills/basic_skill_usage.py` around lines 55 - 63, Update the
example header/comment to match the actual code: replace the text referencing
"skills_dirs" with wording that reflects the Agent(...) call using the skills
parameter (e.g., "Using skills for discovery" or "Scanning current directory via
skills"), so the printed banner and comment align with the Agent(...)
instantiation and the skills=["./"] argument.
examples/python/usecases/analysis/code-analysis-agents.py (3)

103-106: ⚡ Quick win

Narrow exception handling may miss operational failures.

The try/except block only catches RuntimeError, but other exceptions (network errors, API failures, authentication issues) from the LLM or gitingest could propagate uncaught, causing unhelpful stack traces for users.

🛡️ Suggested improvement
     try:
         result = analyze_code(code_source)
-    except RuntimeError as exc:
-        print(f"Code analysis failed: {exc}")
+    except Exception as exc:
+        print(f"Code analysis failed: {exc.__class__.__name__}: {exc}")
         sys.exit(1)
🤖 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 `@examples/python/usecases/analysis/code-analysis-agents.py` around lines 103 -
106, The current try/except around the analyze_code call only catches
RuntimeError and can let other failures (network, API, auth, gitingest) crash
with raw traces; change the handler for the analyze_code invocation to catch
broad exceptions (e.g., Exception) instead of only RuntimeError, and log or
print the full error details/stack (use logging.exception or include str(exc)
and traceback) before calling sys.exit(1); locate the block around the
analyze_code(...) call and update its except clause accordingly so all
operational failures are caught and reported clearly.

93-96: ⚡ Quick win

Add remediation hint to error message.

The error message should help users understand why the result is None and what they can do about it.

💬 Suggested improvement
     if result is None:
-        raise RuntimeError("No analysis result returned by AgentTeam.start()")
+        raise RuntimeError(
+            "No analysis result returned by AgentTeam.start(). "
+            "Verify the agent configuration, LLM connectivity, and that the code source contains analyzable content."
+        )

As per coding guidelines: "Fail fast with clear error messages; include remediation hints in exceptions".

🤖 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 `@examples/python/usecases/analysis/code-analysis-agents.py` around lines 93 -
96, The runtime check after calling agents.start(context_text) should raise a
RuntimeError that includes a remediation hint; update the exception thrown where
result is None (the block after agents.start(context_text) / AgentTeam.start())
to include actionable guidance such as verifying the provided context_text is
non-empty, confirming agents are configured/enabled, and checking individual
agent run logs or exceptions for failures so users know what to inspect to fix
the issue.

Source: Coding guidelines


64-67: ⚡ Quick win

Add remediation hint to error message.

The error message should guide users on how to fix the problem. Consider including installation instructions or troubleshooting steps.

💬 Suggested improvement
     except Exception as exc:
-        raise RuntimeError(f"Failed to ingest code source: {exc}") from exc
+        raise RuntimeError(
+            f"Failed to ingest code source: {exc}. "
+            "Ensure 'gitingest' is installed (pip install gitingest) and the source path/URL is accessible."
+        ) from exc

As per coding guidelines: "Fail fast with clear error messages; include remediation hints in exceptions".

🤖 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 `@examples/python/usecases/analysis/code-analysis-agents.py` around lines 64 -
67, The RuntimeError raised in the ingest block should include a remediation
hint to help users fix the issue: update the message raised from the except
clause (around the ingest(code_source) call) to append guidance such as
verifying that code_source path/URL is correct, ensuring required dependencies
are installed, and providing example install/troubleshooting commands (e.g., pip
install <needed-package> or checking read permissions). Keep the original
exception chained (from exc) and include the ingest function name and
code_source reference in the message for context.

Source: Coding guidelines

examples/managed-agents/persistence/neon_managed.py (1)

28-33: 💤 Low value

Update commented example to match the new API.

The commented "Option 2" example still uses the old API with separate db= and session_id= parameters. For consistency and to avoid confusion, update it to use the memory={...} pattern like the active code above.

♻️ Proposed update
 # Option 2: Direct URL
 # agent = Agent(
 #     name="Neon Agent",
 #     instructions="You are a helpful assistant.",
-#     db={"database_url": "postgresql://user:pass@ep-xxx.neon.tech/dbname?sslmode=require"},
-#     session_id="neon-demo-session",
+#     memory={
+#         "session_id": "neon-demo-session",
+#         "db": {"database_url": "postgresql://user:pass@ep-xxx.neon.tech/dbname?sslmode=require"},
+#     },
 # )
🤖 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 `@examples/managed-agents/persistence/neon_managed.py` around lines 28 - 33,
The commented example uses the old API with db= and session_id=; update the
Agent instantiation to the new memory= pattern used elsewhere: create
Agent(name="Neon Agent", instructions="You are a helpful assistant.",
memory={"neon": {"database_url":
"postgresql://user:pass@ep-xxx.neon.tech/dbname?sslmode=require"}, "session_id":
"neon-demo-session"}) instead of db=... and session_id=..., so adjust the
commented block around the Agent(...) call to pass a single memory dict.
🤖 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 `@examples/observability/multi_agent_tracing.py`:
- Around line 23-31: The helper set_span_attr currently silently no-ops when the
span neither implements set_attribute() nor exposes an attributes dict; update
set_span_attr to explicitly raise a clear exception (e.g., TypeError) in that
fallback path with a message naming the function (set_span_attr) and the span
object, describing that the span type is unsupported and advising to provide an
object implementing set_attribute(key, value) or an attributes dict so
attributes appear in traces; this ensures callers fail fast and get remediation
guidance instead of silent omission.

In `@examples/persistence/knowledge_qdrant.py`:
- Around line 53-57: Remove the stray "main" token from the knowledge dict (it's
invalid Python syntax) and replace it with the expected nested vector_store
configuration described in the PR: ensure the knowledge dict (where "sources":
[doc_path]) contains a "vector_store" mapping that sets "provider" (e.g.,
"qdrant") and the "url" (or connection details) so the structure matches the
nested vector_store configuration used elsewhere; update the dict assigned to
knowledge in examples/persistence/knowledge_qdrant.py (search for the knowledge
variable) to a valid Python dict without the leftover merge token.

In `@examples/policy/basic_policy.py`:
- Around line 57-61: The docstring/example for PolicyConfig is inconsistent with
the actual Agent API: Agent.__init__ has no policy parameter but Agent.policy
setter exists and examples use agent.policy = engine; update the PolicyConfig
docstring/snippet to construct a PolicyEngine from PolicyConfig (use
PolicyEngine(PolicyConfig(...))) and then set it via agent.policy = engine (or
alternatively add a policy parameter to Agent.__init__ if you prefer to change
the API), referencing the Agent class, its policy property setter, PolicyConfig,
and PolicyEngine so the snippet matches the real usage.

In `@examples/python/agents/autoagents-hierarchical-generation.py`:
- Around line 63-69: Top-level print statements cause import-time side effects;
move all banner/console output and any demo setup into the existing entrypoint
guard so importing the module is side-effect free. Specifically, relocate the
prints around agents_system.start() (the banner lines and the two informational
print() calls) so they execute only inside the if __name__ == "__main__": block
and ensure any demo initialization that produces console output is also moved
there; leave agents_system.start() invocation inside that guard and remove or
wrap any remaining top-level prints.

In `@examples/python/camera/camera-basic.py`:
- Line 93: The lookup for task_results can return None because
result.get("task_results") has no default; update the parsing so task_results =
result.get("task_results", result) (use a default of result) wherever you
extract task_results from a dict (e.g., the task_results assignment in
camera-basic.py that reads result and assigns task_results) to preserve non-dict
or alternate payloads—make the same change at the other symmetric occurrence
noted in the review.

In `@examples/python/failover_example.py`:
- Line 21: Update the code that prints/reads auth profiles to use the renamed
field profile.rate_limit_rpm instead of the old profile.rate_limit; locate the
print/logging logic and any places in the __main__ flow that reference
profile.rate_limit (e.g., when iterating over auth profiles or calling a
function that formats profile info) and change those accesses to
profile.rate_limit_rpm so the output path matches the new profile field name.

In `@examples/python/managed-agents/19_manage_environments.py`:
- Around line 41-42: Replace the broad "except Exception as e:" that prints
"Delete skipped (expected if sessions exist): {e}" with narrowly scoped handlers
for the specific delete-conflict and expected HTTP errors (e.g.,
ResourceConflictError or ConflictError from your SDK, and
HTTPError/HTTPStatusError if using requests/httpx) and import those exception
classes; for example, handle "except (ConflictError, HTTPStatusError) as e:" to
print the expected message and let any other exceptions propagate (or re-raise
them) so unexpected auth/network/schema failures are not masked.

In `@examples/python/memory/gemini-embedding-example.py`:
- Around line 88-97: Remove the stray bare token "main" from the memory
dictionary so the dict directly contains the "embedder" and "config" keys; edit
the memory structure around where the variable/assignment named memory is
defined (the block containing "embedder": {"provider":"gemini",...} and
"config": {"provider":"sqlite"}) to eliminate the merge residue and restore
valid Python dict syntax.

In `@examples/python/save_output/03_workflow_output_file.py`:
- Around line 36-62: The module executes the workflow at import time via result
= workflow.start() and prints results; refactor by moving the creation of
writer, workflow, and the call to workflow.start() and subsequent print("✅
Workflow completed!")/print("Output saved to: generated/tutorial.md") into a
main() function, then call that function under an if __name__ == "__main__":
guard; keep the Agent/AgentFlow/Task construction (symbols: Agent, AgentFlow,
Task, writer, workflow, workflow.start()) unchanged except to relocate them
inside main().

In `@examples/python/stateful/session-example.py`:
- Around line 16-19: The Session constructor call has a stray token "main"
causing a syntax error and an invalid positional-after-keyword argument; update
the Session(...) invocation (the Session class instantiation where
session_id="demo_chat_001") to remove the stray token and pass the intended
memory keyword argument, e.g. include memory={"user_id": "demo_user"} alongside
session_id so the call becomes Session(session_id="demo_chat_001",
memory={"user_id": "demo_user"}).

In `@src/praisonai-agents/praisonaiagents/agent/router_agent.py`:
- Around line 356-358: RouterAgent._build_system_prompt currently accepts
**kwargs but calls super()._build_system_prompt(tools=tools) so any extra
keyword args are silently dropped; either remove **kwargs from the
RouterAgent._build_system_prompt signature or explicitly validate and reject
unexpected kwargs by checking if kwargs is non-empty and raising a clear error
that tells callers which unsupported keys were passed and suggests removing them
or adding support; update the method (RouterAgent._build_system_prompt) to
forward kwargs to super()._build_system_prompt if the parent supports them,
otherwise raise a ValueError listing the keys in kwargs and remediation.

---

Outside diff comments:
In `@examples/knowledge/context_required_example.py`:
- Around line 95-96: The verification branch that checks for "47.50" currently
assumes response is a string and can raise if agent.chat() returned None or a
non-string; normalize the value the same way as the other checks by creating a
normalized = str(response or "") before using it in the if condition and then
check normalized for "47.50" or "$47.50" (use the existing response
normalization pattern seen around the other agent.chat() checks).

In `@examples/python/concepts/self-reflection-optimization-patterns.py`:
- Line 11: The top-level print("=== Self-Reflection Optimization Patterns
Example ===\n") causes import-time side effects; move this banner into the
module's entry point by placing the print inside an if __name__ == "__main__":
block (and ensure any demo/run logic in this file is also executed only under
that guard), referencing the module's top-level print statement and the main
guard to locate where to move it.

In `@examples/python/managed-agents/19_manage_environments.py`:
- Around line 5-16: The demo currently instantiates ManagedAgent/ManagedConfig
and calls agent.start("Say hello briefly") at import time; wrap the demo setup
and execution (the ManagedAgent(...), Agent(...), and agent.start(...) lines)
inside a main guard by moving them under if __name__ == "__main__": so importing
this module has no network side effects while still allowing the script to run
when executed directly.

In `@examples/python/mongodb/mongodb_memory_example.py`:
- Around line 30-39: The mongodb_memory_config object has provider nested under
"config" but the Memory config expects provider at the top level; update
mongodb_memory_config so "provider": "mongodb" is a top-level key and leave only
connection/database/vector/search options (connection_string, database,
use_vector_search, max_pool_size, min_pool_size, server_selection_timeout)
inside the "config" dict to match the expected shape used by Memory.

In `@examples/python/token-metrics/01_basic_token_tracking.py`:
- Around line 2-5: The example prose still instructs using the old
Agent(metrics=True) API; update all user-facing text and comments to reflect the
current API by replacing references to "metrics=True" or "Agent(metrics=True)"
with the new usage "output={\"metrics\": True}" (and mention
Agent(output={\"metrics\": True}) where applicable) so copy-paste snippets and
onboarding text match the actual code; change this in the token-metrics example
and its companion doc/comments to keep them consistent.

In `@examples/python/token-metrics/03_cost_estimation.py`:
- Line 4: Update the docstring sentence that currently mentions
"Agent(metrics=True)" to reference the new consolidated API by mentioning the
actual parameter used in the code: "output={\"metrics\": True}" (or say using
Agent(..., output={\"metrics\": True} if you want to show context). Locate the
docstring near the top where Agent is described and replace the old API text so
the docstring matches the runtime usage of output={"metrics": True}.

In `@examples/python/tools/langchain/google-serper-search.py`:
- Line 2: The module-level import of GoogleSerperAPIWrapper causes ImportError
before the SERPER_API_KEY guard runs; move the import of
langchain_community.utilities.GoogleSerperAPIWrapper inside the if __name__ ==
"__main__": block (after checking SERPER_API_KEY) and wrap it in a try/except
ImportError that prints a clear message advising to pip install
langchain-community (or skips running the example), so the example doesn’t crash
when langchain_community is not installed; apply the same lazy-import pattern to
other example files that import langchain_community.utilities (e.g.,
serp-search.py, serp-api.py, searchapi-search.py, wikipedia-search.py).

In `@examples/web/01_agent_web_config.py`:
- Around line 1-5: The example's docstring wrongly promises "fine-grained
control" via WebConfig but WebConfig was removed and both agents use the same
web="search_only" preset; either update the docstring to explain the new
preset-based, simplified API (mentioning web="search_only" preset) or modify the
example to demonstrate different presets/configurations (e.g., use two different
web presets or agent configs instead of WebConfig) so the code actually shows
differentiated behavior; locate references to WebConfig and the
web="search_only" usage in this file and apply the chosen change.

---

Nitpick comments:
In `@examples/managed-agents/persistence/neon_managed.py`:
- Around line 28-33: The commented example uses the old API with db= and
session_id=; update the Agent instantiation to the new memory= pattern used
elsewhere: create Agent(name="Neon Agent", instructions="You are a helpful
assistant.", memory={"neon": {"database_url":
"postgresql://user:pass@ep-xxx.neon.tech/dbname?sslmode=require"}, "session_id":
"neon-demo-session"}) instead of db=... and session_id=..., so adjust the
commented block around the Agent(...) call to pass a single memory dict.

In `@examples/python/mcp/websocket-mcp.py`:
- Around line 29-33: Replace the inline auth token literals passed to the MCP
constructor with environment-backed values: read the token via os.environ.get or
os.getenv (e.g., token = os.getenv("MCP_AUTH_TOKEN")) and pass that variable
into MCP(..., auth_token=token, ...), using a safe default or raising a clear
error when missing; update both occurrences around the MCP(...) instantiation
and any other examples that currently use "Bearer your-secret-token" so examples
illustrate secure env-backed patterns.

In `@examples/python/telemetry/production-telemetry-example.py`:
- Around line 41-49: The loop around Task/AgentTeam execution lacks exception
handling so a failure in agents.start() will abort the script; wrap the call to
AgentTeam.start() (reference: AgentTeam and its agents.start()) in a try/except
that catches Exception, logs the error (include context like task
name/customer_request_{idx}) and records/flushes telemetry before continuing to
the next iteration, ensuring the Task creation/print remains outside or in the
finally block as appropriate.
- Around line 38-40: Add a brief inline comment above the trace context setup
(the trace_ctx/trace_cm assignments) explaining the fallback pattern: we use
getattr(collector, "trace", None) to safely obtain a trace context factory,
check callable(trace_ctx) to ensure it can be used as a context manager, and
fall back to nullcontext() when the collector does not support tracing so the
with trace_cm: block remains safe. Include reference to the variables trace_ctx,
trace_cm, collector, and nullcontext so readers understand the defensive
behavior.

In `@examples/python/usecases/analysis/code-analysis-agents.py`:
- Around line 103-106: The current try/except around the analyze_code call only
catches RuntimeError and can let other failures (network, API, auth, gitingest)
crash with raw traces; change the handler for the analyze_code invocation to
catch broad exceptions (e.g., Exception) instead of only RuntimeError, and log
or print the full error details/stack (use logging.exception or include str(exc)
and traceback) before calling sys.exit(1); locate the block around the
analyze_code(...) call and update its except clause accordingly so all
operational failures are caught and reported clearly.
- Around line 93-96: The runtime check after calling agents.start(context_text)
should raise a RuntimeError that includes a remediation hint; update the
exception thrown where result is None (the block after
agents.start(context_text) / AgentTeam.start()) to include actionable guidance
such as verifying the provided context_text is non-empty, confirming agents are
configured/enabled, and checking individual agent run logs or exceptions for
failures so users know what to inspect to fix the issue.
- Around line 64-67: The RuntimeError raised in the ingest block should include
a remediation hint to help users fix the issue: update the message raised from
the except clause (around the ingest(code_source) call) to append guidance such
as verifying that code_source path/URL is correct, ensuring required
dependencies are installed, and providing example install/troubleshooting
commands (e.g., pip install <needed-package> or checking read permissions). Keep
the original exception chained (from exc) and include the ingest function name
and code_source reference in the message for context.

In `@examples/skills/basic_skill_usage.py`:
- Around line 55-63: Update the example header/comment to match the actual code:
replace the text referencing "skills_dirs" with wording that reflects the
Agent(...) call using the skills parameter (e.g., "Using skills for discovery"
or "Scanning current directory via skills"), so the printed banner and comment
align with the Agent(...) instantiation and the skills=["./"] argument.
🪄 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: 64a6be5b-83fe-42fb-a994-868a6f6818cd

📥 Commits

Reviewing files that changed from the base of the PR and between ce97667 and e89b50d.

📒 Files selected for processing (73)
  • examples/approval/agent_approval.py
  • examples/consolidated_params/advanced_workflow_full_features.py
  • examples/consolidated_params/basic_web.py
  • examples/knowledge/context_required_example.py
  • examples/managed-agents/persistence/cockroachdb_managed.py
  • examples/managed-agents/persistence/neon_managed.py
  • examples/managed-agents/persistence/supabase_direct_managed.py
  • examples/managed-agents/persistence/turso_managed.py
  • examples/middleware/configurable_model.py
  • examples/middleware/injected_state.py
  • examples/observability/multi_agent_tracing.py
  • examples/persistence/knowledge_qdrant.py
  • examples/persistence/minimal_agent_db.py
  • examples/persistence/postgres_runs_traces.py
  • examples/persistence/redis_state.py
  • examples/persistence/session_resume.py
  • examples/persistence/simple_db_agent.py
  • examples/persistence/sqlite_local.py
  • examples/policy/basic_policy.py
  • examples/python/agents/autoagents-hierarchical-generation.py
  • examples/python/api/simple-mcp-server.py
  • examples/python/camera/camera-basic.py
  • examples/python/camera/camera-continuous.py
  • examples/python/camera/camera-multi-agent.py
  • examples/python/cli/autonomy_modes_example.py
  • examples/python/cli/cost_tracking_example.py
  • examples/python/cli/slash_commands_example.py
  • examples/python/concepts/repetitive-agents.py
  • examples/python/concepts/self-reflection-optimization-patterns.py
  • examples/python/custom_tools/example_latency_tracking.py
  • examples/python/data/cot-agents.py
  • examples/python/failover_example.py
  • examples/python/general/memory_example.py
  • examples/python/general/multimodal.py
  • examples/python/guardrails/production-guardrails-patterns.py
  • examples/python/linear_agent_example.py
  • examples/python/managed-agents/19_manage_environments.py
  • examples/python/mcp/mcp-resumability.py
  • examples/python/mcp/mcp-session-management.py
  • examples/python/mcp/streamable-http-mcp.py
  • examples/python/mcp/websocket-mcp.py
  • examples/python/memory/advanced-graph-memory-integration.py
  • examples/python/memory/advanced-memory-search-optimization.py
  • examples/python/memory/gemini-embedding-example.py
  • examples/python/models/deepseek/deepseek-rag-agents.py
  • examples/python/models/googlegemini/any-llm-agents-advanced.py
  • examples/python/mongodb/mongodb_memory_example.py
  • examples/python/save_output/03_workflow_output_file.py
  • examples/python/session/session_persistence_example.py
  • examples/python/stateful/advanced-state-management-patterns.py
  • examples/python/stateful/session-example.py
  • examples/python/telemetry/production-telemetry-example.py
  • examples/python/token-metrics/01_basic_token_tracking.py
  • examples/python/token-metrics/02_session_metrics.py
  • examples/python/token-metrics/03_cost_estimation.py
  • examples/python/tools/exa-tool/rag_examples/agentic_rag/rag_agent.py
  • examples/python/tools/langchain/google-serper-search.py
  • examples/python/usecases/analysis/code-analysis-agents.py
  • examples/python/usecases/analysis/cv-analysis.py
  • examples/python/usecases/analysis/hackathon-judge-agent.py
  • examples/python/video/video_azure.py
  • examples/python/workflows/task_callbacks.py
  • examples/python/workflows/workflow_conditional.py
  • examples/python/workflows/workflow_mixed_steps.py
  • examples/python/workflows/workflow_robustness.py
  • examples/retrieval/basic_retrieval.py
  • examples/skills/basic_skill_usage.py
  • examples/storage/storage_backends_example.py
  • examples/terminal_bench/test_integration.py
  • examples/web/00_agent_web_basic.py
  • examples/web/01_agent_web_config.py
  • examples/yaml/workflows/example_usage.py
  • src/praisonai-agents/praisonaiagents/agent/router_agent.py
💤 Files with no reviewable changes (1)
  • examples/python/custom_tools/example_latency_tracking.py

Comment on lines +23 to +31
def set_span_attr(span, key, value):
"""Set span attribute safely across observability implementations."""
if hasattr(span, "set_attribute"):
span.set_attribute(key, value)
return
attrs = getattr(span, "attributes", None)
if attrs is not None:
attrs[key] = value

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add explicit error handling for unsupported span objects.

The helper silently does nothing when the span supports neither set_attribute() nor an attributes dict. For an example demonstrating observability patterns, this silent failure could confuse users who copy this code—attributes won't appear in traces without any indication why.

As per coding guidelines, you should "fail fast with clear error messages; include remediation hints in exceptions."

🛡️ Proposed fix to add explicit error handling
 def set_span_attr(span, key, value):
     """Set span attribute safely across observability implementations."""
     if hasattr(span, "set_attribute"):
         span.set_attribute(key, value)
         return
     attrs = getattr(span, "attributes", None)
     if attrs is not None:
         attrs[key] = value
+        return
+    raise AttributeError(
+        f"Span object does not support attribute setting. "
+        f"Expected 'set_attribute' method or 'attributes' dict, got {type(span).__name__}"
+    )
🤖 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 `@examples/observability/multi_agent_tracing.py` around lines 23 - 31, The
helper set_span_attr currently silently no-ops when the span neither implements
set_attribute() nor exposes an attributes dict; update set_span_attr to
explicitly raise a clear exception (e.g., TypeError) in that fallback path with
a message naming the function (set_span_attr) and the span object, describing
that the span type is unsupported and advising to provide an object implementing
set_attribute(key, value) or an attributes dict so attributes appear in traces;
this ensures callers fail fast and get remediation guidance instead of silent
omission.

Source: Coding guidelines

Comment thread examples/persistence/knowledge_qdrant.py
Comment on lines 57 to +61
agent = Agent(
name="SecureAgent",
instructions="You are a file management assistant.",
policy=engine
)
agent.policy = engine

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.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check if PolicyConfig pattern exists and how policy is used in other examples

# Search for PolicyConfig usage
ast-grep --pattern 'class PolicyConfig'

# Search for policy parameter usage in Agent constructor
rg -n -C3 'Agent\(' --type=py | rg -C3 'policy='

# Search for post-construction policy assignment pattern
rg -n 'agent\.policy\s*=' --type=py

Repository: MervinPraison/PraisonAI

Length of output: 22058


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Inspect the example around the flagged lines
echo "### examples/policy/basic_policy.py:57-80"
sed -n '50,90p' examples/policy/basic_policy.py

# 2) Find the Agent class definition and show its __init__ signature
echo
echo "### Locate Agent class"
fd -a "agent.py" . || true
fd -a "*agent*" src examples -t f || true

# Prefer AST-grep to find the class and __init__ params
echo
echo "### AST-grep: class Agent and __init__"
ast-grep --pattern $'class Agent { $$$ }' || true

# Fallback: text search for def __init__ with policy inside Agent-related files
echo
echo "### rg: Agent __init__ signature candidates"
rg -n --type=py "class Agent\b" -S src/praisonai-agents/praisonaiagents || true
rg -n --type=py "def __init__\(" -S src/praisonai-agents/praisonaiagents | rg -n "Agent|agent" || true
rg -n --type=py "policy\s*=" -S examples src/praisonai-agents/praisonaiagents | head -n 50

# 3) Search for Agent(policy=...) more robustly (multiline friendly)
echo
echo "### rg multiline-ish: Agent( ... policy="
rg -n --type=py "Agent\s*\(\s*[\s\S]{0,200}policy\s*=" src examples || true

Repository: MervinPraison/PraisonAI

Length of output: 50685


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Read the Python Agent implementation used by examples/policy/basic_policy.py
echo "### Candidate Agent python files (praisonai-agents)"
fd -a "agent.py" src/praisonai-agents/praisonaiagents/agent -t f

# Print the most likely one(s)
for f in src/praisonai-agents/praisonaiagents/agent/agent.py src/praisonai-agents/praisonaiagents/agent/*.py; do
  if [ -f "$f" ]; then
    echo "---- $f"
    rg -n "class Agent\b|def __init__\(" "$f" | head -n 30 || true
    rg -n "\bpolicy\b" "$f" | head -n 80 || true
  fi
done

# 2) Focused: show Agent __init__ signature where 'policy' is mentioned
echo
echo "### Focused search for policy in python Agent __init__"
rg -n --type=py "def __init__\(" src/praisonai-agents/praisonaiagents/agent | head -n 50

rg -n --type=py -C3 "\bpolicy\b" src/praisonai-agents/praisonaiagents/agent/agent.py src/praisonai-agents/praisonaiagents/agent/*.py || true

# 3) Scan examples for policy usage patterns
echo
echo "### examples: PolicyConfig usage"
rg -n --type=py "PolicyConfig\s*\(" examples | head -n 50 || true

echo
echo "### examples: direct Agent(..., policy=...)"
rg -n --type=py -S "Agent\s*\(" examples | rg -n "policy\s*=" | head -n 80 || true

echo
echo "### examples: post-construction agent.policy assignment"
rg -n --type=py "agent\.policy\s*=" examples | head -n 50 || true

Repository: MervinPraison/PraisonAI

Length of output: 27379


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the flagged example end-to-end enough to see how `engine` is created.
echo "### examples/policy/basic_policy.py (top to ~90)"
sed -n '1,120p' examples/policy/basic_policy.py

# Inspect Agent.__init__ signature/doc around where `policy` is defined (agent.py is large).
echo
echo "### src/praisonai-agents/praisonaiagents/agent/agent.py: __init__ policy parameter context"
python3 - <<'PY'
import itertools
path="src/praisonai-agents/praisonaiagents/agent/agent.py"
start=480
end=920
with open(path,'r',encoding='utf-8') as f:
    for i,line in enumerate(f,1):
        if start<=i<=end:
            print(f"{i}:{line.rstrip()}")
PY

# Inspect how policy is applied during execution (quick targeted searches).
echo
echo "### Search for policy usage inside agent.py (top-level)"
rg -n "policy" src/praisonai-agents/praisonaiagents/agent/agent.py | head -n 80

echo
echo "### Search for PolicyEngine/PolicyConfig classes"
fd -a "engine.py|Engine|policy_engine|PolicyEngine" src/praisonai-agents/praisonaiagents/policy -t f || true
rg -n --type=py "class PolicyEngine|PolicyEngine|PolicyConfig" src/praisonai-agents/praisonaiagents/policy -S || true

# Inspect policy engine implementation and whether it is configured via PolicyConfig.
echo
echo "### src/praisonai-agents/praisonaiagents/policy/* (policy engine/config definitions)"
for f in $(fd -a -t f src/praisonai-agents/praisonaiagents/policy); do
  rg -n --type=py "class (PolicyEngine|PolicyConfig)\b" "$f" && echo "---- $f"
done 2>/dev/null || true

# Finally, scan for any other examples that do Agent(policy=PolicyConfig(...)) for policy engine usage.
echo
echo "### examples: Agent(..., policy=...) where policy is present (broader)"
rg -n --type=py "Agent\s*\(" examples | rg -n "policy\s*=" | head -n 100 || true

Repository: MervinPraison/PraisonAI

Length of output: 31742


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Re-print the full Agent.__init__ signature area (small window) and search for "policy" inside it
echo "### Print Agent.__init__ signature lines 500-590"
sed -n '500,590p' src/praisonai-agents/praisonaiagents/agent/agent.py

echo
echo "### rg for 'policy' within the Agent.__init__ signature window"
rg -n --type=py "policy\s*:" -n src/praisonai-agents/praisonaiagents/agent/agent.py | head -n 50 || true

# 2) Look for any config default resolver / consolidated param handling for policy
echo
echo "### rg for consolidated handling of policy in agent.py"
rg -n --type=py "PolicyConfig|policy\s*=|apply_config_defaults\(\"policy\"\)|param_name=\"policy\"|resolve\(.*policy" src/praisonai-agents/praisonaiagents/agent/agent.py | head -n 120

# 3) Find where policy is actually used during execution/tool checks
echo
echo "### rg for self._policy usage"
rg -n --type=py "self\._policy|_policy" src/praisonai-agents/praisonaiagents/agent/agent.py | head -n 120

# 4) Search in whole python package for Agent(policy=...) usage (beyond examples)
echo
echo "### rg: Agent(policy=...) across src/praisonai-agents"
rg -n --type=py "Agent\s*\([^)]*policy\s*=" src/praisonai-agents | head -n 80 || true

Repository: MervinPraison/PraisonAI

Length of output: 6858


🏁 Script executed:

#!/bin/bash
set -euo pipefail

AGENT_PY="src/praisonai-agents/praisonaiagents/agent/agent.py"

echo "### All occurrences of 'policy' in $AGENT_PY (first 80)"
rg -n "policy" "$AGENT_PY" | head -n 80

echo
echo "### Agent policy resolution block (around line 800-900)"
python3 - <<'PY'
path="src/praisonai-agents/praisonaiagents/agent/agent.py"
for start,end in [(760,880),(880,1020),(1860,2020),(2020,2210)]:
    print(f"\n--- {start}-{end} ---")
    with open(path,'r',encoding='utf-8') as f:
        for i,line in enumerate(f,1):
            if start<=i<=end:
                print(f"{i}:{line.rstrip()}")
PY

echo
echo "### Look for 'param_name=\"policy\"' or 'policy' passed to resolve/apply_config_defaults"
rg -n --type=py "param_name\s*=\s*\"policy\"|apply_config_defaults\\(\"policy\"\\)|resolve\\(.*policy" "$AGENT_PY" || true

echo
echo "### Search for any mention of PolicyEngine/PolicyConfig in Agent python code"
rg -n --type=py "PolicyEngine|PolicyConfig" src/praisonai-agents/praisonaiagents/agent | head -n 50 || true

Repository: MervinPraison/PraisonAI

Length of output: 30826


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show PolicyEngine/PolicyConfig definitions relevant to configuration expectations
echo "### src/praisonai-agents/praisonaiagents/policy/engine.py"
sed -n '1,120p' src/praisonai-agents/praisonaiagents/policy/engine.py

echo
echo "### src/praisonai-agents/praisonaiagents/policy/config.py (top + usage snippet)"
sed -n '1,120p' src/praisonai-agents/praisonaiagents/policy/config.py

echo
echo "### src/praisonai-agents/praisonaiagents/policy/config.py (end of file / helpers if any)"
tail -n 80 src/praisonai-agents/praisonaiagents/policy/config.py

echo
echo "### src/praisonai-agents/praisonaiagents/policy/__init__.py"
sed -n '1,120p' src/praisonai-agents/praisonaiagents/policy/__init__.py

echo
echo "### Scan for any docs/example using Agent(policy=PolicyConfig(...)) in python agent codebase"
rg -n --type=py "Agent\s*\(\s*policy\s*=" src/praisonai-agents | head -n 50 || true

Repository: MervinPraison/PraisonAI

Length of output: 13060


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Confirm what praisonaiagents.Agent exports
echo "### src/praisonai-agents/praisonaiagents/__init__.py"
sed -n '1,120p' src/praisonai-agents/praisonaiagents/__init__.py

echo
echo "### src/praisonai-agents/praisonaiagents/agent/__init__.py"
sed -n '1,120p' src/praisonai-agents/praisonaiagents/agent/__init__.py

# 2) Search for any Python Agent __init__ that has a 'policy' parameter in its signature
echo
echo "### Search: Python Agent __init__ signatures that mention 'policy' (single-line)"
rg -n --type=py "def __init__\([^)]*policy[^)]*\)" src/praisonai-agents | head -n 50 || true

echo
echo "### Search: broader 'policy' near Agent __init__ (within same file)"
rg -n --type=py "def __init__\(" src/praisonai-agents/praisonaiagents/agent | head -n 50 || true

# 3) Check PolicyEngine supports PolicyConfig input (already saw config param, but confirm usage)
echo
echo "### Search in policy/engine.py for PolicyConfig usage"
rg -n "PolicyConfig" src/praisonai-agents/praisonaiagents/policy/engine.py

echo
echo "### Search examples for PolicyEngine(PolicyConfig"
rg -n --type=py "PolicyEngine\s*\(\s*PolicyConfig" examples src || true

Repository: MervinPraison/PraisonAI

Length of output: 13557


Clarify policy configuration API: agent.policy = engine is the current supported pattern

  • examples/policy/basic_policy.py uses agent.policy = engine, which matches the current praisonaiagents.agent.Agent API: Agent.__init__ has no policy parameter, but the policy property setter exists.
  • The PolicyConfig docstring still shows Agent(policy=PolicyConfig(...)), which doesn’t align with the Python Agent signature; update that snippet to use PolicyEngine(PolicyConfig(...)) + agent.policy = engine (or add policy support to Agent.__init__).
🤖 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 `@examples/policy/basic_policy.py` around lines 57 - 61, The docstring/example
for PolicyConfig is inconsistent with the actual Agent API: Agent.__init__ has
no policy parameter but Agent.policy setter exists and examples use agent.policy
= engine; update the PolicyConfig docstring/snippet to construct a PolicyEngine
from PolicyConfig (use PolicyEngine(PolicyConfig(...))) and then set it via
agent.policy = engine (or alternatively add a policy parameter to Agent.__init__
if you prefer to change the API), referencing the Agent class, its policy
property setter, PolicyConfig, and PolicyEngine so the snippet matches the real
usage.

Source: Coding guidelines

Comment on lines +63 to +69
if __name__ == "__main__":
print("Starting hierarchical agent generation...")
result = agents_system.start()

print(f"\nHierarchical Result: {result[:200]}...")
print("\n✅ AutoAgents hierarchical generation complete!")
print("Demonstrated coordinated hierarchical workflow between manager and specialist agents.") No newline at end of file
print(f"\nHierarchical Result: {str(result)[:200]}...")
print("\n✅ AutoAgents hierarchical generation complete!")
print("Demonstrated coordinated hierarchical workflow between manager and specialist agents.") No newline at end of file

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Root cause: partial entrypoint-guard migration still leaves top-level side effects.
Both files guard start() but still print at module scope (Line 11 in each file). Move banner/console output (and ideally demo setup) fully under if __name__ == "__main__": to make imports side-effect free.

🤖 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 `@examples/python/agents/autoagents-hierarchical-generation.py` around lines 63
- 69, Top-level print statements cause import-time side effects; move all
banner/console output and any demo setup into the existing entrypoint guard so
importing the module is side-effect free. Specifically, relocate the prints
around agents_system.start() (the banner lines and the two informational print()
calls) so they execute only inside the if __name__ == "__main__": block and
ensure any demo initialization that produces console output is also moved there;
leave agents_system.start() invocation inside that guard and remove or wrap any
remaining top-level prints.

if result:
print("\n🔍 Analysis Results:")
for task_id, task_result in result["task_results"].items():
task_results = result.get("task_results") if isinstance(result, dict) else result

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Shared result-parsing bug: missing default for task_results lookup.

Both files use result.get("task_results") without a fallback, so alternate dict payloads degrade to None. Use result.get("task_results", result) in both places.

🤖 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 `@examples/python/camera/camera-basic.py` at line 93, The lookup for
task_results can return None because result.get("task_results") has no default;
update the parsing so task_results = result.get("task_results", result) (use a
default of result) wherever you extract task_results from a dict (e.g., the
task_results assignment in camera-basic.py that reads result and assigns
task_results) to preserve non-dict or alternate payloads—make the same change at
the other symmetric occurrence noted in the review.

Comment on lines +41 to +42
except Exception as e:
print(f"Delete skipped (expected if sessions exist): {e}")

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Narrow exception handling for environment deletion.

except Exception masks unexpected failures (auth/network/schema) as “expected.” Catch only the known delete-conflict/error types and let others surface.

🧰 Tools
🪛 Ruff (0.15.15)

[warning] 41-41: Do not catch blind exception: Exception

(BLE001)

🤖 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 `@examples/python/managed-agents/19_manage_environments.py` around lines 41 -
42, Replace the broad "except Exception as e:" that prints "Delete skipped
(expected if sessions exist): {e}" with narrowly scoped handlers for the
specific delete-conflict and expected HTTP errors (e.g., ResourceConflictError
or ConflictError from your SDK, and HTTPError/HTTPStatusError if using
requests/httpx) and import those exception classes; for example, handle "except
(ConflictError, HTTPStatusError) as e:" to print the expected message and let
any other exceptions propagate (or re-raise them) so unexpected
auth/network/schema failures are not masked.

Source: Linters/SAST tools

Comment thread examples/python/memory/gemini-embedding-example.py
Comment on lines +36 to 62
# Build agent and workflow from config dict
writer_cfg = workflow_config["agents"]["writer"]
writer = Agent(
name="writer",
role=writer_cfg["role"],
goal=writer_cfg["goal"],
llm=writer_cfg["llm"],
)

step_cfg = workflow_config["steps"][0]
workflow = AgentFlow(
name=workflow_config["metadata"]["name"],
variables=workflow_config["variables"],
steps=[
Task(
name="write_tutorial",
description=step_cfg["action"],
expected_output=step_cfg["expected_output"],
output_file=step_cfg["output_file"],
agent=writer,
)
],
)
result = workflow.start()

print("✅ Workflow completed!")
print("Output saved to: generated/tutorial.md")

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Move workflow execution behind a main guard to avoid import-time side effects.

Line 59 executes workflow.start() at import time, which can trigger external calls/file writes when this module is imported by tests or docs tooling. Wrap execution/prints in main() and gate with if __name__ == "__main__":.

Suggested fix
-# Build agent and workflow from config dict
-writer_cfg = workflow_config["agents"]["writer"]
-writer = Agent(
-    name="writer",
-    role=writer_cfg["role"],
-    goal=writer_cfg["goal"],
-    llm=writer_cfg["llm"],
-)
-
-step_cfg = workflow_config["steps"][0]
-workflow = AgentFlow(
-    name=workflow_config["metadata"]["name"],
-    variables=workflow_config["variables"],
-    steps=[
-        Task(
-            name="write_tutorial",
-            description=step_cfg["action"],
-            expected_output=step_cfg["expected_output"],
-            output_file=step_cfg["output_file"],
-            agent=writer,
-        )
-    ],
-)
-result = workflow.start()
-
-print("✅ Workflow completed!")
-print("Output saved to: generated/tutorial.md")
+def main():
+    # Build agent and workflow from config dict
+    writer_cfg = workflow_config["agents"]["writer"]
+    writer = Agent(
+        name="writer",
+        role=writer_cfg["role"],
+        goal=writer_cfg["goal"],
+        llm=writer_cfg["llm"],
+    )
+
+    step_cfg = workflow_config["steps"][0]
+    workflow = AgentFlow(
+        name=workflow_config["metadata"]["name"],
+        variables=workflow_config["variables"],
+        steps=[
+            Task(
+                name="write_tutorial",
+                description=step_cfg["action"],
+                expected_output=step_cfg["expected_output"],
+                output_file=step_cfg["output_file"],
+                agent=writer,
+            )
+        ],
+    )
+    workflow.start()
+
+    print("✅ Workflow completed!")
+    print("Output saved to: generated/tutorial.md")
+
+
+if __name__ == "__main__":
+    main()
🤖 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 `@examples/python/save_output/03_workflow_output_file.py` around lines 36 - 62,
The module executes the workflow at import time via result = workflow.start()
and prints results; refactor by moving the creation of writer, workflow, and the
call to workflow.start() and subsequent print("✅ Workflow
completed!")/print("Output saved to: generated/tutorial.md") into a main()
function, then call that function under an if __name__ == "__main__": guard;
keep the Agent/AgentFlow/Task construction (symbols: Agent, AgentFlow, Task,
writer, workflow, workflow.start()) unchanged except to relocate them inside
main().

Comment thread examples/python/stateful/session-example.py
Comment thread src/praisonai-agents/praisonaiagents/agent/router_agent.py Outdated

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
examples/persistence/knowledge_qdrant.py (1)

42-67: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Protect temp directory cleanup with try/finally.

If Agent(...) or agent.chat(...) raises, shutil.rmtree(temp_dir) is skipped and temp artifacts are leaked. Wrap the runtime block so cleanup always executes.

Suggested fix
 temp_dir = tempfile.mkdtemp()
 doc_path = os.path.join(temp_dir, "guide.txt")
-with open(doc_path, "w") as f:
-    f.write(sample_doc)
-
-print("=== Qdrant Knowledge Store Demo (Agent-First) ===")
-
-# Agent-first approach: use knowledge parameter with Qdrant
-agent = Agent(
-    name="KnowledgeAssistant",
-    instructions="You are a helpful assistant with access to technical documentation.",
-    knowledge={
-        "sources": [doc_path],
-        "vector_store": {
-            "provider": "qdrant",
-            "url": "http://localhost:6333",
-        },
-    }
-)
-
-# Chat - agent uses knowledge for RAG
-response = agent.chat("What programming language is good for AI?")
-print(f"Response: {response}")
-
-# Cleanup
-shutil.rmtree(temp_dir)
+try:
+    with open(doc_path, "w") as f:
+        f.write(sample_doc)
+
+    print("=== Qdrant Knowledge Store Demo (Agent-First) ===")
+
+    # Agent-first approach: use knowledge parameter with Qdrant
+    agent = Agent(
+        name="KnowledgeAssistant",
+        instructions="You are a helpful assistant with access to technical documentation.",
+        knowledge={
+            "sources": [doc_path],
+            "vector_store": {
+                "provider": "qdrant",
+                "url": "http://localhost:6333",
+            },
+        }
+    )
+
+    # Chat - agent uses knowledge for RAG
+    response = agent.chat("What programming language is good for AI?")
+    print(f"Response: {response}")
+finally:
+    shutil.rmtree(temp_dir, ignore_errors=True)
🤖 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 `@examples/persistence/knowledge_qdrant.py` around lines 42 - 67, The temp
directory cleanup can be skipped if Agent(...) or agent.chat(...) raises; wrap
the runtime block that uses tempfile.mkdtemp(), doc_path, Agent
(KnowledgeAssistant) and agent.chat(...) in a try/finally so
shutil.rmtree(temp_dir) is always executed; locate the temp_dir usage around
tempfile.mkdtemp(), doc_path, Agent(...) and agent.chat(...) and move those
calls into the try block and place shutil.rmtree(temp_dir) in the finally block
to guarantee cleanup even on exceptions.
🧹 Nitpick comments (1)
examples/persistence/knowledge_qdrant.py (1)

24-69: ⚡ Quick win

Move executable demo flow under a __main__ guard.

Line 24 onward runs on import (file I/O + network-dependent chat). Gate this under if __name__ == "__main__": to prevent import-time side effects.

🤖 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 `@examples/persistence/knowledge_qdrant.py` around lines 24 - 69, The demo code
runs on import and should be guarded; wrap the executable flow in an if __name__
== "__main__": block. Move creation of sample_doc, temp_dir, doc_path, writing
the file, Agent instantiation (Agent, knowledge config with qdrant), the
agent.chat call and shutil.rmtree cleanup into that guard so imports don’t
perform file I/O or network calls; ensure variables remain scoped inside the
block and preserve existing behavior/output.
🤖 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.

Outside diff comments:
In `@examples/persistence/knowledge_qdrant.py`:
- Around line 42-67: The temp directory cleanup can be skipped if Agent(...) or
agent.chat(...) raises; wrap the runtime block that uses tempfile.mkdtemp(),
doc_path, Agent (KnowledgeAssistant) and agent.chat(...) in a try/finally so
shutil.rmtree(temp_dir) is always executed; locate the temp_dir usage around
tempfile.mkdtemp(), doc_path, Agent(...) and agent.chat(...) and move those
calls into the try block and place shutil.rmtree(temp_dir) in the finally block
to guarantee cleanup even on exceptions.

---

Nitpick comments:
In `@examples/persistence/knowledge_qdrant.py`:
- Around line 24-69: The demo code runs on import and should be guarded; wrap
the executable flow in an if __name__ == "__main__": block. Move creation of
sample_doc, temp_dir, doc_path, writing the file, Agent instantiation (Agent,
knowledge config with qdrant), the agent.chat call and shutil.rmtree cleanup
into that guard so imports don’t perform file I/O or network calls; ensure
variables remain scoped inside the block and preserve existing behavior/output.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2bfbe39d-c29a-4f8a-8b59-37b7cb1e80da

📥 Commits

Reviewing files that changed from the base of the PR and between e89b50d and 9c334bc.

📒 Files selected for processing (7)
  • examples/persistence/knowledge_qdrant.py
  • examples/python/concepts/self-reflection-optimization-patterns.py
  • examples/python/general/memory_example.py
  • examples/python/memory/gemini-embedding-example.py
  • examples/python/models/deepseek/deepseek-rag-agents.py
  • examples/python/stateful/session-example.py
  • src/praisonai-agents/praisonaiagents/agent/router_agent.py
💤 Files with no reviewable changes (2)
  • examples/python/memory/gemini-embedding-example.py
  • examples/python/general/memory_example.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/praisonai-agents/praisonaiagents/agent/router_agent.py
  • examples/python/concepts/self-reflection-optimization-patterns.py

@greptile-apps

greptile-apps Bot commented Jun 11, 2026

Copy link
Copy Markdown

Greptile encountered an error while reviewing this PR. Please reach out to support@greptile.com for assistance.

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