PraisonAI 0.0.59__cp312-cp312-manylinux_2_35_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of PraisonAI might be problematic. Click here for more details.
- praisonai/__init__.py +6 -0
- praisonai/__main__.py +10 -0
- praisonai/agents_generator.py +381 -0
- praisonai/auto.py +190 -0
- praisonai/chainlit_ui.py +304 -0
- praisonai/cli.py +416 -0
- praisonai/deploy.py +138 -0
- praisonai/inbuilt_tools/__init__.py +2 -0
- praisonai/inbuilt_tools/autogen_tools.py +209 -0
- praisonai/inc/__init__.py +2 -0
- praisonai/inc/config.py +96 -0
- praisonai/inc/models.py +128 -0
- praisonai/public/android-chrome-192x192.png +0 -0
- praisonai/public/android-chrome-512x512.png +0 -0
- praisonai/public/apple-touch-icon.png +0 -0
- praisonai/public/fantasy.svg +3 -0
- praisonai/public/favicon-16x16.png +0 -0
- praisonai/public/favicon-32x32.png +0 -0
- praisonai/public/favicon.ico +0 -0
- praisonai/public/game.svg +3 -0
- praisonai/public/logo_dark.png +0 -0
- praisonai/public/logo_light.png +0 -0
- praisonai/public/movie.svg +3 -0
- praisonai/public/thriller.svg +3 -0
- praisonai/setup/__init__.py +0 -0
- praisonai/setup/build.py +21 -0
- praisonai/setup/config.yaml +60 -0
- praisonai/setup/post_install.py +20 -0
- praisonai/setup/setup_conda_env.py +25 -0
- praisonai/setup/setup_conda_env.sh +72 -0
- praisonai/test.py +105 -0
- praisonai/train.py +276 -0
- praisonai/ui/chat.py +304 -0
- praisonai/ui/code.py +318 -0
- praisonai/ui/context.py +283 -0
- praisonai/ui/public/fantasy.svg +3 -0
- praisonai/ui/public/game.svg +3 -0
- praisonai/ui/public/logo_dark.png +0 -0
- praisonai/ui/public/logo_light.png +0 -0
- praisonai/ui/public/movie.svg +3 -0
- praisonai/ui/public/thriller.svg +3 -0
- praisonai/ui/sql_alchemy.py +638 -0
- praisonai/version.py +1 -0
- praisonai-0.0.59.dist-info/LICENSE +20 -0
- praisonai-0.0.59.dist-info/METADATA +344 -0
- praisonai-0.0.59.dist-info/RECORD +48 -0
- praisonai-0.0.59.dist-info/WHEEL +4 -0
- praisonai-0.0.59.dist-info/entry_points.txt +5 -0
praisonai/cli.py
ADDED
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
# praisonai/cli.py
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from .version import __version__
|
|
5
|
+
import yaml, os
|
|
6
|
+
from rich import print
|
|
7
|
+
from dotenv import load_dotenv
|
|
8
|
+
from crewai import Agent, Task, Crew
|
|
9
|
+
load_dotenv()
|
|
10
|
+
import autogen
|
|
11
|
+
import argparse
|
|
12
|
+
from .auto import AutoGenerator
|
|
13
|
+
from .agents_generator import AgentsGenerator
|
|
14
|
+
from .inbuilt_tools import *
|
|
15
|
+
from .inc.config import generate_config
|
|
16
|
+
import shutil
|
|
17
|
+
import subprocess
|
|
18
|
+
import logging
|
|
19
|
+
logging.basicConfig(level=os.environ.get('LOGLEVEL', 'INFO'), format='%(asctime)s - %(levelname)s - %(message)s')
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
from chainlit.cli import chainlit_run
|
|
23
|
+
CHAINLIT_AVAILABLE = True
|
|
24
|
+
except ImportError:
|
|
25
|
+
CHAINLIT_AVAILABLE = False
|
|
26
|
+
|
|
27
|
+
try:
|
|
28
|
+
import gradio as gr
|
|
29
|
+
GRADIO_AVAILABLE = True
|
|
30
|
+
except ImportError:
|
|
31
|
+
GRADIO_AVAILABLE = False
|
|
32
|
+
|
|
33
|
+
def stream_subprocess(command, env=None):
|
|
34
|
+
"""
|
|
35
|
+
Execute a subprocess command and stream the output to the terminal in real-time.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
command (list): A list containing the command and its arguments.
|
|
39
|
+
env (dict, optional): Environment variables for the subprocess.
|
|
40
|
+
"""
|
|
41
|
+
process = subprocess.Popen(
|
|
42
|
+
command,
|
|
43
|
+
stdout=subprocess.PIPE,
|
|
44
|
+
stderr=subprocess.STDOUT,
|
|
45
|
+
text=True,
|
|
46
|
+
bufsize=1,
|
|
47
|
+
universal_newlines=True,
|
|
48
|
+
env=env
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
for line in iter(process.stdout.readline, ''):
|
|
52
|
+
print(line, end='')
|
|
53
|
+
sys.stdout.flush() # Ensure output is flushed immediately
|
|
54
|
+
|
|
55
|
+
process.stdout.close()
|
|
56
|
+
return_code = process.wait()
|
|
57
|
+
|
|
58
|
+
if return_code != 0:
|
|
59
|
+
raise subprocess.CalledProcessError(return_code, command)
|
|
60
|
+
|
|
61
|
+
class PraisonAI:
|
|
62
|
+
def __init__(self, agent_file="agents.yaml", framework="", auto=False, init=False, agent_yaml=None):
|
|
63
|
+
"""
|
|
64
|
+
Initialize the PraisonAI object with default parameters.
|
|
65
|
+
|
|
66
|
+
Parameters:
|
|
67
|
+
agent_file (str): The default agent file to use. Defaults to "agents.yaml".
|
|
68
|
+
framework (str): The default framework to use. Defaults to "crewai".
|
|
69
|
+
auto (bool): A flag indicating whether to enable auto mode. Defaults to False.
|
|
70
|
+
init (bool): A flag indicating whether to enable initialization mode. Defaults to False.
|
|
71
|
+
|
|
72
|
+
Attributes:
|
|
73
|
+
config_list (list): A list of configuration dictionaries for the OpenAI API.
|
|
74
|
+
agent_file (str): The agent file to use.
|
|
75
|
+
framework (str): The framework to use.
|
|
76
|
+
auto (bool): A flag indicating whether to enable auto mode.
|
|
77
|
+
init (bool): A flag indicating whether to enable initialization mode.
|
|
78
|
+
agent_yaml (str, optional): The content of the YAML file. Defaults to None.
|
|
79
|
+
"""
|
|
80
|
+
self.agent_yaml = agent_yaml
|
|
81
|
+
self.config_list = [
|
|
82
|
+
{
|
|
83
|
+
'model': os.environ.get("OPENAI_MODEL_NAME", "gpt-4o"),
|
|
84
|
+
'base_url': os.environ.get("OPENAI_API_BASE", "https://api.openai.com/v1"),
|
|
85
|
+
'api_key': os.environ.get("OPENAI_API_KEY")
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
self.agent_file = agent_file
|
|
89
|
+
self.framework = framework
|
|
90
|
+
self.auto = auto
|
|
91
|
+
self.init = init
|
|
92
|
+
|
|
93
|
+
def run(self):
|
|
94
|
+
"""
|
|
95
|
+
Run the PraisonAI application.
|
|
96
|
+
"""
|
|
97
|
+
self.main()
|
|
98
|
+
|
|
99
|
+
def main(self):
|
|
100
|
+
"""
|
|
101
|
+
The main function of the PraisonAI object. It parses the command-line arguments,
|
|
102
|
+
initializes the necessary attributes, and then calls the appropriate methods based on the
|
|
103
|
+
provided arguments.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
self (PraisonAI): An instance of the PraisonAI class.
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
Any: Depending on the arguments provided, the function may return a result from the
|
|
110
|
+
AgentsGenerator, a deployment result from the CloudDeployer, or a message indicating
|
|
111
|
+
the successful creation of a file.
|
|
112
|
+
"""
|
|
113
|
+
args = self.parse_args()
|
|
114
|
+
if args is None:
|
|
115
|
+
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
|
|
116
|
+
result = agents_generator.generate_crew_and_kickoff()
|
|
117
|
+
return result
|
|
118
|
+
if args.deploy:
|
|
119
|
+
from .deploy import CloudDeployer
|
|
120
|
+
deployer = CloudDeployer()
|
|
121
|
+
deployer.run_commands()
|
|
122
|
+
return
|
|
123
|
+
|
|
124
|
+
if getattr(args, 'chat', False):
|
|
125
|
+
self.create_chainlit_chat_interface()
|
|
126
|
+
return
|
|
127
|
+
|
|
128
|
+
if getattr(args, 'code', False):
|
|
129
|
+
self.create_code_interface()
|
|
130
|
+
return
|
|
131
|
+
|
|
132
|
+
if args.agent_file == 'train':
|
|
133
|
+
package_root = os.path.dirname(os.path.abspath(__file__))
|
|
134
|
+
config_yaml_destination = os.path.join(os.getcwd(), 'config.yaml')
|
|
135
|
+
|
|
136
|
+
# Create config.yaml only if it doesn't exist or --model or --dataset is provided
|
|
137
|
+
if not os.path.exists(config_yaml_destination) or args.model or args.dataset:
|
|
138
|
+
config = generate_config(
|
|
139
|
+
model_name=args.model,
|
|
140
|
+
hf_model_name=args.hf,
|
|
141
|
+
ollama_model_name=args.ollama,
|
|
142
|
+
dataset=[{
|
|
143
|
+
"name": args.dataset
|
|
144
|
+
}]
|
|
145
|
+
)
|
|
146
|
+
with open('config.yaml', 'w') as f:
|
|
147
|
+
yaml.dump(config, f, default_flow_style=False, indent=2)
|
|
148
|
+
|
|
149
|
+
# Overwrite huggingface_save and ollama_save if --hf or --ollama are provided
|
|
150
|
+
if args.hf:
|
|
151
|
+
config["huggingface_save"] = "true"
|
|
152
|
+
if args.ollama:
|
|
153
|
+
config["ollama_save"] = "true"
|
|
154
|
+
|
|
155
|
+
if 'init' in sys.argv:
|
|
156
|
+
from praisonai.setup.setup_conda_env import main as setup_conda_main
|
|
157
|
+
setup_conda_main()
|
|
158
|
+
print("All packages installed")
|
|
159
|
+
return
|
|
160
|
+
|
|
161
|
+
try:
|
|
162
|
+
result = subprocess.check_output(['conda', 'env', 'list'])
|
|
163
|
+
if 'praison_env' in result.decode('utf-8'):
|
|
164
|
+
print("Conda environment 'praison_env' found.")
|
|
165
|
+
else:
|
|
166
|
+
raise subprocess.CalledProcessError(1, 'grep')
|
|
167
|
+
except subprocess.CalledProcessError:
|
|
168
|
+
print("Conda environment 'praison_env' not found. Setting it up...")
|
|
169
|
+
from praisonai.setup.setup_conda_env import main as setup_conda_main
|
|
170
|
+
setup_conda_main()
|
|
171
|
+
print("All packages installed.")
|
|
172
|
+
|
|
173
|
+
train_args = sys.argv[2:] # Get all arguments after 'train'
|
|
174
|
+
train_script_path = os.path.join(package_root, 'train.py')
|
|
175
|
+
|
|
176
|
+
# Set environment variables
|
|
177
|
+
env = os.environ.copy()
|
|
178
|
+
env['PYTHONUNBUFFERED'] = '1'
|
|
179
|
+
|
|
180
|
+
stream_subprocess(['conda', 'run', '--no-capture-output', '--name', 'praison_env', 'python', '-u', train_script_path, 'train'] + train_args, env=env)
|
|
181
|
+
return
|
|
182
|
+
|
|
183
|
+
invocation_cmd = "praisonai"
|
|
184
|
+
version_string = f"PraisonAI version {__version__}"
|
|
185
|
+
|
|
186
|
+
self.framework = args.framework or self.framework
|
|
187
|
+
|
|
188
|
+
if args.agent_file:
|
|
189
|
+
if args.agent_file.startswith("tests.test"): # Argument used for testing purposes. eg: python -m unittest tests.test
|
|
190
|
+
print("test")
|
|
191
|
+
else:
|
|
192
|
+
self.agent_file = args.agent_file
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
if args.auto or args.init:
|
|
196
|
+
temp_topic = ' '.join(args.auto) if args.auto else ' '.join(args.init)
|
|
197
|
+
self.topic = temp_topic
|
|
198
|
+
elif self.auto or self.init: # Use the auto attribute if args.auto is not provided
|
|
199
|
+
self.topic = self.auto
|
|
200
|
+
|
|
201
|
+
if args.auto or self.auto:
|
|
202
|
+
self.agent_file = "test.yaml"
|
|
203
|
+
generator = AutoGenerator(topic=self.topic , framework=self.framework, agent_file=self.agent_file)
|
|
204
|
+
self.agent_file = generator.generate()
|
|
205
|
+
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
|
|
206
|
+
result = agents_generator.generate_crew_and_kickoff()
|
|
207
|
+
return result
|
|
208
|
+
elif args.init or self.init:
|
|
209
|
+
self.agent_file = "agents.yaml"
|
|
210
|
+
generator = AutoGenerator(topic=self.topic , framework=self.framework, agent_file=self.agent_file)
|
|
211
|
+
self.agent_file = generator.generate()
|
|
212
|
+
print("File {} created successfully".format(self.agent_file))
|
|
213
|
+
return "File {} created successfully".format(self.agent_file)
|
|
214
|
+
|
|
215
|
+
if args.ui:
|
|
216
|
+
if args.ui == "gradio":
|
|
217
|
+
self.create_gradio_interface()
|
|
218
|
+
elif args.ui == "chainlit":
|
|
219
|
+
self.create_chainlit_interface()
|
|
220
|
+
else:
|
|
221
|
+
# Modify below code to allow default ui
|
|
222
|
+
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list, agent_yaml=self.agent_yaml)
|
|
223
|
+
result = agents_generator.generate_crew_and_kickoff()
|
|
224
|
+
return result
|
|
225
|
+
else:
|
|
226
|
+
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list, agent_yaml=self.agent_yaml)
|
|
227
|
+
result = agents_generator.generate_crew_and_kickoff()
|
|
228
|
+
return result
|
|
229
|
+
|
|
230
|
+
def parse_args(self):
|
|
231
|
+
"""
|
|
232
|
+
Parse the command-line arguments for the PraisonAI CLI.
|
|
233
|
+
|
|
234
|
+
Args:
|
|
235
|
+
self (PraisonAI): An instance of the PraisonAI class.
|
|
236
|
+
|
|
237
|
+
Returns:
|
|
238
|
+
argparse.Namespace: An object containing the parsed command-line arguments.
|
|
239
|
+
|
|
240
|
+
Raises:
|
|
241
|
+
argparse.ArgumentError: If the arguments provided are invalid.
|
|
242
|
+
|
|
243
|
+
Example:
|
|
244
|
+
>>> args = praison_ai.parse_args()
|
|
245
|
+
>>> print(args.agent_file) # Output: 'agents.yaml'
|
|
246
|
+
"""
|
|
247
|
+
parser = argparse.ArgumentParser(prog="praisonai", description="praisonAI command-line interface")
|
|
248
|
+
parser.add_argument("--framework", choices=["crewai", "autogen"], help="Specify the framework")
|
|
249
|
+
parser.add_argument("--ui", choices=["chainlit", "gradio"], help="Specify the UI framework (gradio or chainlit).")
|
|
250
|
+
parser.add_argument("--auto", nargs=argparse.REMAINDER, help="Enable auto mode and pass arguments for it")
|
|
251
|
+
parser.add_argument("--init", nargs=argparse.REMAINDER, help="Enable auto mode and pass arguments for it")
|
|
252
|
+
parser.add_argument("agent_file", nargs="?", help="Specify the agent file")
|
|
253
|
+
parser.add_argument("--deploy", action="store_true", help="Deploy the application")
|
|
254
|
+
parser.add_argument("--model", type=str, help="Model name")
|
|
255
|
+
parser.add_argument("--hf", type=str, help="Hugging Face model name")
|
|
256
|
+
parser.add_argument("--ollama", type=str, help="Ollama model name")
|
|
257
|
+
parser.add_argument("--dataset", type=str, help="Dataset name for training", default="yahma/alpaca-cleaned")
|
|
258
|
+
args, unknown_args = parser.parse_known_args()
|
|
259
|
+
|
|
260
|
+
if unknown_args and unknown_args[0] == '-b' and unknown_args[1] == 'api:app':
|
|
261
|
+
args.agent_file = 'agents.yaml'
|
|
262
|
+
if args.agent_file == 'api:app' or args.agent_file == '/app/api:app':
|
|
263
|
+
args.agent_file = 'agents.yaml'
|
|
264
|
+
if args.agent_file == 'ui':
|
|
265
|
+
args.ui = 'chainlit'
|
|
266
|
+
if args.agent_file == 'chat':
|
|
267
|
+
args.ui = 'chainlit'
|
|
268
|
+
args.chat = True
|
|
269
|
+
if args.agent_file == 'code':
|
|
270
|
+
args.ui = 'chainlit'
|
|
271
|
+
args.code = True
|
|
272
|
+
|
|
273
|
+
return args
|
|
274
|
+
|
|
275
|
+
def create_chainlit_chat_interface(self):
|
|
276
|
+
"""
|
|
277
|
+
Create a Chainlit interface for the chat application.
|
|
278
|
+
|
|
279
|
+
This function sets up a Chainlit application that listens for messages.
|
|
280
|
+
When a message is received, it runs PraisonAI with the provided message as the topic.
|
|
281
|
+
The generated agents are then used to perform tasks.
|
|
282
|
+
|
|
283
|
+
Returns:
|
|
284
|
+
None: This function does not return any value. It starts the Chainlit application.
|
|
285
|
+
"""
|
|
286
|
+
if CHAINLIT_AVAILABLE:
|
|
287
|
+
import praisonai
|
|
288
|
+
os.environ["CHAINLIT_PORT"] = "8084"
|
|
289
|
+
public_folder = os.path.join(os.path.dirname(praisonai.__file__), 'public')
|
|
290
|
+
if not os.path.exists("public"): # Check if the folder exists in the current directory
|
|
291
|
+
if os.path.exists(public_folder):
|
|
292
|
+
shutil.copytree(public_folder, 'public', dirs_exist_ok=True)
|
|
293
|
+
logging.info("Public folder copied successfully!")
|
|
294
|
+
else:
|
|
295
|
+
logging.info("Public folder not found in the package.")
|
|
296
|
+
else:
|
|
297
|
+
logging.info("Public folder already exists.")
|
|
298
|
+
chat_ui_path = os.path.join(os.path.dirname(praisonai.__file__), 'ui', 'chat.py')
|
|
299
|
+
chainlit_run([chat_ui_path])
|
|
300
|
+
else:
|
|
301
|
+
print("ERROR: Chat UI is not installed. Please install it with 'pip install \"praisonai\[chat]\"' to use the chat UI.")
|
|
302
|
+
|
|
303
|
+
def create_code_interface(self):
|
|
304
|
+
"""
|
|
305
|
+
Create a Chainlit interface for the code application.
|
|
306
|
+
|
|
307
|
+
This function sets up a Chainlit application that listens for messages.
|
|
308
|
+
When a message is received, it runs PraisonAI with the provided message as the topic.
|
|
309
|
+
The generated agents are then used to perform tasks.
|
|
310
|
+
|
|
311
|
+
Returns:
|
|
312
|
+
None: This function does not return any value. It starts the Chainlit application.
|
|
313
|
+
"""
|
|
314
|
+
if CHAINLIT_AVAILABLE:
|
|
315
|
+
import praisonai
|
|
316
|
+
os.environ["CHAINLIT_PORT"] = "8086"
|
|
317
|
+
public_folder = os.path.join(os.path.dirname(praisonai.__file__), 'public')
|
|
318
|
+
if not os.path.exists("public"): # Check if the folder exists in the current directory
|
|
319
|
+
if os.path.exists(public_folder):
|
|
320
|
+
shutil.copytree(public_folder, 'public', dirs_exist_ok=True)
|
|
321
|
+
logging.info("Public folder copied successfully!")
|
|
322
|
+
else:
|
|
323
|
+
logging.info("Public folder not found in the package.")
|
|
324
|
+
else:
|
|
325
|
+
logging.info("Public folder already exists.")
|
|
326
|
+
code_ui_path = os.path.join(os.path.dirname(praisonai.__file__), 'ui', 'code.py')
|
|
327
|
+
chainlit_run([code_ui_path])
|
|
328
|
+
else:
|
|
329
|
+
print("ERROR: Code UI is not installed. Please install it with 'pip install \"praisonai\[code]\"' to use the code UI.")
|
|
330
|
+
|
|
331
|
+
def create_gradio_interface(self):
|
|
332
|
+
"""
|
|
333
|
+
Create a Gradio interface for generating agents and performing tasks.
|
|
334
|
+
|
|
335
|
+
Args:
|
|
336
|
+
self (PraisonAI): An instance of the PraisonAI class.
|
|
337
|
+
|
|
338
|
+
Returns:
|
|
339
|
+
None: This method does not return any value. It launches the Gradio interface.
|
|
340
|
+
|
|
341
|
+
Raises:
|
|
342
|
+
None: This method does not raise any exceptions.
|
|
343
|
+
|
|
344
|
+
Example:
|
|
345
|
+
>>> praison_ai.create_gradio_interface()
|
|
346
|
+
"""
|
|
347
|
+
if GRADIO_AVAILABLE:
|
|
348
|
+
def generate_crew_and_kickoff_interface(auto_args, framework):
|
|
349
|
+
"""
|
|
350
|
+
Generate a crew and kick off tasks based on the provided auto arguments and framework.
|
|
351
|
+
|
|
352
|
+
Args:
|
|
353
|
+
auto_args (list): Topic.
|
|
354
|
+
framework (str): The framework to use for generating agents.
|
|
355
|
+
|
|
356
|
+
Returns:
|
|
357
|
+
str: A string representing the result of generating the crew and kicking off tasks.
|
|
358
|
+
|
|
359
|
+
Raises:
|
|
360
|
+
None: This method does not raise any exceptions.
|
|
361
|
+
|
|
362
|
+
Example:
|
|
363
|
+
>>> result = generate_crew_and_kickoff_interface("Create a movie about Cat in Mars", "crewai")
|
|
364
|
+
>>> print(result)
|
|
365
|
+
"""
|
|
366
|
+
self.framework = framework
|
|
367
|
+
self.agent_file = "test.yaml"
|
|
368
|
+
generator = AutoGenerator(topic=auto_args , framework=self.framework)
|
|
369
|
+
self.agent_file = generator.generate()
|
|
370
|
+
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
|
|
371
|
+
result = agents_generator.generate_crew_and_kickoff()
|
|
372
|
+
return result
|
|
373
|
+
|
|
374
|
+
gr.Interface(
|
|
375
|
+
fn=generate_crew_and_kickoff_interface,
|
|
376
|
+
inputs=[gr.Textbox(lines=2, label="Auto Args"), gr.Dropdown(choices=["crewai", "autogen"], label="Framework")],
|
|
377
|
+
outputs="textbox",
|
|
378
|
+
title="Praison AI Studio",
|
|
379
|
+
description="Create Agents and perform tasks",
|
|
380
|
+
theme="default"
|
|
381
|
+
).launch()
|
|
382
|
+
else:
|
|
383
|
+
print("ERROR: Gradio is not installed. Please install it with 'pip install gradio' to use this feature.")
|
|
384
|
+
|
|
385
|
+
def create_chainlit_interface(self):
|
|
386
|
+
"""
|
|
387
|
+
Create a Chainlit interface for generating agents and performing tasks.
|
|
388
|
+
|
|
389
|
+
This function sets up a Chainlit application that listens for messages.
|
|
390
|
+
When a message is received, it runs PraisonAI with the provided message as the topic.
|
|
391
|
+
The generated agents are then used to perform tasks.
|
|
392
|
+
|
|
393
|
+
Returns:
|
|
394
|
+
None: This function does not return any value. It starts the Chainlit application.
|
|
395
|
+
"""
|
|
396
|
+
if CHAINLIT_AVAILABLE:
|
|
397
|
+
import praisonai
|
|
398
|
+
os.environ["CHAINLIT_PORT"] = "8082"
|
|
399
|
+
# Get the path to the 'public' folder within the package
|
|
400
|
+
public_folder = os.path.join(os.path.dirname(praisonai.__file__), 'public')
|
|
401
|
+
if not os.path.exists("public"): # Check if the folder exists in the current directory
|
|
402
|
+
if os.path.exists(public_folder):
|
|
403
|
+
shutil.copytree(public_folder, 'public', dirs_exist_ok=True)
|
|
404
|
+
logging.info("Public folder copied successfully!")
|
|
405
|
+
else:
|
|
406
|
+
logging.info("Public folder not found in the package.")
|
|
407
|
+
else:
|
|
408
|
+
logging.info("Public folder already exists.")
|
|
409
|
+
chainlit_ui_path = os.path.join(os.path.dirname(praisonai.__file__), 'chainlit_ui.py')
|
|
410
|
+
chainlit_run([chainlit_ui_path])
|
|
411
|
+
else:
|
|
412
|
+
print("ERROR: Chainlit is not installed. Please install it with 'pip install \"praisonai\[ui]\"' to use the UI.")
|
|
413
|
+
|
|
414
|
+
if __name__ == "__main__":
|
|
415
|
+
praison_ai = PraisonAI()
|
|
416
|
+
praison_ai.main()
|
praisonai/deploy.py
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import os
|
|
3
|
+
from dotenv import load_dotenv
|
|
4
|
+
|
|
5
|
+
class CloudDeployer:
|
|
6
|
+
"""
|
|
7
|
+
A class for deploying a cloud-based application.
|
|
8
|
+
|
|
9
|
+
Attributes:
|
|
10
|
+
None
|
|
11
|
+
|
|
12
|
+
Methods:
|
|
13
|
+
__init__(self):
|
|
14
|
+
Loads environment variables from .env file or system and sets them.
|
|
15
|
+
|
|
16
|
+
"""
|
|
17
|
+
def __init__(self):
|
|
18
|
+
"""
|
|
19
|
+
Loads environment variables from .env file or system and sets them.
|
|
20
|
+
|
|
21
|
+
Parameters:
|
|
22
|
+
self: An instance of the CloudDeployer class.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
None
|
|
26
|
+
|
|
27
|
+
Raises:
|
|
28
|
+
None
|
|
29
|
+
|
|
30
|
+
"""
|
|
31
|
+
# Load environment variables from .env file or system
|
|
32
|
+
load_dotenv()
|
|
33
|
+
self.set_environment_variables()
|
|
34
|
+
|
|
35
|
+
def create_dockerfile(self):
|
|
36
|
+
"""
|
|
37
|
+
Creates a Dockerfile for the application.
|
|
38
|
+
|
|
39
|
+
Parameters:
|
|
40
|
+
self: An instance of the CloudDeployer class.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
None
|
|
44
|
+
|
|
45
|
+
Raises:
|
|
46
|
+
None
|
|
47
|
+
|
|
48
|
+
This method creates a Dockerfile in the current directory with the specified content.
|
|
49
|
+
The Dockerfile is used to build a Docker image for the application.
|
|
50
|
+
The content of the Dockerfile includes instructions to use the Python 3.11-slim base image,
|
|
51
|
+
set the working directory to /app, copy the current directory contents into the container,
|
|
52
|
+
install the required Python packages (flask, praisonai, gunicorn, and markdown),
|
|
53
|
+
expose port 8080, and run the application using Gunicorn.
|
|
54
|
+
"""
|
|
55
|
+
with open("Dockerfile", "w") as file:
|
|
56
|
+
file.write("FROM python:3.11-slim\n")
|
|
57
|
+
file.write("WORKDIR /app\n")
|
|
58
|
+
file.write("COPY . .\n")
|
|
59
|
+
file.write("RUN pip install flask praisonai==0.0.59 gunicorn markdown\n")
|
|
60
|
+
file.write("EXPOSE 8080\n")
|
|
61
|
+
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
|
|
62
|
+
|
|
63
|
+
def create_api_file(self):
|
|
64
|
+
"""
|
|
65
|
+
Creates an API file for the application.
|
|
66
|
+
|
|
67
|
+
Parameters:
|
|
68
|
+
self (CloudDeployer): An instance of the CloudDeployer class.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
None
|
|
72
|
+
|
|
73
|
+
This method creates an API file named "api.py" in the current directory. The file contains a basic Flask application that uses the PraisonAI library to run a simple agent and returns the output as an HTML page. The application listens on the root path ("/") and uses the Markdown library to format the output.
|
|
74
|
+
"""
|
|
75
|
+
with open("api.py", "w") as file:
|
|
76
|
+
file.write("from flask import Flask\n")
|
|
77
|
+
file.write("from praisonai import PraisonAI\n")
|
|
78
|
+
file.write("import markdown\n\n")
|
|
79
|
+
file.write("app = Flask(__name__)\n\n")
|
|
80
|
+
file.write("def basic():\n")
|
|
81
|
+
file.write(" praisonai = PraisonAI(agent_file=\"agents.yaml\")\n")
|
|
82
|
+
file.write(" return praisonai.run()\n\n")
|
|
83
|
+
file.write("@app.route('/')\n")
|
|
84
|
+
file.write("def home():\n")
|
|
85
|
+
file.write(" output = basic()\n")
|
|
86
|
+
file.write(" html_output = markdown.markdown(output)\n")
|
|
87
|
+
file.write(" return f'<html><body>{html_output}</body></html>'\n\n")
|
|
88
|
+
file.write("if __name__ == \"__main__\":\n")
|
|
89
|
+
file.write(" app.run(debug=True)\n")
|
|
90
|
+
|
|
91
|
+
def set_environment_variables(self):
|
|
92
|
+
"""Sets environment variables with fallback to .env values or defaults."""
|
|
93
|
+
os.environ["OPENAI_MODEL_NAME"] = os.getenv("OPENAI_MODEL_NAME", "gpt-4o")
|
|
94
|
+
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY", "Enter your API key")
|
|
95
|
+
os.environ["OPENAI_API_BASE"] = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1")
|
|
96
|
+
|
|
97
|
+
def run_commands(self):
|
|
98
|
+
"""
|
|
99
|
+
Sets environment variables with fallback to .env values or defaults.
|
|
100
|
+
|
|
101
|
+
Parameters:
|
|
102
|
+
None
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
None
|
|
106
|
+
|
|
107
|
+
Raises:
|
|
108
|
+
None
|
|
109
|
+
|
|
110
|
+
This method sets environment variables for the application. It uses the `os.environ` dictionary to set the following environment variables:
|
|
111
|
+
|
|
112
|
+
- `OPENAI_MODEL_NAME`: The name of the OpenAI model to use. If not specified in the .env file, it defaults to "gpt-4o".
|
|
113
|
+
- `OPENAI_API_KEY`: The API key for accessing the OpenAI API. If not specified in the .env file, it defaults to "Enter your API key".
|
|
114
|
+
- `OPENAI_API_BASE`: The base URL for the OpenAI API. If not specified in the .env file, it defaults to "https://api.openai.com/v1".
|
|
115
|
+
"""
|
|
116
|
+
self.create_api_file()
|
|
117
|
+
self.create_dockerfile()
|
|
118
|
+
"""Runs a sequence of shell commands for deployment, continues on error."""
|
|
119
|
+
commands = [
|
|
120
|
+
"yes | gcloud auth configure-docker us-central1-docker.pkg.dev",
|
|
121
|
+
"gcloud artifacts repositories create praisonai-repository --repository-format=docker --location=us-central1",
|
|
122
|
+
"docker build --platform linux/amd64 -t gcr.io/$(gcloud config get-value project)/praisonai-app:latest .",
|
|
123
|
+
"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",
|
|
124
|
+
"docker push us-central1-docker.pkg.dev/$(gcloud config get-value project)/praisonai-repository/praisonai-app:latest",
|
|
125
|
+
"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}"
|
|
126
|
+
]
|
|
127
|
+
|
|
128
|
+
for cmd in commands:
|
|
129
|
+
try:
|
|
130
|
+
subprocess.run(cmd, shell=True, check=True)
|
|
131
|
+
except subprocess.CalledProcessError as e:
|
|
132
|
+
print(f"ERROR: Command '{e.cmd}' failed with exit status {e.returncode}")
|
|
133
|
+
print(f"Continuing with the next command...")
|
|
134
|
+
|
|
135
|
+
# Usage
|
|
136
|
+
if __name__ == "__main__":
|
|
137
|
+
deployer = CloudDeployer()
|
|
138
|
+
deployer.run_commands()
|