praisonaiagents 0.0.96__py3-none-any.whl → 0.0.98__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.
- praisonaiagents/__init__.py +6 -1
- praisonaiagents/agent/agent.py +125 -92
- praisonaiagents/agents/agents.py +99 -6
- praisonaiagents/approval.py +263 -0
- praisonaiagents/knowledge/knowledge.py +27 -4
- praisonaiagents/llm/llm.py +4 -0
- praisonaiagents/main.py +15 -0
- praisonaiagents/memory/memory.py +67 -6
- praisonaiagents/session.py +291 -0
- praisonaiagents/task/task.py +121 -3
- praisonaiagents/tools/file_tools.py +5 -0
- praisonaiagents/tools/python_tools.py +2 -0
- praisonaiagents/tools/shell_tools.py +3 -0
- {praisonaiagents-0.0.96.dist-info → praisonaiagents-0.0.98.dist-info}/METADATA +5 -1
- {praisonaiagents-0.0.96.dist-info → praisonaiagents-0.0.98.dist-info}/RECORD +17 -15
- {praisonaiagents-0.0.96.dist-info → praisonaiagents-0.0.98.dist-info}/WHEEL +0 -0
- {praisonaiagents-0.0.96.dist-info → praisonaiagents-0.0.98.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,291 @@
|
|
1
|
+
"""
|
2
|
+
Session Management for PraisonAI Agents
|
3
|
+
|
4
|
+
A simple wrapper around existing stateful capabilities to provide a unified
|
5
|
+
session API for developers building stateful agent applications.
|
6
|
+
"""
|
7
|
+
|
8
|
+
import os
|
9
|
+
import uuid
|
10
|
+
from typing import Any, Dict, List, Optional
|
11
|
+
from .agent import Agent
|
12
|
+
from .memory import Memory
|
13
|
+
from .knowledge import Knowledge
|
14
|
+
|
15
|
+
|
16
|
+
class Session:
|
17
|
+
"""
|
18
|
+
A simple wrapper around PraisonAI's existing stateful capabilities.
|
19
|
+
|
20
|
+
Provides a unified API for:
|
21
|
+
- Session management with persistent state
|
22
|
+
- Memory operations (short-term, long-term, user-specific)
|
23
|
+
- Knowledge base operations
|
24
|
+
- Agent state management
|
25
|
+
|
26
|
+
Example:
|
27
|
+
session = Session(session_id="chat_123", user_id="user_456")
|
28
|
+
|
29
|
+
# Create stateful agent
|
30
|
+
agent = session.Agent(
|
31
|
+
name="Assistant",
|
32
|
+
role="Helpful AI",
|
33
|
+
memory=True
|
34
|
+
)
|
35
|
+
|
36
|
+
# Save session state
|
37
|
+
session.save_state({"conversation_topic": "AI research"})
|
38
|
+
|
39
|
+
# Restore state later
|
40
|
+
session.restore_state()
|
41
|
+
"""
|
42
|
+
|
43
|
+
def __init__(
|
44
|
+
self,
|
45
|
+
session_id: Optional[str] = None,
|
46
|
+
user_id: Optional[str] = None,
|
47
|
+
memory_config: Optional[Dict[str, Any]] = None,
|
48
|
+
knowledge_config: Optional[Dict[str, Any]] = None
|
49
|
+
):
|
50
|
+
"""
|
51
|
+
Initialize a new session with optional persistence.
|
52
|
+
|
53
|
+
Args:
|
54
|
+
session_id: Unique session identifier. Auto-generated if None.
|
55
|
+
user_id: User identifier for user-specific memory operations.
|
56
|
+
memory_config: Configuration for memory system (defaults to RAG)
|
57
|
+
knowledge_config: Configuration for knowledge base system
|
58
|
+
"""
|
59
|
+
self.session_id = session_id or str(uuid.uuid4())[:8]
|
60
|
+
self.user_id = user_id or "default_user"
|
61
|
+
|
62
|
+
# Initialize memory with sensible defaults
|
63
|
+
default_memory_config = {
|
64
|
+
"provider": "rag",
|
65
|
+
"use_embedding": True,
|
66
|
+
"rag_db_path": f".praison/sessions/{self.session_id}/chroma_db"
|
67
|
+
}
|
68
|
+
if memory_config:
|
69
|
+
default_memory_config.update(memory_config)
|
70
|
+
self.memory_config = default_memory_config
|
71
|
+
|
72
|
+
# Initialize knowledge with session-specific config
|
73
|
+
default_knowledge_config = knowledge_config or {}
|
74
|
+
self.knowledge_config = default_knowledge_config
|
75
|
+
|
76
|
+
# Create session directory
|
77
|
+
os.makedirs(f".praison/sessions/{self.session_id}", exist_ok=True)
|
78
|
+
|
79
|
+
# Initialize components lazily
|
80
|
+
self._memory = None
|
81
|
+
self._knowledge = None
|
82
|
+
self._agents_instance = None
|
83
|
+
|
84
|
+
@property
|
85
|
+
def memory(self) -> Memory:
|
86
|
+
"""Lazy-loaded memory instance"""
|
87
|
+
if self._memory is None:
|
88
|
+
self._memory = Memory(config=self.memory_config)
|
89
|
+
return self._memory
|
90
|
+
|
91
|
+
@property
|
92
|
+
def knowledge(self) -> Knowledge:
|
93
|
+
"""Lazy-loaded knowledge instance"""
|
94
|
+
if self._knowledge is None:
|
95
|
+
self._knowledge = Knowledge(config=self.knowledge_config)
|
96
|
+
return self._knowledge
|
97
|
+
|
98
|
+
def Agent(
|
99
|
+
self,
|
100
|
+
name: str,
|
101
|
+
role: str = "Assistant",
|
102
|
+
instructions: Optional[str] = None,
|
103
|
+
tools: Optional[List[Any]] = None,
|
104
|
+
memory: bool = True,
|
105
|
+
knowledge: Optional[List[str]] = None,
|
106
|
+
**kwargs
|
107
|
+
) -> Agent:
|
108
|
+
"""
|
109
|
+
Create an agent with session context.
|
110
|
+
|
111
|
+
Args:
|
112
|
+
name: Agent name
|
113
|
+
role: Agent role
|
114
|
+
instructions: Agent instructions
|
115
|
+
tools: List of tools for the agent
|
116
|
+
memory: Enable memory for the agent
|
117
|
+
knowledge: Knowledge sources for the agent
|
118
|
+
**kwargs: Additional agent parameters
|
119
|
+
|
120
|
+
Returns:
|
121
|
+
Configured Agent instance
|
122
|
+
"""
|
123
|
+
agent_kwargs = {
|
124
|
+
"name": name,
|
125
|
+
"role": role,
|
126
|
+
"user_id": self.user_id,
|
127
|
+
**kwargs
|
128
|
+
}
|
129
|
+
|
130
|
+
if instructions:
|
131
|
+
agent_kwargs["instructions"] = instructions
|
132
|
+
if tools:
|
133
|
+
agent_kwargs["tools"] = tools
|
134
|
+
if memory:
|
135
|
+
agent_kwargs["memory"] = self.memory
|
136
|
+
if knowledge:
|
137
|
+
agent_kwargs["knowledge"] = knowledge
|
138
|
+
agent_kwargs["knowledge_config"] = self.knowledge_config
|
139
|
+
|
140
|
+
return Agent(**agent_kwargs)
|
141
|
+
|
142
|
+
# Keep create_agent for backward compatibility
|
143
|
+
def create_agent(self, *args, **kwargs) -> Agent:
|
144
|
+
"""Backward compatibility wrapper for Agent method"""
|
145
|
+
return self.Agent(*args, **kwargs)
|
146
|
+
|
147
|
+
def save_state(self, state_data: Dict[str, Any]) -> None:
|
148
|
+
"""
|
149
|
+
Save session state data to memory.
|
150
|
+
|
151
|
+
Args:
|
152
|
+
state_data: Dictionary of state data to save
|
153
|
+
"""
|
154
|
+
state_text = f"Session state: {state_data}"
|
155
|
+
self.memory.store_short_term(
|
156
|
+
text=state_text,
|
157
|
+
metadata={
|
158
|
+
"type": "session_state",
|
159
|
+
"session_id": self.session_id,
|
160
|
+
"user_id": self.user_id,
|
161
|
+
**state_data
|
162
|
+
}
|
163
|
+
)
|
164
|
+
|
165
|
+
def restore_state(self) -> Dict[str, Any]:
|
166
|
+
"""
|
167
|
+
Restore session state from memory.
|
168
|
+
|
169
|
+
Returns:
|
170
|
+
Dictionary of restored state data
|
171
|
+
"""
|
172
|
+
# Use metadata-based search for better SQLite compatibility
|
173
|
+
results = self.memory.search_short_term(
|
174
|
+
query=f"type:session_state",
|
175
|
+
limit=10 # Get more results to filter by session_id
|
176
|
+
)
|
177
|
+
|
178
|
+
# Filter results by session_id in metadata
|
179
|
+
for result in results:
|
180
|
+
metadata = result.get("metadata", {})
|
181
|
+
if (metadata.get("type") == "session_state" and
|
182
|
+
metadata.get("session_id") == self.session_id):
|
183
|
+
# Extract state data from metadata (excluding system fields)
|
184
|
+
state_data = {k: v for k, v in metadata.items()
|
185
|
+
if k not in ["type", "session_id", "user_id"]}
|
186
|
+
return state_data
|
187
|
+
|
188
|
+
return {}
|
189
|
+
|
190
|
+
def get_state(self, key: str, default: Any = None) -> Any:
|
191
|
+
"""Get a specific state value"""
|
192
|
+
state = self.restore_state()
|
193
|
+
return state.get(key, default)
|
194
|
+
|
195
|
+
def set_state(self, key: str, value: Any) -> None:
|
196
|
+
"""Set a specific state value"""
|
197
|
+
current_state = self.restore_state()
|
198
|
+
current_state[key] = value
|
199
|
+
self.save_state(current_state)
|
200
|
+
|
201
|
+
def add_memory(self, text: str, memory_type: str = "long", **metadata) -> None:
|
202
|
+
"""
|
203
|
+
Add information to session memory.
|
204
|
+
|
205
|
+
Args:
|
206
|
+
text: Text to store
|
207
|
+
memory_type: "short" or "long" term memory
|
208
|
+
**metadata: Additional metadata
|
209
|
+
"""
|
210
|
+
metadata.update({
|
211
|
+
"session_id": self.session_id,
|
212
|
+
"user_id": self.user_id
|
213
|
+
})
|
214
|
+
|
215
|
+
if memory_type == "short":
|
216
|
+
self.memory.store_short_term(text, metadata=metadata)
|
217
|
+
else:
|
218
|
+
self.memory.store_long_term(text, metadata=metadata)
|
219
|
+
|
220
|
+
def search_memory(self, query: str, memory_type: str = "long", limit: int = 5) -> List[Dict[str, Any]]:
|
221
|
+
"""
|
222
|
+
Search session memory.
|
223
|
+
|
224
|
+
Args:
|
225
|
+
query: Search query
|
226
|
+
memory_type: "short" or "long" term memory
|
227
|
+
limit: Maximum results to return
|
228
|
+
|
229
|
+
Returns:
|
230
|
+
List of memory results
|
231
|
+
"""
|
232
|
+
if memory_type == "short":
|
233
|
+
return self.memory.search_short_term(query, limit=limit)
|
234
|
+
return self.memory.search_long_term(query, limit=limit)
|
235
|
+
|
236
|
+
def add_knowledge(self, source: str) -> None:
|
237
|
+
"""
|
238
|
+
Add knowledge source to session.
|
239
|
+
|
240
|
+
Args:
|
241
|
+
source: File path, URL, or text content
|
242
|
+
"""
|
243
|
+
self.knowledge.add(source, user_id=self.user_id, agent_id=self.session_id)
|
244
|
+
|
245
|
+
def search_knowledge(self, query: str, limit: int = 5) -> List[Dict[str, Any]]:
|
246
|
+
"""
|
247
|
+
Search session knowledge base.
|
248
|
+
|
249
|
+
Args:
|
250
|
+
query: Search query
|
251
|
+
limit: Maximum results to return
|
252
|
+
|
253
|
+
Returns:
|
254
|
+
List of knowledge results
|
255
|
+
"""
|
256
|
+
return self.knowledge.search(query, agent_id=self.session_id, limit=limit)
|
257
|
+
|
258
|
+
def clear_memory(self, memory_type: str = "all") -> None:
|
259
|
+
"""
|
260
|
+
Clear session memory.
|
261
|
+
|
262
|
+
Args:
|
263
|
+
memory_type: "short", "long", or "all"
|
264
|
+
"""
|
265
|
+
if memory_type in ["short", "all"]:
|
266
|
+
self.memory.reset_short_term()
|
267
|
+
if memory_type in ["long", "all"]:
|
268
|
+
self.memory.reset_long_term()
|
269
|
+
|
270
|
+
def get_context(self, query: str, max_items: int = 3) -> str:
|
271
|
+
"""
|
272
|
+
Build context from session memory and knowledge.
|
273
|
+
|
274
|
+
Args:
|
275
|
+
query: Query to build context for
|
276
|
+
max_items: Maximum items per section
|
277
|
+
|
278
|
+
Returns:
|
279
|
+
Formatted context string
|
280
|
+
"""
|
281
|
+
return self.memory.build_context_for_task(
|
282
|
+
task_descr=query,
|
283
|
+
user_id=self.user_id,
|
284
|
+
max_items=max_items
|
285
|
+
)
|
286
|
+
|
287
|
+
def __str__(self) -> str:
|
288
|
+
return f"Session(id='{self.session_id}', user='{self.user_id}')"
|
289
|
+
|
290
|
+
def __repr__(self) -> str:
|
291
|
+
return self.__str__()
|
praisonaiagents/task/task.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import logging
|
2
2
|
import asyncio
|
3
|
-
|
3
|
+
import inspect
|
4
|
+
from typing import List, Optional, Dict, Any, Type, Callable, Union, Coroutine, Literal, Tuple, get_args, get_origin
|
4
5
|
from pydantic import BaseModel
|
5
6
|
from ..main import TaskOutput
|
6
7
|
from ..agent.agent import Agent
|
@@ -40,7 +41,10 @@ class Task:
|
|
40
41
|
quality_check=True,
|
41
42
|
input_file: Optional[str] = None,
|
42
43
|
rerun: bool = False, # Renamed from can_rerun and logic inverted, default True for backward compatibility
|
43
|
-
retain_full_context: bool = False # By default, only use previous task output, not all previous tasks
|
44
|
+
retain_full_context: bool = False, # By default, only use previous task output, not all previous tasks
|
45
|
+
guardrail: Optional[Union[Callable[[TaskOutput], Tuple[bool, Any]], str]] = None,
|
46
|
+
max_retries: int = 3,
|
47
|
+
retry_count: int = 0
|
44
48
|
):
|
45
49
|
# Add check if memory config is provided
|
46
50
|
if memory is not None or (config and config.get('memory_config')):
|
@@ -80,6 +84,10 @@ class Task:
|
|
80
84
|
self.quality_check = quality_check
|
81
85
|
self.rerun = rerun # Assigning the rerun parameter
|
82
86
|
self.retain_full_context = retain_full_context
|
87
|
+
self.guardrail = guardrail
|
88
|
+
self.max_retries = max_retries
|
89
|
+
self.retry_count = retry_count
|
90
|
+
self._guardrail_fn = None
|
83
91
|
|
84
92
|
# Set logger level based on config verbose level
|
85
93
|
verbose = self.config.get("verbose", 0)
|
@@ -141,6 +149,55 @@ class Task:
|
|
141
149
|
|
142
150
|
self.output_pydantic = LoopModel
|
143
151
|
|
152
|
+
# Initialize guardrail
|
153
|
+
self._setup_guardrail()
|
154
|
+
|
155
|
+
def _setup_guardrail(self):
|
156
|
+
"""Setup the guardrail function based on the provided guardrail parameter."""
|
157
|
+
if self.guardrail is None:
|
158
|
+
self._guardrail_fn = None
|
159
|
+
return
|
160
|
+
|
161
|
+
if callable(self.guardrail):
|
162
|
+
# Validate function signature
|
163
|
+
sig = inspect.signature(self.guardrail)
|
164
|
+
positional_args = [
|
165
|
+
param for param in sig.parameters.values()
|
166
|
+
if param.default is inspect.Parameter.empty
|
167
|
+
]
|
168
|
+
if len(positional_args) != 1:
|
169
|
+
raise ValueError("Guardrail function must accept exactly one parameter (TaskOutput)")
|
170
|
+
|
171
|
+
# Check return annotation if present
|
172
|
+
return_annotation = sig.return_annotation
|
173
|
+
if return_annotation != inspect.Signature.empty:
|
174
|
+
return_annotation_args = get_args(return_annotation)
|
175
|
+
if not (
|
176
|
+
get_origin(return_annotation) is tuple
|
177
|
+
and len(return_annotation_args) == 2
|
178
|
+
and return_annotation_args[0] is bool
|
179
|
+
and (
|
180
|
+
return_annotation_args[1] is Any
|
181
|
+
or return_annotation_args[1] is str
|
182
|
+
or return_annotation_args[1] is TaskOutput
|
183
|
+
or return_annotation_args[1] == Union[str, TaskOutput]
|
184
|
+
)
|
185
|
+
):
|
186
|
+
raise ValueError(
|
187
|
+
"If return type is annotated, it must be Tuple[bool, Any]"
|
188
|
+
)
|
189
|
+
|
190
|
+
self._guardrail_fn = self.guardrail
|
191
|
+
elif isinstance(self.guardrail, str):
|
192
|
+
# Create LLM-based guardrail
|
193
|
+
from ..guardrails import LLMGuardrail
|
194
|
+
if not self.agent:
|
195
|
+
raise ValueError("Agent is required for string-based guardrails")
|
196
|
+
llm = getattr(self.agent, 'llm', None) or getattr(self.agent, 'llm_instance', None)
|
197
|
+
self._guardrail_fn = LLMGuardrail(description=self.guardrail, llm=llm)
|
198
|
+
else:
|
199
|
+
raise ValueError("Guardrail must be either a callable or a string description")
|
200
|
+
|
144
201
|
def __str__(self):
|
145
202
|
return f"Task(name='{self.name if self.name else 'None'}', description='{self.description}', agent='{self.agent.name if self.agent else 'None'}', status='{self.status}')"
|
146
203
|
|
@@ -187,6 +244,37 @@ class Task:
|
|
187
244
|
logger.info(f"Task {self.id}: execute_callback called")
|
188
245
|
logger.info(f"Quality check enabled: {self.quality_check}")
|
189
246
|
|
247
|
+
# Process guardrail if configured
|
248
|
+
if self._guardrail_fn:
|
249
|
+
try:
|
250
|
+
guardrail_result = self._process_guardrail(task_output)
|
251
|
+
if not guardrail_result.success:
|
252
|
+
if self.retry_count >= self.max_retries:
|
253
|
+
raise Exception(
|
254
|
+
f"Task failed guardrail validation after {self.max_retries} retries. "
|
255
|
+
f"Last error: {guardrail_result.error}"
|
256
|
+
)
|
257
|
+
|
258
|
+
self.retry_count += 1
|
259
|
+
logger.warning(f"Task {self.id}: Guardrail validation failed (retry {self.retry_count}/{self.max_retries}): {guardrail_result.error}")
|
260
|
+
# Note: In a real execution, this would trigger a retry, but since this is a callback
|
261
|
+
# the retry logic would need to be handled at the agent/execution level
|
262
|
+
return
|
263
|
+
|
264
|
+
# If guardrail passed and returned a modified result
|
265
|
+
if guardrail_result.result is not None:
|
266
|
+
if isinstance(guardrail_result.result, str):
|
267
|
+
# Update the task output with the modified result
|
268
|
+
task_output.raw = guardrail_result.result
|
269
|
+
elif isinstance(guardrail_result.result, TaskOutput):
|
270
|
+
# Replace with the new task output
|
271
|
+
task_output = guardrail_result.result
|
272
|
+
|
273
|
+
logger.info(f"Task {self.id}: Guardrail validation passed")
|
274
|
+
except Exception as e:
|
275
|
+
logger.error(f"Task {self.id}: Error in guardrail processing: {e}")
|
276
|
+
# Continue execution even if guardrail fails to avoid breaking the task
|
277
|
+
|
190
278
|
# Initialize memory if not already initialized
|
191
279
|
if not self.memory:
|
192
280
|
self.memory = self.initialize_memory()
|
@@ -334,4 +422,34 @@ Context:
|
|
334
422
|
loop.run_until_complete(self.execute_callback(task_output))
|
335
423
|
except RuntimeError:
|
336
424
|
# If no loop is running in this context
|
337
|
-
asyncio.run(self.execute_callback(task_output))
|
425
|
+
asyncio.run(self.execute_callback(task_output))
|
426
|
+
|
427
|
+
def _process_guardrail(self, task_output: TaskOutput):
|
428
|
+
"""Process the guardrail validation for a task output.
|
429
|
+
|
430
|
+
Args:
|
431
|
+
task_output: The task output to validate
|
432
|
+
|
433
|
+
Returns:
|
434
|
+
GuardrailResult: The result of the guardrail validation
|
435
|
+
"""
|
436
|
+
from ..guardrails import GuardrailResult
|
437
|
+
|
438
|
+
if not self._guardrail_fn:
|
439
|
+
return GuardrailResult(success=True, result=task_output)
|
440
|
+
|
441
|
+
try:
|
442
|
+
# Call the guardrail function
|
443
|
+
result = self._guardrail_fn(task_output)
|
444
|
+
|
445
|
+
# Convert the result to a GuardrailResult
|
446
|
+
return GuardrailResult.from_tuple(result)
|
447
|
+
|
448
|
+
except Exception as e:
|
449
|
+
logger.error(f"Task {self.id}: Error in guardrail validation: {e}")
|
450
|
+
# On error, return failure
|
451
|
+
return GuardrailResult(
|
452
|
+
success=False,
|
453
|
+
result=None,
|
454
|
+
error=f"Guardrail validation error: {str(e)}"
|
455
|
+
)
|
@@ -16,6 +16,7 @@ from typing import List, Dict, Union, Optional
|
|
16
16
|
from pathlib import Path
|
17
17
|
import shutil
|
18
18
|
import logging
|
19
|
+
from ..approval import require_approval
|
19
20
|
|
20
21
|
class FileTools:
|
21
22
|
"""Tools for file operations including read, write, list, and information."""
|
@@ -41,6 +42,7 @@ class FileTools:
|
|
41
42
|
return error_msg
|
42
43
|
|
43
44
|
@staticmethod
|
45
|
+
@require_approval(risk_level="high")
|
44
46
|
def write_file(filepath: str, content: str, encoding: str = 'utf-8') -> bool:
|
45
47
|
"""
|
46
48
|
Write content to a file.
|
@@ -134,6 +136,7 @@ class FileTools:
|
|
134
136
|
return {'error': error_msg}
|
135
137
|
|
136
138
|
@staticmethod
|
139
|
+
@require_approval(risk_level="high")
|
137
140
|
def copy_file(src: str, dst: str) -> bool:
|
138
141
|
"""
|
139
142
|
Copy a file from source to destination.
|
@@ -156,6 +159,7 @@ class FileTools:
|
|
156
159
|
return False
|
157
160
|
|
158
161
|
@staticmethod
|
162
|
+
@require_approval(risk_level="high")
|
159
163
|
def move_file(src: str, dst: str) -> bool:
|
160
164
|
"""
|
161
165
|
Move a file from source to destination.
|
@@ -178,6 +182,7 @@ class FileTools:
|
|
178
182
|
return False
|
179
183
|
|
180
184
|
@staticmethod
|
185
|
+
@require_approval(risk_level="high")
|
181
186
|
def delete_file(filepath: str) -> bool:
|
182
187
|
"""
|
183
188
|
Delete a file.
|
@@ -15,6 +15,7 @@ from importlib import util
|
|
15
15
|
import io
|
16
16
|
from contextlib import redirect_stdout, redirect_stderr
|
17
17
|
import traceback
|
18
|
+
from ..approval import require_approval
|
18
19
|
|
19
20
|
class PythonTools:
|
20
21
|
"""Tools for Python code execution and analysis."""
|
@@ -36,6 +37,7 @@ class PythonTools:
|
|
36
37
|
f"Run: pip install {' '.join(missing)}"
|
37
38
|
)
|
38
39
|
|
40
|
+
@require_approval(risk_level="critical")
|
39
41
|
def execute_code(
|
40
42
|
self,
|
41
43
|
code: str,
|
@@ -13,6 +13,7 @@ import logging
|
|
13
13
|
import os
|
14
14
|
import time
|
15
15
|
from typing import Dict, List, Optional, Union
|
16
|
+
from ..approval import require_approval
|
16
17
|
|
17
18
|
class ShellTools:
|
18
19
|
"""Tools for executing shell commands safely."""
|
@@ -31,6 +32,7 @@ class ShellTools:
|
|
31
32
|
"Run: pip install psutil"
|
32
33
|
)
|
33
34
|
|
35
|
+
@require_approval(risk_level="critical")
|
34
36
|
def execute_command(
|
35
37
|
self,
|
36
38
|
command: str,
|
@@ -146,6 +148,7 @@ class ShellTools:
|
|
146
148
|
logging.error(error_msg)
|
147
149
|
return []
|
148
150
|
|
151
|
+
@require_approval(risk_level="critical")
|
149
152
|
def kill_process(
|
150
153
|
self,
|
151
154
|
pid: int,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: praisonaiagents
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.98
|
4
4
|
Summary: Praison AI agents for completing complex tasks with Self Reflection Agents
|
5
5
|
Author: Mervin Praison
|
6
6
|
Requires-Python: >=3.10
|
@@ -19,6 +19,9 @@ Requires-Dist: mem0ai>=0.1.0; extra == "knowledge"
|
|
19
19
|
Requires-Dist: chromadb>=1.0.0; extra == "knowledge"
|
20
20
|
Requires-Dist: markitdown[all]>=0.1.0; extra == "knowledge"
|
21
21
|
Requires-Dist: chonkie>=1.0.2; extra == "knowledge"
|
22
|
+
Provides-Extra: graph
|
23
|
+
Requires-Dist: mem0ai[graph]>=0.1.0; extra == "graph"
|
24
|
+
Requires-Dist: chromadb>=1.0.0; extra == "graph"
|
22
25
|
Provides-Extra: llm
|
23
26
|
Requires-Dist: litellm>=1.50.0; extra == "llm"
|
24
27
|
Requires-Dist: pydantic>=2.4.2; extra == "llm"
|
@@ -28,6 +31,7 @@ Requires-Dist: uvicorn>=0.34.0; extra == "api"
|
|
28
31
|
Provides-Extra: all
|
29
32
|
Requires-Dist: praisonaiagents[memory]; extra == "all"
|
30
33
|
Requires-Dist: praisonaiagents[knowledge]; extra == "all"
|
34
|
+
Requires-Dist: praisonaiagents[graph]; extra == "all"
|
31
35
|
Requires-Dist: praisonaiagents[llm]; extra == "all"
|
32
36
|
Requires-Dist: praisonaiagents[mcp]; extra == "all"
|
33
37
|
Requires-Dist: praisonaiagents[api]; extra == "all"
|
@@ -1,24 +1,26 @@
|
|
1
|
-
praisonaiagents/__init__.py,sha256=
|
2
|
-
praisonaiagents/
|
1
|
+
praisonaiagents/__init__.py,sha256=GmTiMNta4iwmfarh_6cTUpry50hpqFE8YqolrYfZ_7U,1465
|
2
|
+
praisonaiagents/approval.py,sha256=UJ4OhfihpFGR5CAaMphqpSvqdZCHi5w2MGw1MByZ1FQ,9813
|
3
|
+
praisonaiagents/main.py,sha256=_-XE7_Y7ChvtLQMivfNFrrnAhv4wSSDhH9WJMWlkS0w,16315
|
4
|
+
praisonaiagents/session.py,sha256=CI-ffCiOfmgB-1zFFik9daKCB5Sm41Q9ZOaq1-oSLW8,9250
|
3
5
|
praisonaiagents/agent/__init__.py,sha256=j0T19TVNbfZcClvpbZDDinQxZ0oORgsMrMqx16jZ-bA,128
|
4
|
-
praisonaiagents/agent/agent.py,sha256=
|
6
|
+
praisonaiagents/agent/agent.py,sha256=be5E_uEXxZo4xmRRoRQoCpZ964pzlakC_QCOOsG4rCA,88440
|
5
7
|
praisonaiagents/agent/image_agent.py,sha256=-5MXG594HVwSpFMcidt16YBp7udtik-Cp7eXlzLE1fY,8696
|
6
8
|
praisonaiagents/agents/__init__.py,sha256=_1d6Pqyk9EoBSo7E68sKyd1jDRlN1vxvVIRpoMc0Jcw,168
|
7
|
-
praisonaiagents/agents/agents.py,sha256
|
9
|
+
praisonaiagents/agents/agents.py,sha256=C_yDdJB4XUuwKA9DrysAtAj3zSYT0IKtfCT4Pxo0oyI,63309
|
8
10
|
praisonaiagents/agents/autoagents.py,sha256=Lc_b9mO2MeefBrsHkHoqFxEr5iRGrYuzDhslyybXwdw,13649
|
9
11
|
praisonaiagents/knowledge/__init__.py,sha256=xL1Eh-a3xsHyIcU4foOWF-JdWYIYBALJH9bge0Ujuto,246
|
10
12
|
praisonaiagents/knowledge/chunking.py,sha256=G6wyHa7_8V0_7VpnrrUXbEmUmptlT16ISJYaxmkSgmU,7678
|
11
|
-
praisonaiagents/knowledge/knowledge.py,sha256=
|
13
|
+
praisonaiagents/knowledge/knowledge.py,sha256=OKPar-XGyAp1ndmbOOdCgqFnTCqpOThYVSIZRxZyP58,15683
|
12
14
|
praisonaiagents/llm/__init__.py,sha256=ttPQQJQq6Tah-0updoEXDZFKWtJAM93rBWRoIgxRWO8,689
|
13
|
-
praisonaiagents/llm/llm.py,sha256=
|
15
|
+
praisonaiagents/llm/llm.py,sha256=SzD_qoUqQnC9FpY-d1HHqKQGkIGPR5wEmE1OcqVEPFY,93577
|
14
16
|
praisonaiagents/mcp/__init__.py,sha256=ibbqe3_7XB7VrIcUcetkZiUZS1fTVvyMy_AqCSFG8qc,240
|
15
17
|
praisonaiagents/mcp/mcp.py,sha256=_gfp8hrSVT9aPqEDDfU8MiCdg0-3dVQpEQUE6AbrJlo,17243
|
16
18
|
praisonaiagents/mcp/mcp_sse.py,sha256=DLh3F_aoVRM1X-7hgIOWOw4FQ1nGmn9YNbQTesykzn4,6792
|
17
|
-
praisonaiagents/memory/memory.py,sha256=
|
19
|
+
praisonaiagents/memory/memory.py,sha256=6tvsLWkpvyNU-t-8d6XpW7vOFUm1pNReW5B7rA8c04M,38612
|
18
20
|
praisonaiagents/process/__init__.py,sha256=lkYbL7Hn5a0ldvJtkdH23vfIIZLIcanK-65C0MwaorY,52
|
19
21
|
praisonaiagents/process/process.py,sha256=gxhMXG3s4CzaREyuwE5zxCMx2Wp_b_Wd53tDfkj8Qk8,66567
|
20
22
|
praisonaiagents/task/__init__.py,sha256=VL5hXVmyGjINb34AalxpBMl-YW9m5EDcRkMTKkSSl7c,80
|
21
|
-
praisonaiagents/task/task.py,sha256=
|
23
|
+
praisonaiagents/task/task.py,sha256=60JE07JPpRowbEO420f4Ol49e_1AK856wSJDi_ricbg,20531
|
22
24
|
praisonaiagents/tools/__init__.py,sha256=Rrgi7_3-yLHpfBB81WUi0-wD_wb_BsukwHVdjDYAF-0,9316
|
23
25
|
praisonaiagents/tools/arxiv_tools.py,sha256=1stb31zTjLTon4jCnpZG5de9rKc9QWgC0leLegvPXWo,10528
|
24
26
|
praisonaiagents/tools/calculator_tools.py,sha256=S1xPT74Geurvjm52QMMIG29zDXVEWJmM6nmyY7yF298,9571
|
@@ -26,12 +28,12 @@ praisonaiagents/tools/csv_tools.py,sha256=4Yr0QYwBXt-1BDXGLalB2eSsFR2mB5rH3KdHmR
|
|
26
28
|
praisonaiagents/tools/duckdb_tools.py,sha256=KB3b-1HcX7ocoxskDpk_7RRpTGHnH8hizIY0ZdLRbIE,8816
|
27
29
|
praisonaiagents/tools/duckduckgo_tools.py,sha256=ynlB5ZyWfHYjUq0JZXH12TganqTihgD-2IyRgs32y84,1657
|
28
30
|
praisonaiagents/tools/excel_tools.py,sha256=e2HqcwnyBueOyss0xEKxff3zB4w4sNWCOMXvZfbDYlE,11309
|
29
|
-
praisonaiagents/tools/file_tools.py,sha256
|
31
|
+
praisonaiagents/tools/file_tools.py,sha256=-RE1LfJA3vr7JYoHQaElGTLMAEvc0NvN8pCsO8YGOHg,9011
|
30
32
|
praisonaiagents/tools/json_tools.py,sha256=ApUYNuQ1qnbmYNCxSlx6Tth_H1yo8mhWtZ7Rr2WS6C4,16507
|
31
33
|
praisonaiagents/tools/newspaper_tools.py,sha256=NyhojNPeyULBGcAWGOT1X70qVkh3FgZrpH-S7PEmrwI,12667
|
32
34
|
praisonaiagents/tools/pandas_tools.py,sha256=yzCeY4jetKrFIRA15Tr5OQ5d94T8DaSpzglx2UiWfPs,11092
|
33
|
-
praisonaiagents/tools/python_tools.py,sha256=
|
34
|
-
praisonaiagents/tools/shell_tools.py,sha256=
|
35
|
+
praisonaiagents/tools/python_tools.py,sha256=puqLANl5YaG1YG8ixkl_MgWayF7uj5iXUEE15UYwIZE,13513
|
36
|
+
praisonaiagents/tools/shell_tools.py,sha256=6IlnFkNg04tVxQVM_fYgscIWLtcgIikpEi3olB1THuA,9431
|
35
37
|
praisonaiagents/tools/spider_tools.py,sha256=lrZnT1V1BC46We-AzBrDB1Ryifr3KKGmYNntMsScU7w,15094
|
36
38
|
praisonaiagents/tools/test.py,sha256=UHOTNrnMo0_H6I2g48re1WNZkrR7f6z25UnlWxiOSbM,1600
|
37
39
|
praisonaiagents/tools/tools.py,sha256=TK5njOmDSpMlyBnbeBzNSlnzXWlnNaTpVqkFPhkMArg,265
|
@@ -40,7 +42,7 @@ praisonaiagents/tools/xml_tools.py,sha256=iYTMBEk5l3L3ryQ1fkUnNVYK-Nnua2Kx2S0dxN
|
|
40
42
|
praisonaiagents/tools/yaml_tools.py,sha256=uogAZrhXV9O7xvspAtcTfpKSQYL2nlOTvCQXN94-G9A,14215
|
41
43
|
praisonaiagents/tools/yfinance_tools.py,sha256=s2PBj_1v7oQnOobo2fDbQBACEHl61ftG4beG6Z979ZE,8529
|
42
44
|
praisonaiagents/tools/train/data/generatecot.py,sha256=H6bNh-E2hqL5MW6kX3hqZ05g9ETKN2-kudSjiuU_SD8,19403
|
43
|
-
praisonaiagents-0.0.
|
44
|
-
praisonaiagents-0.0.
|
45
|
-
praisonaiagents-0.0.
|
46
|
-
praisonaiagents-0.0.
|
45
|
+
praisonaiagents-0.0.98.dist-info/METADATA,sha256=CGUF2azfrJRTc_js-tPZRX4-U2MIGe8v9wcCWa0pL6w,1452
|
46
|
+
praisonaiagents-0.0.98.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
47
|
+
praisonaiagents-0.0.98.dist-info/top_level.txt,sha256=_HsRddrJ23iDx5TTqVUVvXG2HeHBL5voshncAMDGjtA,16
|
48
|
+
praisonaiagents-0.0.98.dist-info/RECORD,,
|
File without changes
|
File without changes
|