From 23ec867aada31949eaa4e08a4c68b57302a0421e Mon Sep 17 00:00:00 2001 From: MervinPraison Date: Mon, 25 Mar 2024 23:39:08 +0000 Subject: [PATCH] Version 0.0.10 --- .env.example | 3 ++ Dockerfile | 7 +++ README.md | 125 +++++++++++++++++++++++++++++++++++++++++++- api.py | 17 ++++++ example.py | 12 ++--- poetry.lock | 114 +++++++++++++++++++++++++++++++--------- praisonai/auto.py | 6 +-- praisonai/cli.py | 27 ++++++++-- praisonai/deploy.py | 35 +++++++++++++ pyproject.toml | 3 +- 10 files changed, 306 insertions(+), 43 deletions(-) create mode 100644 .env.example create mode 100644 Dockerfile create mode 100644 api.py create mode 100644 praisonai/deploy.py diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..51a41aae --- /dev/null +++ b/.env.example @@ -0,0 +1,3 @@ +OPENAI_MODEL_NAME="gpt-4-turbo-preview" +OPENAI_API_KEY="Enter your API key" +OPENAI_API_BASE="https://api.openai.com/v1" \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..00dadf6a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3.11-slim +WORKDIR /app +# Copy only api.py and agents.yaml to /app in the container +COPY api.py agents.yaml ./ +RUN pip install flask praisonai gunicorn +EXPOSE 8080 +CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"] \ No newline at end of file diff --git a/README.md b/README.md index 829d669c..91ff1d8c 100644 --- a/README.md +++ b/README.md @@ -8,14 +8,137 @@ Praison AI, leveraging both AutoGen and CrewAI or any other agent framework, rep pip install praisonai ``` +## Initialise + +```bash +praisonai --init create a movie script about dog in moon +``` +This will automatically create agents.yaml file in the current directory. + + ## Run ```bash praisonai ``` +or + +```bash +python -m praisonai +``` + +### Specify the agent framework + +```bash +praisonai --framework autogen +``` + +### Full Automatic Mode + +```bash +praisonai --auto create a movie script about Dog in Moon +``` + ## Test ```bash python -m unittest tests.test -``` \ No newline at end of file +``` + +## Agents Playbook + +```yaml +framework: crewai +topic: Artificial Intelligence +roles: + movie_concept_creator: + backstory: 'Creative thinker with a deep understanding of cinematic storytelling, + capable of using AI-generated storylines to create unique and compelling movie + ideas.' + goal: Generate engaging movie concepts using AI storylines + role: Movie Concept Creator + tasks: + movie_concept_development: + description: 'Develop movie concepts from AI-generated storylines, ensuring + they are engaging and have strong narrative arcs.' + expected_output: 'Well-structured movie concept document with character + bios, settings, and plot outlines.' + screenwriter: + backstory: 'Expert in writing engaging dialogue and script structure, able to + turn movie concepts into production-ready scripts.' + goal: Write compelling scripts based on movie concepts + role: Screenwriter + tasks: + scriptwriting_task: + description: 'Turn movie concepts into polished scripts with well-developed + characters, strong dialogue, and effective scene transitions.' + expected_output: 'Production-ready script with a beginning, middle, and + end, along with character development and engaging dialogues.' + editor: + backstory: 'Adept at identifying inconsistencies, improving language usage, + and maintaining the overall flow of the script.' + goal: Refine the scripts and ensure continuity of the movie storyline + role: Editor + tasks: + editing_task: + description: 'Review, edit, and refine the scripts to ensure they are cohesive + and follow a well-structured narrative.' + expected_output: 'A polished final draft of the script with no inconsistencies, + strong character development, and effective dialogue.' +dependencies: [] +``` + +## Include praisonai package in your project + +```python +from praisonai import PraisonAI + +def basic(): # Basic Mode + praison_ai = PraisonAI(agent_file="agents.yaml") + praison_ai.main() + +def advanced(): # Advanced Mode with options + praison_ai = PraisonAI( + agent_file="agents.yaml", + framework="autogen", + ) + praison_ai.main() + +def auto(): # Full Automatic Mode + praison_ai = PraisonAI( + auto="Create a movie script about car in mars", + framework="autogen" + ) + print(praison_ai.framework) + praison_ai.main() + +if __name__ == "__main__": + basic() + advanced() + auto() +``` + +## Deploy + +```bash +gcloud init +export OPENAI_MODEL_NAME="gpt-4-turbo-preview" +export OPENAI_API_KEY="Enter your API key" +export OPENAI_API_BASE="https://api.openai.com/v1" + +yes | gcloud auth configure-docker us-central1-docker.pkg.dev +gcloud artifacts repositories create praisonai-repository --repository-format=docker --location=us-central1 + +PROJECT_ID=$(gcloud config get-value project) +TAG="latest" +docker build --platform linux/amd64 -t gcr.io/${PROJECT_ID}/praisonai-app:${TAG} . +docker tag gcr.io/${PROJECT_ID}/praisonai-app:${TAG} us-central1-docker.pkg.dev/${PROJECT_ID}/praisonai-repository/praisonai-app:${TAG} +docker push us-central1-docker.pkg.dev/${PROJECT_ID}/praisonai-repository/praisonai-app:${TAG} + +gcloud run deploy praisonai-service \ + --image us-central1-docker.pkg.dev/${PROJECT_ID}/praisonai-repository/praisonai-app:${TAG} \ + --platform managed \ + --region us-central1 \ + --allow-unauthenticated \ + --set-env-vars OPENAI_MODEL_NAME=${OPENAI_MODEL_NAME},OPENAI_API_KEY=${OPENAI_API_KEY},OPENAI_API_BASE=${OPENAI_API_BASE} \ No newline at end of file diff --git a/api.py b/api.py new file mode 100644 index 00000000..36e51f45 --- /dev/null +++ b/api.py @@ -0,0 +1,17 @@ +# api.py +from flask import Flask +from praisonai import PraisonAI + +app = Flask(__name__) + +def basic(): + praison_ai = PraisonAI(agent_file="agents.yaml") + return praison_ai.main() + +@app.route('/') +def home(): + basic() + return basic() + +if __name__ == "__main__": + app.run(debug=True) \ No newline at end of file diff --git a/example.py b/example.py index 8b5adc92..10ea82a0 100644 --- a/example.py +++ b/example.py @@ -1,17 +1,17 @@ from praisonai import PraisonAI -def main(): +def basic(): praison_ai = PraisonAI(agent_file="agents.yaml") praison_ai.main() -def configuration(): +def advanced(): praison_ai = PraisonAI( agent_file="agents.yaml", framework="autogen", ) praison_ai.main() -def automatic(): +def auto(): praison_ai = PraisonAI( auto="Create a movie script about car in mars", framework="autogen" @@ -20,6 +20,6 @@ def automatic(): praison_ai.main() if __name__ == "__main__": - main() - configuration() - automatic() \ No newline at end of file + basic() + advanced() + auto() \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 32e7bb6e..0ddf1e97 100644 --- a/poetry.lock +++ b/poetry.lock @@ -218,6 +218,17 @@ tests = ["attrs[tests-no-zope]", "zope-interface"] tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] +[[package]] +name = "blinker" +version = "1.7.0" +description = "Fast, simple object-to-object and broadcast signaling" +optional = false +python-versions = ">=3.8" +files = [ + {file = "blinker-1.7.0-py3-none-any.whl", hash = "sha256:c3f865d4d54db7abc53758a01601cf343fe55b84c1de4e3fa910e420b438d5b9"}, + {file = "blinker-1.7.0.tar.gz", hash = "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182"}, +] + [[package]] name = "certifi" version = "2024.2.2" @@ -611,18 +622,18 @@ files = [ [[package]] name = "filelock" -version = "3.13.1" +version = "3.13.3" description = "A platform independent file lock." optional = false python-versions = ">=3.8" files = [ - {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, - {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, + {file = "filelock-3.13.3-py3-none-any.whl", hash = "sha256:5ffa845303983e7a0b7ae17636509bc97997d58afeafa72fb141a17b152284cb"}, + {file = "filelock-3.13.3.tar.gz", hash = "sha256:a79895a25bbefdf55d1a2a0a80968f7dbb28edcd6d4234a0afb3f37ecde4b546"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] typing = ["typing-extensions (>=4.8)"] [[package]] @@ -662,6 +673,28 @@ test = ["catboost (>=0.26,<1.2)", "coverage (>=5.3)", "dataclasses", "datasets", ts-forecast = ["hcrystalball (==0.1.10)", "holidays (<0.14)", "prophet (>=1.0.1)", "statsmodels (>=0.12.2)"] vw = ["scikit-learn", "vowpalwabbit (>=8.10.0,<9.0.0)"] +[[package]] +name = "flask" +version = "3.0.2" +description = "A simple framework for building complex web applications." +optional = false +python-versions = ">=3.8" +files = [ + {file = "flask-3.0.2-py3-none-any.whl", hash = "sha256:3232e0e9c850d781933cf0207523d1ece087eb8d87b23777ae38456e2fbe7c6e"}, + {file = "flask-3.0.2.tar.gz", hash = "sha256:822c03f4b799204250a7ee84b1eddc40665395333973dfb9deebfe425fefcb7d"}, +] + +[package.dependencies] +blinker = ">=1.6.2" +click = ">=8.1.3" +itsdangerous = ">=2.1.2" +Jinja2 = ">=3.1.2" +Werkzeug = ">=3.0.0" + +[package.extras] +async = ["asgiref (>=3.2)"] +dotenv = ["python-dotenv"] + [[package]] name = "fonttools" version = "4.50.0" @@ -867,13 +900,13 @@ grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] [[package]] name = "gradio" -version = "4.22.0" +version = "4.23.0" description = "Python library for easily interacting with trained machine learning models" optional = false python-versions = ">=3.8" files = [ - {file = "gradio-4.22.0-py3-none-any.whl", hash = "sha256:f8bfff36ee1c1219610f58d0f597864e3e99edcebfeafabed1557e99af8b2626"}, - {file = "gradio-4.22.0.tar.gz", hash = "sha256:9e1ad3e74f71077f91f8717a4c5e404069dfb9f4fa88d9b38f16607152fb7c1a"}, + {file = "gradio-4.23.0-py3-none-any.whl", hash = "sha256:a5be2485f967fed83b82395b345caee28dfd15cdfe7a487b5817f31803981b5a"}, + {file = "gradio-4.23.0.tar.gz", hash = "sha256:f75772a5316e4492e49f3e52aaa9f7d9325b7d2b15594ba50fcabbf169ecd166"}, ] [package.dependencies] @@ -881,7 +914,7 @@ aiofiles = ">=22.0,<24.0" altair = ">=4.2.0,<6.0" fastapi = "*" ffmpy = "*" -gradio-client = "0.13.0" +gradio-client = "0.14.0" httpx = ">=0.24.1" huggingface-hub = ">=0.19.3" importlib-resources = ">=1.3,<7.0" @@ -897,25 +930,25 @@ pydantic = ">=2.0" pydub = "*" python-multipart = ">=0.0.9" pyyaml = ">=5.0,<7.0" -ruff = ">=0.2.2" +ruff = {version = ">=0.2.2", markers = "sys_platform != \"emscripten\""} semantic-version = ">=2.0,<3.0" tomlkit = "0.12.0" typer = {version = ">=0.9,<1.0", extras = ["all"]} typing-extensions = ">=4.0,<5.0" -uvicorn = ">=0.14.0" +uvicorn = {version = ">=0.14.0", markers = "sys_platform != \"emscripten\""} [package.extras] oauth = ["authlib", "itsdangerous"] [[package]] name = "gradio-client" -version = "0.13.0" +version = "0.14.0" description = "Python library for easily interacting with trained machine learning models" optional = false python-versions = ">=3.8" files = [ - {file = "gradio_client-0.13.0-py3-none-any.whl", hash = "sha256:f47225bb274834a33a297b5bba95250b63a76ae9f90217631e1e29e90cd857f1"}, - {file = "gradio_client-0.13.0.tar.gz", hash = "sha256:273b51cc86a39c7ec8ebdda6c8110687e5225c187d25d4a723d15e57edc5c549"}, + {file = "gradio_client-0.14.0-py3-none-any.whl", hash = "sha256:fdce4ecabc1d06d40bffd18923c9710b021d012edba8a1f851bc109eb9ee443e"}, + {file = "gradio_client-0.14.0.tar.gz", hash = "sha256:18be8d5fb6468729f19547b39d89b66ec9e775d0c5ce9666cc940f11ab1a519c"}, ] [package.dependencies] @@ -1055,13 +1088,13 @@ socks = ["socksio (==1.*)"] [[package]] name = "huggingface-hub" -version = "0.21.4" +version = "0.22.0" description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub" optional = false python-versions = ">=3.8.0" files = [ - {file = "huggingface_hub-0.21.4-py3-none-any.whl", hash = "sha256:df37c2c37fc6c82163cdd8a67ede261687d80d1e262526d6c0ce73b6b3630a7b"}, - {file = "huggingface_hub-0.21.4.tar.gz", hash = "sha256:e1f4968c93726565a80edf6dc309763c7b546d0cfe79aa221206034d50155531"}, + {file = "huggingface_hub-0.22.0-py3-none-any.whl", hash = "sha256:72dea96299751699180184c06a4689e54cbfacecb1a3d08ac7a269c884bb17c3"}, + {file = "huggingface_hub-0.22.0.tar.gz", hash = "sha256:304f1e235c68c0a9f58bced47f13d6df241a5b4e3678f4981aa1e4f4bce63f6d"}, ] [package.dependencies] @@ -1074,15 +1107,16 @@ tqdm = ">=4.42.1" typing-extensions = ">=3.7.4.3" [package.extras] -all = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "gradio", "jedi", "mypy (==1.5.1)", "numpy", "pydantic (>1.1,<2.0)", "pydantic (>1.1,<3.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.1.3)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] +all = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "gradio", "jedi", "minijinja (>=1.0)", "mypy (==1.5.1)", "numpy", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.3.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] cli = ["InquirerPy (==0.3.4)"] -dev = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "gradio", "jedi", "mypy (==1.5.1)", "numpy", "pydantic (>1.1,<2.0)", "pydantic (>1.1,<3.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.1.3)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] +dev = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "gradio", "jedi", "minijinja (>=1.0)", "mypy (==1.5.1)", "numpy", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.3.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] fastai = ["fastai (>=2.4)", "fastcore (>=1.3.27)", "toml"] hf-transfer = ["hf-transfer (>=0.1.4)"] -inference = ["aiohttp", "pydantic (>1.1,<2.0)", "pydantic (>1.1,<3.0)"] -quality = ["mypy (==1.5.1)", "ruff (>=0.1.3)"] +inference = ["aiohttp", "minijinja (>=1.0)"] +quality = ["mypy (==1.5.1)", "ruff (>=0.3.0)"] tensorflow = ["graphviz", "pydot", "tensorflow"] -testing = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "gradio", "jedi", "numpy", "pydantic (>1.1,<2.0)", "pydantic (>1.1,<3.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "soundfile", "urllib3 (<2.0)"] +tensorflow-testing = ["keras (<3.0)", "tensorflow"] +testing = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "gradio", "jedi", "minijinja (>=1.0)", "numpy", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "soundfile", "urllib3 (<2.0)"] torch = ["safetensors", "torch"] typing = ["types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)"] @@ -1165,6 +1199,17 @@ rich = ">=13.7.0,<14.0.0" tenacity = ">=8.2.3,<9.0.0" typer = ">=0.9.0,<0.10.0" +[[package]] +name = "itsdangerous" +version = "2.1.2" +description = "Safely pass data to untrusted environments and back." +optional = false +python-versions = ">=3.7" +files = [ + {file = "itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"}, + {file = "itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"}, +] + [[package]] name = "jinja2" version = "3.1.3" @@ -1849,13 +1894,13 @@ files = [ [[package]] name = "openai" -version = "1.14.2" +version = "1.14.3" description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-1.14.2-py3-none-any.whl", hash = "sha256:a48b3c4d635b603952189ac5a0c0c9b06c025b80eb2900396939f02bb2104ac3"}, - {file = "openai-1.14.2.tar.gz", hash = "sha256:e5642f7c02cf21994b08477d7bb2c1e46d8f335d72c26f0396c5f89b15b5b153"}, + {file = "openai-1.14.3-py3-none-any.whl", hash = "sha256:7a465994a7ccf677a110c6cc2ef9d86229bad42c060b585b67049aa749f3b774"}, + {file = "openai-1.14.3.tar.gz", hash = "sha256:37b514e9c0ff45383ec9b242abd0f7859b1080d4b54b61393ed341ecad1b8eb9"}, ] [package.dependencies] @@ -3403,6 +3448,23 @@ files = [ {file = "websockets-11.0.3.tar.gz", hash = "sha256:88fc51d9a26b10fc331be344f1781224a375b78488fc343620184e95a4b27016"}, ] +[[package]] +name = "werkzeug" +version = "3.0.1" +description = "The comprehensive WSGI web application library." +optional = false +python-versions = ">=3.8" +files = [ + {file = "werkzeug-3.0.1-py3-none-any.whl", hash = "sha256:90a285dc0e42ad56b34e696398b8122ee4c681833fb35b8334a095d82c56da10"}, + {file = "werkzeug-3.0.1.tar.gz", hash = "sha256:507e811ecea72b18a404947aded4b3390e1db8f826b494d76550ef45bb3b1dcc"}, +] + +[package.dependencies] +MarkupSafe = ">=2.1.1" + +[package.extras] +watchdog = ["watchdog (>=2.3)"] + [[package]] name = "wrapt" version = "1.16.0" @@ -3606,4 +3668,4 @@ tools = [] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.13" -content-hash = "99265c9b260449d4938036ca6e5d271ae03fe60a55c3d3b8e30427b61a09caf2" +content-hash = "2ddc23d281ea17f8693d6df925b83d2da323ef7cbc05301a3191b80ee65c0fb7" diff --git a/praisonai/auto.py b/praisonai/auto.py index 62bc25c6..558cbc12 100644 --- a/praisonai/auto.py +++ b/praisonai/auto.py @@ -70,8 +70,6 @@ def convert_and_save(self, json_data): "roles": {}, "dependencies": [] } - print(self.topic) - print(self.framework) for role_id, role_details in json_data['roles'].items(): yaml_data['roles'][role_id] = { @@ -131,5 +129,5 @@ def get_user_content(self): return user_content -generator = AutoGenerator(framework="crewai", topic="Create a snake game in python") -print(generator.generate()) \ No newline at end of file +# generator = AutoGenerator(framework="crewai", topic="Create a snake game in python") +# print(generator.generate()) \ No newline at end of file diff --git a/praisonai/cli.py b/praisonai/cli.py index b82d7f06..a519af48 100644 --- a/praisonai/cli.py +++ b/praisonai/cli.py @@ -13,7 +13,7 @@ from .auto import AutoGenerator class PraisonAI: - def __init__(self, agent_file="agents.yaml", framework="crewai", auto=False): + def __init__(self, agent_file="agents.yaml", framework="crewai", auto=False, init=False): self.config_list = [ { 'model': os.environ.get("OPENAI_MODEL_NAME", "gpt-4-turbo-preview"), @@ -23,6 +23,7 @@ def __init__(self, agent_file="agents.yaml", framework="crewai", auto=False): self.agent_file = agent_file self.framework = framework self.auto = auto + self.init = init def generate_crew_and_kickoff(self): with open(self.agent_file, 'r') as f: @@ -123,16 +124,24 @@ def main(self): full_path = os.path.abspath(self.agent_file) self.filename = full_path - if args.auto: - self.topic = ' '.join(args.auto) - elif self.auto: # Use the auto attribute if args.auto is not provided + if args.auto or args.init: + temp_topic = ' '.join(args.auto) if args.auto else ' '.join(args.init) + self.topic = temp_topic + elif self.auto or self.init: # Use the auto attribute if args.auto is not provided self.topic = self.auto if args.auto or self.auto: + self.filename = "test.yaml" generator = AutoGenerator(topic=self.topic , framework=self.framework) self.agent_file = generator.generate() result = self.generate_crew_and_kickoff() return result + elif args.init or self.init: + self.filename = "agents.yaml" + generator = AutoGenerator(topic=self.topic , framework=self.framework, filename=self.filename) + self.agent_file = generator.generate() + print("File {} created successfully".format(self.agent_file)) + return "File {} created successfully".format(self.agent_file) if ui: self.create_gradio_interface() @@ -145,9 +154,17 @@ def parse_args(self): parser.add_argument("--framework", choices=["crewai", "autogen"], default="crewai", help="Specify the framework") parser.add_argument("--ui", action="store_true", help="Enable UI mode") parser.add_argument("--auto", nargs=argparse.REMAINDER, help="Enable auto mode and pass arguments for it") + parser.add_argument("--init", nargs=argparse.REMAINDER, help="Enable auto mode and pass arguments for it") parser.add_argument("agent_file", nargs="?", help="Specify the agent file") + parser.add_argument("-b", "--bind", help=argparse.SUPPRESS) # This will catch and ignore -b + + args = parser.parse_args() + + # If -b was provided, remove it and its value from args + if hasattr(args, "bind") and args.bind is not None: + delattr(args, "bind") - return parser.parse_args() + return args def create_gradio_interface(self): def generate_crew_and_kickoff_interface(agent_file, framework): diff --git a/praisonai/deploy.py b/praisonai/deploy.py new file mode 100644 index 00000000..86516490 --- /dev/null +++ b/praisonai/deploy.py @@ -0,0 +1,35 @@ +import subprocess +import os +from dotenv import load_dotenv + +class CloudDeployer: + def __init__(self): + # Load environment variables from .env file or system + load_dotenv() + self.set_environment_variables() + + def set_environment_variables(self): + """Sets environment variables with fallback to .env values or defaults.""" + os.environ["OPENAI_MODEL_NAME"] = os.getenv("OPENAI_MODEL_NAME", "gpt-4-turbo-preview") + os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY", "Enter your API key") + os.environ["OPENAI_API_BASE"] = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1") + + def run_commands(self): + """Runs a sequence of shell commands for deployment.""" + commands = [ + "yes | gcloud auth configure-docker us-central1-docker.pkg.dev", + "gcloud artifacts repositories create praisonai-repository --repository-format=docker --location=us-central1", + "$(gcloud config get-value project)", + "docker build --platform linux/amd64 -t gcr.io/$(gcloud config get-value project)/praisonai-app:latest .", + "docker tag gcr.io/$(gcloud config get-value project)/praisonai-app:latest us-central1-docker.pkg.dev/$(gcloud config get-value project)/praisonai-repository/praisonai-app:latest", + "docker push us-central1-docker.pkg.dev/$(gcloud config get-value project)/praisonai-repository/praisonai-app:latest", + "gcloud run deploy praisonai-service --image us-central1-docker.pkg.dev/$(gcloud config get-value project)/praisonai-repository/praisonai-app:latest --platform managed --region us-central1 --allow-unauthenticated --set-env-vars OPENAI_MODEL_NAME=${OPENAI_MODEL_NAME},OPENAI_API_KEY=${OPENAI_API_KEY},OPENAI_API_BASE=${OPENAI_API_BASE}" + ] + + for cmd in commands: + subprocess.run(cmd, shell=True, check=True) + +# Usage +if __name__ == "__main__": + deployer = CloudDeployer() + deployer.run_commands() diff --git a/pyproject.toml b/pyproject.toml index 515cef1d..a4f6f80c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "praisonAI" -version = "0.0.8" +version = "0.0.10" 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 = "" @@ -19,6 +19,7 @@ rich = ">=13.7" pyautogen = ">=0.2.19" crewai = ">=0.22.5" gradio = ">=4.20.0" +Flask = ">=3.0.0" [tool.poetry.dev-dependencies] pytest = "^5.2"