-
-
Notifications
You must be signed in to change notification settings - Fork 688
Add Real Estate Chatbot Notebook #693
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add Real Estate Chatbot Notebook #693
Conversation
WalkthroughThree new Jupyter notebook examples are introduced: a Chilean government services chatbot using Firecrawl and translation, a cybersecurity PoC validation agent for CVEs, and a real estate chatbot leveraging PraisonAI and OpenAI. Each notebook demonstrates setup, core logic, and interactive workflows tailored to their respective domains. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Notebook
participant AI_Agent
participant External_API
User->>Notebook: Enter query/input
Notebook->>AI_Agent: Pass input (may translate or preprocess)
AI_Agent->>External_API: Fetch/validate/query data (e.g., Firecrawl, OpenAI)
External_API-->>AI_Agent: Return data/response
AI_Agent->>Notebook: Return processed answer
Notebook->>User: Display response (may translate or format)
Suggested labels
Poem
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Summary of Changes
Hello @Dhivya-Bharathy, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request primarily introduces three new Google Colab notebooks, expanding the examples and capabilities of AI agents within the repository. The main addition, as per the PR title, is a Real Estate Chatbot, alongside a Chilean Government Services Assistant and a Cybersecurity PoC Agent, showcasing diverse applications of AI-powered conversational and search tools.
Highlights
- New Real Estate Chatbot Notebook: I've added a new Google Colab notebook (
Praison_AI_Real_Estate_Chatbot.ipynb
) that demonstrates an interactive AI agent for real estate Q&A. This agent, built with PraisonAI, provides advice on buying, selling, or renting property using an OpenAI API key. - New Chile Government Services Assistant Notebook: A new Google Colab notebook (
Chile_Government_Services_Assistant.ipynb
) has been introduced. This notebook features an AI chatbot designed to answer questions about Chilean government services and procedures, utilizing the Firecrawl API and deep-translator for language handling. - New Cybersecurity PoC Agent Notebook: I've also included a new Google Colab notebook (
Pocky_Cybersecurity_PoC_Agent.ipynb
) for an automated CVE PoC (Proof of Concept) search and validation tool. This notebook outlines a lightweight agent for finding, filtering, and fetching real-world PoC exploits.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command>
or @gemini-code-assist <command>
. Below is a summary of the supported commands.
Feature | Command | Description |
---|---|---|
Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/
folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #693 +/- ##
=======================================
Coverage 14.50% 14.50%
=======================================
Files 25 25
Lines 2517 2517
Branches 357 357
=======================================
Hits 365 365
Misses 2136 2136
Partials 16 16
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
The pull request adds three new Google Colab notebooks demonstrating the capabilities of Praison AI agents. The notebooks cover real estate chatbots, cybersecurity PoC search, and a Chile government services assistant. The review identifies a critical security issue related to hardcoding API keys directly in the notebooks, and suggests using environment variables instead.
"os.environ['FIRECRAWL_API_KEY'] = \"your api key here\"\n", | ||
"os.environ['OPENAI_API_KEY'] = \"your api key here\"" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's generally not a good practice to hardcode API keys directly in the code. This can lead to security vulnerabilities if the code is accidentally exposed. Consider using a more secure method for managing API keys, such as environment variables or a dedicated secrets management system. If you are using environment variables, you should validate that they are set before proceeding, and throw an error if not.
os.environ['FIRECRAWL_API_KEY'] = os.getenv('FIRECRAWL_API_KEY', 'your api key here') # Provide a default value or raise an error if not set
os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY', 'your api key here')
"OPENAI_API_KEY = \"Enter your api key here\" # <-- Replace with your key\n", | ||
"os.environ[\"OPENAI_API_KEY\"] = OPENAI_API_KEY" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's generally not a good practice to hardcode API keys directly in the code. This can lead to security vulnerabilities if the code is accidentally exposed. Consider using a more secure method for managing API keys, such as environment variables or a dedicated secrets management system. If you are using environment variables, you should validate that they are set before proceeding, and throw an error if not.
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY', "Enter your api key here") # <-- Replace with your key or set as environment variable
os.environ["OPENAI_API_KEY"] = OPENAI_API_KEY
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 8
🧹 Nitpick comments (5)
examples/cookbooks/Pocky_Cybersecurity_PoC_Agent.ipynb (1)
37-37
: Update Colab badge URL to reference the main repository.The Colab badge URL references a user's fork (
DhivyaBharathy-web
) instead of the main repository. This should point to the canonical repository.-"[](https://colab.research.google.com/github/DhivyaBharathy-web/PraisonAI/blob/main/examples/cookbooks/Pocky_Cybersecurity_PoC_Agent.ipynb)\n" +"[](https://colab.research.google.com/github/MervinPraison/PraisonAI/blob/main/examples/cookbooks/Pocky_Cybersecurity_PoC_Agent.ipynb)\n"examples/cookbooks/Chile_Government_Services_Assistant.ipynb (2)
27-27
: Update Colab badge URL to reference the main repository.The Colab badge URL references a user's fork instead of the main repository.
-"[](https://colab.research.google.com/github/DhivyaBharathy-web/PraisonAI/blob/main/examples/cookbooks/Chile_Government_Services_Assistant.ipynb)\n" +"[](https://colab.research.google.com/github/MervinPraison/PraisonAI/blob/main/examples/cookbooks/Chile_Government_Services_Assistant.ipynb)\n"
150-152
: Make URL filtering more robust and configurable.The URL filtering logic is hardcoded and could be more flexible.
+ # Define allowed URL patterns + allowed_patterns = [ + "https://www.chileatiende.gob.cl/fichas", + "https://www.chileatiende.gob.cl/tramites" + ] + excluded_extensions = [".pdf", ".doc", ".docx"] + filtered_results = [ result for result in search_result.data - if str(result.get("url", "")).startswith("https://www.chileatiende.gob.cl/fichas") and not str(result.get("url", "")).endswith("pdf") + if any(str(result.get("url", "")).startswith(pattern) for pattern in allowed_patterns) + and not any(str(result.get("url", "")).endswith(ext) for ext in excluded_extensions) ]examples/cookbooks/Praison_AI_Real_Estate_Chatbot.ipynb (2)
27-27
: Update Colab badge URL to reference the main repository.The Colab badge URL references a user's fork instead of the main repository.
-"[](https://colab.research.google.com/github/DhivyaBharathy-web/PraisonAI/blob/main/examples/cookbooks/Praison_AI_Real_Estate_Chatbot.ipynb)\n" +"[](https://colab.research.google.com/github/MervinPraison/PraisonAI/blob/main/examples/cookbooks/Praison_AI_Real_Estate_Chatbot.ipynb)\n"
93-102
: Enhance agent configuration with more comprehensive instructions.The agent configuration could be more detailed to provide better real estate guidance.
praison_agent = Agent( name="Praison Real Estate Chatbot", role="Answer real estate questions and provide helpful advice.", instructions=[ "You are a helpful real estate assistant.", - "Answer user questions about buying, selling, or renting property.", - "Provide clear, concise, and friendly advice." + "Answer user questions about buying, selling, or renting property.", + "Provide clear, concise, and friendly advice.", + "Consider factors like location, budget, market conditions, and legal requirements.", + "Suggest when users should consult with real estate professionals.", + "Avoid giving specific financial or legal advice.", + "Be encouraging and supportive for first-time buyers or sellers." ], markdown=True )
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
examples/cookbooks/Chile_Government_Services_Assistant.ipynb
(1 hunks)examples/cookbooks/Pocky_Cybersecurity_PoC_Agent.ipynb
(1 hunks)examples/cookbooks/Praison_AI_Real_Estate_Chatbot.ipynb
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: Run tests and collect coverage
- GitHub Check: test-core (3.11)
- GitHub Check: quick-test
"os.environ[\"EXA_API_KEY\"] = \"your api key\"\n", | ||
"os.environ[\"OPENAI_API_KEY\"] = \"your api key\"\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve API key setup with user prompts.
Hardcoded placeholder API keys could lead to confusion or security issues. Consider using getpass
for secure input or clear instructions for users.
-"os.environ[\"EXA_API_KEY\"] = \"your api key\"\n",
-"os.environ[\"OPENAI_API_KEY\"] = \"your api key\"\n",
+"import getpass\n",
+"os.environ[\"EXA_API_KEY\"] = getpass.getpass(\"Enter your EXA API key: \")\n",
+"os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"Enter your OpenAI API key: \")\n",
📝 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.
"os.environ[\"EXA_API_KEY\"] = \"your api key\"\n", | |
"os.environ[\"OPENAI_API_KEY\"] = \"your api key\"\n", | |
import os | |
from exa import Client | |
from exa.openapi import OpenAICompletionModel | |
# you can also set up your API key via REPL or env var | |
import getpass | |
os.environ["EXA_API_KEY"] = getpass.getpass("Enter your EXA API key: ") | |
os.environ["OPENAI_API_KEY"] = getpass.getpass("Enter your OpenAI API key: ") | |
# initialize exa client | |
client = Client() |
🤖 Prompt for AI Agents
In examples/cookbooks/Pocky_Cybersecurity_PoC_Agent.ipynb around lines 78 to 79,
the API keys are hardcoded as placeholders which can cause confusion or security
risks. Replace these hardcoded assignments with code that prompts the user to
securely input their API keys using the getpass module or provide clear
instructions for manual input. This ensures keys are not exposed in the code and
improves security and usability.
"class ValidationAgent:\n", | ||
" def __init__(self, input_json):\n", | ||
" self.input_json = input_json\n", | ||
" def run(self):\n", | ||
" # Dummy validation logic for notebook demo\n", | ||
" data = json.loads(self.input_json)\n", | ||
" return True if \"attack_intent\" in data and \"poc_sample\" in data else False\n", | ||
"\n", | ||
"class AttackIntentAgent:\n", | ||
" def __init__(self, description):\n", | ||
" self.description = description\n", | ||
" def run(self):\n", | ||
" # Dummy intent extraction for notebook demo\n", | ||
" return f\"Intent for: {self.description[:50]}...\"" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance dummy agent implementations with more realistic logic.
The current dummy implementations are too simplistic and don't demonstrate the actual validation concepts described in the notebook.
class ValidationAgent:
def __init__(self, input_json):
self.input_json = input_json
def run(self):
- # Dummy validation logic for notebook demo
- data = json.loads(self.input_json)
- return True if "attack_intent" in data and "poc_sample" in data else False
+ # Enhanced validation logic for notebook demo
+ try:
+ data = json.loads(self.input_json)
+ if not ("attack_intent" in data and "poc_sample" in data):
+ return {"valid": False, "reasoning": "Missing required fields"}
+ # Simple heuristic validation
+ intent = data["attack_intent"].lower()
+ poc = data["poc_sample"].lower()
+ # Check for common attack patterns
+ has_relevant_keywords = any(keyword in poc for keyword in ["exploit", "payload", "vulnerability"])
+ return {"valid": has_relevant_keywords, "reasoning": "Basic keyword validation completed"}
+ except Exception as e:
+ return {"valid": False, "reasoning": f"Validation error: {str(e)}"}
📝 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 ValidationAgent:\n", | |
" def __init__(self, input_json):\n", | |
" self.input_json = input_json\n", | |
" def run(self):\n", | |
" # Dummy validation logic for notebook demo\n", | |
" data = json.loads(self.input_json)\n", | |
" return True if \"attack_intent\" in data and \"poc_sample\" in data else False\n", | |
"\n", | |
"class AttackIntentAgent:\n", | |
" def __init__(self, description):\n", | |
" self.description = description\n", | |
" def run(self):\n", | |
" # Dummy intent extraction for notebook demo\n", | |
" return f\"Intent for: {self.description[:50]}...\"" | |
class ValidationAgent: | |
def __init__(self, input_json): | |
self.input_json = input_json | |
def run(self): | |
# Enhanced validation logic for notebook demo | |
try: | |
data = json.loads(self.input_json) | |
if not ("attack_intent" in data and "poc_sample" in data): | |
return {"valid": False, "reasoning": "Missing required fields"} | |
# Simple heuristic validation | |
intent = data["attack_intent"].lower() | |
poc = data["poc_sample"].lower() | |
# Check for common attack patterns | |
has_relevant_keywords = any( | |
keyword in poc for keyword in ["exploit", "payload", "vulnerability"] | |
) | |
return { | |
"valid": has_relevant_keywords, | |
"reasoning": "Basic keyword validation completed" | |
} | |
except Exception as e: | |
return {"valid": False, "reasoning": f"Validation error: {str(e)}"} | |
class AttackIntentAgent: | |
def __init__(self, description): | |
self.description = description | |
def run(self): | |
# Dummy intent extraction for notebook demo | |
return f"Intent for: {self.description[:50]}..." |
🤖 Prompt for AI Agents
In examples/cookbooks/Pocky_Cybersecurity_PoC_Agent.ipynb around lines 105 to
118, the dummy agent classes ValidationAgent and AttackIntentAgent have overly
simplistic logic that does not reflect realistic validation or intent
extraction. Enhance ValidationAgent to perform more meaningful checks on the
input JSON structure and content, such as verifying required fields and data
types. Improve AttackIntentAgent to simulate extracting intent by analyzing
keywords or patterns in the description rather than returning a fixed string.
This will better demonstrate the validation concepts described in the notebook.
"def run_pocky_for_cve(cve_id):\n", | ||
" # Example: Simulate fetching a description and PoC (replace with real logic)\n", | ||
" description = f\"Description for {cve_id} (replace with real Exa/OpenAI search)\"\n", | ||
" poc_sample = f\"PoC code for {cve_id} (replace with real PoC search)\"\n", | ||
"\n", | ||
" # Stage 2: Attack Intent\n", | ||
" intent = AttackIntentAgent(description).run()\n", | ||
" print(f\"Attack Intent: {intent}\")\n", | ||
"\n", | ||
" # Stage 3: Validation\n", | ||
" validation_input = json.dumps({\"attack_intent\": intent, \"poc_sample\": poc_sample}, indent=2)\n", | ||
" valid = ValidationAgent(validation_input).run()\n", | ||
" print(f\"Validation Result: {valid}\")\n", | ||
" if valid:\n", | ||
" print(f\"PoC for {cve_id} is valid and ready to use.\")\n", | ||
" else:\n", | ||
" print(f\"PoC for {cve_id} failed validation.\")" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add error handling and input validation to the main function.
The function lacks error handling and input validation, which could lead to unexpected failures.
def run_pocky_for_cve(cve_id):
+ if not cve_id or not isinstance(cve_id, str) or len(cve_id.strip()) < 5:
+ print("Error: Please provide a valid CVE ID")
+ return
+
+ try:
# Example: Simulate fetching a description and PoC (replace with real logic)
description = f"Description for {cve_id} (replace with real Exa/OpenAI search)"
poc_sample = f"PoC code for {cve_id} (replace with real PoC search)"
# Stage 2: Attack Intent
intent = AttackIntentAgent(description).run()
print(f"Attack Intent: {intent}")
# Stage 3: Validation
validation_input = json.dumps({"attack_intent": intent, "poc_sample": poc_sample}, indent=2)
valid = ValidationAgent(validation_input).run()
print(f"Validation Result: {valid}")
- if valid:
+ if isinstance(valid, dict) and valid.get("valid", False):
print(f"PoC for {cve_id} is valid and ready to use.")
else:
- print(f"PoC for {cve_id} failed validation.")
+ reasoning = valid.get("reasoning", "Unknown error") if isinstance(valid, dict) else "Validation failed"
+ print(f"PoC for {cve_id} failed validation: {reasoning}")
+ except Exception as e:
+ print(f"Error processing CVE {cve_id}: {str(e)}")
📝 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.
"def run_pocky_for_cve(cve_id):\n", | |
" # Example: Simulate fetching a description and PoC (replace with real logic)\n", | |
" description = f\"Description for {cve_id} (replace with real Exa/OpenAI search)\"\n", | |
" poc_sample = f\"PoC code for {cve_id} (replace with real PoC search)\"\n", | |
"\n", | |
" # Stage 2: Attack Intent\n", | |
" intent = AttackIntentAgent(description).run()\n", | |
" print(f\"Attack Intent: {intent}\")\n", | |
"\n", | |
" # Stage 3: Validation\n", | |
" validation_input = json.dumps({\"attack_intent\": intent, \"poc_sample\": poc_sample}, indent=2)\n", | |
" valid = ValidationAgent(validation_input).run()\n", | |
" print(f\"Validation Result: {valid}\")\n", | |
" if valid:\n", | |
" print(f\"PoC for {cve_id} is valid and ready to use.\")\n", | |
" else:\n", | |
" print(f\"PoC for {cve_id} failed validation.\")" | |
def run_pocky_for_cve(cve_id): | |
# Input validation | |
if not cve_id or not isinstance(cve_id, str) or len(cve_id.strip()) < 5: | |
print("Error: Please provide a valid CVE ID") | |
return | |
try: | |
# Example: Simulate fetching a description and PoC (replace with real logic) | |
description = f"Description for {cve_id} (replace with real Exa/OpenAI search)" | |
poc_sample = f"PoC code for {cve_id} (replace with real PoC search)" | |
# Stage 2: Attack Intent | |
intent = AttackIntentAgent(description).run() | |
print(f"Attack Intent: {intent}") | |
# Stage 3: Validation | |
validation_input = json.dumps( | |
{"attack_intent": intent, "poc_sample": poc_sample}, | |
indent=2 | |
) | |
valid = ValidationAgent(validation_input).run() | |
print(f"Validation Result: {valid}") | |
if isinstance(valid, dict) and valid.get("valid", False): | |
print(f"PoC for {cve_id} is valid and ready to use.") | |
else: | |
reasoning = ( | |
valid.get("reasoning", "Unknown error") | |
if isinstance(valid, dict) | |
else "Validation failed" | |
) | |
print(f"PoC for {cve_id} failed validation: {reasoning}") | |
except Exception as e: | |
print(f"Error processing CVE {cve_id}: {e}") |
🤖 Prompt for AI Agents
In examples/cookbooks/Pocky_Cybersecurity_PoC_Agent.ipynb around lines 174 to
190, the function run_pocky_for_cve lacks error handling and input validation.
Add input validation to check that cve_id is a non-empty string before
proceeding. Wrap the main logic in a try-except block to catch and handle any
exceptions, logging or printing an error message to avoid unexpected failures
and improve robustness.
"while True:\n", | ||
" user_input = input(\"\\nYou: \")\n", | ||
" if user_input.lower() in [\"exit\", \"quit\"]:\n", | ||
" print(\"Tomás: It was a pleasure to help you. Goodbye!\")\n", | ||
" break\n", | ||
"\n", | ||
" # Translate English input to Spanish for Firecrawl\n", | ||
" spanish_query = translate_to_spanish(user_input)\n", | ||
" spanish_answer = firecrawl_tool.search(spanish_query)\n", | ||
"\n", | ||
" # Only translate if we got a real answer\n", | ||
" if spanish_answer and isinstance(spanish_answer, str) and spanish_answer.strip() and \"Error\" not in spanish_answer:\n", | ||
" try:\n", | ||
" english_answer = translate_to_english(spanish_answer)\n", | ||
" print(\"\\nTomás (in English):\\n\", english_answer)\n", | ||
" except Exception as e:\n", | ||
" print(f\"\\nTomás: I found information, but couldn't translate it. Here it is in Spanish:\\n{spanish_answer}\\n(Translation error: {e})\")\n", | ||
" else:\n", | ||
" print(\"\\nTomás: Sorry, I couldn't find relevant information. Try rephrasing your question or ask about another service.\")" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add comprehensive error handling to the chat loop.
The chat loop needs better error handling for translation failures and API errors.
while True:
- user_input = input("\nYou: ")
+ try:
+ user_input = input("\nYou: ")
+ except (KeyboardInterrupt, EOFError):
+ print("\nTomás: It was a pleasure to help you. Goodbye!")
+ break
+
if user_input.lower() in ["exit", "quit"]:
print("Tomás: It was a pleasure to help you. Goodbye!")
break
+
+ if not user_input.strip():
+ print("\nTomás: Please ask me a question about Chilean government services.")
+ continue
- # Translate English input to Spanish for Firecrawl
- spanish_query = translate_to_spanish(user_input)
- spanish_answer = firecrawl_tool.search(spanish_query)
+ try:
+ # Translate English input to Spanish for Firecrawl
+ spanish_query = translate_to_spanish(user_input)
+ spanish_answer = firecrawl_tool.search(spanish_query)
+ except Exception as e:
+ print(f"\nTomás: Sorry, I encountered an error while searching: {e}")
+ continue
# Only translate if we got a real answer
if spanish_answer and isinstance(spanish_answer, str) and spanish_answer.strip() and "Error" not in spanish_answer:
🤖 Prompt for AI Agents
In examples/cookbooks/Chile_Government_Services_Assistant.ipynb around lines 264
to 282, the chat loop lacks comprehensive error handling for translation
failures and API errors. Wrap the entire user input processing, including
translation and Firecrawl search calls, in a try-except block to catch and
handle any exceptions gracefully. Provide user-friendly error messages when
exceptions occur, ensuring the loop continues running without crashing.
"os.environ['FIRECRAWL_API_KEY'] = \"your api key here\"\n", | ||
"os.environ['OPENAI_API_KEY'] = \"your api key here\"" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve API key setup with secure input methods.
Hardcoded placeholder API keys should be replaced with secure input methods.
-"os.environ['FIRECRAWL_API_KEY'] = \"your api key here\"\n",
-"os.environ['OPENAI_API_KEY'] = \"your api key here\""
+"import getpass\n",
+"os.environ['FIRECRAWL_API_KEY'] = getpass.getpass(\"Enter your Firecrawl API key: \")\n",
+"os.environ['OPENAI_API_KEY'] = getpass.getpass(\"Enter your OpenAI API key: \")"
📝 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.
"os.environ['FIRECRAWL_API_KEY'] = \"your api key here\"\n", | |
"os.environ['OPENAI_API_KEY'] = \"your api key here\"" | |
"import getpass\n", | |
"os.environ['FIRECRAWL_API_KEY'] = getpass.getpass(\"Enter your Firecrawl API key: \")\n", | |
"os.environ['OPENAI_API_KEY'] = getpass.getpass(\"Enter your OpenAI API key: \")" |
🤖 Prompt for AI Agents
In examples/cookbooks/Chile_Government_Services_Assistant.ipynb around lines 69
to 70, replace the hardcoded placeholder API key assignments with a secure input
method such as using getpass or environment variable prompts to securely input
the API keys at runtime instead of embedding them directly in the code.
"def translate_to_spanish(text):\n", | ||
" try:\n", | ||
" return GoogleTranslator(source='auto', target='es').translate(text)\n", | ||
" except Exception as e:\n", | ||
" print(\"Translation to Spanish failed:\", e)\n", | ||
" return text\n", | ||
"\n", | ||
"def translate_to_english(text):\n", | ||
" try:\n", | ||
" # Remove Markdown images and None values before translation\n", | ||
" text = str(text).replace(\"None\", \"\")\n", | ||
" text = re.sub(r'!\\[.*?\\]\\(.*?\\)', '', text)\n", | ||
" return GoogleTranslator(source='auto', target='en').translate(text)\n", | ||
" except Exception as e:\n", | ||
" print(\"Translation to English failed:\", e)\n", | ||
" return text" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance translation functions with better error handling.
The translation functions need improved handling of edge cases and better error recovery.
def translate_to_spanish(text):
+ if not text or not text.strip():
+ return text
try:
return GoogleTranslator(source='auto', target='es').translate(text)
except Exception as e:
print("Translation to Spanish failed:", e)
return text
def translate_to_english(text):
+ if not text or not str(text).strip():
+ return text
try:
# Remove Markdown images and None values before translation
text = str(text).replace("None", "")
text = re.sub(r'!\[.*?\]\(.*?\)', '', text)
+ if not text.strip():
+ return ""
return GoogleTranslator(source='auto', target='en').translate(text)
except Exception as e:
print("Translation to English failed:", e)
return text
📝 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.
"def translate_to_spanish(text):\n", | |
" try:\n", | |
" return GoogleTranslator(source='auto', target='es').translate(text)\n", | |
" except Exception as e:\n", | |
" print(\"Translation to Spanish failed:\", e)\n", | |
" return text\n", | |
"\n", | |
"def translate_to_english(text):\n", | |
" try:\n", | |
" # Remove Markdown images and None values before translation\n", | |
" text = str(text).replace(\"None\", \"\")\n", | |
" text = re.sub(r'!\\[.*?\\]\\(.*?\\)', '', text)\n", | |
" return GoogleTranslator(source='auto', target='en').translate(text)\n", | |
" except Exception as e:\n", | |
" print(\"Translation to English failed:\", e)\n", | |
" return text" | |
def translate_to_spanish(text): | |
if not text or not text.strip(): | |
return text | |
try: | |
return GoogleTranslator(source='auto', target='es').translate(text) | |
except Exception as e: | |
print("Translation to Spanish failed:", e) | |
return text | |
def translate_to_english(text): | |
if not text or not str(text).strip(): | |
return text | |
try: | |
# Remove Markdown images and None values before translation | |
text = str(text).replace("None", "") | |
text = re.sub(r'!\[.*?\]\(.*?\)', '', text) | |
if not text.strip(): | |
return "" | |
return GoogleTranslator(source='auto', target='en').translate(text) | |
except Exception as e: | |
print("Translation to English failed:", e) | |
return text |
🤖 Prompt for AI Agents
In examples/cookbooks/Chile_Government_Services_Assistant.ipynb around lines 94
to 109, the translation functions lack robust error handling for edge cases.
Enhance these functions by adding checks for empty or null input before
attempting translation, and improve exception handling to log errors more
informatively without stopping execution. Also, ensure any preprocessing steps
like removing Markdown images handle unexpected input gracefully to avoid
runtime errors.
"import os\n", | ||
"\n", | ||
"# Enter your OpenAI API key here\n", | ||
"OPENAI_API_KEY = \"Enter your api key here\" # <-- Replace with your key\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve API key setup with secure input method.
Hardcoded placeholder API key should be replaced with secure input.
-"OPENAI_API_KEY = \"Enter your api key here\" # <-- Replace with your key\n",
+"import getpass\n",
+"OPENAI_API_KEY = getpass.getpass(\"Enter your OpenAI API key: \")\n",
📝 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.
"OPENAI_API_KEY = \"Enter your api key here\" # <-- Replace with your key\n", | |
"import getpass\n", | |
"OPENAI_API_KEY = getpass.getpass(\"Enter your OpenAI API key: \")\n", |
🤖 Prompt for AI Agents
In examples/cookbooks/Praison_AI_Real_Estate_Chatbot.ipynb at line 70, replace
the hardcoded placeholder API key string with a secure input method such as
using getpass or environment variables to prompt the user for the API key at
runtime without exposing it in the code. This improves security by preventing
the API key from being hardcoded and visible in the notebook.
"def ask_agent(question):\n", | ||
" # Use the .chat() method for the public praisonaiagents package\n", | ||
" response = praison_agent.chat(question)\n", | ||
" display(Markdown(f\"**Praison AI:** {response}\"))\n", | ||
"\n", | ||
"question = widgets.Text(\n", | ||
" value='',\n", | ||
" placeholder='Type your real estate question here...',\n", | ||
" description='You:',\n", | ||
" disabled=False\n", | ||
")\n", | ||
"button = widgets.Button(description=\"Ask Praison AI\")\n", | ||
"\n", | ||
"def on_button_clicked(b):\n", | ||
" ask_agent(question.value)\n", | ||
"\n", | ||
"button.on_click(on_button_clicked)\n", | ||
"display(question, button)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add error handling and input validation to the chat interface.
The chat function lacks error handling and input validation, which could lead to poor user experience.
def ask_agent(question):
- # Use the .chat() method for the public praisonaiagents package
- response = praison_agent.chat(question)
- display(Markdown(f"**Praison AI:** {response}"))
+ if not question or not question.strip():
+ display(Markdown("**Praison AI:** Please ask me a real estate question."))
+ return
+
+ try:
+ # Use the .chat() method for the public praisonaiagents package
+ response = praison_agent.chat(question.strip())
+ if response:
+ display(Markdown(f"**Praison AI:** {response}"))
+ else:
+ display(Markdown("**Praison AI:** I'm sorry, I couldn't generate a response. Please try again."))
+ except Exception as e:
+ display(Markdown(f"**Praison AI:** I encountered an error: {str(e)}. Please try again."))
question = widgets.Text(
value='',
placeholder='Type your real estate question here...',
description='You:',
- disabled=False
+ disabled=False,
+ layout=widgets.Layout(width='500px')
)
def on_button_clicked(b):
- ask_agent(question.value)
+ if question.value:
+ ask_agent(question.value)
+ question.value = '' # Clear input after submission
📝 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.
"def ask_agent(question):\n", | |
" # Use the .chat() method for the public praisonaiagents package\n", | |
" response = praison_agent.chat(question)\n", | |
" display(Markdown(f\"**Praison AI:** {response}\"))\n", | |
"\n", | |
"question = widgets.Text(\n", | |
" value='',\n", | |
" placeholder='Type your real estate question here...',\n", | |
" description='You:',\n", | |
" disabled=False\n", | |
")\n", | |
"button = widgets.Button(description=\"Ask Praison AI\")\n", | |
"\n", | |
"def on_button_clicked(b):\n", | |
" ask_agent(question.value)\n", | |
"\n", | |
"button.on_click(on_button_clicked)\n", | |
"display(question, button)" | |
def ask_agent(question): | |
if not question or not question.strip(): | |
display(Markdown("**Praison AI:** Please ask me a real estate question.")) | |
return | |
try: | |
# Use the .chat() method for the public praisonaiagents package | |
response = praison_agent.chat(question.strip()) | |
if response: | |
display(Markdown(f"**Praison AI:** {response}")) | |
else: | |
display(Markdown("**Praison AI:** I'm sorry, I couldn't generate a response. Please try again.")) | |
except Exception as e: | |
display(Markdown(f"**Praison AI:** I encountered an error: {str(e)}. Please try again.")) | |
question = widgets.Text( | |
value='', | |
placeholder='Type your real estate question here...', | |
description='You:', | |
disabled=False, | |
layout=widgets.Layout(width='500px') | |
) | |
button = widgets.Button(description="Ask Praison AI") | |
def on_button_clicked(b): | |
if question.value: | |
ask_agent(question.value) | |
question.value = '' # Clear input after submission | |
button.on_click(on_button_clicked) | |
display(question, button) |
🤖 Prompt for AI Agents
In examples/cookbooks/Praison_AI_Real_Estate_Chatbot.ipynb around lines 446 to
463, the ask_agent function and chat interface lack error handling and input
validation. Add a check to ensure the question input is not empty before calling
praison_agent.chat. Wrap the chat call in a try-except block to catch and
display any errors gracefully to the user, improving robustness and user
experience.
Summary by CodeRabbit