PraisonAI 0.0.15__tar.gz → 0.0.17__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: praisonAI
3
- Version: 0.0.15
3
+ Version: 0.0.17
4
4
  Summary: 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.
5
5
  Author: Mervin Praison
6
6
  Requires-Python: >=3.10,<3.13
@@ -36,6 +36,11 @@ praisonai --init create a movie script about dog in moon
36
36
  ```
37
37
  This will automatically create agents.yaml file in the current directory.
38
38
 
39
+ To initialse with a specific agent framework:
40
+
41
+ ```bash
42
+ praisonai --framework autogen --init create movie script about cat in mars
43
+ ```
39
44
 
40
45
  ## Run
41
46
 
@@ -186,6 +191,28 @@ gcloud run deploy praisonai-service \
186
191
  --allow-unauthenticated \
187
192
  --set-env-vars OPENAI_MODEL_NAME=${OPENAI_MODEL_NAME},OPENAI_API_KEY=${OPENAI_API_KEY},OPENAI_API_BASE=${OPENAI_API_BASE}
188
193
 
194
+ ## Other Models
195
+
196
+ Ollama
197
+ OPENAI_API_BASE='http://localhost:11434/v1'
198
+ OPENAI_MODEL_NAME='mistral'
199
+ OPENAI_API_KEY='NA'
200
+
201
+ FastChat¶
202
+ OPENAI_API_BASE="http://localhost:8001/v1"
203
+ OPENAI_MODEL_NAME='oh-2.5m7b-q51'
204
+ OPENAI_API_KEY=NA
205
+
206
+ LM Studio¶
207
+ OPENAI_API_BASE="http://localhost:8000/v1"
208
+ OPENAI_MODEL_NAME=NA
209
+ OPENAI_API_KEY=NA
210
+
211
+ Mistral API¶
212
+ OPENAI_API_BASE=https://api.mistral.ai/v1
213
+ OPENAI_MODEL_NAME="mistral-small"
214
+ OPENAI_API_KEY=your-mistral-api-key
215
+
189
216
  ## Contributing
190
217
 
191
218
  - Fork on GitHub: Use the "Fork" button on the repository page.
@@ -15,6 +15,11 @@ praisonai --init create a movie script about dog in moon
15
15
  ```
16
16
  This will automatically create agents.yaml file in the current directory.
17
17
 
18
+ To initialse with a specific agent framework:
19
+
20
+ ```bash
21
+ praisonai --framework autogen --init create movie script about cat in mars
22
+ ```
18
23
 
19
24
  ## Run
20
25
 
@@ -165,6 +170,28 @@ gcloud run deploy praisonai-service \
165
170
  --allow-unauthenticated \
166
171
  --set-env-vars OPENAI_MODEL_NAME=${OPENAI_MODEL_NAME},OPENAI_API_KEY=${OPENAI_API_KEY},OPENAI_API_BASE=${OPENAI_API_BASE}
167
172
 
173
+ ## Other Models
174
+
175
+ Ollama
176
+ OPENAI_API_BASE='http://localhost:11434/v1'
177
+ OPENAI_MODEL_NAME='mistral'
178
+ OPENAI_API_KEY='NA'
179
+
180
+ FastChat¶
181
+ OPENAI_API_BASE="http://localhost:8001/v1"
182
+ OPENAI_MODEL_NAME='oh-2.5m7b-q51'
183
+ OPENAI_API_KEY=NA
184
+
185
+ LM Studio¶
186
+ OPENAI_API_BASE="http://localhost:8000/v1"
187
+ OPENAI_MODEL_NAME=NA
188
+ OPENAI_API_KEY=NA
189
+
190
+ Mistral API¶
191
+ OPENAI_API_BASE=https://api.mistral.ai/v1
192
+ OPENAI_MODEL_NAME="mistral-small"
193
+ OPENAI_API_KEY=your-mistral-api-key
194
+
168
195
  ## Contributing
169
196
 
170
197
  - Fork on GitHub: Use the "Fork" button on the repository page.
