Compare commits

...
2 Commits
Author SHA1 Message Date
Mervin Praison 42a86c831f Release v2.8.8 2025-12-31 12:46:10 +00:00
Mervin Praison 48443b11d6 Release v2.8.7 2025-12-31 12:28:44 +00:00
10 changed files with 82 additions and 74 deletions

No files matched your search

+1 -1
View File
@@ -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.8.6" \
"praisonai>=2.8.8" \
"praisonai[chat]" \
"embedchain[github,youtube]"
+1 -1
View File
@@ -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.8.6" \
"praisonai>=2.8.8" \
"praisonai[ui]" \
"praisonai[chat]" \
"praisonai[realtime]" \
+1 -1
View File
@@ -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.8.6" \
"praisonai>=2.8.8" \
"praisonai[ui]" \
"praisonai[crewai]"
+2 -2
View File
@@ -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.8.6.tar.gz"
sha256 `curl -sL https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v2.8.6.tar.gz | shasum -a 256`.split.first
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v2.8.8.tar.gz"
sha256 `curl -sL https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v2.8.8.tar.gz | shasum -a 256`.split.first
license "MIT"
depends_on "[email protected]"
+1 -1
View File
@@ -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.8.6 gunicorn markdown\n")
file.write("RUN pip install flask praisonai==2.8.8 gunicorn markdown\n")
file.write("EXPOSE 8080\n")
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
+9 -1
View File
@@ -319,7 +319,6 @@ User Question: {message.content}
message_history.append({"role": "user", "content": user_message})
msg = cl.Message(content="")
await msg.send()
completion_params = {
"model": model_name,
@@ -349,6 +348,7 @@ User Question: {message.content}
full_response = ""
tool_calls = []
current_tool_call = None
msg_sent = False
async for part in response:
if 'choices' in part and len(part['choices']) > 0:
@@ -356,6 +356,10 @@ User Question: {message.content}
if 'content' in delta and delta['content'] is not None:
token = delta['content']
# Send message on first token to avoid delay
if not msg_sent:
await msg.send()
msg_sent = True
await msg.stream_token(token)
full_response += token
@@ -382,6 +386,10 @@ User Question: {message.content}
if current_tool_call:
tool_calls.append(current_tool_call)
# Ensure message is sent even if no content (e.g., tool calls only)
if not msg_sent:
await msg.send()
logger.debug(f"Full response: {full_response}")
logger.debug(f"Tool calls: {tool_calls}")
message_history.append({"role": "assistant", "content": full_response})
+32 -17
View File
@@ -398,7 +398,6 @@ Context:
message_history.append({"role": "user", "content": user_message})
msg = cl.Message(content="")
await msg.send()
# Use PraisonAI Agents if available, otherwise fallback to litellm
if PRAISONAI_AGENTS_AVAILABLE:
@@ -433,41 +432,47 @@ Then use the Claude Code tool to handle those requests.
For informational questions, explanations, or general conversations, respond normally without using Claude Code."""
# Create agent
# Create agent with streaming enabled
agent = Agent(
name="PraisonAI Assistant",
instructions=instructions,
llm=model_name,
tools=available_tools if available_tools else None
tools=available_tools if available_tools else None,
stream=True
)
# Execute agent with streaming
full_response = ""
msg_sent = False
# Use agent's streaming capabilities if available
try:
# For now, use synchronous execution and stream the result
# TODO: Implement proper streaming when PraisonAI agents support it
result = agent.start(user_message)
# Use async chat for proper streaming
result = await agent.achat(user_message)
# Stream the response character by character for better UX
# Get the response text
if hasattr(result, 'raw'):
response_text = result.raw
else:
response_text = str(result)
for char in response_text:
await msg.stream_token(char)
full_response += char
# Small delay to make streaming visible
await asyncio.sleep(0.01)
# Send message on first content
if not msg_sent:
await msg.send()
msg_sent = True
# Stream in word chunks for better UX (not char-by-char which is too slow)
words = response_text.split(' ')
for i, word in enumerate(words):
token = word + (' ' if i < len(words) - 1 else '')
await msg.stream_token(token)
full_response += token
except Exception as e:
error_response = f"Error executing agent: {str(e)}"
for char in error_response:
await msg.stream_token(char)
full_response += char
await asyncio.sleep(0.01)
if not msg_sent:
await msg.send()
await msg.stream_token(error_response)
full_response = error_response
msg.content = full_response
await msg.update()
@@ -475,6 +480,7 @@ For informational questions, explanations, or general conversations, respond nor
except Exception as e:
error_msg = f"Failed to use PraisonAI Agents: {str(e)}"
logger.error(error_msg)
await msg.send()
await msg.stream_token(error_msg)
msg.content = error_msg
await msg.update()
@@ -515,6 +521,7 @@ async def handle_with_litellm(user_message, model_name, message_history, msg, im
full_response = ""
tool_calls = []
current_tool_call = None
msg_sent = False
async for part in response:
logger.debug(f"LLM part: {part}")
@@ -523,6 +530,10 @@ async def handle_with_litellm(user_message, model_name, message_history, msg, im
if 'content' in delta and delta['content'] is not None:
token = delta['content']
# Send message on first token
if not msg_sent:
await msg.send()
msg_sent = True
await msg.stream_token(token)
full_response += token
@@ -549,6 +560,10 @@ async def handle_with_litellm(user_message, model_name, message_history, msg, im
if current_tool_call:
tool_calls.append(current_tool_call)
# Ensure message is sent even if no content (tool calls only)
if not msg_sent:
await msg.send()
logger.debug(f"Full response: {full_response}")
logger.debug(f"Tool calls: {tool_calls}")
message_history.append({"role": "assistant", "content": full_response})
+1 -1
View File
@@ -1 +1 @@
__version__ = "2.8.6"
__version__ = "2.8.8"
+4 -4
View File
@@ -26,7 +26,7 @@ praisonai-call = "praisonai.api.call:main"
[project.optional-dependencies]
ui = [
"chainlit>=2.5.5,<2.6.0",
"chainlit>=2.8.5,<2.9.0",
"sqlalchemy>=2.0.36",
"aiosqlite>=0.20.0",
"greenlet>=3.0.3",
@@ -45,7 +45,7 @@ openai = ["langchain-openai>=0.2.1,<0.3.0"]
anthropic = ["langchain-anthropic>=0.3.0"]
cohere = ["langchain-cohere>=0.3.0,<0.4.0"]
chat = [
"chainlit>=2.5.5,<2.6.0",
"chainlit>=2.8.5,<2.9.0",
"litellm>=1.72.6",
"aiosqlite>=0.20.0",
"greenlet>=3.0.3",
@@ -57,7 +57,7 @@ chat = [
"pydantic<=2.10.1"
]
code = [
"chainlit>=2.5.5,<2.6.0",
"chainlit>=2.8.5,<2.9.0",
"litellm>=1.72.6",
"aiosqlite>=0.20.0",
"greenlet>=3.0.3",
@@ -68,7 +68,7 @@ code = [
"pydantic<=2.10.1"
]
realtime = [
"chainlit>=2.5.5,<2.6.0",
"chainlit>=2.8.5,<2.9.0",
"litellm>=1.72.6",
"aiosqlite>=0.20.0",
"greenlet>=3.0.3",
+30 -45
View File
@@ -177,6 +177,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/e4/ad/77fad9d6f974ec58d837cb49fb9b483d6227a420c4f908c3578633de1d47/alphashape-1.3.1-py2.py3-none-any.whl", hash = "sha256:96a5ddd5f09534a35f03a8916aeeaac00fe4d6bec2f9ad78f87f57be3007f795", size = 13122, upload-time = "2021-04-16T17:47:17.773Z" },
]
[[package]]
name = "annotated-doc"
version = "0.0.4"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" },
]
[[package]]
name = "annotated-types"
version = "0.7.0"
@@ -260,14 +269,15 @@ wheels = [
[[package]]
name = "asyncer"
version = "0.0.7"
version = "0.0.12"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
{ name = "sniffio" },
]
sdist = { url = "https://files.pythonhosted.org/packages/39/29/245ba9fa5769a1e3226c1157aedb372fe9dab28c4e1dcf6911d84d3a5e04/asyncer-0.0.7.tar.gz", hash = "sha256:d5e563fb0f56eb87b97257984703658a4f5bbdb52ff851b3e8ed864cc200b1d2", size = 14437, upload-time = "2024-04-30T06:26:00.79Z" }
sdist = { url = "https://files.pythonhosted.org/packages/33/3a/e3d6919a41328f837a1c73ac057a8be35276c350046a79af588c536bd0fc/asyncer-0.0.12.tar.gz", hash = "sha256:4ceaa472bf40f3778caa3bd7f7dfcbafec0a948a9688e3c90a1796469ebe5e19", size = 17909, upload-time = "2025-12-26T12:05:10.248Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/3e/4b/40a1dc52fc26695b1e80a9e67dfb0fe7e6ddc57bbc5b61348e40c0045abb/asyncer-0.0.7-py3-none-any.whl", hash = "sha256:f0d579d4f67c4ead52ede3a45c854f462cae569058a8a6a68a4ebccac1c335d8", size = 8476, upload-time = "2024-04-30T06:25:58.991Z" },
{ url = "https://files.pythonhosted.org/packages/54/f6/ebdca24b43151ed2a7dcf98bab4b61fdfc50dbd7224b9b4de195099fa65e/asyncer-0.0.12-py3-none-any.whl", hash = "sha256:2eb8bb255bdecf04a81df2d47cf168401df1f65a5f62e1bccc1f86ba375c9913", size = 9320, upload-time = "2025-12-26T12:05:08.848Z" },
]
[[package]]
@@ -602,11 +612,12 @@ wheels = [
[[package]]
name = "chainlit"
version = "2.5.5"
version = "2.8.5"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "aiofiles" },
{ name = "asyncer" },
{ name = "audioop-lts", marker = "python_full_version >= '3.13'" },
{ name = "click" },
{ name = "dataclasses-json" },
{ name = "fastapi" },
@@ -618,6 +629,7 @@ dependencies = [
{ name = "nest-asyncio" },
{ name = "packaging" },
{ name = "pydantic" },
{ name = "pydantic-settings" },
{ name = "pyjwt" },
{ name = "python-dotenv" },
{ name = "python-multipart" },
@@ -625,13 +637,12 @@ dependencies = [
{ name = "starlette" },
{ name = "syncer" },
{ name = "tomli" },
{ name = "uptrace" },
{ name = "uvicorn" },
{ name = "watchfiles" },
]
sdist = { url = "https://files.pythonhosted.org/packages/d9/32/e4a6ac0a8e7430cd7b76b712b8df2f83abf129e7b843180e319f647fd3be/chainlit-2.5.5.tar.gz", hash = "sha256:d6388f93b9089e3a80bc2bd286a157a4a9d8016dc2c806372fd77119bcc0d36c", size = 9520733, upload-time = "2025-04-14T13:27:15.432Z" }
sdist = { url = "https://files.pythonhosted.org/packages/46/71/d0465682910792ff382d604b9973dcd0115c682dde6c22753eaa4304afe3/chainlit-2.8.5.tar.gz", hash = "sha256:ebe73b3ad9d7e545454432eb280618ef92d69d6470eb66488149c9bb7f6c526d", size = 9884512, upload-time = "2025-11-07T22:58:11.181Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d8/b2/9bf8c07b18ef34dc70771a0e21f6f0a5392dd3a753135743178cd59f1b7f/chainlit-2.5.5-py3-none-any.whl", hash = "sha256:1783c7b868fe41158283b498020fa18a23c39d07319ad9927e429f1e888f6eb5", size = 9670768, upload-time = "2025-04-14T13:27:13.415Z" },
{ url = "https://files.pythonhosted.org/packages/2f/e2/c9a1ff354acc05fe910a19a8053647674315c091f33fe3b1eef3c69fcbe7/chainlit-2.8.5-py3-none-any.whl", hash = "sha256:1d6ef81a14f4b9a526229b0e6839f364c8ef1a3335e648889d43c0c8f8444a8e", size = 9725985, upload-time = "2025-11-07T22:58:08.631Z" },
]
[[package]]
@@ -1130,16 +1141,17 @@ wheels = [
[[package]]
name = "fastapi"
version = "0.115.14"
version = "0.128.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "annotated-doc" },
{ name = "pydantic" },
{ name = "starlette" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/ca/53/8c38a874844a8b0fa10dd8adf3836ac154082cf88d3f22b544e9ceea0a15/fastapi-0.115.14.tar.gz", hash = "sha256:b1de15cdc1c499a4da47914db35d0e4ef8f1ce62b624e94e0e5824421df99739", size = 296263, upload-time = "2025-06-26T15:29:08.21Z" }
sdist = { url = "https://files.pythonhosted.org/packages/52/08/8c8508db6c7b9aae8f7175046af41baad690771c9bcde676419965e338c7/fastapi-0.128.0.tar.gz", hash = "sha256:1cc179e1cef10a6be60ffe429f79b829dce99d8de32d7acb7e6c8dfdf7f2645a", size = 365682, upload-time = "2025-12-27T15:21:13.714Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/53/50/b1222562c6d270fea83e9c9075b8e8600b8479150a18e4516a6138b980d1/fastapi-0.115.14-py3-none-any.whl", hash = "sha256:6c0c8bf9420bd58f565e585036d971872472b4f7d3f6c73b698e10cffdefb3ca", size = 95514, upload-time = "2025-06-26T15:29:06.49Z" },
{ url = "https://files.pythonhosted.org/packages/5c/05/5cbb59154b093548acd0f4c7c474a118eda06da25aa75c616b72d8fcd92a/fastapi-0.128.0-py3-none-any.whl", hash = "sha256:aebd93f9716ee3b4f4fcfe13ffb7cf308d99c9f3ab5622d8877441072561582d", size = 103094, upload-time = "2025-12-27T15:21:12.154Z" },
]
[[package]]
@@ -2961,19 +2973,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/1d/5a/3f8d078dbf55d18442f6a2ecedf6786d81d7245844b2b20ce2b8ad6f0307/opentelemetry_api-1.35.0-py3-none-any.whl", hash = "sha256:c4ea7e258a244858daf18474625e9cc0149b8ee354f37843415771a40c25ee06", size = 65566, upload-time = "2025-07-11T12:23:07.944Z" },
]
[[package]]
name = "opentelemetry-exporter-otlp"
version = "1.35.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "opentelemetry-exporter-otlp-proto-grpc" },
{ name = "opentelemetry-exporter-otlp-proto-http" },
]
sdist = { url = "https://files.pythonhosted.org/packages/2e/2e/63718faa67b17f449a7fb7efdc7125a408cbe5d8c0bb35f423f2776d60b5/opentelemetry_exporter_otlp-1.35.0.tar.gz", hash = "sha256:f94feff09b3524df867c7876b79c96cef20068106cb5efe55340e8d08192c8a4", size = 6142, upload-time = "2025-07-11T12:23:30.128Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/cf/db/2da28358d3101ca936c1643becbb4ebd69e9e48acf27f153d735a4813c6b/opentelemetry_exporter_otlp-1.35.0-py3-none-any.whl", hash = "sha256:8e6bb9025f6238db7d69bba7ee37c77e4858d0a1ff22a9e126f7c9e017e83afe", size = 7016, upload-time = "2025-07-11T12:23:10.679Z" },
]
[[package]]
name = "opentelemetry-exporter-otlp-proto-common"
version = "1.35.0"
@@ -4084,10 +4083,10 @@ requires-dist = [
{ name = "autogen-agentchat", marker = "extra == 'autogen-v4'", specifier = ">=0.4.0" },
{ name = "autogen-core", marker = "extra == 'autogen-v4'", specifier = ">=0.4.0" },
{ name = "autogen-ext", extras = ["openai"], marker = "extra == 'autogen-v4'", specifier = ">=0.4.0" },
{ name = "chainlit", marker = "extra == 'chat'", specifier = ">=2.5.5,<2.6.0" },
{ name = "chainlit", marker = "extra == 'code'", specifier = ">=2.5.5,<2.6.0" },
{ name = "chainlit", marker = "extra == 'realtime'", specifier = ">=2.5.5,<2.6.0" },
{ name = "chainlit", marker = "extra == 'ui'", specifier = ">=2.5.5,<2.6.0" },
{ name = "chainlit", marker = "extra == 'chat'", specifier = ">=2.8.5,<2.9.0" },
{ name = "chainlit", marker = "extra == 'code'", specifier = ">=2.8.5,<2.9.0" },
{ name = "chainlit", marker = "extra == 'realtime'", specifier = ">=2.8.5,<2.9.0" },
{ name = "chainlit", marker = "extra == 'ui'", specifier = ">=2.8.5,<2.9.0" },
{ name = "crawl4ai", marker = "extra == 'chat'", specifier = ">=0.7.0" },
{ name = "crawl4ai", marker = "extra == 'code'", specifier = ">=0.7.0" },
{ name = "crawl4ai", marker = "extra == 'realtime'", specifier = ">=0.7.0" },
@@ -5438,14 +5437,15 @@ wheels = [
[[package]]
name = "starlette"
version = "0.41.3"
version = "0.50.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/1a/4c/9b5764bd22eec91c4039ef4c55334e9187085da2d8a2df7bd570869aae18/starlette-0.41.3.tar.gz", hash = "sha256:0e4ab3d16522a255be6b28260b938eae2482f98ce5cc934cb08dce8dc3ba5835", size = 2574159, upload-time = "2024-11-18T19:45:04.283Z" }
sdist = { url = "https://files.pythonhosted.org/packages/ba/b8/73a0e6a6e079a9d9cfa64113d771e421640b6f679a52eeb9b32f72d871a1/starlette-0.50.0.tar.gz", hash = "sha256:a2a17b22203254bcbc2e1f926d2d55f3f9497f769416b3190768befe598fa3ca", size = 2646985, upload-time = "2025-11-01T15:25:27.516Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/96/00/2b325970b3060c7cecebab6d295afe763365822b1306a12eeab198f74323/starlette-0.41.3-py3-none-any.whl", hash = "sha256:44cedb2b7c77a9de33a8b74b2b90e9f50d11fcf25d8270ea525ad71a25374ff7", size = 73225, upload-time = "2024-11-18T19:45:02.027Z" },
{ url = "https://files.pythonhosted.org/packages/d9/52/1064f510b141bd54025f9b55105e26d1fa970b9be67ad766380a3c9b74b0/starlette-0.50.0-py3-none-any.whl", hash = "sha256:9e5391843ec9b6e472eed1365a78c8098cfceb7a74bfd4d6b1c0c0095efb3bca", size = 74033, upload-time = "2025-11-01T15:25:25.461Z" },
]
[[package]]
@@ -5933,21 +5933,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/a6/ab/7e5f53c3b9d14972843a647d8d7a853969a58aecc7559cb3267302c94774/tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd", size = 346586, upload-time = "2024-09-23T18:56:45.478Z" },
]
[[package]]
name = "uptrace"
version = "1.35.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "opentelemetry-api" },
{ name = "opentelemetry-exporter-otlp" },
{ name = "opentelemetry-instrumentation" },
{ name = "opentelemetry-sdk" },
]
sdist = { url = "https://files.pythonhosted.org/packages/1b/e7/090a8b7404b1fcf74c22aed25bb04601740bd1707e31579095b166fa2b19/uptrace-1.35.0.tar.gz", hash = "sha256:0897ea40fcc22122a11d05a0bbcacffc55d2a9a18dd03cffd6c5625e5afa55f0", size = 7660, upload-time = "2025-07-14T11:37:52.142Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b3/db/73bf119afdadbbc8578a61ce41117cda05f8703eaa24163e9236b96ccc40/uptrace-1.35.0-py3-none-any.whl", hash = "sha256:c98ce900d3c660c99763a684f5a51f876d93660114d9ed51de676ed886e5106a", size = 8590, upload-time = "2025-07-14T11:37:51.252Z" },
]
[[package]]
name = "urllib3"
version = "2.3.0"