PraisonAI 0.0.41__py3-none-any.whl → 0.0.46__py3-none-any.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/agents_generator.py +10 -0
- praisonai/cli.py +43 -1
- praisonai/deploy.py +1 -1
- 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/favicon-16x16.png +0 -0
- praisonai/public/favicon-32x32.png +0 -0
- praisonai/public/favicon.ico +0 -0
- praisonai/public/logo_dark.png +0 -0
- praisonai/public/logo_light.png +0 -0
- praisonai/ui/chat.py +438 -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-0.0.41.dist-info → praisonai-0.0.46.dist-info}/METADATA +84 -143
- praisonai-0.0.46.dist-info/RECORD +37 -0
- praisonai-0.0.41.dist-info/RECORD +0 -22
- {praisonai-0.0.41.dist-info → praisonai-0.0.46.dist-info}/LICENSE +0 -0
- {praisonai-0.0.41.dist-info → praisonai-0.0.46.dist-info}/WHEEL +0 -0
- {praisonai-0.0.41.dist-info → praisonai-0.0.46.dist-info}/entry_points.txt +0 -0
praisonai/agents_generator.py
CHANGED
|
@@ -279,6 +279,9 @@ class AgentsGenerator:
|
|
|
279
279
|
else: # framework=crewai
|
|
280
280
|
if agentops_exists:
|
|
281
281
|
agentops.init(os.environ.get("AGENTOPS_API_KEY"), tags=["crewai"])
|
|
282
|
+
|
|
283
|
+
tasks_dict = {}
|
|
284
|
+
|
|
282
285
|
for role, details in config['roles'].items():
|
|
283
286
|
role_filled = details['role'].format(topic=topic)
|
|
284
287
|
goal_filled = details['goal'].format(topic=topic)
|
|
@@ -352,7 +355,14 @@ class AgentsGenerator:
|
|
|
352
355
|
task.callback = self.task_callback
|
|
353
356
|
|
|
354
357
|
tasks.append(task)
|
|
358
|
+
tasks_dict[task_name] = task
|
|
355
359
|
|
|
360
|
+
for role, details in config['roles'].items():
|
|
361
|
+
for task_name, task_details in details.get('tasks', {}).items():
|
|
362
|
+
task = tasks_dict[task_name]
|
|
363
|
+
context_tasks = [tasks_dict[ctx] for ctx in task_details.get('context', []) if ctx in tasks_dict]
|
|
364
|
+
task.context = context_tasks
|
|
365
|
+
|
|
356
366
|
crew = Crew(
|
|
357
367
|
agents=list(agents.values()),
|
|
358
368
|
tasks=tasks,
|
praisonai/cli.py
CHANGED
|
@@ -60,6 +60,12 @@ class PraisonAI:
|
|
|
60
60
|
self.auto = auto
|
|
61
61
|
self.init = init
|
|
62
62
|
|
|
63
|
+
def run(self):
|
|
64
|
+
"""
|
|
65
|
+
Run the PraisonAI application.
|
|
66
|
+
"""
|
|
67
|
+
self.main()
|
|
68
|
+
|
|
63
69
|
def main(self):
|
|
64
70
|
"""
|
|
65
71
|
The main function of the PraisonAI object. It parses the command-line arguments,
|
|
@@ -84,6 +90,11 @@ class PraisonAI:
|
|
|
84
90
|
deployer = CloudDeployer()
|
|
85
91
|
deployer.run_commands()
|
|
86
92
|
return
|
|
93
|
+
|
|
94
|
+
if getattr(args, 'chat', False):
|
|
95
|
+
self.create_chainlit_chat_interface()
|
|
96
|
+
return
|
|
97
|
+
|
|
87
98
|
invocation_cmd = "praisonai"
|
|
88
99
|
version_string = f"PraisonAI version {__version__}"
|
|
89
100
|
|
|
@@ -163,8 +174,39 @@ class PraisonAI:
|
|
|
163
174
|
args.agent_file = 'agents.yaml'
|
|
164
175
|
if args.agent_file == 'ui':
|
|
165
176
|
args.ui = 'chainlit'
|
|
177
|
+
if args.agent_file == 'chat':
|
|
178
|
+
args.ui = 'chainlit'
|
|
179
|
+
args.chat = True
|
|
166
180
|
|
|
167
181
|
return args
|
|
182
|
+
|
|
183
|
+
def create_chainlit_chat_interface(self):
|
|
184
|
+
"""
|
|
185
|
+
Create a Chainlit interface for the chat application.
|
|
186
|
+
|
|
187
|
+
This function sets up a Chainlit application that listens for messages.
|
|
188
|
+
When a message is received, it runs PraisonAI with the provided message as the topic.
|
|
189
|
+
The generated agents are then used to perform tasks.
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
None: This function does not return any value. It starts the Chainlit application.
|
|
193
|
+
"""
|
|
194
|
+
if CHAINLIT_AVAILABLE:
|
|
195
|
+
import praisonai
|
|
196
|
+
os.environ["CHAINLIT_PORT"] = "8084"
|
|
197
|
+
public_folder = os.path.join(os.path.dirname(praisonai.__file__), 'public')
|
|
198
|
+
if not os.path.exists("public"): # Check if the folder exists in the current directory
|
|
199
|
+
if os.path.exists(public_folder):
|
|
200
|
+
shutil.copytree(public_folder, 'public', dirs_exist_ok=True)
|
|
201
|
+
logging.info("Public folder copied successfully!")
|
|
202
|
+
else:
|
|
203
|
+
logging.info("Public folder not found in the package.")
|
|
204
|
+
else:
|
|
205
|
+
logging.info("Public folder already exists.")
|
|
206
|
+
chat_ui_path = os.path.join(os.path.dirname(praisonai.__file__), 'ui', 'chat.py')
|
|
207
|
+
chainlit_run([chat_ui_path])
|
|
208
|
+
else:
|
|
209
|
+
print("ERROR: Chat UI is not installed. Please install it with 'pip install \"praisonai\[chat]\"' to use the chat UI.")
|
|
168
210
|
|
|
169
211
|
def create_gradio_interface(self):
|
|
170
212
|
"""
|
|
@@ -247,7 +289,7 @@ class PraisonAI:
|
|
|
247
289
|
chainlit_ui_path = os.path.join(os.path.dirname(praisonai.__file__), 'chainlit_ui.py')
|
|
248
290
|
chainlit_run([chainlit_ui_path])
|
|
249
291
|
else:
|
|
250
|
-
print("ERROR: Chainlit is not installed. Please install it with 'pip install
|
|
292
|
+
print("ERROR: Chainlit is not installed. Please install it with 'pip install \"praisonai\[ui]\"' to use the UI.")
|
|
251
293
|
|
|
252
294
|
if __name__ == "__main__":
|
|
253
295
|
praison_ai = PraisonAI()
|
praisonai/deploy.py
CHANGED
|
@@ -56,7 +56,7 @@ class CloudDeployer:
|
|
|
56
56
|
file.write("FROM python:3.11-slim\n")
|
|
57
57
|
file.write("WORKDIR /app\n")
|
|
58
58
|
file.write("COPY . .\n")
|
|
59
|
-
file.write("RUN pip install flask praisonai==0.0.
|
|
59
|
+
file.write("RUN pip install flask praisonai==0.0.46 gunicorn markdown\n")
|
|
60
60
|
file.write("EXPOSE 8080\n")
|
|
61
61
|
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
|
|
62
62
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
praisonai/ui/chat.py
ADDED
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
import chainlit as cl
|
|
2
|
+
from chainlit.input_widget import TextInput
|
|
3
|
+
from chainlit.types import ThreadDict
|
|
4
|
+
from litellm import acompletion
|
|
5
|
+
import os
|
|
6
|
+
import sqlite3
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
from typing import Dict, List, Optional
|
|
9
|
+
from dotenv import load_dotenv
|
|
10
|
+
load_dotenv()
|
|
11
|
+
import chainlit.data as cl_data
|
|
12
|
+
from chainlit.step import StepDict
|
|
13
|
+
from literalai.helper import utc_now
|
|
14
|
+
import logging
|
|
15
|
+
|
|
16
|
+
# Set up logging
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
log_level = os.getenv("LOGLEVEL", "INFO").upper()
|
|
19
|
+
logger.handlers = []
|
|
20
|
+
|
|
21
|
+
# Set up logging to console
|
|
22
|
+
console_handler = logging.StreamHandler()
|
|
23
|
+
console_handler.setLevel(log_level)
|
|
24
|
+
console_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
|
25
|
+
console_handler.setFormatter(console_formatter)
|
|
26
|
+
logger.addHandler(console_handler)
|
|
27
|
+
|
|
28
|
+
# Set the logging level for the logger
|
|
29
|
+
logger.setLevel(log_level)
|
|
30
|
+
|
|
31
|
+
CHAINLIT_AUTH_SECRET = os.getenv("CHAINLIT_AUTH_SECRET")
|
|
32
|
+
|
|
33
|
+
if not CHAINLIT_AUTH_SECRET:
|
|
34
|
+
os.environ["CHAINLIT_AUTH_SECRET"] = "p8BPhQChpg@J>jBz$wGxqLX2V>yTVgP*7Ky9H$aV:axW~ANNX-7_T:o@lnyCBu^U"
|
|
35
|
+
CHAINLIT_AUTH_SECRET = os.getenv("CHAINLIT_AUTH_SECRET")
|
|
36
|
+
|
|
37
|
+
now = utc_now()
|
|
38
|
+
|
|
39
|
+
create_step_counter = 0
|
|
40
|
+
|
|
41
|
+
import json
|
|
42
|
+
|
|
43
|
+
DB_PATH = "threads.db"
|
|
44
|
+
|
|
45
|
+
def initialize_db():
|
|
46
|
+
conn = sqlite3.connect(DB_PATH)
|
|
47
|
+
cursor = conn.cursor()
|
|
48
|
+
cursor.execute('''
|
|
49
|
+
CREATE TABLE IF NOT EXISTS threads (
|
|
50
|
+
id TEXT PRIMARY KEY,
|
|
51
|
+
name TEXT,
|
|
52
|
+
createdAt TEXT,
|
|
53
|
+
userId TEXT,
|
|
54
|
+
userIdentifier TEXT
|
|
55
|
+
)
|
|
56
|
+
''')
|
|
57
|
+
cursor.execute('''
|
|
58
|
+
CREATE TABLE IF NOT EXISTS steps (
|
|
59
|
+
id TEXT PRIMARY KEY,
|
|
60
|
+
threadId TEXT,
|
|
61
|
+
name TEXT,
|
|
62
|
+
createdAt TEXT,
|
|
63
|
+
type TEXT,
|
|
64
|
+
output TEXT,
|
|
65
|
+
FOREIGN KEY (threadId) REFERENCES threads (id)
|
|
66
|
+
)
|
|
67
|
+
''')
|
|
68
|
+
cursor.execute('''
|
|
69
|
+
CREATE TABLE IF NOT EXISTS settings (
|
|
70
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
71
|
+
key TEXT UNIQUE,
|
|
72
|
+
value TEXT
|
|
73
|
+
)
|
|
74
|
+
''')
|
|
75
|
+
conn.commit()
|
|
76
|
+
conn.close()
|
|
77
|
+
|
|
78
|
+
def save_setting(key: str, value: str):
|
|
79
|
+
"""Saves a setting to the database.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
key: The setting key.
|
|
83
|
+
value: The setting value.
|
|
84
|
+
"""
|
|
85
|
+
conn = sqlite3.connect(DB_PATH)
|
|
86
|
+
cursor = conn.cursor()
|
|
87
|
+
cursor.execute(
|
|
88
|
+
"""
|
|
89
|
+
INSERT OR REPLACE INTO settings (id, key, value)
|
|
90
|
+
VALUES ((SELECT id FROM settings WHERE key = ?), ?, ?)
|
|
91
|
+
""",
|
|
92
|
+
(key, key, value),
|
|
93
|
+
)
|
|
94
|
+
conn.commit()
|
|
95
|
+
conn.close()
|
|
96
|
+
|
|
97
|
+
def load_setting(key: str) -> str:
|
|
98
|
+
"""Loads a setting from the database.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
key: The setting key.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
The setting value, or None if the key is not found.
|
|
105
|
+
"""
|
|
106
|
+
conn = sqlite3.connect(DB_PATH)
|
|
107
|
+
cursor = conn.cursor()
|
|
108
|
+
cursor.execute('SELECT value FROM settings WHERE key = ?', (key,))
|
|
109
|
+
result = cursor.fetchone()
|
|
110
|
+
conn.close()
|
|
111
|
+
return result[0] if result else None
|
|
112
|
+
|
|
113
|
+
def save_thread_to_db(thread):
|
|
114
|
+
conn = sqlite3.connect(DB_PATH)
|
|
115
|
+
cursor = conn.cursor()
|
|
116
|
+
cursor.execute('''
|
|
117
|
+
INSERT OR REPLACE INTO threads (id, name, createdAt, userId, userIdentifier)
|
|
118
|
+
VALUES (?, ?, ?, ?, ?)
|
|
119
|
+
''', (thread['id'], thread['name'], thread['createdAt'], thread['userId'], thread['userIdentifier']))
|
|
120
|
+
|
|
121
|
+
# No steps to save as steps are empty in the provided thread data
|
|
122
|
+
conn.commit()
|
|
123
|
+
conn.close()
|
|
124
|
+
logger.debug("Thread saved to DB")
|
|
125
|
+
|
|
126
|
+
def update_thread_in_db(thread):
|
|
127
|
+
conn = sqlite3.connect(DB_PATH)
|
|
128
|
+
cursor = conn.cursor()
|
|
129
|
+
|
|
130
|
+
# Insert or update the thread
|
|
131
|
+
cursor.execute('''
|
|
132
|
+
INSERT OR REPLACE INTO threads (id, name, createdAt, userId, userIdentifier)
|
|
133
|
+
VALUES (?, ?, ?, ?, ?)
|
|
134
|
+
''', (thread['id'], thread['name'], thread['createdAt'], thread['userId'], thread['userIdentifier']))
|
|
135
|
+
|
|
136
|
+
# Fetch message_history from metadata
|
|
137
|
+
message_history = cl.user_session.get("message_history", [])
|
|
138
|
+
|
|
139
|
+
# Ensure user messages come first followed by assistant messages
|
|
140
|
+
user_messages = [msg for msg in message_history if msg['role'] == 'user']
|
|
141
|
+
assistant_messages = [msg for msg in message_history if msg['role'] == 'assistant']
|
|
142
|
+
ordered_steps = [val for pair in zip(user_messages, assistant_messages) for val in pair]
|
|
143
|
+
|
|
144
|
+
# Generate steps from ordered message_history
|
|
145
|
+
steps = []
|
|
146
|
+
for idx, message in enumerate(ordered_steps):
|
|
147
|
+
step_id = f"{thread['id']}-step-{idx}"
|
|
148
|
+
step_type = 'user_message' if message['role'] == 'user' else 'assistant_message'
|
|
149
|
+
step_name = 'user' if message['role'] == 'user' else 'assistant'
|
|
150
|
+
created_at = message.get('createdAt', thread['createdAt']) # Use thread's createdAt if no timestamp in message
|
|
151
|
+
steps.append({
|
|
152
|
+
'id': step_id,
|
|
153
|
+
'threadId': thread['id'],
|
|
154
|
+
'name': step_name,
|
|
155
|
+
'createdAt': created_at,
|
|
156
|
+
'type': step_type,
|
|
157
|
+
'output': message['content']
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
# Insert all steps into the database
|
|
161
|
+
for step in steps:
|
|
162
|
+
cursor.execute('''
|
|
163
|
+
INSERT OR REPLACE INTO steps (id, threadId, name, createdAt, type, output)
|
|
164
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
165
|
+
''', (step['id'], step['threadId'], step['name'], step['createdAt'], step['type'], step['output']))
|
|
166
|
+
|
|
167
|
+
conn.commit()
|
|
168
|
+
conn.close()
|
|
169
|
+
logger.debug("Thread updated in DB")
|
|
170
|
+
|
|
171
|
+
def delete_thread_from_db(thread_id: str):
|
|
172
|
+
"""Deletes a thread and its steps from the database.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
thread_id: The ID of the thread to delete.
|
|
176
|
+
"""
|
|
177
|
+
conn = sqlite3.connect(DB_PATH)
|
|
178
|
+
cursor = conn.cursor()
|
|
179
|
+
cursor.execute('DELETE FROM threads WHERE id = ?', (thread_id,))
|
|
180
|
+
cursor.execute('DELETE FROM steps WHERE threadId = ?', (thread_id,))
|
|
181
|
+
conn.commit()
|
|
182
|
+
conn.close()
|
|
183
|
+
|
|
184
|
+
def load_threads_from_db():
|
|
185
|
+
conn = sqlite3.connect(DB_PATH)
|
|
186
|
+
cursor = conn.cursor()
|
|
187
|
+
cursor.execute('SELECT * FROM threads ORDER BY createdAt ASC')
|
|
188
|
+
thread_rows = cursor.fetchall()
|
|
189
|
+
threads = []
|
|
190
|
+
for thread_row in thread_rows:
|
|
191
|
+
cursor.execute('SELECT * FROM steps WHERE threadId = ? ORDER BY createdAt ASC', (thread_row[0],))
|
|
192
|
+
step_rows = cursor.fetchall()
|
|
193
|
+
steps = []
|
|
194
|
+
for step_row in step_rows:
|
|
195
|
+
steps.append({
|
|
196
|
+
"id": step_row[0],
|
|
197
|
+
"threadId": step_row[1],
|
|
198
|
+
"name": step_row[2],
|
|
199
|
+
"createdAt": step_row[3],
|
|
200
|
+
"type": step_row[4],
|
|
201
|
+
"output": step_row[5]
|
|
202
|
+
})
|
|
203
|
+
threads.append({
|
|
204
|
+
"id": thread_row[0],
|
|
205
|
+
"name": thread_row[1],
|
|
206
|
+
"createdAt": thread_row[2],
|
|
207
|
+
"userId": thread_row[3],
|
|
208
|
+
"userIdentifier": thread_row[4],
|
|
209
|
+
"steps": steps
|
|
210
|
+
})
|
|
211
|
+
conn.close()
|
|
212
|
+
logger.debug("Threads loaded from DB")
|
|
213
|
+
return threads
|
|
214
|
+
|
|
215
|
+
# Initialize the database
|
|
216
|
+
initialize_db()
|
|
217
|
+
thread_history = load_threads_from_db()
|
|
218
|
+
|
|
219
|
+
deleted_thread_ids = [] # type: List[str]
|
|
220
|
+
|
|
221
|
+
class TestDataLayer(cl_data.BaseDataLayer): # Implement SQLAlchemyDataLayer
|
|
222
|
+
async def get_user(self, identifier: str):
|
|
223
|
+
logger.debug(f"Getting user: {identifier}")
|
|
224
|
+
return cl.PersistedUser(id="test", createdAt=now, identifier=identifier)
|
|
225
|
+
|
|
226
|
+
async def create_user(self, user: cl.User):
|
|
227
|
+
logger.debug(f"Creating user: {user.identifier}")
|
|
228
|
+
return cl.PersistedUser(id="test", createdAt=now, identifier=user.identifier)
|
|
229
|
+
|
|
230
|
+
async def update_thread(
|
|
231
|
+
self,
|
|
232
|
+
thread_id: str,
|
|
233
|
+
name: Optional[str] = None,
|
|
234
|
+
user_id: Optional[str] = None,
|
|
235
|
+
metadata: Optional[Dict] = None,
|
|
236
|
+
tags: Optional[List[str]] = None,
|
|
237
|
+
):
|
|
238
|
+
logger.debug(f"Updating thread: {thread_id}")
|
|
239
|
+
thread = next((t for t in thread_history if t["id"] == thread_id), None)
|
|
240
|
+
if thread:
|
|
241
|
+
if name:
|
|
242
|
+
thread["name"] = name
|
|
243
|
+
if metadata:
|
|
244
|
+
thread["metadata"] = metadata
|
|
245
|
+
if tags:
|
|
246
|
+
thread["tags"] = tags
|
|
247
|
+
|
|
248
|
+
logger.debug(f"Thread: {thread}")
|
|
249
|
+
cl.user_session.set("message_history", thread['metadata']['message_history'])
|
|
250
|
+
cl.user_session.set("thread_id", thread["id"])
|
|
251
|
+
update_thread_in_db(thread)
|
|
252
|
+
logger.debug(f"Thread updated: {thread_id}")
|
|
253
|
+
|
|
254
|
+
else:
|
|
255
|
+
thread_history.append(
|
|
256
|
+
{
|
|
257
|
+
"id": thread_id,
|
|
258
|
+
"name": name,
|
|
259
|
+
"metadata": metadata,
|
|
260
|
+
"tags": tags,
|
|
261
|
+
"createdAt": utc_now(),
|
|
262
|
+
"userId": user_id,
|
|
263
|
+
"userIdentifier": "admin",
|
|
264
|
+
"steps": [],
|
|
265
|
+
}
|
|
266
|
+
)
|
|
267
|
+
thread = {
|
|
268
|
+
"id": thread_id,
|
|
269
|
+
"name": name,
|
|
270
|
+
"metadata": metadata,
|
|
271
|
+
"tags": tags,
|
|
272
|
+
"createdAt": utc_now(),
|
|
273
|
+
"userId": user_id,
|
|
274
|
+
"userIdentifier": "admin",
|
|
275
|
+
"steps": [],
|
|
276
|
+
}
|
|
277
|
+
save_thread_to_db(thread)
|
|
278
|
+
logger.debug(f"Thread created: {thread_id}")
|
|
279
|
+
|
|
280
|
+
@cl_data.queue_until_user_message()
|
|
281
|
+
async def create_step(self, step_dict: StepDict):
|
|
282
|
+
global create_step_counter
|
|
283
|
+
create_step_counter += 1
|
|
284
|
+
|
|
285
|
+
thread = next(
|
|
286
|
+
(t for t in thread_history if t["id"] == step_dict.get("threadId")), None
|
|
287
|
+
)
|
|
288
|
+
if thread:
|
|
289
|
+
thread["steps"].append(step_dict)
|
|
290
|
+
|
|
291
|
+
async def get_thread_author(self, thread_id: str):
|
|
292
|
+
logger.debug(f"Getting thread author: {thread_id}")
|
|
293
|
+
return "admin"
|
|
294
|
+
|
|
295
|
+
async def list_threads(
|
|
296
|
+
self, pagination: cl_data.Pagination, filters: cl_data.ThreadFilter
|
|
297
|
+
) -> cl_data.PaginatedResponse[cl_data.ThreadDict]:
|
|
298
|
+
logger.debug(f"Listing threads")
|
|
299
|
+
return cl_data.PaginatedResponse(
|
|
300
|
+
data=[t for t in thread_history if t["id"] not in deleted_thread_ids][::-1],
|
|
301
|
+
pageInfo=cl_data.PageInfo(
|
|
302
|
+
hasNextPage=False, startCursor=None, endCursor=None
|
|
303
|
+
),
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
async def get_thread(self, thread_id: str):
|
|
307
|
+
logger.debug(f"Getting thread: {thread_id}")
|
|
308
|
+
thread_history = load_threads_from_db()
|
|
309
|
+
return next((t for t in thread_history if t["id"] == thread_id), None)
|
|
310
|
+
|
|
311
|
+
async def delete_thread(self, thread_id: str):
|
|
312
|
+
deleted_thread_ids.append(thread_id)
|
|
313
|
+
delete_thread_from_db(thread_id)
|
|
314
|
+
logger.debug(f"Deleted thread: {thread_id}")
|
|
315
|
+
|
|
316
|
+
cl_data._data_layer = TestDataLayer()
|
|
317
|
+
|
|
318
|
+
@cl.on_chat_start
|
|
319
|
+
async def start():
|
|
320
|
+
initialize_db()
|
|
321
|
+
model_name = load_setting("model_name")
|
|
322
|
+
|
|
323
|
+
if model_name:
|
|
324
|
+
cl.user_session.set("model_name", model_name)
|
|
325
|
+
else:
|
|
326
|
+
# If no setting found, use default or environment variable
|
|
327
|
+
model_name = os.getenv("MODEL_NAME", "gpt-3.5-turbo")
|
|
328
|
+
cl.user_session.set("model_name", model_name)
|
|
329
|
+
logger.debug(f"Model name: {model_name}")
|
|
330
|
+
settings = cl.ChatSettings(
|
|
331
|
+
[
|
|
332
|
+
TextInput(
|
|
333
|
+
id="model_name",
|
|
334
|
+
label="Enter the Model Name",
|
|
335
|
+
placeholder="e.g., gpt-3.5-turbo",
|
|
336
|
+
initial=model_name
|
|
337
|
+
)
|
|
338
|
+
]
|
|
339
|
+
)
|
|
340
|
+
cl.user_session.set("settings", settings)
|
|
341
|
+
await settings.send()
|
|
342
|
+
|
|
343
|
+
@cl.on_settings_update
|
|
344
|
+
async def setup_agent(settings):
|
|
345
|
+
logger.debug(settings)
|
|
346
|
+
cl.user_session.set("settings", settings)
|
|
347
|
+
model_name = settings["model_name"]
|
|
348
|
+
cl.user_session.set("model_name", model_name)
|
|
349
|
+
|
|
350
|
+
# Save in settings table
|
|
351
|
+
save_setting("model_name", model_name)
|
|
352
|
+
|
|
353
|
+
# Save in thread metadata
|
|
354
|
+
thread_id = cl.user_session.get("thread_id")
|
|
355
|
+
if thread_id:
|
|
356
|
+
thread = await cl_data.get_thread(thread_id)
|
|
357
|
+
if thread:
|
|
358
|
+
metadata = thread.get("metadata", {})
|
|
359
|
+
metadata["model_name"] = model_name
|
|
360
|
+
await cl_data.update_thread(thread_id, metadata=metadata)
|
|
361
|
+
|
|
362
|
+
@cl.on_message
|
|
363
|
+
async def main(message: cl.Message):
|
|
364
|
+
model_name = load_setting("model_name") or os.getenv("MODEL_NAME") or "gpt-3.5-turbo"
|
|
365
|
+
message_history = cl.user_session.get("message_history", [])
|
|
366
|
+
message_history.append({"role": "user", "content": message.content})
|
|
367
|
+
|
|
368
|
+
msg = cl.Message(content="")
|
|
369
|
+
await msg.send()
|
|
370
|
+
|
|
371
|
+
response = await acompletion(
|
|
372
|
+
model=model_name,
|
|
373
|
+
messages=message_history,
|
|
374
|
+
stream=True,
|
|
375
|
+
temperature=0.7,
|
|
376
|
+
max_tokens=500,
|
|
377
|
+
top_p=1
|
|
378
|
+
)
|
|
379
|
+
|
|
380
|
+
full_response = ""
|
|
381
|
+
async for part in response:
|
|
382
|
+
if token := part['choices'][0]['delta']['content']:
|
|
383
|
+
await msg.stream_token(token)
|
|
384
|
+
full_response += token
|
|
385
|
+
logger.debug(f"Full response: {full_response}")
|
|
386
|
+
message_history.append({"role": "assistant", "content": full_response})
|
|
387
|
+
logger.debug(f"Message history: {message_history}")
|
|
388
|
+
cl.user_session.set("message_history", message_history)
|
|
389
|
+
await msg.update()
|
|
390
|
+
|
|
391
|
+
username = os.getenv("CHAINLIT_USERNAME", "admin") # Default to "admin" if not found
|
|
392
|
+
password = os.getenv("CHAINLIT_PASSWORD", "admin") # Default to "admin" if not found
|
|
393
|
+
|
|
394
|
+
@cl.password_auth_callback
|
|
395
|
+
def auth_callback(username: str, password: str):
|
|
396
|
+
if (username, password) == (username, password):
|
|
397
|
+
return cl.User(
|
|
398
|
+
identifier=username, metadata={"role": "ADMIN", "provider": "credentials"}
|
|
399
|
+
)
|
|
400
|
+
else:
|
|
401
|
+
return None
|
|
402
|
+
|
|
403
|
+
async def send_count():
|
|
404
|
+
await cl.Message(
|
|
405
|
+
f"Create step counter: {create_step_counter}", disable_feedback=True
|
|
406
|
+
).send()
|
|
407
|
+
|
|
408
|
+
@cl.on_chat_resume
|
|
409
|
+
async def on_chat_resume(thread: cl_data.ThreadDict):
|
|
410
|
+
logger.info(f"Resuming chat: {thread['id']}")
|
|
411
|
+
model_name = load_setting("model_name") or os.getenv("MODEL_NAME") or "gpt-3.5-turbo"
|
|
412
|
+
logger.debug(f"Model name: {model_name}")
|
|
413
|
+
settings = cl.ChatSettings(
|
|
414
|
+
[
|
|
415
|
+
TextInput(
|
|
416
|
+
id="model_name",
|
|
417
|
+
label="Enter the Model Name",
|
|
418
|
+
placeholder="e.g., gpt-3.5-turbo",
|
|
419
|
+
initial=model_name
|
|
420
|
+
)
|
|
421
|
+
]
|
|
422
|
+
)
|
|
423
|
+
await settings.send()
|
|
424
|
+
thread_id = thread["id"]
|
|
425
|
+
cl.user_session.set("thread_id", thread["id"])
|
|
426
|
+
message_history = cl.user_session.get("message_history", [])
|
|
427
|
+
steps = thread["steps"]
|
|
428
|
+
|
|
429
|
+
for message in steps:
|
|
430
|
+
msg_type = message.get("type")
|
|
431
|
+
if msg_type == "user_message":
|
|
432
|
+
message_history.append({"role": "user", "content": message.get("output", "")})
|
|
433
|
+
elif msg_type == "assistant_message":
|
|
434
|
+
message_history.append({"role": "assistant", "content": message.get("output", "")})
|
|
435
|
+
else:
|
|
436
|
+
logger.warning(f"Message without type: {message}")
|
|
437
|
+
|
|
438
|
+
cl.user_session.set("message_history", message_history)
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
+
<svg width="800px" height="800px" viewBox="0 0 1024 1024" class="icon" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M840.5 798.2L662.3 599.5l-151 173.7-173.7-173.7-167.7 201c-21 30.4 0.9 71.8 37.9 71.6l594.7-3.3c36.2-0.1 57.8-40.3 38-70.6z" fill="#FFB89A" /><path d="M741.6 647.3l-52.3-47.7c-12.2-11.2-31.2-10.3-42.4 1.9s-10.3 31.2 1.9 42.4l52.3 47.7c5.8 5.3 13 7.8 20.2 7.8 8.1 0 16.2-3.3 22.2-9.8 11.2-12.1 10.3-31.1-1.9-42.3zM631.2 546.5c-12.4-11-31.4-9.8-42.3 2.6l-98.8 111.7-171-165.7L87.9 724.7c-11.8 11.7-11.8 30.7-0.1 42.4 5.9 5.9 13.6 8.9 21.3 8.9 7.6 0 15.3-2.9 21.1-8.7l189.4-188.1 173.8 168.5L633.8 589c11-12.5 9.8-31.5-2.6-42.5z" fill="#33CC99" /><path d="M721.3 342.8m-35.1 0a35.1 35.1 0 1 0 70.2 0 35.1 35.1 0 1 0-70.2 0Z" fill="#33CC99" /><path d="M743.2 175.1H191.6c-70.6 0-128.3 57.7-128.3 128.3v499.2c0 70.6 57.7 128.3 128.3 128.3h551.5c70.6 0 128.3-57.7 128.3-128.3V303.5c0.1-70.6-57.7-128.4-128.2-128.4z m68.3 627.6c0 18.1-7.1 35.2-20.1 48.2-13 13-30.1 20.1-48.2 20.1H191.6c-18.1 0-35.2-7.1-48.2-20.1-13-13-20.1-30.1-20.1-48.2V303.5c0-18.1 7.1-35.2 20.1-48.2 13-13 30.1-20.1 48.2-20.1h551.5c18.1 0 35.2 7.1 48.2 20.1 13 13 20.1 30.1 20.1 48.2v499.2z" fill="#45484C" /><path d="M799.7 90.9H237.2c-16.6 0-30 13.4-30 30s13.4 30 30 30h562.4c26.1 0 50.8 10.3 69.4 28.9 18.6 18.6 28.9 43.3 28.9 69.4v482.4c0 16.6 13.4 30 30 30s30-13.4 30-30V249.2C958 161.9 887 90.9 799.7 90.9z" fill="#45484C" /></svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
+
<svg width="800px" height="800px" viewBox="0 0 1024 1024" class="icon" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M570.2 842c-50.6 0-278.7-180-278.7-401.9 0-58.8-2.9-133.1-1-183.9-50.8 3.2-91.4 45.7-91.4 97.3v272.1c37.4 194.7 137.5 334 255.2 334 69.5 0 132.9-48.6 180.9-128.5-20.8 7.1-42.6 10.9-65 10.9z" fill="#FFB89A" /><path d="M926.1 191.8C900.5 74.1 817.9 62.1 704.9 62.1c-29.1 0-60.3 0.8-93 0.8-36 0-70.5-1.1-102.5-1.1-109.7 0-189.8 12.5-201.3 123.7-20.4 198.3 30 617.1 306.1 617.1S939 414.3 926.1 191.8z m-76.9 268.5c-9.5 47.9-22.3 90.8-38.1 127.7-16.8 39.2-37 71.4-60 95.8-37.3 39.5-82.1 58.7-137 58.7-53.4 0-97.6-20.1-134.9-61.6-45.5-50.5-79.8-131.5-99-234.2-15.6-83.5-20.3-178.9-12.4-255.2 1.8-17.3 5.7-30.7 11.6-39.8 4.4-6.8 10.1-11.7 18.7-15.8 25.8-12.5 70.8-14.2 111.4-14.2 15 0 30.7 0.2 47.3 0.5 17.8 0.3 36.2 0.6 55.2 0.6 17.2 0 33.9-0.2 50-0.4 15.1-0.2 29.3-0.4 43.1-0.4 44.5 0 89.5 1.8 118 15.1 15.9 7.4 33.4 20.8 43.6 63 2.6 53.3 3.6 153.5-17.5 260.2z" fill="#4E5155" /><path d="M532 841.7c-32.5 22.3-70.6 33.7-113.2 33.7-29.7 0-57.3-6-82.1-17.7-23.2-11-44.7-27.4-63.9-48.7-46-50.9-80.3-131.3-99.2-232.4-15.1-80.6-19.6-172.9-12-246.8 3-29.5 12-50.2 27.5-63.2 14.2-12 35.1-19.2 65.8-22.9 16.5-2 28.2-16.9 26.3-33.3-2-16.5-16.9-28.2-33.3-26.3-42.9 5.1-73.8 16.7-97.4 36.5-27.9 23.5-43.8 57.2-48.5 103-8.2 79.3-3.4 178.1 12.7 264 9.7 51.9 23.4 99.4 40.6 141.2 19.8 48.1 44.4 88.6 73 120.4 51.6 57.2 115.7 86.2 190.6 86.2 55 0 104.5-14.9 147.2-44.2 13.7-9.4 17.1-28.1 7.7-41.7-9.4-13.7-28.1-17.2-41.8-7.8z" fill="#4E5155" /><path d="M519.7 248.5c-16.6 0-30 13.4-30 30v91.3c0 16.6 13.4 30 30 30s30-13.4 30-30v-91.3c0-16.6-13.5-30-30-30zM299.5 385.5c0-16.6-13.4-30-30-30s-30 13.4-30 30v91.3c0 16.6 13.4 30 30 30s30-13.4 30-30v-91.3zM754.6 248.5c-16.6 0-30 13.4-30 30v91.3c0 16.6 13.4 30 30 30s30-13.4 30-30v-91.3c0-16.6-13.4-30-30-30zM716.7 554.5c0-16.6-13.4-30-30-30H551v30c0 58.5 38.1 123.7 92.8 123.7 22.9 0 45-11.9 62.2-33.6 10.3-13 8.1-31.9-4.9-42.1-13-10.3-31.9-8.1-42.1 4.9-5.3 6.7-11.1 10.9-15.1 10.9-4.3 0-11.9-5.1-19.1-16.4-3.3-5.3-6.2-11.2-8.4-17.4h70.4c16.4 0 29.9-13.4 29.9-30zM401.6 704c-25.4 0-46.1-24.2-46.1-53.9 0-16.6-13.4-30-30-30s-30 13.4-30 30c0 62.8 47.6 113.9 106.1 113.9 16.6 0 30-13.4 30-30s-13.5-30-30-30z" fill="#33CC99" /></svg>
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
+
<svg width="800px" height="800px" viewBox="0 0 1024 1024" class="icon" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M861.9 383.8H218.1c-36.4 0-66.1-29.8-66.1-66.1V288c0-36.4 29.8-66.1 66.1-66.1h643.8c36.4 0 66.1 29.8 66.1 66.1v29.7c0 36.3-29.8 66.1-66.1 66.1z" fill="#FFB89A" /><path d="M822.9 129.2H199.8c-77.2 0-140.4 63.2-140.4 140.4v487.2c0 77.2 63.2 140.4 140.4 140.4h623.1c77.2 0 140.4-63.2 140.4-140.4V269.6c0-77.2-63.2-140.4-140.4-140.4z m80.4 177H760.4L864.6 201c5.4 3.3 10.4 7.3 15 11.8 15.3 15.3 23.7 35.4 23.7 56.8v36.6z m-673.3 0l104-117h61.3l-109.1 117H230z m247.4-117h169.2L532 306.2H368.3l109.1-117z m248.8 0h65.6L676 306.2h-60l112.5-114.8-2.3-2.2zM143 212.9c15.3-15.3 35.4-23.7 56.8-23.7h53.9l-104 117h-30.4v-36.5c0.1-21.4 8.5-41.5 23.7-56.8z m736.6 600.7c-15.3 15.3-35.4 23.7-56.8 23.7h-623c-21.3 0-41.5-8.4-56.8-23.7-15.3-15.3-23.7-35.4-23.7-56.8V366.2h783.9v390.6c0.1 21.3-8.3 41.5-23.6 56.8z" fill="#45484C" /><path d="M400.5 770.6V430.9L534.1 508c14.3 8.3 19.3 26.6 11 41-8.3 14.3-26.6 19.3-41 11l-43.6-25.2v131.8l114.1-65.9-7.5-4.3c-14.3-8.3-19.3-26.6-11-41 8.3-14.3 26.6-19.3 41-11l97.5 56.3-294.1 169.9z" fill="#33CC99" /></svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
+
<svg width="800px" height="800px" viewBox="0 0 1024 1024" class="icon" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M188.3 766.5a94.4 135.8 0 1 0 188.8 0 94.4 135.8 0 1 0-188.8 0Z" fill="#FFB89A" /><path d="M931.5 397s0-0.1 0 0c-34.2-82.6-119.3-141-218.8-141-129.7 0-234.9 99.3-234.9 221.9 0 52.1 19.1 100.1 50.9 138 1 14.5 1.8 29.1 1.8 43.6 0 148.5 98.1 269 219.2 269 121 0 219.2-120.4 219.2-269 0-70.1-1.7-214.7-37.4-262.5z m-36.6 347.5c-8.7 25.3-21.1 47.9-36.8 67.1-29.8 36.5-68.3 56.7-108.5 56.7s-78.7-20.1-108.5-56.7c-15.7-19.2-28-41.8-36.8-67.1-9.3-26.9-13.9-55.5-13.9-85.1 0-16.8-1-33.5-2-47.7l-1.3-19.5-12.6-15c-24.1-28.6-36.8-63-36.8-99.3 0-89.3 78.5-161.9 174.9-161.9 36.4 0 71.4 10.3 101 29.7 28.4 18.7 65.5 81.7 65.5 81.7s17.9 27.5 24.7 98.2c4.5 46.5 5 95.9 5 133.8 0.1 29.6-4.6 58.2-13.9 85.1zM377.1 219.9c-51.8 0-93.8 42-93.8 93.8s42 93.8 93.8 93.8 93.8-42 93.8-93.8-42-93.8-93.8-93.8z m0 127.5c-18.6 0-33.8-15.2-33.8-33.8 0-18.6 15.2-33.8 33.8-33.8 18.6 0 33.8 15.2 33.8 33.8 0 18.7-15.1 33.8-33.8 33.8z" fill="#45484C" /><path d="M521.2 206.7m-50.3 0a50.3 50.3 0 1 0 100.6 0 50.3 50.3 0 1 0-100.6 0Z" fill="#45484C" /><path d="M653 156.4m-50.3 0a50.3 50.3 0 1 0 100.6 0 50.3 50.3 0 1 0-100.6 0Z" fill="#45484C" /><path d="M781.9 158.4m-50.3 0a50.3 50.3 0 1 0 100.6 0 50.3 50.3 0 1 0-100.6 0Z" fill="#45484C" /><path d="M909 206.7m-50.3 0a50.3 50.3 0 1 0 100.6 0 50.3 50.3 0 1 0-100.6 0Z" fill="#45484C" /><path d="M263.9 602.7c44.7 0 81 31.5 81 70.3 0 20.9-10.2 35.9-18.7 44.8l-15.9 19.7-0.5 27.2c0.7 7.2 0.6 16.9 0.6 24.7v4.8c0 33.7-27.4 61.2-61.2 61.2-14.9 0-33.3-9.6-48.1-25-15.2-15.9-24.6-35.9-24.6-52.3v-3.2c0-12.7 0-36.2 1-60.2 1.4-33 7.4-57.3 7.4-57.3 3.9-14.7 13.4-28.2 26.8-38 14.8-11 32.8-16.7 52.2-16.7m0-60c-66.4 0-122 42.4-137 99.4-10.9 23-10.4 112.6-10.4 135.9 0 66.9 65.8 137.3 132.7 137.3 66.9 0 121.2-54.3 121.2-121.2 0-9.2 0.3-23-0.8-34.9 22-23 35.4-53.2 35.4-86.3-0.1-71.9-63.2-130.2-141.1-130.2zM444.4 559.9c-26.4 0-47.8 21.4-47.8 47.8s21.4 47.8 47.8 47.8 47.8-21.4 47.8-47.8-21.4-47.8-47.8-47.8zM377.1 494.5c-15.2 0-27.5 12.3-27.5 27.5s12.3 27.5 27.5 27.5 27.5-12.3 27.5-27.5c0-15.3-12.3-27.5-27.5-27.5zM288.1 471.5c-15.2 0-27.5 12.3-27.5 27.5s12.3 27.5 27.5 27.5 27.5-12.3 27.5-27.5-12.4-27.5-27.5-27.5zM188.3 477.9c-15.2 0-27.5 12.3-27.5 27.5s12.3 27.5 27.5 27.5 27.5-12.3 27.5-27.5-12.3-27.5-27.5-27.5zM100.6 538.4c-15.2 0-27.5 12.3-27.5 27.5s12.3 27.5 27.5 27.5 27.5-12.3 27.5-27.5c-0.1-15.2-12.4-27.5-27.5-27.5z" fill="#45484C" /><path d="M670.1 584.6c-41.4 0-80.2-20.3-103.9-54.3-9.5-13.6-6.2-32.3 7.4-41.8 13.6-9.5 32.3-6.2 41.8 7.4 12.5 17.9 33 28.6 54.7 28.6 36.8 0 66.7-29.9 66.7-66.7 0-19.8-8.7-38.4-23.9-51.2-12.7-10.6-14.4-29.6-3.7-42.3s29.6-14.4 42.3-3.7c28.9 24.2 45.4 59.6 45.4 97.2-0.1 70-56.9 126.8-126.8 126.8z" fill="#33CC99" /><path d="M853 556.4c-26 0-49.6-14.5-60.1-36.9-7-15-0.6-32.9 14.4-39.9s32.9-0.6 39.9 14.4c0.3 0.6 2.2 2.4 5.8 2.4 1.2 0 2.3-0.2 3.3-0.6 15.5-5.9 32.8 1.8 38.7 17.3 5.9 15.5-1.8 32.8-17.3 38.7-7.9 3.1-16.2 4.6-24.7 4.6z" fill="#33CC99" /></svg>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: PraisonAI
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.46
|
|
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
|
|
@@ -11,13 +11,14 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
11
11
|
Provides-Extra: agentops
|
|
12
12
|
Provides-Extra: anthropic
|
|
13
13
|
Provides-Extra: api
|
|
14
|
+
Provides-Extra: chat
|
|
14
15
|
Provides-Extra: cohere
|
|
15
16
|
Provides-Extra: google
|
|
16
17
|
Provides-Extra: gradio
|
|
17
18
|
Provides-Extra: openai
|
|
18
19
|
Provides-Extra: ui
|
|
19
20
|
Requires-Dist: agentops (>=0.2.6) ; extra == "agentops"
|
|
20
|
-
Requires-Dist: chainlit (>=1.1.301,<2.0.0) ; extra == "ui"
|
|
21
|
+
Requires-Dist: chainlit (>=1.1.301,<2.0.0) ; extra == "ui" or extra == "chat"
|
|
21
22
|
Requires-Dist: crewai (>=0.32.0)
|
|
22
23
|
Requires-Dist: flask (>=3.0.0) ; extra == "api"
|
|
23
24
|
Requires-Dist: gradio (>=4.26.0) ; extra == "gradio"
|
|
@@ -25,6 +26,7 @@ Requires-Dist: langchain-anthropic (>=0.1.13) ; extra == "anthropic"
|
|
|
25
26
|
Requires-Dist: langchain-cohere (>=0.1.4) ; extra == "cohere"
|
|
26
27
|
Requires-Dist: langchain-google-genai (>=1.0.4) ; extra == "google"
|
|
27
28
|
Requires-Dist: langchain-openai (>=0.1.7) ; extra == "openai"
|
|
29
|
+
Requires-Dist: litellm (>=1.41.8) ; extra == "chat"
|
|
28
30
|
Requires-Dist: markdown (>=3.5)
|
|
29
31
|
Requires-Dist: praisonai-tools (>=0.0.7)
|
|
30
32
|
Requires-Dist: pyautogen (>=0.2.19)
|
|
@@ -34,10 +36,26 @@ Project-URL: Homepage, https://docs.praison.ai
|
|
|
34
36
|
Project-URL: Repository, https://github.com/mervinpraison/PraisonAI
|
|
35
37
|
Description-Content-Type: text/markdown
|
|
36
38
|
|
|
39
|
+
<p align="center">
|
|
40
|
+
<picture>
|
|
41
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/images/praisonai-logo-large.png">
|
|
42
|
+
<source media="(prefers-color-scheme: light)" srcset="docs/images/praisonai-logo-black-large.png">
|
|
43
|
+
<img alt="PraisonAI Logo" src="docs/images/praisonai-logo-black-large.png">
|
|
44
|
+
</picture>
|
|
45
|
+
</p>
|
|
46
|
+
<div align="center">
|
|
47
|
+
|
|
37
48
|
# Praison AI
|
|
38
49
|
|
|
50
|
+
</div>
|
|
51
|
+
|
|
39
52
|
Praison AI, leveraging both AutoGen and CrewAI or any other agent framework, represents a low-code, centralised framework designed to simplify the creation and orchestration of multi-agent systems for various LLM applications, emphasizing ease of use, customization, and human-agent interaction.
|
|
40
53
|
|
|
54
|
+
| | Cookbook | Open in Colab |
|
|
55
|
+
| --- | --- | --- |
|
|
56
|
+
| Basic | PraisonAI | <a target="_blank" href="https://colab.research.google.com/github/MervinPraison/PraisonAI/blob/main/cookbooks/praisonai-googlecolab.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a> |
|
|
57
|
+
| Include Tools | PraisonAI Tools | <a target="_blank" href="https://colab.research.google.com/github/MervinPraison/PraisonAI/blob/main/cookbooks/praisonai-tools-googlecolab.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a> |
|
|
58
|
+
|
|
41
59
|
## TL;DR
|
|
42
60
|
```bash
|
|
43
61
|
pip install praisonai
|
|
@@ -46,13 +64,21 @@ praisonai --init create a movie script about dog in moon
|
|
|
46
64
|
praisonai
|
|
47
65
|
```
|
|
48
66
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
67
|
+
## Table of Contents
|
|
68
|
+
|
|
69
|
+
- [Installation](#installation)
|
|
70
|
+
- [Initialise](#initialise)
|
|
71
|
+
- [Run](#run)
|
|
72
|
+
- [Full Automatic Mode](#full-automatic-mode)
|
|
73
|
+
- [User Interface](#user-interface)
|
|
74
|
+
- [Praison AI Chat](#praison-ai-chat)
|
|
75
|
+
- [Create Custom Tools](#create-custom-tools)
|
|
76
|
+
- [Agents Playbook](#agents-playbook)
|
|
77
|
+
- [Include praisonai package in your project](#include-praisonai-package-in-your-project)
|
|
78
|
+
- [Commands to Install Dev Dependencies](#commands-to-install-dependencies)
|
|
79
|
+
- [Other Models](#other-models)
|
|
80
|
+
- [Contributing](#contributing)
|
|
81
|
+
- [Star History](#star-history)
|
|
56
82
|
|
|
57
83
|
## Installation
|
|
58
84
|
|
|
@@ -121,29 +147,26 @@ or
|
|
|
121
147
|
python -m praisonai ui
|
|
122
148
|
```
|
|
123
149
|
|
|
124
|
-
##
|
|
150
|
+
## Praison AI Chat
|
|
125
151
|
|
|
126
|
-
|
|
152
|
+
* https://docs.praison.ai/chat/
|
|
127
153
|
|
|
128
154
|
```bash
|
|
129
|
-
pip install praisonai
|
|
155
|
+
pip install "praisonai[chat]"
|
|
130
156
|
export OPENAI_API_KEY="Enter your API key"
|
|
131
|
-
praisonai
|
|
157
|
+
praisonai chat
|
|
132
158
|
```
|
|
133
159
|
|
|
134
|
-
|
|
135
|
-
- Create a file called tools.py and add this code [tools.py](./tools.py)
|
|
160
|
+
## Create Custom Tools
|
|
136
161
|
|
|
137
|
-
|
|
138
|
-
praisonai
|
|
139
|
-
```
|
|
162
|
+
* https://docs.praison.ai/tools/custom/
|
|
140
163
|
|
|
141
|
-
### Pre-requisite to Create a Custom Tool
|
|
164
|
+
### Step 1: Pre-requisite to Create a Custom Tool
|
|
142
165
|
`agents.yaml` file should be present in the current directory.
|
|
143
166
|
|
|
144
167
|
If it doesn't exist, create it by running the command `praisonai --init research about the latest AI News and prepare a detailed report`.
|
|
145
168
|
|
|
146
|
-
### Step
|
|
169
|
+
### Step 2: to Create a Custom Tool
|
|
147
170
|
|
|
148
171
|
Create a file called tools.py in the same directory as the agents.yaml file.
|
|
149
172
|
|
|
@@ -162,7 +185,7 @@ class InternetSearchTool(BaseTool):
|
|
|
162
185
|
return results
|
|
163
186
|
```
|
|
164
187
|
|
|
165
|
-
### Step
|
|
188
|
+
### Step 3: to Create a Custom Tool
|
|
166
189
|
|
|
167
190
|
Add the tool to the agents.yaml file as show below under the tools section `- InternetSearchTool`.
|
|
168
191
|
|
|
@@ -183,12 +206,6 @@ roles:
|
|
|
183
206
|
- InternetSearchTool
|
|
184
207
|
```
|
|
185
208
|
|
|
186
|
-
## Test
|
|
187
|
-
|
|
188
|
-
```bash
|
|
189
|
-
python -m unittest tests.test
|
|
190
|
-
```
|
|
191
|
-
|
|
192
209
|
## Agents Playbook
|
|
193
210
|
|
|
194
211
|
### Simple Playbook Example
|
|
@@ -207,50 +224,50 @@ roles:
|
|
|
207
224
|
expected_output: 'Complete script ready for production.'
|
|
208
225
|
```
|
|
209
226
|
|
|
210
|
-
|
|
227
|
+
## Use 100+ Models
|
|
228
|
+
|
|
229
|
+
* https://docs.praison.ai/models/
|
|
230
|
+
|
|
231
|
+
## Include praisonai package in your project
|
|
232
|
+
|
|
233
|
+
* https://docs.praison.ai/developers/wrapper
|
|
234
|
+
* https://docs.praison.ai/developers/wrapper-tools/
|
|
235
|
+
|
|
236
|
+
## Option 1: Using RAW YAML
|
|
237
|
+
|
|
238
|
+
```python
|
|
239
|
+
from praisonai import PraisonAI
|
|
240
|
+
|
|
241
|
+
# Example agent_yaml content
|
|
242
|
+
agent_yaml = """
|
|
243
|
+
framework: "crewai"
|
|
244
|
+
topic: "Space Exploration"
|
|
211
245
|
|
|
212
|
-
```yaml
|
|
213
|
-
framework: crewai
|
|
214
|
-
topic: Artificial Intelligence
|
|
215
246
|
roles:
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
goal: Generate engaging movie concepts using AI storylines
|
|
221
|
-
role: Movie Concept Creator
|
|
222
|
-
tasks:
|
|
223
|
-
movie_concept_development:
|
|
224
|
-
description: 'Develop movie concepts from AI-generated storylines, ensuring
|
|
225
|
-
they are engaging and have strong narrative arcs.'
|
|
226
|
-
expected_output: 'Well-structured movie concept document with character
|
|
227
|
-
bios, settings, and plot outlines.'
|
|
228
|
-
screenwriter:
|
|
229
|
-
backstory: 'Expert in writing engaging dialogue and script structure, able to
|
|
230
|
-
turn movie concepts into production-ready scripts.'
|
|
231
|
-
goal: Write compelling scripts based on movie concepts
|
|
232
|
-
role: Screenwriter
|
|
233
|
-
tasks:
|
|
234
|
-
scriptwriting_task:
|
|
235
|
-
description: 'Turn movie concepts into polished scripts with well-developed
|
|
236
|
-
characters, strong dialogue, and effective scene transitions.'
|
|
237
|
-
expected_output: 'Production-ready script with a beginning, middle, and
|
|
238
|
-
end, along with character development and engaging dialogues.'
|
|
239
|
-
editor:
|
|
240
|
-
backstory: 'Adept at identifying inconsistencies, improving language usage,
|
|
241
|
-
and maintaining the overall flow of the script.'
|
|
242
|
-
goal: Refine the scripts and ensure continuity of the movie storyline
|
|
243
|
-
role: Editor
|
|
247
|
+
astronomer:
|
|
248
|
+
role: "Space Researcher"
|
|
249
|
+
goal: "Discover new insights about {topic}"
|
|
250
|
+
backstory: "You are a curious and dedicated astronomer with a passion for unraveling the mysteries of the cosmos."
|
|
244
251
|
tasks:
|
|
245
|
-
|
|
246
|
-
description:
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
252
|
+
investigate_exoplanets:
|
|
253
|
+
description: "Research and compile information about exoplanets discovered in the last decade."
|
|
254
|
+
expected_output: "A summarized report on exoplanet discoveries, including their size, potential habitability, and distance from Earth."
|
|
255
|
+
"""
|
|
256
|
+
|
|
257
|
+
# Create a PraisonAI instance with the agent_yaml content
|
|
258
|
+
praison_ai = PraisonAI(agent_yaml=agent_yaml)
|
|
259
|
+
|
|
260
|
+
# Run PraisonAI
|
|
261
|
+
result = praison_ai.main()
|
|
262
|
+
|
|
263
|
+
# Print the result
|
|
264
|
+
print(result)
|
|
251
265
|
```
|
|
252
266
|
|
|
253
|
-
##
|
|
267
|
+
## Option 2: Using separate agents.yaml file
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
Note: Please create agents.yaml file before hand.
|
|
254
271
|
|
|
255
272
|
```python
|
|
256
273
|
from praisonai import PraisonAI
|
|
@@ -258,64 +275,12 @@ from praisonai import PraisonAI
|
|
|
258
275
|
def basic(): # Basic Mode
|
|
259
276
|
praison_ai = PraisonAI(agent_file="agents.yaml")
|
|
260
277
|
praison_ai.main()
|
|
261
|
-
|
|
262
|
-
def advanced(): # Advanced Mode with options
|
|
263
|
-
praison_ai = PraisonAI(
|
|
264
|
-
agent_file="agents.yaml",
|
|
265
|
-
framework="autogen",
|
|
266
|
-
)
|
|
267
|
-
praison_ai.main()
|
|
268
|
-
|
|
269
|
-
def auto(): # Full Automatic Mode
|
|
270
|
-
praison_ai = PraisonAI(
|
|
271
|
-
auto="Create a movie script about car in mars",
|
|
272
|
-
framework="autogen"
|
|
273
|
-
)
|
|
274
|
-
print(praison_ai.framework)
|
|
275
|
-
praison_ai.main()
|
|
276
278
|
|
|
277
279
|
if __name__ == "__main__":
|
|
278
280
|
basic()
|
|
279
|
-
advanced()
|
|
280
|
-
auto()
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
## Include CrewAI Tools
|
|
284
|
-
|
|
285
|
-
```
|
|
286
|
-
pip install "praisonai[crewai-tools]"
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
## Deploy
|
|
290
|
-
|
|
291
|
-
```bash
|
|
292
|
-
gcloud init
|
|
293
|
-
gcloud services enable run.googleapis.com
|
|
294
|
-
gcloud services enable containerregistry.googleapis.com
|
|
295
|
-
gcloud services enable cloudbuild.googleapis.com
|
|
296
|
-
|
|
297
|
-
export OPENAI_MODEL_NAME="gpt-4o"
|
|
298
|
-
export OPENAI_API_KEY="Enter your API key"
|
|
299
|
-
export OPENAI_API_BASE="https://api.openai.com/v1"
|
|
300
|
-
|
|
301
|
-
yes | gcloud auth configure-docker us-central1-docker.pkg.dev
|
|
302
|
-
gcloud artifacts repositories create praisonai-repository --repository-format=docker --location=us-central1
|
|
303
|
-
|
|
304
|
-
PROJECT_ID=$(gcloud config get-value project)
|
|
305
|
-
TAG="latest"
|
|
306
|
-
docker build --platform linux/amd64 -t gcr.io/${PROJECT_ID}/praisonai-app:${TAG} .
|
|
307
|
-
docker tag gcr.io/${PROJECT_ID}/praisonai-app:${TAG} us-central1-docker.pkg.dev/${PROJECT_ID}/praisonai-repository/praisonai-app:${TAG}
|
|
308
|
-
docker push us-central1-docker.pkg.dev/${PROJECT_ID}/praisonai-repository/praisonai-app:${TAG}
|
|
309
|
-
|
|
310
|
-
gcloud run deploy praisonai-service \
|
|
311
|
-
--image us-central1-docker.pkg.dev/${PROJECT_ID}/praisonai-repository/praisonai-app:${TAG} \
|
|
312
|
-
--platform managed \
|
|
313
|
-
--region us-central1 \
|
|
314
|
-
--allow-unauthenticated \
|
|
315
|
-
--set-env-vars OPENAI_MODEL_NAME=${OPENAI_MODEL_NAME},OPENAI_API_KEY=${OPENAI_API_KEY},OPENAI_API_BASE=${OPENAI_API_BASE}
|
|
316
281
|
```
|
|
317
282
|
|
|
318
|
-
|
|
283
|
+
## Commands to Install Dependencies:
|
|
319
284
|
|
|
320
285
|
1. **Install all dependencies, including dev dependencies:**
|
|
321
286
|
```sh
|
|
@@ -339,30 +304,6 @@ gcloud run deploy praisonai-service \
|
|
|
339
304
|
|
|
340
305
|
This configuration ensures that your development dependencies are correctly categorized and installed as needed.
|
|
341
306
|
|
|
342
|
-
## Other Models
|
|
343
|
-
|
|
344
|
-
```bash
|
|
345
|
-
# Ollama
|
|
346
|
-
OPENAI_API_BASE='http://localhost:11434/v1'
|
|
347
|
-
OPENAI_MODEL_NAME='mistral'
|
|
348
|
-
OPENAI_API_KEY='NA'
|
|
349
|
-
|
|
350
|
-
# FastChat
|
|
351
|
-
OPENAI_API_BASE="http://localhost:8001/v1"
|
|
352
|
-
OPENAI_MODEL_NAME='oh-2.5m7b-q51'
|
|
353
|
-
OPENAI_API_KEY=NA
|
|
354
|
-
|
|
355
|
-
# LM Studio
|
|
356
|
-
OPENAI_API_BASE="http://localhost:1234/v1"
|
|
357
|
-
OPENAI_MODEL_NAME=NA
|
|
358
|
-
OPENAI_API_KEY=NA
|
|
359
|
-
|
|
360
|
-
# Mistral API
|
|
361
|
-
OPENAI_API_BASE=https://api.mistral.ai/v1
|
|
362
|
-
OPENAI_MODEL_NAME="mistral-small"
|
|
363
|
-
OPENAI_API_KEY=your-mistral-api-key
|
|
364
|
-
```
|
|
365
|
-
|
|
366
307
|
## Contributing
|
|
367
308
|
|
|
368
309
|
- Fork on GitHub: Use the "Fork" button on the repository page.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
praisonai/__init__.py,sha256=JrgyPlzZfLlozoW7SHZ1nVJ63rLPR3ki2k5ZPywYrnI,175
|
|
2
|
+
praisonai/__main__.py,sha256=MVgsjMThjBexHt4nhd760JCqvP4x0IQcwo8kULOK4FQ,144
|
|
3
|
+
praisonai/agents_generator.py,sha256=8d1WRbubvEkBrW1HZ7_xnGyqgJi0yxmXa3MgTIqef1c,19127
|
|
4
|
+
praisonai/auto.py,sha256=9spTXqj47Hmmqv5QHRYE_RzSVHH_KoPbaZjskUj2UcE,7895
|
|
5
|
+
praisonai/chainlit_ui.py,sha256=bNR7s509lp0I9JlJNvwCZRUZosC64qdvlFCt8NmFamQ,12216
|
|
6
|
+
praisonai/cli.py,sha256=JBI3JjI7RB0QQipuy-utJpP3jxj8gnG5roMLW2Zjq6A,12851
|
|
7
|
+
praisonai/deploy.py,sha256=UmebXvdSfKGk4A-nQeOkbj2bieEOcMK9VZMTn2z1AOY,6031
|
|
8
|
+
praisonai/inbuilt_tools/__init__.py,sha256=mUKnbL6Gram9c9f2m8wJwEzURBLmPEOcHzwySBH89YA,74
|
|
9
|
+
praisonai/inbuilt_tools/autogen_tools.py,sha256=svYkM2N7DVFvbiwgoAS7U_MqTOD8rHf8VD3BaFUV5_Y,14907
|
|
10
|
+
praisonai/inc/__init__.py,sha256=sPDlYBBwdk0VlWzaaM_lG0_LD07lS2HRGvPdxXJFiYg,62
|
|
11
|
+
praisonai/inc/models.py,sha256=1kwP9o56AvN8L38x7eeAzudjAvstN0uWu-woQkgxAe4,5449
|
|
12
|
+
praisonai/public/android-chrome-192x192.png,sha256=ENJEqhDE3XEQViRhKNDezQKRiOiuHOUj5nzRN43fz50,6535
|
|
13
|
+
praisonai/public/android-chrome-512x512.png,sha256=4txEwB0cJkxFVarRdvFGJZR1DtWJ2h-L_2cUEjBXHAc,15244
|
|
14
|
+
praisonai/public/apple-touch-icon.png,sha256=YLlEhlenm24QY_yv-5wb_mxDxJ8H22H_S8Khlvz-zVA,6001
|
|
15
|
+
praisonai/public/fantasy.svg,sha256=4Gs3kIOux-pjGtw6ogI_rv5_viVJxnE5gRwGilsSg0o,1553
|
|
16
|
+
praisonai/public/favicon-16x16.png,sha256=jFiLfRSaEw_kwSxVQQUNV7Auc6oDRvZVKEIiUqC7vYE,429
|
|
17
|
+
praisonai/public/favicon-32x32.png,sha256=cgKvhHroXWNl1Err0TFr8tGepjNzIBpaTinFUT5pbZk,872
|
|
18
|
+
praisonai/public/favicon.ico,sha256=SOcyfycBi_8rd9ff3gmSuZ3M-rkxv1RpHi76cwvmsQ0,15406
|
|
19
|
+
praisonai/public/game.svg,sha256=y2QMaA01m8XzuDjTOBWzupOC3-TpnUl9ah89mIhviUw,2406
|
|
20
|
+
praisonai/public/logo_dark.png,sha256=frHz1zkrnivGssJgk9iy1cabojkVgm8B4MllFwL_CnI,17050
|
|
21
|
+
praisonai/public/logo_light.png,sha256=8cQRti_Ysa30O3_7C3ku2w40LnVUUlUok47H-3ZZHSU,19656
|
|
22
|
+
praisonai/public/movie.svg,sha256=aJ2EQ8vXZusVsF2SeuAVxP4RFJzQ14T26ejrGYdBgzk,1289
|
|
23
|
+
praisonai/public/thriller.svg,sha256=2dYY72EcgbEyTxS4QzjAm37Y4srtPWEW4vCMFki98ZI,3163
|
|
24
|
+
praisonai/test.py,sha256=RZKq3UEFb6AnFFiHER3zBXfNmlteSLBlrTmOvnpnZLo,4092
|
|
25
|
+
praisonai/ui/chat.py,sha256=Gx0SmnE5P6f8csS--gfnInJVmLF-5bWyOBLu1o4AXgc,14643
|
|
26
|
+
praisonai/ui/public/fantasy.svg,sha256=4Gs3kIOux-pjGtw6ogI_rv5_viVJxnE5gRwGilsSg0o,1553
|
|
27
|
+
praisonai/ui/public/game.svg,sha256=y2QMaA01m8XzuDjTOBWzupOC3-TpnUl9ah89mIhviUw,2406
|
|
28
|
+
praisonai/ui/public/logo_dark.png,sha256=frHz1zkrnivGssJgk9iy1cabojkVgm8B4MllFwL_CnI,17050
|
|
29
|
+
praisonai/ui/public/logo_light.png,sha256=8cQRti_Ysa30O3_7C3ku2w40LnVUUlUok47H-3ZZHSU,19656
|
|
30
|
+
praisonai/ui/public/movie.svg,sha256=aJ2EQ8vXZusVsF2SeuAVxP4RFJzQ14T26ejrGYdBgzk,1289
|
|
31
|
+
praisonai/ui/public/thriller.svg,sha256=2dYY72EcgbEyTxS4QzjAm37Y4srtPWEW4vCMFki98ZI,3163
|
|
32
|
+
praisonai/version.py,sha256=ugyuFliEqtAwQmH4sTlc16YXKYbFWDmfyk87fErB8-8,21
|
|
33
|
+
praisonai-0.0.46.dist-info/LICENSE,sha256=kqvFysVlnFxYOu0HxCe2HlmZmJtdmNGOxWRRkT9TsWc,1035
|
|
34
|
+
praisonai-0.0.46.dist-info/METADATA,sha256=HFsoACSl5CZakd3MXJtl4pFGB3_6fV-6jBEYyY07wR8,9307
|
|
35
|
+
praisonai-0.0.46.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
36
|
+
praisonai-0.0.46.dist-info/entry_points.txt,sha256=Qg41eW3A1-dvdV5tF7LqChfYof8Rihk2rN1fiEE3vnk,53
|
|
37
|
+
praisonai-0.0.46.dist-info/RECORD,,
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
praisonai/__init__.py,sha256=JrgyPlzZfLlozoW7SHZ1nVJ63rLPR3ki2k5ZPywYrnI,175
|
|
2
|
-
praisonai/__main__.py,sha256=MVgsjMThjBexHt4nhd760JCqvP4x0IQcwo8kULOK4FQ,144
|
|
3
|
-
praisonai/agents_generator.py,sha256=B1rHxzdJRgfnZZ8ykG7ch00_49qQBesht4QWAKWnFQY,18668
|
|
4
|
-
praisonai/auto.py,sha256=9spTXqj47Hmmqv5QHRYE_RzSVHH_KoPbaZjskUj2UcE,7895
|
|
5
|
-
praisonai/chainlit_ui.py,sha256=bNR7s509lp0I9JlJNvwCZRUZosC64qdvlFCt8NmFamQ,12216
|
|
6
|
-
praisonai/cli.py,sha256=cwuXGubuac7yTeiqx5o5S7ZN7erZAfe-6p35b3HM5SU,11066
|
|
7
|
-
praisonai/deploy.py,sha256=SHX8Cok7YfAYXtj5ZD_F3idk0BkOmaBwaA2UmZmuSko,6031
|
|
8
|
-
praisonai/inbuilt_tools/__init__.py,sha256=mUKnbL6Gram9c9f2m8wJwEzURBLmPEOcHzwySBH89YA,74
|
|
9
|
-
praisonai/inbuilt_tools/autogen_tools.py,sha256=svYkM2N7DVFvbiwgoAS7U_MqTOD8rHf8VD3BaFUV5_Y,14907
|
|
10
|
-
praisonai/inc/__init__.py,sha256=sPDlYBBwdk0VlWzaaM_lG0_LD07lS2HRGvPdxXJFiYg,62
|
|
11
|
-
praisonai/inc/models.py,sha256=1kwP9o56AvN8L38x7eeAzudjAvstN0uWu-woQkgxAe4,5449
|
|
12
|
-
praisonai/public/fantasy.svg,sha256=4Gs3kIOux-pjGtw6ogI_rv5_viVJxnE5gRwGilsSg0o,1553
|
|
13
|
-
praisonai/public/game.svg,sha256=y2QMaA01m8XzuDjTOBWzupOC3-TpnUl9ah89mIhviUw,2406
|
|
14
|
-
praisonai/public/movie.svg,sha256=aJ2EQ8vXZusVsF2SeuAVxP4RFJzQ14T26ejrGYdBgzk,1289
|
|
15
|
-
praisonai/public/thriller.svg,sha256=2dYY72EcgbEyTxS4QzjAm37Y4srtPWEW4vCMFki98ZI,3163
|
|
16
|
-
praisonai/test.py,sha256=RZKq3UEFb6AnFFiHER3zBXfNmlteSLBlrTmOvnpnZLo,4092
|
|
17
|
-
praisonai/version.py,sha256=ugyuFliEqtAwQmH4sTlc16YXKYbFWDmfyk87fErB8-8,21
|
|
18
|
-
praisonai-0.0.41.dist-info/LICENSE,sha256=kqvFysVlnFxYOu0HxCe2HlmZmJtdmNGOxWRRkT9TsWc,1035
|
|
19
|
-
praisonai-0.0.41.dist-info/METADATA,sha256=W33-uZ-WZg-HsXJUlYLsKSw1MKUihsNG5HmQhoe5hFA,11183
|
|
20
|
-
praisonai-0.0.41.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
21
|
-
praisonai-0.0.41.dist-info/entry_points.txt,sha256=Qg41eW3A1-dvdV5tF7LqChfYof8Rihk2rN1fiEE3vnk,53
|
|
22
|
-
praisonai-0.0.41.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|