mirror of
https://github.com/MervinPraison/PraisonAI.git
synced 2026-11-07 17:33:33 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98874da689 | ||
|
|
6f019de05c | ||
|
|
a03d288e01 | ||
|
|
03c23021ab | ||
|
|
0178ec807e | ||
|
|
9757e3dea7 |
No files matched your search
+1
-1
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
|
||||
# Install Python packages (using latest versions)
|
||||
RUN pip install --no-cache-dir \
|
||||
flask \
|
||||
"praisonai>=2.2.38" \
|
||||
"praisonai>=2.2.39" \
|
||||
"praisonai[api]" \
|
||||
gunicorn \
|
||||
markdown
|
||||
|
||||
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
|
||||
# Install Python packages (using latest versions)
|
||||
RUN pip install --no-cache-dir \
|
||||
praisonai_tools \
|
||||
"praisonai>=2.2.38" \
|
||||
"praisonai>=2.2.39" \
|
||||
"praisonai[chat]" \
|
||||
"embedchain[github,youtube]"
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ RUN mkdir -p /root/.praison
|
||||
# Install Python packages (using latest versions)
|
||||
RUN pip install --no-cache-dir \
|
||||
praisonai_tools \
|
||||
"praisonai>=2.2.38" \
|
||||
"praisonai>=2.2.39" \
|
||||
"praisonai[ui]" \
|
||||
"praisonai[chat]" \
|
||||
"praisonai[realtime]" \
|
||||
|
||||
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
|
||||
# Install Python packages (using latest versions)
|
||||
RUN pip install --no-cache-dir \
|
||||
praisonai_tools \
|
||||
"praisonai>=2.2.38" \
|
||||
"praisonai>=2.2.39" \
|
||||
"praisonai[ui]" \
|
||||
"praisonai[crewai]"
|
||||
|
||||
|
||||
+2
-2
@@ -121,7 +121,7 @@ healthcheck:
|
||||
## 📦 Package Versions
|
||||
|
||||
All Docker images use consistent, up-to-date versions:
|
||||
- PraisonAI: `>=2.2.38`
|
||||
- PraisonAI: `>=2.2.39`
|
||||
- PraisonAI Agents: `>=0.0.92`
|
||||
- Python: `3.11-slim`
|
||||
|
||||
@@ -218,7 +218,7 @@ docker-compose up -d
|
||||
### Version Pinning
|
||||
To use specific versions, update the Dockerfile:
|
||||
```dockerfile
|
||||
RUN pip install "praisonai==2.2.38" "praisonaiagents==0.0.92"
|
||||
RUN pip install "praisonai==2.2.39" "praisonaiagents==0.0.92"
|
||||
```
|
||||
|
||||
## 🌐 Production Deployment
|
||||
|
||||
@@ -0,0 +1,401 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "W5cYeCT1jIBS",
|
||||
"metadata": {
|
||||
"id": "W5cYeCT1jIBS"
|
||||
},
|
||||
"source": [
|
||||
"# 🗣️ Talk2Find: Voice-Driven Knowledge Agent (with Synthetic Audio)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "uTxgPYvKjJty",
|
||||
"metadata": {
|
||||
"id": "uTxgPYvKjJty"
|
||||
},
|
||||
"source": [
|
||||
"This notebook demonstrates a voice-driven knowledge agent using PraisonAI Agents. It generates a valid WAV file from text using gTTS and pydub, transcribes the audio with SpeechRecognition, and then uses PraisonAI Agents to answer the spoken question. This workflow is robust, reproducible, and does not require manual audio uploads."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "CJdIonVMjgU7",
|
||||
"metadata": {
|
||||
"id": "CJdIonVMjgU7"
|
||||
},
|
||||
"source": [
|
||||
"[](https://colab.research.google.com/github/Dhivya-Bharathy/PraisonAI/blob/main/examples/cookbooks/talk2find_voice_agent_demo.ipynb)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "wjVE-KWwjQxP",
|
||||
"metadata": {
|
||||
"id": "wjVE-KWwjQxP"
|
||||
},
|
||||
"source": [
|
||||
"# Dependencies"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "RFG1v766idiL",
|
||||
"metadata": {
|
||||
"id": "RFG1v766idiL"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install praisonaiagents openai SpeechRecognition pydub gTTS --quiet"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "0IYiVLgsjTJf",
|
||||
"metadata": {
|
||||
"id": "0IYiVLgsjTJf"
|
||||
},
|
||||
"source": [
|
||||
"# Set API Key"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "3AVzmY5FilJ9",
|
||||
"metadata": {
|
||||
"id": "3AVzmY5FilJ9"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"os.environ[\"OPENAI_API_KEY\"] = \"Enter your api key\" # <-- Replace with your actual OpenAI API key"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "SfHMkOTHjVMa",
|
||||
"metadata": {
|
||||
"id": "SfHMkOTHjVMa"
|
||||
},
|
||||
"source": [
|
||||
"# Tools"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "Hj28HfsNip9V",
|
||||
"metadata": {
|
||||
"id": "Hj28HfsNip9V"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from praisonaiagents import Agent\n",
|
||||
"import speech_recognition as sr\n",
|
||||
"from gtts import gTTS\n",
|
||||
"from pydub import AudioSegment\n",
|
||||
"from IPython.display import Audio"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8BIPQ6fzjXu4",
|
||||
"metadata": {
|
||||
"id": "8BIPQ6fzjXu4"
|
||||
},
|
||||
"source": [
|
||||
"# Generate a Valid WAV File from Text"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "rdcn-AiYisHb",
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 92
|
||||
},
|
||||
"id": "rdcn-AiYisHb",
|
||||
"outputId": "2daf8cb4-93f6-4e02-ab2b-3e449d7deee0"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"✅ WAV file 'question.wav' has been created.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"\n",
|
||||
" <audio controls=\"controls\" >\n",
|
||||
" <source src=\"data:audio/x-wav;base64,UklGRiRfAQBXQVZFZm10IBAAAAABAAEAwF0AAIC7AAACABAAZGF0YQBfAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAEAAAAAAAEAAQAAAAAAAAABAAEAAQAAAAEAAQABAAAA//8AAP//AAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAABAAAA//8BAP////8AAAAAAAAAAAAA//8AAAAAAAAAAAAAAAD//wEAAAAAAP//AAAAAAAA//8AAAAA//8AAP//AAAAAAAAAAAAAAAA/////wAAAAAAAAAA//8AAAAAAQABAAAAAAAAAAEAAQAAAAEAAQABAP//AQAAAP//AQAAAAEAAQAAAAAAAQABAAEAAAACAAIAAQABAAEAAQABAAEAAQABAAEAAgABAAEAAAABAAEAAQABAAAAAAD/////AAD//wAAAAAAAP///v8AAAAA/////wEA//////////8AAAAAAAD//wAA/v8AAAAA//8AAAAAAAAAAAAAAAAAAP//AQAAAAAAAAAAAAAAAAAAAAgABwD+/wEAAQD7//7/AgACAAEAAgAEAAQAAwABAAEAAAABAAEAAQD//wAA/v/8//3//f/+//7//v/9//3//v///////f/9/wAA/////wAAAQAAAP7////9/wEAAAD///3//P/8//7////+/wEA///+//7//v/+//z//v8AAP///v/9//z//v/8//r//f/9//v/+v/5//v/+//7//z/+v/7//r//P/6//n/+//6//z/+f/4//n/+v/8//3///////z/+///////AAAAAAIA///+//////8CAP7///8BAAMAAAD9//7/AQABAAEA///8/////P8AAP3/+//+//v//P/9//z/9f/4//3/+f/9//r/9f/5//j/9f/5//3/+P/7//b/9//2/Line truncated
|
||||
" Your browser does not support the audio element.\n",
|
||||
" </audio>\n",
|
||||
" "
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.lib.display.Audio object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Step 1: Define the text you want to convert to speech\n",
|
||||
"text = \"What time is the meeting?\"\n",
|
||||
"\n",
|
||||
"# Step 2: Generate speech from text and save as MP3\n",
|
||||
"tts = gTTS(text=text, lang='en')\n",
|
||||
"tts.save(\"question.mp3\")\n",
|
||||
"\n",
|
||||
"# Step 3: Convert MP3 to WAV using pydub\n",
|
||||
"sound = AudioSegment.from_mp3(\"question.mp3\")\n",
|
||||
"sound.export(\"question.wav\", format=\"wav\")\n",
|
||||
"\n",
|
||||
"print(\"✅ WAV file 'question.wav' has been created.\")\n",
|
||||
"\n",
|
||||
"# Optional: Play the audio (works in Jupyter/Colab)\n",
|
||||
"try:\n",
|
||||
" display(Audio(\"question.wav\"))\n",
|
||||
"except:\n",
|
||||
" print(\"You can now play 'question.wav' manually.\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "AuA3Cj7mjamh",
|
||||
"metadata": {
|
||||
"id": "AuA3Cj7mjamh"
|
||||
},
|
||||
"source": [
|
||||
"# YAML Prompt (Role, Goal, Instructions)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "Au5fg-6UiwDP",
|
||||
"metadata": {
|
||||
"id": "Au5fg-6UiwDP"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"ROLE = \"Voice-driven knowledge assistant. Expert in understanding spoken queries and providing accurate, concise answers.\"\n",
|
||||
"GOAL = \"Transcribe the user's voice input and answer their question or find relevant information.\"\n",
|
||||
"INSTRUCTIONS = \"Given a transcribed user question, provide a clear, factual, and helpful answer. If the question is unclear, ask for clarification.\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "yz4P9xvpjc4b",
|
||||
"metadata": {
|
||||
"id": "yz4P9xvpjc4b"
|
||||
},
|
||||
"source": [
|
||||
"# Main (Transcription + Agent)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "ubYuWOYCiyCx",
|
||||
"metadata": {
|
||||
"id": "ubYuWOYCiyCx"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def transcribe_audio(audio_file):\n",
|
||||
" recognizer = sr.Recognizer()\n",
|
||||
" with sr.AudioFile(audio_file) as source:\n",
|
||||
" audio = recognizer.record(source)\n",
|
||||
" try:\n",
|
||||
" return recognizer.recognize_google(audio)\n",
|
||||
" except Exception as e:\n",
|
||||
" print(\"Transcription error:\", e)\n",
|
||||
" return None\n",
|
||||
"\n",
|
||||
"def talk2find_agent(audio_file):\n",
|
||||
" query = transcribe_audio(audio_file)\n",
|
||||
" if not query:\n",
|
||||
" return {\"error\": \"Could not transcribe audio.\"}\n",
|
||||
" print(\"Transcribed text:\", query)\n",
|
||||
" agent = Agent(role=ROLE, goal=GOAL, instructions=INSTRUCTIONS)\n",
|
||||
" return agent.start(query)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "VDMMruvCiz8r",
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 314,
|
||||
"referenced_widgets": [
|
||||
"b72c0f15f2e24a678edcf696b7cc13a3",
|
||||
"99867a03f5474e4c9f22ec5ea948a6ed"
|
||||
]
|
||||
},
|
||||
"id": "VDMMruvCiz8r",
|
||||
"outputId": "14354595-25ef-4600-c3c8-8b1ff9c4aba0"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Transcribed text: what time is the meeting\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╭─ </span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8; font-weight: bold\">Agent Info</span><span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\"> ────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>\n",
|
||||
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
|
||||
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ff9b9b; text-decoration-color: #ff9b9b; font-weight: bold\">👤 Agent:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Agent</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
|
||||
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #b4b4b3; text-decoration-color: #b4b4b3; font-weight: bold\">Role:</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">Voice-driven knowledge assistant. Expert in understanding spoken queries and providing accurate, </span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
|
||||
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #ffe5e5; text-decoration-color: #ffe5e5\">concise answers.</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
|
||||
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span> <span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">│</span>\n",
|
||||
"<span style=\"color: #d2e3c8; text-decoration-color: #d2e3c8\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
|
||||
"</pre>\n"
|
||||
],
|
||||
"text/plain": [
|
||||
"\u001b[38;2;210;227;200m╭─\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[1;38;2;210;227;200mAgent Info\u001b[0m\u001b[38;2;210;227;200m \u001b[0m\u001b[38;2;210;227;200m───────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\u001b[38;2;210;227;200m─╮\u001b[0m\n",
|
||||
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
|
||||
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;255;155;155m👤 Agent:\u001b[0m \u001b[38;2;255;229;229mAgent\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
|
||||
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[1;38;2;180;180;179mRole:\u001b[0m \u001b[38;2;255;229;229mVoice-driven knowledge assistant. Expert in understanding spoken queries and providing accurate, \u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
|
||||
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;255;229;229mconcise answers.\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
|
||||
"\u001b[38;2;210;227;200m│\u001b[0m \u001b[38;2;210;227;200m│\u001b[0m\n",
|
||||
"\u001b[38;2;210;227;200m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "b72c0f15f2e24a678edcf696b7cc13a3",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Output()"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"></pre>\n"
|
||||
],
|
||||
"text/plain": []
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
|
||||
"</pre>\n"
|
||||
],
|
||||
"text/plain": [
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #7f7f7f; text-decoration-color: #7f7f7f\">Response generated in 2.3s</span>\n",
|
||||
"</pre>\n"
|
||||
],
|
||||
"text/plain": [
|
||||
"\u001b[2mResponse generated in 2.3s\u001b[0m\n"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭───────────────────────────────────────────────────── Task ──────────────────────────────────────────────────────╮</span>\n",
|
||||
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> what time is the meeting <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
|
||||
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
|
||||
"</pre>\n"
|
||||
],
|
||||
"text/plain": [
|
||||
"\u001b[36m╭─\u001b[0m\u001b[36m────────────────────────────────────────────────────\u001b[0m\u001b[36m Task \u001b[0m\u001b[36m─────────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
|
||||
"\u001b[36m│\u001b[0m what time is the meeting \u001b[36m│\u001b[0m\n",
|
||||
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #008080; text-decoration-color: #008080\">╭─────────────────────────────────────────────────── Response ────────────────────────────────────────────────────╮</span>\n",
|
||||
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> I'm sorry, I don't have access to your schedule or specific meeting details. Could you provide more information <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
|
||||
"<span style=\"color: #008080; text-decoration-color: #008080\">│</span> about which meeting you're referring to? <span style=\"color: #008080; text-decoration-color: #008080\">│</span>\n",
|
||||
"<span style=\"color: #008080; text-decoration-color: #008080\">╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
|
||||
"</pre>\n"
|
||||
],
|
||||
"text/plain": [
|
||||
"\u001b[36m╭─\u001b[0m\u001b[36m──────────────────────────────────────────────────\u001b[0m\u001b[36m Response \u001b[0m\u001b[36m───────────────────────────────────────────────────\u001b[0m\u001b[36m─╮\u001b[0m\n",
|
||||
"\u001b[36m│\u001b[0m I'm sorry, I don't have access to your schedule or specific meeting details. Could you provide more information \u001b[36m│\u001b[0m\n",
|
||||
"\u001b[36m│\u001b[0m about which meeting you're referring to? \u001b[36m│\u001b[0m\n",
|
||||
"\u001b[36m╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"I'm sorry, I don't have access to your schedule or specific meeting details. Could you provide more information about which meeting you're referring to?\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"audio_path = \"question.wav\"\n",
|
||||
"result = talk2find_agent(audio_path)\n",
|
||||
"print(result)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"provenance": []
|
||||
},
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "python",
|
||||
"version": "3.x"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Detailed LLM configuration
|
||||
llm_config = {
|
||||
"model": "gemini/gemini-1.5-flash-latest", # Model name without provider prefix
|
||||
|
||||
# Core settings
|
||||
"temperature": 0.7, # Controls randomness (like temperature)
|
||||
"timeout": 30, # Timeout in seconds
|
||||
"top_p": 0.9, # Nucleus sampling parameter
|
||||
"max_tokens": 1000, # Max tokens in response
|
||||
|
||||
# Advanced parameters
|
||||
"presence_penalty": 0.1, # Penalize repetition of topics (-2.0 to 2.0)
|
||||
"frequency_penalty": 0.1, # Penalize token repetition (-2.0 to 2.0)
|
||||
|
||||
# API settings (optional)
|
||||
"api_key": None, # Your API key (or use environment variable)
|
||||
"base_url": None, # Custom API endpoint if needed
|
||||
|
||||
# Response formatting
|
||||
"response_format": { # Force specific response format
|
||||
"type": "text" # Options: "text", "json_object"
|
||||
},
|
||||
|
||||
# Additional controls
|
||||
"seed": 42, # For reproducible responses
|
||||
"stop_phrases": ["##", "END"], # Custom stop sequences
|
||||
}
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a helpful Assistant specialized in scientific explanations. "
|
||||
"Provide clear, accurate, and engaging responses.",
|
||||
llm=llm_config, # Pass the detailed configuration
|
||||
verbose=True, # Enable detailed output
|
||||
markdown=True, # Format responses in markdown
|
||||
self_reflect=True, # Enable self-reflection
|
||||
max_reflect=3, # Maximum reflection iterations
|
||||
min_reflect=1 # Minimum reflection iterations
|
||||
)
|
||||
|
||||
# Test the agent
|
||||
response = agent.start("Why is the sky blue? Please explain in simple terms.")
|
||||
|
||||
print(response)
|
||||
@@ -1,10 +0,0 @@
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.tools import internet_search
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
tools=[internet_search],
|
||||
llm="gemini/gemini-1.5-flash-8b"
|
||||
)
|
||||
|
||||
agent.start("What is Praison AI?")
|
||||
@@ -311,6 +311,58 @@ class LLM:
|
||||
# This ensures we make a single non-streaming call rather than risk
|
||||
# missing tool calls or making duplicate calls
|
||||
return False
|
||||
|
||||
def _build_messages(self, prompt, system_prompt=None, chat_history=None, output_json=None, output_pydantic=None):
|
||||
"""Build messages list for LLM completion. Works for both sync and async.
|
||||
|
||||
Args:
|
||||
prompt: The user prompt (str or list)
|
||||
system_prompt: Optional system prompt
|
||||
chat_history: Optional list of previous messages
|
||||
output_json: Optional Pydantic model for JSON output
|
||||
output_pydantic: Optional Pydantic model for JSON output (alias)
|
||||
|
||||
Returns:
|
||||
tuple: (messages list, original prompt)
|
||||
"""
|
||||
messages = []
|
||||
|
||||
# Handle system prompt
|
||||
if system_prompt:
|
||||
# Append JSON schema if needed
|
||||
if output_json:
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {json.dumps(output_json.model_json_schema())}"
|
||||
elif output_pydantic:
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {json.dumps(output_pydantic.model_json_schema())}"
|
||||
|
||||
# Skip system messages for legacy o1 models as they don't support them
|
||||
if not self._needs_system_message_skip():
|
||||
messages.append({"role": "system", "content": system_prompt})
|
||||
|
||||
# Add chat history if provided
|
||||
if chat_history:
|
||||
messages.extend(chat_history)
|
||||
|
||||
# Handle prompt modifications for JSON output
|
||||
original_prompt = prompt
|
||||
if output_json or output_pydantic:
|
||||
if isinstance(prompt, str):
|
||||
prompt = prompt + "\nReturn ONLY a valid JSON object. No other text or explanation."
|
||||
elif isinstance(prompt, list):
|
||||
# Create a copy to avoid modifying the original
|
||||
prompt = prompt.copy()
|
||||
for item in prompt:
|
||||
if item.get("type") == "text":
|
||||
item["text"] = item["text"] + "\nReturn ONLY a valid JSON object. No other text or explanation."
|
||||
break
|
||||
|
||||
# Add prompt to messages
|
||||
if isinstance(prompt, list):
|
||||
messages.append({"role": "user", "content": prompt})
|
||||
else:
|
||||
messages.append({"role": "user", "content": prompt})
|
||||
|
||||
return messages, original_prompt
|
||||
|
||||
def get_response(
|
||||
self,
|
||||
@@ -421,36 +473,14 @@ class LLM:
|
||||
if not formatted_tools:
|
||||
formatted_tools = None
|
||||
|
||||
# Build messages list
|
||||
messages = []
|
||||
if system_prompt:
|
||||
if output_json:
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {json.dumps(output_json.model_json_schema())}"
|
||||
elif output_pydantic:
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {json.dumps(output_pydantic.model_json_schema())}"
|
||||
# Skip system messages for legacy o1 models as they don't support them
|
||||
if not self._needs_system_message_skip():
|
||||
messages.append({"role": "system", "content": system_prompt})
|
||||
|
||||
if chat_history:
|
||||
messages.extend(chat_history)
|
||||
|
||||
# Handle prompt modifications for JSON output
|
||||
original_prompt = prompt
|
||||
if output_json or output_pydantic:
|
||||
if isinstance(prompt, str):
|
||||
prompt += "\nReturn ONLY a valid JSON object. No other text or explanation."
|
||||
elif isinstance(prompt, list):
|
||||
for item in prompt:
|
||||
if item["type"] == "text":
|
||||
item["text"] += "\nReturn ONLY a valid JSON object. No other text or explanation."
|
||||
break
|
||||
|
||||
# Add prompt to messages
|
||||
if isinstance(prompt, list):
|
||||
messages.append({"role": "user", "content": prompt})
|
||||
else:
|
||||
messages.append({"role": "user", "content": prompt})
|
||||
# Build messages list using shared helper
|
||||
messages, original_prompt = self._build_messages(
|
||||
prompt=prompt,
|
||||
system_prompt=system_prompt,
|
||||
chat_history=chat_history,
|
||||
output_json=output_json,
|
||||
output_pydantic=output_pydantic
|
||||
)
|
||||
|
||||
start_time = time.time()
|
||||
reflection_count = 0
|
||||
@@ -1160,36 +1190,14 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
reasoning_steps = kwargs.pop('reasoning_steps', self.reasoning_steps)
|
||||
litellm.set_verbose = False
|
||||
|
||||
# Build messages list
|
||||
messages = []
|
||||
if system_prompt:
|
||||
if output_json:
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {json.dumps(output_json.model_json_schema())}"
|
||||
elif output_pydantic:
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {json.dumps(output_pydantic.model_json_schema())}"
|
||||
# Skip system messages for legacy o1 models as they don't support them
|
||||
if not self._needs_system_message_skip():
|
||||
messages.append({"role": "system", "content": system_prompt})
|
||||
|
||||
if chat_history:
|
||||
messages.extend(chat_history)
|
||||
|
||||
# Handle prompt modifications for JSON output
|
||||
original_prompt = prompt
|
||||
if output_json or output_pydantic:
|
||||
if isinstance(prompt, str):
|
||||
prompt += "\nReturn ONLY a valid JSON object. No other text or explanation."
|
||||
elif isinstance(prompt, list):
|
||||
for item in prompt:
|
||||
if item["type"] == "text":
|
||||
item["text"] += "\nReturn ONLY a valid JSON object. No other text or explanation."
|
||||
break
|
||||
|
||||
# Add prompt to messages
|
||||
if isinstance(prompt, list):
|
||||
messages.append({"role": "user", "content": prompt})
|
||||
else:
|
||||
messages.append({"role": "user", "content": prompt})
|
||||
# Build messages list using shared helper
|
||||
messages, original_prompt = self._build_messages(
|
||||
prompt=prompt,
|
||||
system_prompt=system_prompt,
|
||||
chat_history=chat_history,
|
||||
output_json=output_json,
|
||||
output_pydantic=output_pydantic
|
||||
)
|
||||
|
||||
start_time = time.time()
|
||||
reflection_count = 0
|
||||
@@ -1901,18 +1909,11 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
}
|
||||
logger.debug(f"Response method configuration: {json.dumps(debug_info, indent=2, default=str)}")
|
||||
|
||||
# Build messages list
|
||||
messages = []
|
||||
if system_prompt:
|
||||
# Skip system messages for legacy o1 models as they don't support them
|
||||
if not self._needs_system_message_skip():
|
||||
messages.append({"role": "system", "content": system_prompt})
|
||||
|
||||
# Add prompt to messages
|
||||
if isinstance(prompt, list):
|
||||
messages.append({"role": "user", "content": prompt})
|
||||
else:
|
||||
messages.append({"role": "user", "content": prompt})
|
||||
# Build messages list using shared helper (simplified version without JSON output)
|
||||
messages, _ = self._build_messages(
|
||||
prompt=prompt,
|
||||
system_prompt=system_prompt
|
||||
)
|
||||
|
||||
# Get response from LiteLLM
|
||||
if stream:
|
||||
@@ -2009,18 +2010,11 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
}
|
||||
logger.debug(f"Async response method configuration: {json.dumps(debug_info, indent=2, default=str)}")
|
||||
|
||||
# Build messages list
|
||||
messages = []
|
||||
if system_prompt:
|
||||
# Skip system messages for legacy o1 models as they don't support them
|
||||
if not self._needs_system_message_skip():
|
||||
messages.append({"role": "system", "content": system_prompt})
|
||||
|
||||
# Add prompt to messages
|
||||
if isinstance(prompt, list):
|
||||
messages.append({"role": "user", "content": prompt})
|
||||
else:
|
||||
messages.append({"role": "user", "content": prompt})
|
||||
# Build messages list using shared helper (simplified version without JSON output)
|
||||
messages, _ = self._build_messages(
|
||||
prompt=prompt,
|
||||
system_prompt=system_prompt
|
||||
)
|
||||
|
||||
# Get response from LiteLLM
|
||||
if stream:
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "praisonaiagents"
|
||||
version = "0.0.111"
|
||||
version = "0.0.112"
|
||||
description = "Praison AI agents for completing complex tasks with Self Reflection Agents"
|
||||
requires-python = ">=3.10"
|
||||
authors = [
|
||||
|
||||
Generated
+1
-1
@@ -2375,7 +2375,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "praisonaiagents"
|
||||
version = "0.0.111"
|
||||
version = "0.0.112"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "mcp" },
|
||||
|
||||
@@ -3,8 +3,8 @@ class Praisonai < Formula
|
||||
|
||||
desc "AI tools for various AI applications"
|
||||
homepage "https://github.com/MervinPraison/PraisonAI"
|
||||
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v2.2.38.tar.gz"
|
||||
sha256 `curl -sL https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v2.2.38.tar.gz | shasum -a 256`.split.first
|
||||
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v2.2.39.tar.gz"
|
||||
sha256 `curl -sL https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v2.2.39.tar.gz | shasum -a 256`.split.first
|
||||
license "MIT"
|
||||
|
||||
depends_on "[email protected]"
|
||||
|
||||
@@ -57,7 +57,7 @@ class CloudDeployer:
|
||||
file.write("FROM python:3.11-slim\n")
|
||||
file.write("WORKDIR /app\n")
|
||||
file.write("COPY . .\n")
|
||||
file.write("RUN pip install flask praisonai==2.2.38 gunicorn markdown\n")
|
||||
file.write("RUN pip install flask praisonai==2.2.39 gunicorn markdown\n")
|
||||
file.write("EXPOSE 8080\n")
|
||||
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "PraisonAI"
|
||||
version = "2.2.38"
|
||||
version = "2.2.39"
|
||||
description = "PraisonAI is an AI Agents Framework with Self Reflection. PraisonAI application combines PraisonAI Agents, AutoGen, and CrewAI into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customisation, and efficient human-agent collaboration."
|
||||
readme = "README.md"
|
||||
license = ""
|
||||
@@ -12,7 +12,7 @@ dependencies = [
|
||||
"rich>=13.7",
|
||||
"markdown>=3.5",
|
||||
"pyparsing>=3.0.0",
|
||||
"praisonaiagents>=0.0.111",
|
||||
"praisonaiagents>=0.0.112",
|
||||
"python-dotenv>=0.19.0",
|
||||
"instructor>=1.3.3",
|
||||
"PyYAML>=6.0",
|
||||
@@ -95,7 +95,7 @@ autogen = ["pyautogen>=0.2.19", "praisonai-tools>=0.0.15", "crewai"]
|
||||
|
||||
[tool.poetry]
|
||||
name = "PraisonAI"
|
||||
version = "2.2.38"
|
||||
version = "2.2.39"
|
||||
description = "PraisonAI is an AI Agents Framework with Self Reflection. PraisonAI application combines PraisonAI Agents, AutoGen, and CrewAI into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customisation, and efficient human-agent collaboration."
|
||||
authors = ["Mervin Praison"]
|
||||
license = ""
|
||||
@@ -113,7 +113,7 @@ python = ">=3.10,<3.13"
|
||||
rich = ">=13.7"
|
||||
markdown = ">=3.5"
|
||||
pyparsing = ">=3.0.0"
|
||||
praisonaiagents = ">=0.0.111"
|
||||
praisonaiagents = ">=0.0.112"
|
||||
python-dotenv = ">=0.19.0"
|
||||
instructor = ">=1.3.3"
|
||||
PyYAML = ">=6.0"
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Test script to verify Phase 2 refactoring maintains backward compatibility"""
|
||||
|
||||
import asyncio
|
||||
from src.praisonai_agents.praisonaiagents.llm.llm import LLM
|
||||
|
||||
def test_sync_methods():
|
||||
"""Test synchronous methods still work correctly"""
|
||||
print("Testing synchronous methods...")
|
||||
|
||||
# Test basic response
|
||||
llm = LLM(model="gpt-3.5-turbo")
|
||||
|
||||
# Test simple prompt
|
||||
print("1. Testing simple prompt...")
|
||||
response = llm.response(
|
||||
prompt="What is 2+2?",
|
||||
verbose=False
|
||||
)
|
||||
print(f" Response: {response}")
|
||||
assert response, "Should get a response"
|
||||
|
||||
# Test with system prompt
|
||||
print("2. Testing with system prompt...")
|
||||
response = llm.response(
|
||||
prompt="Hello",
|
||||
system_prompt="You are a helpful assistant. Always respond politely.",
|
||||
verbose=False
|
||||
)
|
||||
print(f" Response: {response[:50]}...")
|
||||
assert response, "Should get a response with system prompt"
|
||||
|
||||
# Test with chat history
|
||||
print("3. Testing with chat history...")
|
||||
chat_history = [
|
||||
{"role": "user", "content": "My name is Alice"},
|
||||
{"role": "assistant", "content": "Nice to meet you, Alice!"}
|
||||
]
|
||||
response = llm.get_response(
|
||||
prompt="What's my name?",
|
||||
chat_history=chat_history,
|
||||
verbose=False
|
||||
)
|
||||
print(f" Response: {response}")
|
||||
assert response, "Should get a response with chat history"
|
||||
|
||||
print("✅ Synchronous methods working correctly\n")
|
||||
|
||||
async def test_async_methods():
|
||||
"""Test asynchronous methods still work correctly"""
|
||||
print("Testing asynchronous methods...")
|
||||
|
||||
# Test basic async response
|
||||
llm = LLM(model="gpt-3.5-turbo")
|
||||
|
||||
# Test simple prompt
|
||||
print("1. Testing async simple prompt...")
|
||||
response = await llm.aresponse(
|
||||
prompt="What is 3+3?",
|
||||
verbose=False
|
||||
)
|
||||
print(f" Response: {response}")
|
||||
assert response, "Should get an async response"
|
||||
|
||||
# Test with system prompt
|
||||
print("2. Testing async with system prompt...")
|
||||
response = await llm.aresponse(
|
||||
prompt="Goodbye",
|
||||
system_prompt="You are a helpful assistant. Always respond politely.",
|
||||
verbose=False
|
||||
)
|
||||
print(f" Response: {response[:50]}...")
|
||||
assert response, "Should get an async response with system prompt"
|
||||
|
||||
# Test with chat history
|
||||
print("3. Testing async with chat history...")
|
||||
chat_history = [
|
||||
{"role": "user", "content": "My favorite color is blue"},
|
||||
{"role": "assistant", "content": "Blue is a nice color!"}
|
||||
]
|
||||
response = await llm.get_response_async(
|
||||
prompt="What's my favorite color?",
|
||||
chat_history=chat_history,
|
||||
verbose=False
|
||||
)
|
||||
print(f" Response: {response}")
|
||||
assert response, "Should get an async response with chat history"
|
||||
|
||||
print("✅ Asynchronous methods working correctly\n")
|
||||
|
||||
def test_edge_cases():
|
||||
"""Test edge cases and special scenarios"""
|
||||
print("Testing edge cases...")
|
||||
|
||||
llm = LLM(model="gpt-3.5-turbo")
|
||||
|
||||
# Test with list prompt (multimodal-style)
|
||||
print("1. Testing list-style prompt...")
|
||||
prompt = [{"type": "text", "text": "What is 4+4?"}]
|
||||
response = llm.response(
|
||||
prompt=prompt,
|
||||
verbose=False
|
||||
)
|
||||
print(f" Response: {response}")
|
||||
assert response, "Should handle list-style prompts"
|
||||
|
||||
# Test with legacy o1 model (system message should be skipped)
|
||||
print("2. Testing legacy o1 model handling...")
|
||||
llm_o1 = LLM(model="o1-mini")
|
||||
response = llm_o1.response(
|
||||
prompt="Hello",
|
||||
system_prompt="This should be skipped",
|
||||
verbose=False
|
||||
)
|
||||
print(f" Response: {response[:50]}...")
|
||||
assert response, "Should handle legacy o1 models"
|
||||
|
||||
print("✅ Edge cases handled correctly\n")
|
||||
|
||||
def main():
|
||||
"""Run all tests"""
|
||||
print("=== Phase 2 Refactoring Verification ===\n")
|
||||
|
||||
try:
|
||||
# Test sync methods
|
||||
test_sync_methods()
|
||||
|
||||
# Test async methods
|
||||
asyncio.run(test_async_methods())
|
||||
|
||||
# Test edge cases
|
||||
test_edge_cases()
|
||||
|
||||
print("✅ ALL TESTS PASSED! The refactoring maintains backward compatibility.")
|
||||
print("\nSummary:")
|
||||
print("- Message building logic successfully extracted to _build_messages()")
|
||||
print("- All 4 methods (get_response, response, get_response_async, aresponse) updated")
|
||||
print("- ~40 lines of duplicated code removed")
|
||||
print("- No breaking changes detected")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ TEST FAILED: {str(e)}")
|
||||
raise
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Generated
+5
-5
@@ -3931,7 +3931,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "praisonai"
|
||||
version = "2.2.38"
|
||||
version = "2.2.39"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "instructor" },
|
||||
@@ -4073,7 +4073,7 @@ requires-dist = [
|
||||
{ name = "plotly", marker = "extra == 'realtime'", specifier = ">=5.24.0" },
|
||||
{ name = "praisonai-tools", marker = "extra == 'autogen'", specifier = ">=0.0.15" },
|
||||
{ name = "praisonai-tools", marker = "extra == 'crewai'", specifier = ">=0.0.15" },
|
||||
{ name = "praisonaiagents", specifier = ">=0.0.111" },
|
||||
{ name = "praisonaiagents", specifier = ">=0.0.112" },
|
||||
{ name = "pyautogen", marker = "extra == 'autogen'", specifier = ">=0.2.19" },
|
||||
{ name = "pydantic", marker = "extra == 'chat'", specifier = "<=2.10.1" },
|
||||
{ name = "pydantic", marker = "extra == 'code'", specifier = "<=2.10.1" },
|
||||
@@ -4130,7 +4130,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "praisonaiagents"
|
||||
version = "0.0.111"
|
||||
version = "0.0.112"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "mcp" },
|
||||
@@ -4139,9 +4139,9 @@ dependencies = [
|
||||
{ name = "pydantic" },
|
||||
{ name = "rich" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/3c/8f/815e2074fb03d24dd0d89adb28c6150f6112ff23af36bf021f387176cc0c/praisonaiagents-0.0.111.tar.gz", hash = "sha256:17d4fec346d61a9830410a4f23a052da44b3a9978a7304b9ca9ca35cf747ceaa", size = 166895 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b8/f0/f03a2e64ee0f78824a78275b8a2350f2086a37dd75601b43e740f7a55c3b/praisonaiagents-0.0.112.tar.gz", hash = "sha256:504efc8a427b80a2e4865831c651c834239fb33b7766792e2f3d1157518ac09a", size = 166924 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/92/a6/dbbe85f62411b784a79055be924fa3d6c3481ed7659ce2ec3ab3bf315254/praisonaiagents-0.0.111-py3-none-any.whl", hash = "sha256:1a8f884c48eac03eff4ceec11fec4625f01decaaa28636a082cd61797cef984b", size = 186353 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f8/da/83271d3671e468f855e225c9c23fe19b7a5be654ab8f8b0fc305bf1b10f1/praisonaiagents-0.0.112-py3-none-any.whl", hash = "sha256:b402af5eb7e3ffca702aeae89ca01f8f4c223aa194b743a3d9d1feb71e5efd6e", size = 186397 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
Reference in new issue
Block a user