@@ -65,7 +65,7 @@ class AutoGenerator:
65
65
  """
66
66
 
67
67
  yaml_data = {
68
- "framework": "crewai",
68
+ "framework": self.framework,
69
69
  "topic": self.topic,
70
70
  "roles": {},
71
71
  "dependencies": []
@@ -121,8 +121,9 @@ class PraisonAI:
121
121
  invocation_cmd = "praisonai"
122
122
  version_string = f"praisonAI version {__version__}"
123
123
 
124
- # if args.framework:
125
- # self.framework = args.framework
124
+ if args.framework:
125
+ self.framework = args.framework
126
+
126
127
  ui = args.ui
127
128
 
128
129
  if args.agent_file:
@@ -8,6 +8,32 @@ class CloudDeployer:
8
8
  load_dotenv()
9
9
  self.set_environment_variables()
10
10
 
11
+ def create_dockerfile(self):
12
+ with open("Dockerfile", "w") as file:
13
+ file.write("FROM python:3.11-slim\n")
14
+ file.write("WORKDIR /app\n")
15
+ file.write("COPY . .\n")
16
+ file.write("RUN pip install flask praisonai==0.0.17 gunicorn markdown\n")
17
+ file.write("EXPOSE 8080\n")
18
+ file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
19
+
20
+ def create_api_file(self):
21
+ with open("api.py", "w") as file:
22
+ file.write("from flask import Flask\n")
23
+ file.write("from praisonai import PraisonAI\n")
24
+ file.write("import markdown\n\n")
25
+ file.write("app = Flask(__name__)\n\n")
26
+ file.write("def basic():\n")
27
+ file.write(" praison_ai = PraisonAI(agent_file=\"agents.yaml\")\n")
28
+ file.write(" return praison_ai.main()\n\n")
29
+ file.write("@app.route('/')\n")
30
+ file.write("def home():\n")
31
+ file.write(" output = basic()\n")
32
+ file.write(" html_output = markdown.markdown(output)\n")
33
+ file.write(" return f'<html><body>{html_output}</body></html>'\n\n")
34
+ file.write("if __name__ == \"__main__\":\n")
35
+ file.write(" app.run(debug=True)\n")
36
+
11
37
  def set_environment_variables(self):
12
38
  """Sets environment variables with fallback to .env values or defaults."""
13
39
  os.environ["OPENAI_MODEL_NAME"] = os.getenv("OPENAI_MODEL_NAME", "gpt-4-turbo-preview")
@@ -15,6 +41,8 @@ class CloudDeployer:
15
41
  os.environ["OPENAI_API_BASE"] = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1")
16
42
 
17
43
  def run_commands(self):
44
+ self.create_api_file()
45
+ self.create_dockerfile()
18
46
  """Runs a sequence of shell commands for deployment, continues on error."""
19
47
  commands = [
20
48
  "yes | gcloud auth configure-docker us-central1-docker.pkg.dev",
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "praisonAI"
3
- version = "0.0.15"
3
+ version = "0.0.17"
4
4
  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."
5
5
  authors = ["Mervin Praison"]
6
6
  license = ""
@@ -1,151 +0,0 @@
1
- from openai import OpenAI
2
- from pydantic import BaseModel, Field
3
- from typing import Dict
4
- import instructor
5
- import os
6
- import json
7
-
8
- config_list = [
9
- {
10
- 'model': os.environ.get("OPENAI_MODEL_NAME", "gpt-4-turbo-preview"),
11
- 'base_url': os.environ.get("OPENAI_API_BASE", "https://api.openai.com/v1"),
12
- }
13
- ]
14
-
15
- task = "Movie Story writing"
16
-
17
- # Define new Pydantic models to represent the script writing team structure
18
- class TaskDetails(BaseModel):
19
- description: str
20
- expected_output: str
21
-
22
- class RoleDetails(BaseModel):
23
- role: str
24
- goal: str
25
- backstory: str
26
- tasks: Dict[str, TaskDetails]
27
-
28
- class TeamStructure(BaseModel):
29
- roles: Dict[str, RoleDetails]
30
-
31
- # Enables `response_model` in create call with the new model
32
- client = instructor.patch(
33
- OpenAI(
34
- base_url=config_list[0]['base_url'],
35
- api_key=os.getenv("OPENAI_API_KEY"),
36
- ),
37
- mode=instructor.Mode.JSON,
38
- )
39
-
40
- response = client.chat.completions.create(
41
- model=config_list[0]['model'],
42
- response_model=TeamStructure,
43
- max_retries=10,
44
- messages=[
45
- {"role": "system", "content": "You are a helpful assistant designed to output complex team structures."},
46
- {"role": "user", "content":
47
- """Generate a team structure for """ + task + """ task.
48
- No Input data will be provided to the team.
49
- The team will work in sequence. First role will pass the output to the next role, and so on.
50
- The last role will generate the final output.
51
- Think step by step.
52
- With maximum 3 roles, each with 1 task. Include role goals, backstories, task descriptions, and expected outputs.
53
- Output Structure:
54
- {
55
- "roles": {
56
- "<role_id>": {
57
- "role": "<role_name>",
58
- "goal": "<role_goal>",
59
- "backstory": "<role_backstory>",
60
- "tasks": {
61
- "<task_id>": {
62
- "description": "<task_description>",
63
- "expected_output": "<task_expected_output>"
64
- }
65
- }
66
- },
67
- "<role_id>": {
68
- "role": "<role_name>",
69
- "goal": "<role_goal>",
70
- "backstory": "<role_backstory>",
71
- "tasks": {
72
- "<task_id>": {
73
- "description": "<task_description>",
74
- "expected_output": "<task_expected_output>"
75
- }
76
- }
77
- }
78
- }
79
- }
80
- Example Below:
81
- {
82
- "roles": {
83
- "narrative_designer": {
84
- "role": "Narrative Designer",
85
- "goal": "Create AI storylines",
86
- "backstory": "Skilled in narrative development for AI, with a focus on story resonance.",
87
- "tasks": {
88
- "story_concept_development": {
89
- "description": "Craft a unique AI story concept with depth and engagement.",
90
- "expected_output": "Document with narrative arcs, character bios, and settings."
91
- }
92
- }
93
- },
94
- "scriptwriter": {
95
- "role": "Scriptwriter",
96
- "goal": "Write scripts from AI concepts",
97
- "backstory": "Expert in dialogue and script structure, translating concepts into scripts.",
98
- "tasks": {
99
- "scriptwriting_task": {
100
- "description": "Turn narrative concepts into scripts, including dialogue and scenes.",
101
- "expected_output": "Production-ready script with dialogue and scene details."
102
- }
103
- }
104
- }
105
- }
106
- }
107
- """}
108
- ]
109
- )
110
-
111
- print(response.model_dump_json(indent=2))
112
-
113
- import yaml
114
-
115
- def convert_and_save(json_data, topic="Artificial Intelligence", filename="test.yaml"):
116
- """Converts the provided JSON data into the desired YAML format and saves it to a file.
117
-
118
- Args:
119
- json_data (dict): The JSON data representing the team structure.
120
- topic (str, optional): The topic to be inserted into the YAML. Defaults to "Artificial Intelligence".
121
- filename (str, optional): The name of the YAML file to save. Defaults to "test.yaml".
122
- """
123
-
124
- yaml_data = {
125
- "framework": "crewai",
126
- "topic": topic,
127
- "roles": {},
128
- "dependencies": []
129
- }
130
-
131
- # Process roles in the order they appear in JSON
132
- for role_id, role_details in json_data['roles'].items():
133
- yaml_data['roles'][role_id] = {
134
- "backstory": "" + role_details['backstory'],
135
- "goal": role_details['goal'],
136
- "role": role_details['role'],
137
- "tasks": {}
138
- }
139
-
140
- for task_id, task_details in role_details['tasks'].items():
141
- yaml_data['roles'][role_id]['tasks'][task_id] = {
142
- "description": "" + task_details['description'],
143
- "expected_output": "" + task_details['expected_output']
144
- }
145
-
146
- # Save to YAML file, maintaining the order
147
- with open(filename, 'w') as f:
148
- yaml.dump(yaml_data, f, allow_unicode=True, sort_keys=False)
149
-
150
- json_data = json.loads(response.model_dump_json())
151
- convert_and_save(json_data)
@@ -1,143 +0,0 @@
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 gradio as gr
12
- import argparse
13
-
14
- config_list = [
15
- {
16
- 'model': os.environ.get("OPENAI_MODEL_NAME", "gpt-3.5-turbo"),
17
- 'base_url': os.environ.get("OPENAI_API_BASE", "https://api.openai.com/v1"),
18
- }
19
- ]
20
-
21
- def generate_crew_and_kickoff(agent_file, framework=None):
22
- with open(agent_file, 'r') as f:
23
- config = yaml.safe_load(f)
24
-
25
- topic = config['topic']
26
- framework = framework or config.get('framework')
27
-
28
- agents = {}
29
- tasks = []
30
- if framework == "autogen":
31
- # Load the LLM configuration dynamically
32
- print(config_list)
33
- llm_config = {"config_list": config_list}
34
-
35
- for role, details in config['roles'].items():
36
- agent_name = details['role'].format(topic=topic).replace("{topic}", topic)
37
- agent_goal = details['goal'].format(topic=topic)
38
- # Creating an AssistantAgent for each role dynamically
39
- agents[role] = autogen.AssistantAgent(
40
- name=agent_name,
41
- llm_config=llm_config,
42
- system_message=details['backstory'].format(topic=topic)+". Reply \"TERMINATE\" in the end when everything is done.",
43
- )
44
-
45
- # Preparing tasks for initiate_chats
46
- for task_name, task_details in details.get('tasks', {}).items():
47
- description_filled = task_details['description'].format(topic=topic)
48
- expected_output_filled = task_details['expected_output'].format(topic=topic)
49
-
50
- chat_task = {
51
- "recipient": agents[role],
52
- "message": description_filled,
53
- "summary_method": "last_msg",
54
- # Additional fields like carryover can be added based on dependencies
55
- }
56
- tasks.append(chat_task)
57
-
58
- # Assuming the user proxy agent is set up as per your requirements
59
- user = autogen.UserProxyAgent(
60
- name="User",
61
- human_input_mode="NEVER",
62
- is_termination_msg=lambda x: (x.get("content") or "").rstrip().rstrip(".").lower().endswith("terminate") or "TERMINATE" in (x.get("content") or ""),
63
- code_execution_config={
64
- "work_dir": "coding",
65
- "use_docker": False,
66
- },
67
- # additional setup for the user proxy agent
68
- )
69
- response = user.initiate_chats(tasks)
70
- result = "### Output ###\n"+response[-1].summary if hasattr(response[-1], 'summary') else ""
71
- else:
72
- for role, details in config['roles'].items():
73
- role_filled = details['role'].format(topic=topic)
74
- goal_filled = details['goal'].format(topic=topic)
75
- backstory_filled = details['backstory'].format(topic=topic)
76
-
77
- # Assume tools are loaded and handled here as per your requirements
78
- agent = Agent(role=role_filled, goal=goal_filled, backstory=backstory_filled, allow_delegation=False)
79
- agents[role] = agent
80
-
81
- for task_name, task_details in details.get('tasks', {}).items():
82
- description_filled = task_details['description'].format(topic=topic)
83
- expected_output_filled = task_details['expected_output'].format(topic=topic)
84
-
85
- task = Task(description=description_filled, expected_output=expected_output_filled, agent=agent)
86
- tasks.append(task)
87
-
88
- crew = Crew(
89
- agents=list(agents.values()),
90
- tasks=tasks,
91
- verbose=2
92
- )
93
-
94
- response = crew.kickoff()
95
- result = f"### Output ###\n{response}"
96
- return result
97
-
98
- def main(args=None):
99
- if args is None:
100
- args = parse_args()
101
-
102
- invocation_cmd = "praisonai"
103
- version_string = f"praisonAI version {__version__}"
104
- framework = args.framework # Default framework
105
- ui = args.ui # Default UI flag
106
- print(args)
107
-
108
- if args.agent_file:
109
- agent_file = args.agent_file
110
- else:
111
- agent_file = "agents.yaml"
112
-
113
- if ui:
114
- create_gradio_interface()
115
- else:
116
- result = generate_crew_and_kickoff(agent_file, framework)
117
- print(result)
118
-
119
- def parse_args():
120
- parser = argparse.ArgumentParser(prog="praisonai", description="praisonAI command-line interface")
121
- parser.add_argument("--framework", choices=["crewai", "autogen"], default="crewai", help="Specify the framework")
122
- parser.add_argument("--ui", action="store_true", help="Enable UI mode")
123
- parser.add_argument("--auto", action="store_true", help="Enable auto mode")
124
- parser.add_argument("agent_file", nargs="?", help="Specify the agent file")
125
-
126
- return parser.parse_args()
127
-
128
- def create_gradio_interface():
129
- def generate_crew_and_kickoff_interface(agent_file, framework):
130
- result = generate_crew_and_kickoff(agent_file, framework)
131
- return result
132
-
133
- gr.Interface(
134
- fn=generate_crew_and_kickoff_interface,
135
- inputs=["textbox", "radio"],
136
- outputs="textbox",
137
- title="Generate Crew and Kickoff",
138
- description="Generate a crew and kickoff the tasks",
139
- theme="default"
140
- ).launch()
141
-
142
- if __name__ == "__main__":
143
- main()
File without changes