Skip to content

Add Cybersecurity PoC Agent Notebook #688

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
300 changes: 300 additions & 0 deletions examples/cookbooks/Chile_Government_Services_Assistant.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,300 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "ZH_nR-SvvkDG"
},
"source": [
"# Chile Government Services Assistant - AI Chatbot"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "w8B741JgvpFj"
},
"source": [
"This notebook demonstrates how to use an AI-powered assistant to answer questions about Chilean government services and procedures, using the Firecrawl API and a friendly, step-by-step conversational approach."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "y8jiJYf4FA0m"
},
"source": [
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/DhivyaBharathy-web/PraisonAI/blob/main/examples/cookbooks/Chile_Government_Services_Assistant.ipynb)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "RRw8sPG89KNb"
},
"source": [
"# Install dependencies"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "rW8ltqCICV8o"
},
"outputs": [],
"source": [
"!pip install flask firecrawl praisonaiagents google-genai python-dotenv deep-translator"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "XGjyt-B_EfbM"
},
"source": [
"# Set API Keys"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "qf8B_YltDiIe"
},
"outputs": [],
"source": [
"import os\n",
"\n",
"os.environ['FIRECRAWL_API_KEY'] = \"your api key here\"\n",
"os.environ['OPENAI_API_KEY'] = \"your api key here\""
Comment on lines +69 to +70
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Consider using a more secure method for handling API keys, such as storing them in a dedicated secrets management system or using environment variables in a more robust way that avoids hardcoding them directly in the notebook. This is especially important if the notebook is shared or made public. This is a medium severity issue because it exposes sensitive information.

os.environ['FIRECRAWL_API_KEY'] = os.getenv('FIRECRAWL_API_KEY', 'your api key here')
os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY', 'your api key here')

Comment on lines +69 to +70
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Security risk: Hardcoded API key placeholders.

Similar to the other notebook, hardcoded placeholder API keys create security and usability risks.

Apply the same secure approach:

-os.environ['FIRECRAWL_API_KEY'] = "your api key here"
-os.environ['OPENAI_API_KEY'] = "your api key here"
+from getpass import getpass
+
+if not os.environ.get('FIRECRAWL_API_KEY'):
+    os.environ['FIRECRAWL_API_KEY'] = getpass("Enter your Firecrawl API key: ")
+if not os.environ.get('OPENAI_API_KEY'):
+    os.environ['OPENAI_API_KEY'] = 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.

Suggested change
"os.environ['FIRECRAWL_API_KEY'] = \"your api key here\"\n",
"os.environ['OPENAI_API_KEY'] = \"your api key here\""
from getpass import getpass
if not os.environ.get('FIRECRAWL_API_KEY'):
os.environ['FIRECRAWL_API_KEY'] = getpass("Enter your Firecrawl API key: ")
if not os.environ.get('OPENAI_API_KEY'):
os.environ['OPENAI_API_KEY'] = getpass("Enter your OpenAI API key: ")
🤖 Prompt for AI Agents
In examples/cookbooks/Chile_Government_Services_Assistant.ipynb at lines 69-70,
the API keys are hardcoded as placeholders in the environment variables, which
poses security risks. Remove these hardcoded strings and instead instruct users
to set their API keys securely outside the notebook, such as through environment
variables in their system or a secure secrets manager, and access them
dynamically within the code.

]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ccO0vwvCEqUJ"
},
"source": [
"# Import Libraries & Translator"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "0prDQ5TpDnFu"
},
"outputs": [],
"source": [
"from firecrawl import FirecrawlApp, ScrapeOptions\n",
"from deep_translator import GoogleTranslator\n",
"import re\n",
"\n",
"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"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "WxOlCHMmEuK2"
},
"source": [
"# Firecrawl Tool Class"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "G4RyzJ5mDp0t"
},
"outputs": [],
"source": [
"class FirecrawlTool:\n",
" def __init__(self, api_key, instruction: str, template: str):\n",
" if not api_key:\n",
" raise ValueError(\"Firecrawl API key not provided.\")\n",
" self.app = FirecrawlApp(api_key=api_key)\n",
" self.instruction = instruction\n",
" self.template = template\n",
"\n",
" def search(self, search: str) -> str:\n",
" if not search or len(search) < 5:\n",
" return \"Error: Please provide a valid search query (at least 5 characters).\"\n",
" response_md = \"\"\n",
" try:\n",
" search_result = self.app.search(\n",
" query=self.instruction + search,\n",
" limit=2,\n",
" country=\"cl\",\n",
" lang=\"es\", # Always search in Spanish for best results\n",
" scrape_options=ScrapeOptions(formats=[\"markdown\", \"links\"])\n",
" )\n",
" if search_result and hasattr(search_result, 'data') and search_result.data:\n",
" filtered_results = [\n",
" result for result in search_result.data\n",
" if str(result.get(\"url\", \"\")).startswith(\"https://www.chileatiende.gob.cl/fichas\") and not str(result.get(\"url\", \"\")).endswith(\"pdf\")\n",
" ]\n",
" if filtered_results:\n",
" for num, result in enumerate(filtered_results, start=1):\n",
" response_md += self.template.format(\n",
" result_number=num,\n",
" page_title=str(result.get(\"title\", \"\")),\n",
" page_url=str(result.get(\"url\", \"\")),\n",
" page_content=str(result.get(\"markdown\", \"\"))\n",
" )\n",
" return response_md\n",
" else:\n",
" return None\n",
" else:\n",
" return None\n",
" except Exception as e:\n",
" return f\"Error during search: {e}\""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "MjkjTWn_ExS0"
},
"source": [
"# Firecrawl Prompt Template"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "AfivymU8Dufz"
},
"outputs": [],
"source": [
"FIRECRAWL_INSTRUCTION = \"ChileAtiende: \"\n",
"FIRECRAWL_TEMPLATE = \"\"\"\n",
"# Result {result_number}\n",
"\n",
"## Page Name:\n",
"\"{page_title}\"\n",
"\n",
"## URL:\n",
"{page_url}\n",
"\n",
"## Content:\n",
"{page_content}\n",
"\n",
"\"\"\""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "zK8AA_DlEz9K"
},
"source": [
"# Initialize Firecrawl Tool"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "c3NKK0ZjDwKT"
},
"outputs": [],
"source": [
"firecrawl_tool = FirecrawlTool(\n",
" api_key=os.environ['FIRECRAWL_API_KEY'],\n",
" instruction=FIRECRAWL_INSTRUCTION,\n",
" template=FIRECRAWL_TEMPLATE\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "uzXYIF_gE3XV"
},
"source": [
"# Main Chat Loop"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "TXMgZQNkDx7n",
"outputId": "76303cd1-a576-483f-a22d-9857e5e6d797"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello! I am your ChileAtiende assistant, Tomás. How can I help you today?\n",
"You can ask me, for example: How to renew your ID card, How to apply for the Winter Bonus, etc.\n",
"\n",
"You: exit\n",
"Tomás: It was a pleasure to help you. Goodbye!\n"
]
}
],
"source": [
"print(\"Hello! I am your ChileAtiende assistant, Tomás. How can I help you today?\")\n",
"print(\"You can ask me, for example: How to renew your ID card, How to apply for the Winter Bonus, etc.\")\n",
"\n",
"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.\")"
Comment on lines +264 to +282
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Chat loop lacks comprehensive error handling.

The main chat loop doesn't handle potential exceptions from API calls, which could crash the entire interaction.

Add proper error handling:

 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

-    # 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:
         try:
             english_answer = translate_to_english(spanish_answer)
             print("\nTomás (in English):\n", english_answer)
         except Exception as e:
             print(f"\nTomás: I found information, but couldn't translate it. Here it is in Spanish:\n{spanish_answer}\n(Translation error: {e})")
     else:
         print("\nTomás: Sorry, I couldn't find relevant information. Try rephrasing your question or ask about another service.")
📝 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.

Suggested change
"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.\")"
while True:
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
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:
try:
english_answer = translate_to_english(spanish_answer)
print("\nTomás (in English):\n", english_answer)
except Exception as e:
print(
f"\nTomás: I found information, but couldn't translate it. "
f"Here it is in Spanish:\n{spanish_answer}\n(Translation error: {e})"
)
else:
print(
"\nTomás: Sorry, I couldn't find relevant information. "
"Try rephrasing your question or ask about another service."
)
🤖 Prompt for AI Agents
In examples/cookbooks/Chile_Government_Services_Assistant.ipynb around lines 264
to 282, the main chat loop lacks error handling for API calls like
translate_to_spanish, firecrawl_tool.search, and translate_to_english, risking
crashes. Wrap the entire loop body inside a try-except block to catch exceptions
from these calls, and in the except block, print a user-friendly error message
and continue the loop to maintain interaction stability.

]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Loading
Loading