diff --git a/.gitignore b/.gitignore index 822ced4..d5f3694 100644 --- a/.gitignore +++ b/.gitignore @@ -51,4 +51,7 @@ agentops.log crewAI # virtualenv -.venv \ No newline at end of file +.venv + +# Credentials +credentials.json \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 1f773df..a3264d6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM python:3.11-slim WORKDIR /app COPY . . -RUN pip install flask praisonai==0.1.1 gunicorn markdown +RUN pip install flask praisonai==0.1.2 gunicorn markdown EXPOSE 8080 CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"] diff --git a/docs/api/praisonai/deploy.html b/docs/api/praisonai/deploy.html index b067bde..a001bcf 100644 --- a/docs/api/praisonai/deploy.html +++ b/docs/api/praisonai/deploy.html @@ -110,7 +110,7 @@

Raises

file.write("FROM python:3.11-slim\n") file.write("WORKDIR /app\n") file.write("COPY . .\n") - file.write("RUN pip install flask praisonai==0.1.1 gunicorn markdown\n") + file.write("RUN pip install flask praisonai==0.1.2 gunicorn markdown\n") file.write("EXPOSE 8080\n") file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n') diff --git a/praisonai.rb b/praisonai.rb index 50e608d..15a5d1e 100644 --- a/praisonai.rb +++ b/praisonai.rb @@ -3,7 +3,7 @@ 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/0.1.1.tar.gz" + url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/0.1.2.tar.gz" sha256 "1828fb9227d10f991522c3f24f061943a254b667196b40b1a3e4a54a8d30ce32" # Replace with actual SHA256 checksum license "MIT" diff --git a/praisonai/deploy.py b/praisonai/deploy.py index 3c754f2..f93fd23 100644 --- a/praisonai/deploy.py +++ b/praisonai/deploy.py @@ -56,7 +56,7 @@ def create_dockerfile(self): file.write("FROM python:3.11-slim\n") file.write("WORKDIR /app\n") file.write("COPY . .\n") - file.write("RUN pip install flask praisonai==0.1.1 gunicorn markdown\n") + file.write("RUN pip install flask praisonai==0.1.2 gunicorn markdown\n") file.write("EXPOSE 8080\n") file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n') diff --git a/praisonai/ui/realtime.py b/praisonai/ui/realtime.py index 3c2a7b3..f8a261e 100644 --- a/praisonai/ui/realtime.py +++ b/praisonai/ui/realtime.py @@ -144,6 +144,50 @@ def load_setting(key: str) -> str: client = AsyncOpenAI() +# Add these new imports and code +import importlib.util +import logging +from importlib import import_module +from pathlib import Path + +# Set up logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +# Try to import tools from the root directory +root_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +tools_path = os.path.join(root_dir, 'tools.py') +logger.info(f"Tools path: {tools_path}") + +def import_tools_from_file(file_path): + spec = importlib.util.spec_from_file_location("custom_tools", file_path) + custom_tools_module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(custom_tools_module) + logger.debug(f"Imported tools from {file_path}") + logger.debug(f"Tools: {custom_tools_module}") + return custom_tools_module + +try: + if os.path.exists(tools_path): + # tools.py exists in the root directory, import from file + custom_tools_module = import_tools_from_file(tools_path) + logger.info("Successfully imported custom tools from root tools.py") + else: + logger.info("No custom tools.py file found in the root directory") + custom_tools_module = None + + if custom_tools_module: + # Update the tools list with custom tools + if hasattr(custom_tools_module, 'tools') and isinstance(custom_tools_module.tools, list): + tools.extend(custom_tools_module.tools) + else: + for name, obj in custom_tools_module.__dict__.items(): + if callable(obj) and not name.startswith("__"): + tools.append(({"type": "function", "function": obj}, obj)) + +except Exception as e: + logger.warning(f"Error importing custom tools: {str(e)}. Continuing without custom tools.") + @cl.on_chat_start async def start(): initialize_db() @@ -365,4 +409,6 @@ async def on_chat_resume(thread: ThreadDict): cl.user_session.set("message_history", message_history) # Reconnect to OpenAI realtime - await setup_openai_realtime() \ No newline at end of file + await setup_openai_realtime() + + \ No newline at end of file diff --git a/praisonai/ui/realtimeclient/__init__.py b/praisonai/ui/realtimeclient/__init__.py index bb8a6e1..e6931c3 100644 --- a/praisonai/ui/realtimeclient/__init__.py +++ b/praisonai/ui/realtimeclient/__init__.py @@ -552,6 +552,7 @@ async def update_session(self, **kwargs): for key in self.tools ] session = {**self.session_config, "tools": use_tools} + logger.debug(f"Updating session: {session}") if self.realtime.is_connected(): await self.realtime.send("session.update", {"session": session}) return True diff --git a/pyproject.toml b/pyproject.toml index 23e4115..c10c6c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "PraisonAI" -version = "0.1.1" +version = "0.1.2" description = "PraisonAI application combines AutoGen and CrewAI or similar frameworks into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customization, and efficient human-agent collaboration." authors = ["Mervin Praison"] license = "" diff --git a/tools.py b/tools.py index ddef17f..2e3ef0e 100644 --- a/tools.py +++ b/tools.py @@ -1,7 +1,227 @@ # # tools.py + +# from google.oauth2.credentials import Credentials +# from googleapiclient.discovery import build +# from google.auth.transport.requests import Request +# from google_auth_oauthlib.flow import Flow +# from google_auth_oauthlib.flow import InstalledAppFlow +# import os +# import json +# import webbrowser +# from http.server import HTTPServer, BaseHTTPRequestHandler +# from urllib.parse import urlparse, parse_qs +# import threading +# from datetime import datetime, timedelta +# import logging + +# # Set up logging +# log_level = os.getenv('LOGLEVEL', 'INFO').upper() +# logging.basicConfig(level=log_level) +# logger = logging.getLogger(__name__) +# logger.setLevel(log_level) + +# # Set up Google Calendar API +# SCOPES = ['https://www.googleapis.com/auth/calendar'] + +# def get_calendar_service(): +# logger.debug("Getting calendar service") +# creds = None +# token_dir = os.path.join(os.path.expanduser('~'), '.praison') +# token_path = os.path.join(token_dir, 'token.json') +# credentials_path = os.path.join(os.getcwd(), 'credentials.json') + +# if os.path.exists(token_path): +# creds = Credentials.from_authorized_user_file(token_path, SCOPES) +# logger.debug(f"Credentials loaded from {token_path}") + +# if not creds or not creds.valid: +# if creds and creds.expired and creds.refresh_token: +# logger.debug(f"Refreshing credentials") +# creds.refresh(Request()) +# else: +# logger.debug(f"Starting new OAuth 2.0 flow") +# flow = InstalledAppFlow.from_client_secrets_file(credentials_path, SCOPES) +# logger.debug(f"Credentials path: {credentials_path}") +# creds = flow.run_local_server(port=8090) +# logger.debug(f"Setting up flow from {credentials_path}") +# # creds = flow.run_local_server(port=8090) # Use run_local_server from InstalledAppFlow + +# # Ensure the ~/.praison directory exists +# os.makedirs(os.path.dirname(token_path), exist_ok=True) +# logger.debug(f"Saving credentials to {token_path}") +# with open(token_path, 'w') as token: +# token.write(creds.to_json()) + +# logger.debug("Building calendar service") +# return build('calendar', 'v3', credentials=creds) + + +# check_calendar_def = { +# "name": "check_calendar", +# "description": "Check Google Calendar for events within a specified time range", +# "parameters": { +# "type": "object", +# "properties": { +# "start_time": {"type": "string", "description": "Start time in ISO format (e.g., '2023-04-20T09:00:00-07:00')"}, +# "end_time": {"type": "string", "description": "End time in ISO format (e.g., '2023-04-20T17:00:00-07:00')"} +# }, +# "required": ["start_time", "end_time"] +# } +# } + +# async def check_calendar_handler(start_time, end_time): +# try: +# service = get_calendar_service() +# events_result = service.events().list(calendarId='primary', timeMin=start_time, +# timeMax=end_time, singleEvents=True, +# orderBy='startTime').execute() +# events = events_result.get('items', []) +# logger.debug(f"Found {len(events)} events in the calendar") +# logger.debug(f"Events: {events}") +# return json.dumps(events) +# except Exception as e: +# return {"error": str(e)} + +# check_calendar = (check_calendar_def, check_calendar_handler) + +# add_calendar_event_def = { +# "name": "add_calendar_event", +# "description": "Add a new event to Google Calendar", +# "parameters": { +# "type": "object", +# "properties": { +# "summary": {"type": "string", "description": "Event title"}, +# "start_time": {"type": "string", "description": "Start time in ISO format"}, +# "end_time": {"type": "string", "description": "End time in ISO format"}, +# "description": {"type": "string", "description": "Event description"} +# }, +# "required": ["summary", "start_time", "end_time"] +# } +# } + +# async def add_calendar_event_handler(summary, start_time, end_time, description=""): +# try: +# service = get_calendar_service() +# event = { +# 'summary': summary, +# 'description': description, +# 'start': {'dateTime': start_time, 'timeZone': 'UTC'}, +# 'end': {'dateTime': end_time, 'timeZone': 'UTC'}, +# } +# event = service.events().insert(calendarId='primary', body=event).execute() +# logger.debug(f"Event added: {event}") +# return {"status": "success", "event_id": event['id']} +# except Exception as e: +# return {"error": str(e)} + +# add_calendar_event = (add_calendar_event_def, add_calendar_event_handler) + +# list_calendar_events_def = { +# "name": "list_calendar_events", +# "description": "List Google Calendar events for a specific date", +# "parameters": { +# "type": "object", +# "properties": { +# "date": {"type": "string", "description": "Date in YYYY-MM-DD format"} +# }, +# "required": ["date"] +# } +# } + +# async def list_calendar_events_handler(date): +# try: +# service = get_calendar_service() +# start_of_day = f"{date}T00:00:00Z" +# end_of_day = f"{date}T23:59:59Z" +# events_result = service.events().list(calendarId='primary', timeMin=start_of_day, +# timeMax=end_of_day, singleEvents=True, +# orderBy='startTime').execute() +# events = events_result.get('items', []) +# logger.debug(f"Found {len(events)} events in the calendar for {date}") +# logger.debug(f"Events: {events}") +# return json.dumps(events) +# except Exception as e: +# return {"error": str(e)} + +# list_calendar_events = (list_calendar_events_def, list_calendar_events_handler) + +# update_calendar_event_def = { +# "name": "update_calendar_event", +# "description": "Update an existing Google Calendar event", +# "parameters": { +# "type": "object", +# "properties": { +# "event_id": {"type": "string", "description": "ID of the event to update"}, +# "summary": {"type": "string", "description": "New event title"}, +# "start_time": {"type": "string", "description": "New start time in ISO format"}, +# "end_time": {"type": "string", "description": "New end time in ISO format"}, +# "description": {"type": "string", "description": "New event description"} +# }, +# "required": ["event_id"] +# } +# } + +# async def update_calendar_event_handler(event_id, summary=None, start_time=None, end_time=None, description=None): +# try: +# service = get_calendar_service() +# event = service.events().get(calendarId='primary', eventId=event_id).execute() + +# if summary: +# event['summary'] = summary +# if description: +# event['description'] = description +# if start_time: +# event['start'] = {'dateTime': start_time, 'timeZone': 'UTC'} +# if end_time: +# event['end'] = {'dateTime': end_time, 'timeZone': 'UTC'} + +# updated_event = service.events().update(calendarId='primary', eventId=event_id, body=event).execute() +# logger.debug(f"Event updated: {updated_event}") +# return {"status": "success", "updated_event": updated_event} +# except Exception as e: +# return {"error": str(e)} + +# update_calendar_event = (update_calendar_event_def, update_calendar_event_handler) + +# delete_calendar_event_def = { +# "name": "delete_calendar_event", +# "description": "Delete a Google Calendar event", +# "parameters": { +# "type": "object", +# "properties": { +# "event_id": {"type": "string", "description": "ID of the event to delete"} +# }, +# "required": ["event_id"] +# } +# } + +# async def delete_calendar_event_handler(event_id): +# try: +# service = get_calendar_service() +# service.events().delete(calendarId='primary', eventId=event_id).execute() +# logger.debug(f"Event deleted: {event_id}") +# return {"status": "success", "message": f"Event with ID {event_id} has been deleted"} +# except Exception as e: +# return {"error": str(e)} + +# delete_calendar_event = (delete_calendar_event_def, delete_calendar_event_handler) + + + +# tools = [ +# check_calendar, +# add_calendar_event, +# list_calendar_events, +# update_calendar_event, +# delete_calendar_event, +# ] + + + + + # from duckduckgo_search import DDGS # from praisonai_tools import BaseTool - # class InternetSearchTool(BaseTool): # name: str = "InternetSearchTool" # description: str = "Search Internet for relevant information based on a query or latest news"