mirror of
https://github.com/MervinPraison/PraisonAI.git
synced 2026-11-10 03:31:28 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
73f8961e61 | ||
|
|
4caf10a982 | ||
|
|
fb42a1010a | ||
|
|
fe60dd40af | ||
|
|
7f37d754a7 | ||
|
|
26f60fb056 | ||
|
|
0f0b640184 | ||
|
|
d857dfc6b7 | ||
|
|
0135a9e09f | ||
|
|
847b5e6372 | ||
|
|
05a7265c4e | ||
|
|
de1734c29a | ||
|
|
f0e91b11ae | ||
|
|
6e1a9143e2 | ||
|
|
10d76d3a85 | ||
|
|
a38a9c06c6 | ||
|
|
9c90416ab5 | ||
|
|
efa5247344 | ||
|
|
720213d82d | ||
|
|
f6af16ef5e | ||
|
|
8439b98ec2 | ||
|
|
92271fc118 | ||
|
|
1b43dc6a4b | ||
|
|
929cefa55e | ||
|
|
225843e39b | ||
|
|
77913183a9 | ||
|
|
e5b5d747f4 | ||
|
|
8cb779c51c | ||
|
|
020ca46c90 | ||
|
|
557e243eed | ||
|
|
0628204fce | ||
|
|
2a11bf5221 | ||
|
|
ecc2182d24 | ||
|
|
c6b91b2d57 | ||
|
|
a5ed17945f | ||
|
|
ff3ca3052d | ||
|
|
6f1f4a5363 | ||
|
|
dd9dfa5970 | ||
|
|
5f4fc8fa2f | ||
|
|
dd9dd5d5d9 | ||
|
|
d2c629b82c | ||
|
|
609ac5f7a6 | ||
|
|
75c72e909e | ||
|
|
9492ff8de1 | ||
|
|
a0a3aa1a53 | ||
|
|
6a20001551 | ||
|
|
577295c147 | ||
|
|
06f64a551c | ||
|
|
928b824180 | ||
|
|
1631973256 | ||
|
|
a9d7f6fd76 | ||
|
|
cc5360e60e | ||
|
|
863dd9bc34 | ||
|
|
8c39769971 | ||
|
|
93904f8530 | ||
|
|
ffc3775446 | ||
|
|
86e76b7a3e | ||
|
|
b18d6007c2 | ||
|
|
c656af3166 | ||
|
|
3c2fff05dd | ||
|
|
092097faa6 | ||
|
|
068ddecb91 | ||
|
|
444d14cb54 | ||
|
|
090316dce3 | ||
|
|
a40cddd402 | ||
|
|
62472a2342 | ||
|
|
35186a0e66 | ||
|
|
d08d98ca12 | ||
|
|
2c9e8b46cb | ||
|
|
ce3b25c085 | ||
|
|
a928467188 | ||
|
|
8285afe789 | ||
|
|
b529110246 | ||
|
|
2a004bc382 | ||
|
|
b3fecacb2b | ||
|
|
6924077e36 | ||
|
|
63101d7323 | ||
|
|
e9540b2a92 | ||
|
|
75c1c62cec | ||
|
|
de4f251a02 | ||
|
|
d4858b4d5c | ||
|
|
03ca92a7d5 | ||
|
|
cca65dcdab | ||
|
|
93844d9509 | ||
|
|
0849db227d | ||
|
|
914d34e57b | ||
|
|
be66a5e4e1 | ||
|
|
20a19f7958 | ||
|
|
4128a67e10 | ||
|
|
9d29c796c7 | ||
|
|
f058ce018f | ||
|
|
09671d4bd3 | ||
|
|
c1dead194c | ||
|
|
5d67f0fdcf | ||
|
|
fb93b7d6d5 |
No files matched your search
@@ -0,0 +1,145 @@
|
||||
name: Performance Benchmarks
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
iterations:
|
||||
description: 'Number of benchmark iterations'
|
||||
required: false
|
||||
default: '100'
|
||||
fail_on_regression:
|
||||
description: 'Fail if performance regresses'
|
||||
required: false
|
||||
default: 'true'
|
||||
|
||||
jobs:
|
||||
benchmark:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python 3.12
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
cache: 'pip'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -e src/praisonai-agents[all]
|
||||
pip install agno crewai langgraph
|
||||
|
||||
- name: Run Import Time Benchmark
|
||||
id: import_time
|
||||
run: |
|
||||
cd src/praisonai-agents
|
||||
python benchmarks/import_time.py 2>&1 | tee import_time_output.txt
|
||||
|
||||
# Extract import time
|
||||
IMPORT_TIME=$(grep -oP 'Median:\s+\K[\d.]+' import_time_output.txt || echo "0")
|
||||
echo "import_time=$IMPORT_TIME" >> $GITHUB_OUTPUT
|
||||
|
||||
# Check threshold (200ms)
|
||||
if (( $(echo "$IMPORT_TIME > 200" | bc -l) )); then
|
||||
echo "::warning::Import time ${IMPORT_TIME}ms exceeds 200ms threshold"
|
||||
if [ "${{ inputs.fail_on_regression }}" == "true" ]; then
|
||||
echo "import_passed=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
else
|
||||
echo "import_passed=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Run Memory Usage Benchmark
|
||||
id: memory
|
||||
run: |
|
||||
cd src/praisonai-agents
|
||||
python benchmarks/memory_usage.py 2>&1 | tee memory_output.txt
|
||||
|
||||
# Extract peak memory
|
||||
PEAK_MEMORY=$(grep -oP 'Peak:\s+\K[\d.]+' memory_output.txt || echo "0")
|
||||
echo "peak_memory=$PEAK_MEMORY" >> $GITHUB_OUTPUT
|
||||
|
||||
# Check threshold (30MB)
|
||||
if (( $(echo "$PEAK_MEMORY > 30" | bc -l) )); then
|
||||
echo "::warning::Memory usage ${PEAK_MEMORY}MB exceeds 30MB threshold"
|
||||
if [ "${{ inputs.fail_on_regression }}" == "true" ]; then
|
||||
echo "memory_passed=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
else
|
||||
echo "memory_passed=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Run Simple Benchmark
|
||||
id: simple
|
||||
run: |
|
||||
cd src/praisonai-agents
|
||||
python benchmarks/simple_benchmark.py 2>&1 | tee simple_output.txt
|
||||
|
||||
# Extract PraisonAI time
|
||||
PRAISON_TIME=$(grep -oP 'PraisonAI\s+\K[\d.]+' simple_output.txt | head -1 || echo "0")
|
||||
echo "praison_time=$PRAISON_TIME" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Run Tools Benchmark
|
||||
id: tools
|
||||
run: |
|
||||
cd src/praisonai-agents
|
||||
python benchmarks/tools_benchmark.py 2>&1 | tee tools_output.txt
|
||||
|
||||
# Extract PraisonAI time with tools
|
||||
PRAISON_TOOLS_TIME=$(grep -oP 'PraisonAI\s+\K[\d.]+' tools_output.txt | head -1 || echo "0")
|
||||
echo "praison_tools_time=$PRAISON_TOOLS_TIME" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Run Parameter Impact Benchmark
|
||||
id: param_impact
|
||||
run: |
|
||||
cd src/praisonai-agents
|
||||
python benchmarks/param_impact_benchmark.py --no-save --iterations ${{ inputs.iterations }} 2>&1 | tee param_impact_output.txt
|
||||
|
||||
- name: Check Lazy Imports
|
||||
id: lazy_imports
|
||||
run: |
|
||||
cd src/praisonai-agents
|
||||
python -c "
|
||||
import sys
|
||||
from praisonaiagents import Agent
|
||||
agent = Agent(name='Test', output='silent')
|
||||
|
||||
# Check litellm is NOT loaded
|
||||
if 'litellm' in sys.modules:
|
||||
print('FAIL: litellm loaded during silent agent creation')
|
||||
exit(1)
|
||||
else:
|
||||
print('PASS: litellm not loaded (lazy import working)')
|
||||
"
|
||||
|
||||
- name: Generate Benchmark Summary
|
||||
if: always()
|
||||
run: |
|
||||
echo "## Performance Benchmark Results" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Metric | Value | Threshold | Status |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|--------|-------|-----------|--------|" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Import Time | ${{ steps.import_time.outputs.import_time }}ms | <200ms | ${{ steps.import_time.outputs.import_passed == 'true' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Peak Memory | ${{ steps.memory.outputs.peak_memory }}MB | <30MB | ${{ steps.memory.outputs.memory_passed == 'true' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Agent Instantiation | ${{ steps.simple.outputs.praison_time }}μs | - | ℹ️ |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Agent with Tools | ${{ steps.tools.outputs.praison_tools_time }}μs | - | ℹ️ |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### Lazy Import Check" >> $GITHUB_STEP_SUMMARY
|
||||
echo "✅ litellm not loaded during silent agent creation" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Fail on Regression
|
||||
if: inputs.fail_on_regression == 'true'
|
||||
run: |
|
||||
if [ "${{ steps.import_time.outputs.import_passed }}" == "false" ]; then
|
||||
echo "::error::Import time regression detected"
|
||||
exit 1
|
||||
fi
|
||||
if [ "${{ steps.memory.outputs.memory_passed }}" == "false" ]; then
|
||||
echo "::error::Memory usage regression detected"
|
||||
exit 1
|
||||
fi
|
||||
echo "All performance checks passed!"
|
||||
@@ -137,7 +137,6 @@ PraisonAI Agents is the **fastest AI agent framework** for agent instantiation.
|
||||
| PraisonAI (LiteLLM) | 7.56 | 2.00x |
|
||||
| PydanticAI | 226.94 | 60.16x |
|
||||
| LangGraph | 4,558.71 | 1,209x |
|
||||
| CrewAI | 15,607.92 | 4,138x |
|
||||
|
||||
<details>
|
||||
<summary>Run benchmarks yourself</summary>
|
||||
|
||||
@@ -3,16 +3,32 @@
|
||||
This file is auto-generated. Do not edit manually.
|
||||
Regenerate with: `praisonai docs api-md --write`
|
||||
|
||||
# Agents
|
||||
# Shared Types
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import Agent, Agents
|
||||
from praisonaiagents import ContextPolicy, GuardrailResult, HandoffConfig, HandoffCycleError, HandoffDepthError, HandoffError, HandoffInputData, HandoffResult, HandoffTimeoutError, ReflectionOutput, StepResult, TaskOutput, ToolResult, ToolValidationError, WorkflowContext
|
||||
```
|
||||
|
||||
Methods:
|
||||
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">achat</a>(prompt: str, temperature = 1.0, tools = None, output_json = None, output_pydantic = None, reasoning_steps = False, task_name = None, task_description = None, task_id = None)</code>
|
||||
* <code title="class GuardrailResult">GuardrailResult.<a href="./src/praisonai-agents/praisonaiagents/guardrails/guardrail_result.py">from_tuple</a>(result: Tuple[bool, Any]) -> 'GuardrailResult'</code>
|
||||
* <code title="class HandoffConfig">HandoffConfig.<a href="./src/praisonai-agents/praisonaiagents/agent/handoff.py">from_dict</a>(data: Dict[str, Any]) -> 'HandoffConfig'</code>
|
||||
* <code title="class HandoffConfig">HandoffConfig.<a href="./src/praisonai-agents/praisonaiagents/agent/handoff.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class TaskOutput">TaskOutput.<a href="./src/praisonai-agents/praisonaiagents/main.py">json</a>() -> Optional[str]</code>
|
||||
* <code title="class TaskOutput">TaskOutput.<a href="./src/praisonai-agents/praisonaiagents/main.py">to_dict</a>() -> dict</code>
|
||||
* <code title="class ToolResult">ToolResult.<a href="./src/praisonai-agents/praisonaiagents/tools/base.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
|
||||
# Agents
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import Agent, Agents, AutoAgents, AutoRagAgent, ContextAgent, DeepResearchAgent, ImageAgent, PlanningAgent, PromptExpanderAgent, QueryRewriterAgent, create_context_agent
|
||||
```
|
||||
|
||||
Methods:
|
||||
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">achat</a>(prompt: str, temperature = 1.0, tools = None, output_json = None, output_pydantic = None, reasoning_steps = False, task_name = None, task_description = None, task_id = None, attachments = None)</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">aexecute</a>(task, context = None)</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">agent_id</a>()</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">analyze_prompt</a>(prompt: str) -> set</code>
|
||||
@@ -22,7 +38,7 @@ Methods:
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">auto_memory</a>(value)</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">background</a>()</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">background</a>(value)</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">chat</a>(prompt, temperature = 1.0, tools = None, output_json = None, output_pydantic = None, reasoning_steps = False, stream = None, task_name = None, task_description = None, task_id = None, config = None, force_retrieval = False, skip_retrieval = False)</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">chat</a>(prompt, temperature = 1.0, tools = None, output_json = None, output_pydantic = None, reasoning_steps = False, stream = None, task_name = None, task_description = None, task_id = None, config = None, force_retrieval = False, skip_retrieval = False, attachments = None, tool_choice = None)</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">chat_with_context</a>(message: str, context: 'ContextPack', **kwargs) -> str</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">checkpoints</a>()</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">checkpoints</a>(value)</code>
|
||||
@@ -31,13 +47,17 @@ Methods:
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">console</a>()</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">context_manager</a>()</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">context_manager</a>(value)</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">display_generating</a>(content: str, start_time: float)</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">delete_history</a>(index: int) -> bool</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">delete_history_matching</a>(pattern: str) -> int</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">display_name</a>() -> str</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">ephemeral</a>()</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">execute</a>(task, context = None)</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">execute_tool</a>(function_name, arguments)</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">execute_tool_async</a>(function_name: str, arguments: Dict[str, Any]) -> Any</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">from_template</a>(uri: str, config: Optional[Dict[str, Any]] = None, offline: bool = False, **kwargs) -> 'Agent'</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">generate_task</a>() -> 'Task'</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">get_available_tools</a>() -> List[Any]</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">get_history_size</a>() -> int</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">get_memory_context</a>(query: Optional[str] = None) -> str</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">get_recommended_stage</a>(prompt: str) -> str</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">get_rules_context</a>(file_path: Optional[str] = None, include_manual: Optional[List[str]] = None) -> str</code>
|
||||
@@ -51,6 +71,7 @@ Methods:
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">output_style</a>(value)</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">policy</a>()</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">policy</a>(value)</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">prune_history</a>(keep_last: int = 5) -> int</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">query</a>(question: str, **kwargs) -> 'RAGResult'</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">rag</a>()</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">rag_query</a>(question: str, **kwargs) -> 'RAGResult'</code>
|
||||
@@ -58,11 +79,13 @@ Methods:
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">retrieve</a>(query: str, **kwargs) -> 'ContextPack'</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">rules_manager</a>()</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">run</a>(prompt: str, **kwargs)</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">run_autonomous</a>(prompt: str, max_iterations: Optional[int] = None, timeout_seconds: Optional[float] = None)</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">run_autonomous</a>(prompt: str, max_iterations: Optional[int] = None, timeout_seconds: Optional[float] = None, completion_promise: Optional[str] = None, clear_context: bool = False)</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">session_id</a>() -> Optional[str]</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">skill_manager</a>()</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">start</a>(prompt: str = None, **kwargs)</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">store_memory</a>(content: str, memory_type: str = 'short_term', **kwargs)</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">stream_emitter</a>()</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">stream_emitter</a>(value)</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">switch_model</a>(new_model: str) -> None</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">thinking_budget</a>()</code>
|
||||
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">thinking_budget</a>(value)</code>
|
||||
@@ -105,23 +128,613 @@ Methods:
|
||||
* <code title="class Agents">Agents.<a href="./src/praisonai-agents/praisonaiagents/agents/agents.py">todo_list</a>()</code>
|
||||
* <code title="class Agents">Agents.<a href="./src/praisonai-agents/praisonaiagents/agents/agents.py">update_plan_step_status</a>(step_id: str, status: str) -> bool</code>
|
||||
* <code title="class Agents">Agents.<a href="./src/praisonai-agents/praisonaiagents/agents/agents.py">update_state</a>(updates: Dict) -> None</code>
|
||||
* <code title="class AutoAgents">AutoAgents.<a href="./src/praisonai-agents/praisonaiagents/agents/autoagents.py">astart</a>()</code>
|
||||
* <code title="class AutoAgents">AutoAgents.<a href="./src/praisonai-agents/praisonaiagents/agents/autoagents.py">start</a>()</code>
|
||||
* <code title="class AutoRagAgent">AutoRagAgent.<a href="./src/praisonai-agents/praisonaiagents/agents/auto_rag_agent.py">achat</a>(message: str, **kwargs) -> str</code>
|
||||
* <code title="class AutoRagAgent">AutoRagAgent.<a href="./src/praisonai-agents/praisonaiagents/agents/auto_rag_agent.py">chat</a>(message: str, **kwargs) -> str</code>
|
||||
* <code title="class AutoRagAgent">AutoRagAgent.<a href="./src/praisonai-agents/praisonaiagents/agents/auto_rag_agent.py">name</a>() -> str</code>
|
||||
* <code title="class AutoRagAgent">AutoRagAgent.<a href="./src/praisonai-agents/praisonaiagents/agents/auto_rag_agent.py">rag</a>() -> Optional['RAG']</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">aanalyze_codebase</a>(project_path: str) -> Dict[str, Any]</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">acreate_implementation_blueprint</a>(feature_request: str, context_analysis: Optional[Dict[str, Any]] = None) -> Dict[str, Any]</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">agenerate_prp</a>(feature_request: str, context_analysis: Optional[Dict[str, Any]] = None) -> str</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">analyze_codebase</a>(project_path: str) -> Dict[str, Any]</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">analyze_codebase_with_gitingest</a>(project_path: str) -> Dict[str, Any]</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">analyze_integration_points</a>(project_path: str) -> Dict[str, Any]</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">analyze_test_patterns</a>(project_path: str) -> Dict[str, Any]</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">build_implementation_blueprint</a>(feature_request: str, context_analysis: Dict[str, Any] = None) -> Dict[str, Any]</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">compile_context_documentation</a>(project_path: str) -> Dict[str, Any]</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">create_implementation_blueprint</a>(feature_request: str, context_analysis: Optional[Dict[str, Any]] = None) -> Dict[str, Any]</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">create_quality_gates</a>(requirements: List[str]) -> Dict[str, Any]</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">create_validation_framework</a>(project_path: str) -> Dict[str, Any]</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">execute_prp</a>(prp_file_path: str) -> Dict[str, Any]</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">extract_implementation_patterns</a>(project_path: str, ast_analysis: Dict[str, Any] = None) -> Dict[str, Any]</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">generate_comprehensive_prp</a>(feature_request: str, context_analysis: Dict[str, Any] = None) -> str</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">generate_feature_prp</a>(feature_request: str) -> str</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">generate_prp</a>(feature_request: str, context_analysis: Optional[Dict[str, Any]] = None) -> str</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">get_agent_interaction_summary</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">log_debug</a>(message: str, **kwargs)</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">perform_ast_analysis</a>(project_path: str) -> Dict[str, Any]</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">save_comprehensive_session_report</a>()</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">save_markdown_output</a>(content: str, filename: str, section_title: str = 'Output')</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">setup_logging</a>()</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">setup_output_directories</a>()</code>
|
||||
* <code title="class ContextAgent">ContextAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">start</a>(input_text: str) -> str</code>
|
||||
* <code title="class DeepResearchAgent">DeepResearchAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/deep_research_agent.py">aresearch</a>(query: str, instructions: Optional[str] = None, model: Optional[str] = None, summary_mode: Optional[Literal['auto', 'detailed', 'concise']] = None, web_search: Optional[bool] = None, code_interpreter: Optional[bool] = None, mcp_servers: Optional[List[Dict[str, Any]]] = None, file_ids: Optional[List[str]] = None, file_search: Optional[bool] = None, file_search_stores: Optional[List[str]] = None) -> DeepResearchResponse</code>
|
||||
* <code title="class DeepResearchAgent">DeepResearchAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/deep_research_agent.py">async_openai_client</a>()</code>
|
||||
* <code title="class DeepResearchAgent">DeepResearchAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/deep_research_agent.py">clarify</a>(query: str, model: Optional[str] = None) -> str</code>
|
||||
* <code title="class DeepResearchAgent">DeepResearchAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/deep_research_agent.py">follow_up</a>(query: str, previous_interaction_id: str, model: Optional[str] = None) -> DeepResearchResponse</code>
|
||||
* <code title="class DeepResearchAgent">DeepResearchAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/deep_research_agent.py">gemini_client</a>()</code>
|
||||
* <code title="class DeepResearchAgent">DeepResearchAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/deep_research_agent.py">openai_client</a>()</code>
|
||||
* <code title="class DeepResearchAgent">DeepResearchAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/deep_research_agent.py">research</a>(query: str, instructions: Optional[str] = None, model: Optional[str] = None, summary_mode: Optional[Literal['auto', 'detailed', 'concise']] = None, web_search: Optional[bool] = None, code_interpreter: Optional[bool] = None, mcp_servers: Optional[List[Dict[str, Any]]] = None, file_ids: Optional[List[str]] = None, file_search: Optional[bool] = None, file_search_stores: Optional[List[str]] = None, stream: bool = True) -> DeepResearchResponse</code>
|
||||
* <code title="class DeepResearchAgent">DeepResearchAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/deep_research_agent.py">rewrite_query</a>(query: str, model: Optional[str] = None) -> str</code>
|
||||
* <code title="class ImageAgent">ImageAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/image_agent.py">achat</a>(prompt: str, temperature: float = 0.2, tools: Optional[List[Any]] = None, output_json: Optional[str] = None, output_pydantic: Optional[Any] = None, reasoning_steps: bool = False, **kwargs) -> Union[str, Dict[str, Any]]</code>
|
||||
* <code title="class ImageAgent">ImageAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/image_agent.py">aedit</a>(image: str, prompt: str, mask: Optional[str] = None, n: int = 1, size: Optional[str] = None, **kwargs) -> Dict[str, Any]</code>
|
||||
* <code title="class ImageAgent">ImageAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/image_agent.py">agenerate</a>(prompt: str, **kwargs) -> Dict[str, Any]</code>
|
||||
* <code title="class ImageAgent">ImageAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/image_agent.py">agenerate_image</a>(prompt: str, **kwargs) -> Dict[str, Any]</code>
|
||||
* <code title="class ImageAgent">ImageAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/image_agent.py">avariation</a>(image: str, n: int = 1, size: Optional[str] = None, **kwargs) -> Dict[str, Any]</code>
|
||||
* <code title="class ImageAgent">ImageAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/image_agent.py">chat</a>(prompt: str, **kwargs) -> Dict[str, Any]</code>
|
||||
* <code title="class ImageAgent">ImageAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/image_agent.py">edit</a>(image: str, prompt: str, mask: Optional[str] = None, n: int = 1, size: Optional[str] = None, **kwargs) -> Dict[str, Any]</code>
|
||||
* <code title="class ImageAgent">ImageAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/image_agent.py">generate</a>(prompt: str, **kwargs) -> Dict[str, Any]</code>
|
||||
* <code title="class ImageAgent">ImageAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/image_agent.py">generate_image</a>(prompt: str, **kwargs) -> Dict[str, Any]</code>
|
||||
* <code title="class ImageAgent">ImageAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/image_agent.py">litellm</a>()</code>
|
||||
* <code title="class ImageAgent">ImageAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/image_agent.py">variation</a>(image: str, n: int = 1, size: Optional[str] = None, **kwargs) -> Dict[str, Any]</code>
|
||||
* <code title="class PlanningAgent">PlanningAgent.<a href="./src/praisonai-agents/praisonaiagents/planning/planner.py">analyze_context</a>(context: str) -> str</code>
|
||||
* <code title="class PlanningAgent">PlanningAgent.<a href="./src/praisonai-agents/praisonaiagents/planning/planner.py">analyze_context_sync</a>(context: str) -> str</code>
|
||||
* <code title="class PlanningAgent">PlanningAgent.<a href="./src/praisonai-agents/praisonaiagents/planning/planner.py">create_plan</a>(request: str, agents: List['Agent'], tasks: Optional[List['Task']] = None, context: Optional[str] = None) -> Plan</code>
|
||||
* <code title="class PlanningAgent">PlanningAgent.<a href="./src/praisonai-agents/praisonaiagents/planning/planner.py">create_plan_sync</a>(request: str, agents: List['Agent'], tasks: Optional[List['Task']] = None, context: Optional[str] = None) -> Plan</code>
|
||||
* <code title="class PlanningAgent">PlanningAgent.<a href="./src/praisonai-agents/praisonaiagents/planning/planner.py">is_tool_allowed</a>(tool_name: str) -> bool</code>
|
||||
* <code title="class PlanningAgent">PlanningAgent.<a href="./src/praisonai-agents/praisonaiagents/planning/planner.py">refine_plan</a>(plan: Plan, feedback: str) -> Plan</code>
|
||||
* <code title="class PlanningAgent">PlanningAgent.<a href="./src/praisonai-agents/praisonaiagents/planning/planner.py">refine_plan_sync</a>(plan: Plan, feedback: str) -> Plan</code>
|
||||
* <code title="class PromptExpanderAgent">PromptExpanderAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/prompt_expander_agent.py">agent</a>()</code>
|
||||
* <code title="class PromptExpanderAgent">PromptExpanderAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/prompt_expander_agent.py">expand</a>(prompt: str, strategy: ExpandStrategy = ..., context: Optional[str] = None) -> ExpandResult</code>
|
||||
* <code title="class PromptExpanderAgent">PromptExpanderAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/prompt_expander_agent.py">expand_basic</a>(prompt: str, context: Optional[str] = None) -> ExpandResult</code>
|
||||
* <code title="class PromptExpanderAgent">PromptExpanderAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/prompt_expander_agent.py">expand_creative</a>(prompt: str, context: Optional[str] = None) -> ExpandResult</code>
|
||||
* <code title="class PromptExpanderAgent">PromptExpanderAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/prompt_expander_agent.py">expand_detailed</a>(prompt: str, context: Optional[str] = None) -> ExpandResult</code>
|
||||
* <code title="class PromptExpanderAgent">PromptExpanderAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/prompt_expander_agent.py">expand_structured</a>(prompt: str, context: Optional[str] = None) -> ExpandResult</code>
|
||||
* <code title="class QueryRewriterAgent">QueryRewriterAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/query_rewriter_agent.py">add_abbreviation</a>(abbrev: str, expansion: str) -> None</code>
|
||||
* <code title="class QueryRewriterAgent">QueryRewriterAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/query_rewriter_agent.py">add_abbreviations</a>(abbreviations: Dict[str, str]) -> None</code>
|
||||
* <code title="class QueryRewriterAgent">QueryRewriterAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/query_rewriter_agent.py">agent</a>()</code>
|
||||
* <code title="class QueryRewriterAgent">QueryRewriterAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/query_rewriter_agent.py">rewrite</a>(query: str, strategy: RewriteStrategy = ..., chat_history: Optional[List[Dict[str, str]]] = None, context: Optional[str] = None, num_queries: int = None) -> RewriteResult</code>
|
||||
* <code title="class QueryRewriterAgent">QueryRewriterAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/query_rewriter_agent.py">rewrite_basic</a>(query: str) -> RewriteResult</code>
|
||||
* <code title="class QueryRewriterAgent">QueryRewriterAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/query_rewriter_agent.py">rewrite_contextual</a>(query: str, chat_history: List[Dict[str, str]]) -> RewriteResult</code>
|
||||
* <code title="class QueryRewriterAgent">QueryRewriterAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/query_rewriter_agent.py">rewrite_hyde</a>(query: str) -> RewriteResult</code>
|
||||
* <code title="class QueryRewriterAgent">QueryRewriterAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/query_rewriter_agent.py">rewrite_multi_query</a>(query: str, num_queries: int = None) -> RewriteResult</code>
|
||||
* <code title="class QueryRewriterAgent">QueryRewriterAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/query_rewriter_agent.py">rewrite_step_back</a>(query: str) -> RewriteResult</code>
|
||||
* <code title="class QueryRewriterAgent">QueryRewriterAgent.<a href="./src/praisonai-agents/praisonaiagents/agent/query_rewriter_agent.py">rewrite_sub_queries</a>(query: str) -> RewriteResult</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/agent/context_agent.py">create_context_agent</a>(llm: Optional[Union[str, Any]] = None, **kwargs) -> ContextAgent</code>
|
||||
|
||||
# Tools
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import Tools, tool
|
||||
from praisonaiagents import BaseTool, FunctionTool, ToolRegistry, Tools, get_registry, get_tool, register_tool, tool, validate_tool
|
||||
```
|
||||
|
||||
Methods:
|
||||
|
||||
* <code title="class BaseTool">BaseTool.<a href="./src/praisonai-agents/praisonaiagents/tools/base.py">__call__</a>(**kwargs) -> Any</code>
|
||||
* <code title="class BaseTool">BaseTool.<a href="./src/praisonai-agents/praisonaiagents/tools/base.py">get_schema</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class BaseTool">BaseTool.<a href="./src/praisonai-agents/praisonaiagents/tools/base.py">run</a>(**kwargs) -> Any</code>
|
||||
* <code title="class BaseTool">BaseTool.<a href="./src/praisonai-agents/praisonaiagents/tools/base.py">safe_run</a>(**kwargs) -> ToolResult</code>
|
||||
* <code title="class BaseTool">BaseTool.<a href="./src/praisonai-agents/praisonaiagents/tools/base.py">validate</a>() -> bool</code>
|
||||
* <code title="class BaseTool">BaseTool.<a href="./src/praisonai-agents/praisonaiagents/tools/base.py">validate_class</a>() -> bool</code>
|
||||
* <code title="class FunctionTool">FunctionTool.<a href="./src/praisonai-agents/praisonaiagents/tools/decorator.py">__call__</a>(*args, **kwargs) -> Any</code>
|
||||
* <code title="class FunctionTool">FunctionTool.<a href="./src/praisonai-agents/praisonaiagents/tools/decorator.py">injected_params</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class FunctionTool">FunctionTool.<a href="./src/praisonai-agents/praisonaiagents/tools/decorator.py">run</a>(**kwargs) -> Any</code>
|
||||
* <code title="class ToolRegistry">ToolRegistry.<a href="./src/praisonai-agents/praisonaiagents/tools/registry.py">clear</a>() -> None</code>
|
||||
* <code title="class ToolRegistry">ToolRegistry.<a href="./src/praisonai-agents/praisonaiagents/tools/registry.py">discover_plugins</a>() -> int</code>
|
||||
* <code title="class ToolRegistry">ToolRegistry.<a href="./src/praisonai-agents/praisonaiagents/tools/registry.py">get</a>(name: str) -> Optional[Union[BaseTool, Callable]]</code>
|
||||
* <code title="class ToolRegistry">ToolRegistry.<a href="./src/praisonai-agents/praisonaiagents/tools/registry.py">get_all</a>() -> Dict[str, Union[BaseTool, Callable]]</code>
|
||||
* <code title="class ToolRegistry">ToolRegistry.<a href="./src/praisonai-agents/praisonaiagents/tools/registry.py">list_base_tools</a>() -> List[BaseTool]</code>
|
||||
* <code title="class ToolRegistry">ToolRegistry.<a href="./src/praisonai-agents/praisonaiagents/tools/registry.py">list_tools</a>() -> List[str]</code>
|
||||
* <code title="class ToolRegistry">ToolRegistry.<a href="./src/praisonai-agents/praisonaiagents/tools/registry.py">register</a>(tool: Union[BaseTool, Callable], name: Optional[str] = None, overwrite: bool = False) -> None</code>
|
||||
* <code title="class ToolRegistry">ToolRegistry.<a href="./src/praisonai-agents/praisonaiagents/tools/registry.py">unregister</a>(name: str) -> bool</code>
|
||||
* <code title="class Tools">Tools.<a href="./src/praisonai-agents/praisonaiagents/tools/tools.py">internet_search</a>(*args, **kwargs)</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/tools/registry.py">get_registry</a>() -> ToolRegistry</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/tools/registry.py">get_tool</a>(name: str) -> Optional[Union[BaseTool, Callable]]</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/tools/registry.py">register_tool</a>(tool: Union[BaseTool, Callable], name: Optional[str] = None) -> None</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/tools/decorator.py">tool</a>(func: Optional[Callable] = None) -> Union[FunctionTool, Callable[[Callable], FunctionTool]]</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/tools/base.py">validate_tool</a>(tool: Any) -> bool</code>
|
||||
|
||||
# Workflows
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import Loop, Parallel, Pipeline, Repeat, Route, Workflow, WorkflowStep, loop, parallel, repeat, route
|
||||
```
|
||||
|
||||
Methods:
|
||||
|
||||
* <code title="class Workflow">Workflow.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">arun</a>(input: str = '', llm: Optional[str] = None, verbose: bool = False) -> Dict[str, Any]</code>
|
||||
* <code title="class Workflow">Workflow.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">astart</a>(input: str = '', llm: Optional[str] = None, verbose: bool = False) -> Dict[str, Any]</code>
|
||||
* <code title="class Workflow">Workflow.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">from_template</a>(uri: str, config: Optional[Dict[str, Any]] = None, offline: bool = False, **kwargs) -> 'Workflow'</code>
|
||||
* <code title="class Workflow">Workflow.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">memory_config</a>() -> Optional[Dict[str, Any]]</code>
|
||||
* <code title="class Workflow">Workflow.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">on_step_complete</a>() -> Optional[Callable]</code>
|
||||
* <code title="class Workflow">Workflow.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">on_step_error</a>() -> Optional[Callable]</code>
|
||||
* <code title="class Workflow">Workflow.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">on_step_start</a>() -> Optional[Callable]</code>
|
||||
* <code title="class Workflow">Workflow.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">on_workflow_complete</a>() -> Optional[Callable]</code>
|
||||
* <code title="class Workflow">Workflow.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">on_workflow_start</a>() -> Optional[Callable]</code>
|
||||
* <code title="class Workflow">Workflow.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">planning_llm</a>() -> Optional[str]</code>
|
||||
* <code title="class Workflow">Workflow.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">reasoning</a>() -> bool</code>
|
||||
* <code title="class Workflow">Workflow.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">run</a>(input: str = '', llm: Optional[str] = None, verbose: bool = False, stream: bool = None) -> Dict[str, Any]</code>
|
||||
* <code title="class Workflow">Workflow.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">start</a>(input: str = '', **kwargs) -> Dict[str, Any]</code>
|
||||
* <code title="class Workflow">Workflow.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">stream</a>() -> bool</code>
|
||||
* <code title="class Workflow">Workflow.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class Workflow">Workflow.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">verbose</a>() -> bool</code>
|
||||
* <code title="class Workflow">Workflow.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">verbose</a>(value: bool)</code>
|
||||
* <code title="class WorkflowStep">WorkflowStep.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">async_execution</a>() -> bool</code>
|
||||
* <code title="class WorkflowStep">WorkflowStep.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">branch_condition</a>() -> Optional[Dict[str, List[str]]]</code>
|
||||
* <code title="class WorkflowStep">WorkflowStep.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">context_from</a>() -> Optional[List[str]]</code>
|
||||
* <code title="class WorkflowStep">WorkflowStep.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">evaluator</a>()</code>
|
||||
* <code title="class WorkflowStep">WorkflowStep.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">executor</a>()</code>
|
||||
* <code title="class WorkflowStep">WorkflowStep.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">max_retries</a>() -> int</code>
|
||||
* <code title="class WorkflowStep">WorkflowStep.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">next_steps</a>() -> Optional[List[str]]</code>
|
||||
* <code title="class WorkflowStep">WorkflowStep.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">on_error</a>() -> str</code>
|
||||
* <code title="class WorkflowStep">WorkflowStep.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">output_file</a>() -> Optional[str]</code>
|
||||
* <code title="class WorkflowStep">WorkflowStep.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">output_json</a>() -> Optional[Any]</code>
|
||||
* <code title="class WorkflowStep">WorkflowStep.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">output_pydantic</a>() -> Optional[Any]</code>
|
||||
* <code title="class WorkflowStep">WorkflowStep.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">output_variable</a>() -> Optional[str]</code>
|
||||
* <code title="class WorkflowStep">WorkflowStep.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">quality_check</a>() -> bool</code>
|
||||
* <code title="class WorkflowStep">WorkflowStep.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">rerun</a>() -> bool</code>
|
||||
* <code title="class WorkflowStep">WorkflowStep.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">retain_full_context</a>() -> bool</code>
|
||||
* <code title="class WorkflowStep">WorkflowStep.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">loop</a>(step: Any = None, steps: Optional[List[Any]] = None, over: Optional[str] = None, from_csv: Optional[str] = None, from_file: Optional[str] = None, var_name: str = 'item', parallel: bool = False, max_workers: Optional[int] = None, output_variable: Optional[str] = None) -> Loop</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">parallel</a>(steps: List) -> Parallel</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">repeat</a>(step: Any, until: Optional[Callable[[WorkflowContext], bool]] = None, max_iterations: int = 10) -> Repeat</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">route</a>(routes: Dict[str, List], default: Optional[List] = None) -> Route</code>
|
||||
|
||||
# DB
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import db
|
||||
```
|
||||
|
||||
# Memory
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import Memory, MemoryBackend, MemoryConfig
|
||||
```
|
||||
|
||||
Methods:
|
||||
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">build_context_for_task</a>(task_descr: str, user_id: Optional[str] = None, additional: str = '', max_items: int = 3, include_in_output: Optional[bool] = None) -> str</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">calculate_quality_metrics</a>(output: str, expected_output: str, llm: Optional[str] = None, custom_prompt: Optional[str] = None) -> Dict[str, float]</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">compute_quality_score</a>(completeness: float, relevance: float, clarity: float, accuracy: float, weights: Dict[str, float] = None) -> float</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">delete_long_term</a>(memory_id: str) -> bool</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">delete_memories</a>(memory_ids: List[str]) -> int</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">delete_memories_matching</a>(query: str, memory_type: Optional[str] = None, limit: int = 10) -> int</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">delete_memory</a>(memory_id: str, memory_type: Optional[str] = None) -> bool</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">delete_short_term</a>(memory_id: str) -> bool</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">finalize_task_output</a>(content: str, agent_name: str, quality_score: float, threshold: float = 0.7, metrics: Dict[str, Any] = None, task_id: str = None)</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">get_all_memories</a>() -> List[Dict[str, Any]]</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">get_learn_context</a>() -> str</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">learn</a>()</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">reset_all</a>()</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">reset_entity_only</a>()</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">reset_long_term</a>()</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">reset_short_term</a>()</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">reset_user_memory</a>()</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">search</a>(query: str, user_id: Optional[str] = None, agent_id: Optional[str] = None, run_id: Optional[str] = None, limit: int = 5, rerank: bool = False, **kwargs) -> List[Dict[str, Any]]</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">search_entity</a>(query: str, limit: int = 5) -> List[Dict[str, Any]]</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">search_long_term</a>(query: str, limit: int = 5, relevance_cutoff: float = 0.0, min_quality: float = 0.0, rerank: bool = False, **kwargs) -> List[Dict[str, Any]]</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">search_short_term</a>(query: str, limit: int = 5, min_quality: float = 0.0, relevance_cutoff: float = 0.0, rerank: bool = False, **kwargs) -> List[Dict[str, Any]]</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">search_user_memory</a>(user_id: str, query: str, limit: int = 5, rerank: bool = False, **kwargs) -> List[Dict[str, Any]]</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">search_with_quality</a>(query: str, min_quality: float = 0.0, memory_type: Literal['short', 'long'] = 'long', limit: int = 5) -> List[Dict[str, Any]]</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">store_entity</a>(name: str, type_: str, desc: str, relations: str)</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">store_long_term</a>(text: str, metadata: Dict[str, Any] = None, completeness: float = None, relevance: float = None, clarity: float = None, accuracy: float = None, weights: Dict[str, float] = None, evaluator_quality: float = None)</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">store_quality</a>(text: str, quality_score: float, task_id: Optional[str] = None, iteration: Optional[int] = None, metrics: Optional[Dict[str, float]] = None, memory_type: Literal['short', 'long'] = 'long') -> None</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">store_short_term</a>(text: str, metadata: Dict[str, Any] = None, completeness: float = None, relevance: float = None, clarity: float = None, accuracy: float = None, weights: Dict[str, float] = None, evaluator_quality: float = None)</code>
|
||||
* <code title="class Memory">Memory.<a href="./src/praisonai-agents/praisonaiagents/memory/memory.py">store_user_memory</a>(user_id: str, text: str, extra: Dict[str, Any] = None)</code>
|
||||
* <code title="class MemoryConfig">MemoryConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
|
||||
# Knowledge
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import Chunking, ChunkingStrategy, Knowledge, KnowledgeConfig
|
||||
```
|
||||
|
||||
Methods:
|
||||
|
||||
* <code title="class Chunking">Chunking.<a href="./src/praisonai-agents/praisonaiagents/knowledge/chunking.py">SUPPORTED_CHUNKERS</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class Chunking">Chunking.<a href="./src/praisonai-agents/praisonaiagents/knowledge/chunking.py">__call__</a>(text: Union[str, List[str]], **kwargs) -> Union[List[Any], List[List[Any]]]</code>
|
||||
* <code title="class Chunking">Chunking.<a href="./src/praisonai-agents/praisonaiagents/knowledge/chunking.py">chunk</a>(text: Union[str, List[str]], **kwargs) -> Union[List[Any], List[List[Any]]]</code>
|
||||
* <code title="class Chunking">Chunking.<a href="./src/praisonai-agents/praisonaiagents/knowledge/chunking.py">chunker</a>()</code>
|
||||
* <code title="class Chunking">Chunking.<a href="./src/praisonai-agents/praisonaiagents/knowledge/chunking.py">embedding_model</a>()</code>
|
||||
* <code title="class Knowledge">Knowledge.<a href="./src/praisonai-agents/praisonaiagents/knowledge/knowledge.py">add</a>(file_path, user_id = None, agent_id = None, run_id = None, metadata = None)</code>
|
||||
* <code title="class Knowledge">Knowledge.<a href="./src/praisonai-agents/praisonaiagents/knowledge/knowledge.py">chunker</a>()</code>
|
||||
* <code title="class Knowledge">Knowledge.<a href="./src/praisonai-agents/praisonaiagents/knowledge/knowledge.py">config</a>()</code>
|
||||
* <code title="class Knowledge">Knowledge.<a href="./src/praisonai-agents/praisonaiagents/knowledge/knowledge.py">delete</a>(memory_id)</code>
|
||||
* <code title="class Knowledge">Knowledge.<a href="./src/praisonai-agents/praisonaiagents/knowledge/knowledge.py">delete_all</a>(user_id = None, agent_id = None, run_id = None)</code>
|
||||
* <code title="class Knowledge">Knowledge.<a href="./src/praisonai-agents/praisonaiagents/knowledge/knowledge.py">get</a>(memory_id)</code>
|
||||
* <code title="class Knowledge">Knowledge.<a href="./src/praisonai-agents/praisonaiagents/knowledge/knowledge.py">get_all</a>(user_id = None, agent_id = None, run_id = None)</code>
|
||||
* <code title="class Knowledge">Knowledge.<a href="./src/praisonai-agents/praisonaiagents/knowledge/knowledge.py">get_corpus_stats</a>()</code>
|
||||
* <code title="class Knowledge">Knowledge.<a href="./src/praisonai-agents/praisonaiagents/knowledge/knowledge.py">history</a>(memory_id)</code>
|
||||
* <code title="class Knowledge">Knowledge.<a href="./src/praisonai-agents/praisonaiagents/knowledge/knowledge.py">index</a>(path: str, incremental: bool = True, force: bool = False, include_glob: list = None, exclude_glob: list = None, user_id: str = None, agent_id: str = None, run_id: str = None)</code>
|
||||
* <code title="class Knowledge">Knowledge.<a href="./src/praisonai-agents/praisonaiagents/knowledge/knowledge.py">markdown</a>()</code>
|
||||
* <code title="class Knowledge">Knowledge.<a href="./src/praisonai-agents/praisonaiagents/knowledge/knowledge.py">memory</a>()</code>
|
||||
* <code title="class Knowledge">Knowledge.<a href="./src/praisonai-agents/praisonaiagents/knowledge/knowledge.py">normalize_content</a>(content)</code>
|
||||
* <code title="class Knowledge">Knowledge.<a href="./src/praisonai-agents/praisonaiagents/knowledge/knowledge.py">reset</a>()</code>
|
||||
* <code title="class Knowledge">Knowledge.<a href="./src/praisonai-agents/praisonaiagents/knowledge/knowledge.py">search</a>(query, user_id = None, agent_id = None, run_id = None, rerank = None, **kwargs)</code>
|
||||
* <code title="class Knowledge">Knowledge.<a href="./src/praisonai-agents/praisonaiagents/knowledge/knowledge.py">store</a>(content, user_id = None, agent_id = None, run_id = None, metadata = None)</code>
|
||||
* <code title="class Knowledge">Knowledge.<a href="./src/praisonai-agents/praisonaiagents/knowledge/knowledge.py">update</a>(memory_id, data)</code>
|
||||
* <code title="class KnowledgeConfig">KnowledgeConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
|
||||
# RAG
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import CitationsMode, ContextPack, RAG, RAGCitation, RAGConfig, RAGResult, RetrievalConfig, RetrievalPolicy
|
||||
```
|
||||
|
||||
Methods:
|
||||
|
||||
* <code title="class ContextPack">ContextPack.<a href="./src/praisonai-agents/praisonaiagents/rag/models.py">format_for_prompt</a>(include_sources: bool = True) -> str</code>
|
||||
* <code title="class ContextPack">ContextPack.<a href="./src/praisonai-agents/praisonaiagents/rag/models.py">from_dict</a>(data: Dict[str, Any]) -> 'ContextPack'</code>
|
||||
* <code title="class ContextPack">ContextPack.<a href="./src/praisonai-agents/praisonaiagents/rag/models.py">has_citations</a>() -> bool</code>
|
||||
* <code title="class ContextPack">ContextPack.<a href="./src/praisonai-agents/praisonaiagents/rag/models.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class RAG">RAG.<a href="./src/praisonai-agents/praisonaiagents/rag/pipeline.py">aquery</a>(question: str, user_id: Optional[str] = None, agent_id: Optional[str] = None, run_id: Optional[str] = None, **kwargs) -> RAGResult</code>
|
||||
* <code title="class RAG">RAG.<a href="./src/praisonai-agents/praisonaiagents/rag/pipeline.py">aretrieve</a>(query: str, **kwargs) -> ContextPack</code>
|
||||
* <code title="class RAG">RAG.<a href="./src/praisonai-agents/praisonaiagents/rag/pipeline.py">astream</a>(question: str, user_id: Optional[str] = None, agent_id: Optional[str] = None, run_id: Optional[str] = None, **kwargs) -> AsyncIterator[str]</code>
|
||||
* <code title="class RAG">RAG.<a href="./src/praisonai-agents/praisonaiagents/rag/pipeline.py">get_citations</a>(question: str, user_id: Optional[str] = None, agent_id: Optional[str] = None, run_id: Optional[str] = None, **kwargs) -> List[Citation]</code>
|
||||
* <code title="class RAG">RAG.<a href="./src/praisonai-agents/praisonaiagents/rag/pipeline.py">llm</a>()</code>
|
||||
* <code title="class RAG">RAG.<a href="./src/praisonai-agents/praisonaiagents/rag/pipeline.py">query</a>(question: str, user_id: Optional[str] = None, agent_id: Optional[str] = None, run_id: Optional[str] = None, **kwargs) -> RAGResult</code>
|
||||
* <code title="class RAG">RAG.<a href="./src/praisonai-agents/praisonaiagents/rag/pipeline.py">retrieve</a>(query: str, **kwargs) -> ContextPack</code>
|
||||
* <code title="class RAG">RAG.<a href="./src/praisonai-agents/praisonaiagents/rag/pipeline.py">stream</a>(question: str, user_id: Optional[str] = None, agent_id: Optional[str] = None, run_id: Optional[str] = None, **kwargs) -> Iterator[str]</code>
|
||||
* <code title="class RAGCitation">RAGCitation.<a href="./src/praisonai-agents/praisonaiagents/rag/models.py">from_dict</a>(data: Dict[str, Any]) -> 'Citation'</code>
|
||||
* <code title="class RAGCitation">RAGCitation.<a href="./src/praisonai-agents/praisonaiagents/rag/models.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class RAGConfig">RAGConfig.<a href="./src/praisonai-agents/praisonaiagents/rag/models.py">from_dict</a>(data: Dict[str, Any]) -> 'RAGConfig'</code>
|
||||
* <code title="class RAGConfig">RAGConfig.<a href="./src/praisonai-agents/praisonaiagents/rag/models.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class RAGResult">RAGResult.<a href="./src/praisonai-agents/praisonaiagents/rag/models.py">format_answer_with_citations</a>() -> str</code>
|
||||
* <code title="class RAGResult">RAGResult.<a href="./src/praisonai-agents/praisonaiagents/rag/models.py">from_dict</a>(data: Dict[str, Any]) -> 'RAGResult'</code>
|
||||
* <code title="class RAGResult">RAGResult.<a href="./src/praisonai-agents/praisonaiagents/rag/models.py">has_citations</a>() -> bool</code>
|
||||
* <code title="class RAGResult">RAGResult.<a href="./src/praisonai-agents/praisonaiagents/rag/models.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class RetrievalConfig">RetrievalConfig.<a href="./src/praisonai-agents/praisonaiagents/rag/retrieval_config.py">from_dict</a>(data: Dict[str, Any]) -> 'RetrievalConfig'</code>
|
||||
* <code title="class RetrievalConfig">RetrievalConfig.<a href="./src/praisonai-agents/praisonaiagents/rag/retrieval_config.py">get_strategy</a>(corpus_stats = None)</code>
|
||||
* <code title="class RetrievalConfig">RetrievalConfig.<a href="./src/praisonai-agents/praisonaiagents/rag/retrieval_config.py">get_token_budget</a>(model_name: Optional[str] = None)</code>
|
||||
* <code title="class RetrievalConfig">RetrievalConfig.<a href="./src/praisonai-agents/praisonaiagents/rag/retrieval_config.py">should_retrieve</a>(query: str, force: bool = False, skip: bool = False) -> bool</code>
|
||||
* <code title="class RetrievalConfig">RetrievalConfig.<a href="./src/praisonai-agents/praisonaiagents/rag/retrieval_config.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class RetrievalConfig">RetrievalConfig.<a href="./src/praisonai-agents/praisonaiagents/rag/retrieval_config.py">to_knowledge_config</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class RetrievalConfig">RetrievalConfig.<a href="./src/praisonai-agents/praisonaiagents/rag/retrieval_config.py">to_rag_config</a>() -> Dict[str, Any]</code>
|
||||
|
||||
# Handoff
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import Handoff, RECOMMENDED_PROMPT_PREFIX, handoff, handoff_filters, prompt_with_handoff_instructions
|
||||
```
|
||||
|
||||
Methods:
|
||||
|
||||
* <code title="class Handoff">Handoff.<a href="./src/praisonai-agents/praisonaiagents/agent/handoff.py">default_tool_description</a>() -> str</code>
|
||||
* <code title="class Handoff">Handoff.<a href="./src/praisonai-agents/praisonaiagents/agent/handoff.py">default_tool_name</a>() -> str</code>
|
||||
* <code title="class Handoff">Handoff.<a href="./src/praisonai-agents/praisonaiagents/agent/handoff.py">execute_async</a>(source_agent: 'Agent', prompt: str, context: Optional[Dict[str, Any]] = None) -> HandoffResult</code>
|
||||
* <code title="class Handoff">Handoff.<a href="./src/praisonai-agents/praisonaiagents/agent/handoff.py">execute_programmatic</a>(source_agent: 'Agent', prompt: str, context: Optional[Dict[str, Any]] = None) -> HandoffResult</code>
|
||||
* <code title="class Handoff">Handoff.<a href="./src/praisonai-agents/praisonaiagents/agent/handoff.py">to_tool_function</a>(source_agent: 'Agent') -> Callable</code>
|
||||
* <code title="class Handoff">Handoff.<a href="./src/praisonai-agents/praisonaiagents/agent/handoff.py">tool_description</a>() -> str</code>
|
||||
* <code title="class Handoff">Handoff.<a href="./src/praisonai-agents/praisonaiagents/agent/handoff.py">tool_name</a>() -> str</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/agent/handoff.py">handoff</a>(agent: 'Agent', tool_name_override: Optional[str] = None, tool_description_override: Optional[str] = None, on_handoff: Optional[Callable] = None, input_type: Optional[type] = None, input_filter: Optional[Callable[[HandoffInputData], HandoffInputData]] = None, config: Optional[HandoffConfig] = None, context_policy: Optional[str] = None, timeout_seconds: Optional[float] = None, max_concurrent: Optional[int] = None, detect_cycles: Optional[bool] = None, max_depth: Optional[int] = None) -> Handoff</code>
|
||||
* <code title="class handoff_filters">handoff_filters.<a href="./src/praisonai-agents/praisonaiagents/agent/handoff.py">keep_last_n_messages</a>(n: int) -> Callable[[HandoffInputData], HandoffInputData]</code>
|
||||
* <code title="class handoff_filters">handoff_filters.<a href="./src/praisonai-agents/praisonaiagents/agent/handoff.py">remove_all_tools</a>(data: HandoffInputData) -> HandoffInputData</code>
|
||||
* <code title="class handoff_filters">handoff_filters.<a href="./src/praisonai-agents/praisonaiagents/agent/handoff.py">remove_system_messages</a>(data: HandoffInputData) -> HandoffInputData</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/agent/handoff.py">prompt_with_handoff_instructions</a>(base_prompt: str, agent: 'Agent') -> str</code>
|
||||
|
||||
# Guardrails
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import GuardrailAction, GuardrailConfig, LLMGuardrail
|
||||
```
|
||||
|
||||
Methods:
|
||||
|
||||
* <code title="class GuardrailConfig">GuardrailConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class LLMGuardrail">LLMGuardrail.<a href="./src/praisonai-agents/praisonaiagents/guardrails/llm_guardrail.py">__call__</a>(task_output: TaskOutput) -> Tuple[bool, Union[str, TaskOutput]]</code>
|
||||
|
||||
# Planning
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import ApprovalCallback, Plan, PlanStep, PlanStorage, PlanningConfig, READ_ONLY_TOOLS, RESTRICTED_TOOLS, TodoItem, TodoList
|
||||
```
|
||||
|
||||
Methods:
|
||||
|
||||
* <code title="class ApprovalCallback">ApprovalCallback.<a href="./src/praisonai-agents/praisonaiagents/planning/approval.py">__call__</a>(plan: 'Plan') -> bool</code>
|
||||
* <code title="class ApprovalCallback">ApprovalCallback.<a href="./src/praisonai-agents/praisonaiagents/planning/approval.py">always_approve</a>(plan: 'Plan') -> bool</code>
|
||||
* <code title="class ApprovalCallback">ApprovalCallback.<a href="./src/praisonai-agents/praisonaiagents/planning/approval.py">always_reject</a>(plan: 'Plan') -> bool</code>
|
||||
* <code title="class ApprovalCallback">ApprovalCallback.<a href="./src/praisonai-agents/praisonaiagents/planning/approval.py">approve_if_no_dangerous_tools</a>(plan: 'Plan') -> bool</code>
|
||||
* <code title="class ApprovalCallback">ApprovalCallback.<a href="./src/praisonai-agents/praisonaiagents/planning/approval.py">approve_if_small</a>(plan: 'Plan', max_steps: int = 5) -> bool</code>
|
||||
* <code title="class ApprovalCallback">ApprovalCallback.<a href="./src/praisonai-agents/praisonaiagents/planning/approval.py">async_call</a>(plan: 'Plan') -> bool</code>
|
||||
* <code title="class ApprovalCallback">ApprovalCallback.<a href="./src/praisonai-agents/praisonaiagents/planning/approval.py">console_approval</a>(plan: 'Plan') -> bool</code>
|
||||
* <code title="class Plan">Plan.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">add_step</a>(step: PlanStep) -> None</code>
|
||||
* <code title="class Plan">Plan.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">approve</a>() -> None</code>
|
||||
* <code title="class Plan">Plan.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">cancel</a>() -> None</code>
|
||||
* <code title="class Plan">Plan.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">complete</a>() -> None</code>
|
||||
* <code title="class Plan">Plan.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">completed_step_ids</a>() -> List[str]</code>
|
||||
* <code title="class Plan">Plan.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">from_dict</a>(data: Dict[str, Any]) -> 'Plan'</code>
|
||||
* <code title="class Plan">Plan.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">from_markdown</a>(markdown: str) -> 'Plan'</code>
|
||||
* <code title="class Plan">Plan.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">get_next_steps</a>() -> List[PlanStep]</code>
|
||||
* <code title="class Plan">Plan.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">get_step</a>(step_id: str) -> Optional[PlanStep]</code>
|
||||
* <code title="class Plan">Plan.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">is_complete</a>() -> bool</code>
|
||||
* <code title="class Plan">Plan.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">progress</a>() -> float</code>
|
||||
* <code title="class Plan">Plan.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">remove_step</a>(step_id: str) -> bool</code>
|
||||
* <code title="class Plan">Plan.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">start_execution</a>() -> None</code>
|
||||
* <code title="class Plan">Plan.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class Plan">Plan.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">to_markdown</a>() -> str</code>
|
||||
* <code title="class Plan">Plan.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">update_step_status</a>(step_id: str, status: str) -> bool</code>
|
||||
* <code title="class PlanStep">PlanStep.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">from_dict</a>(data: Dict[str, Any]) -> 'PlanStep'</code>
|
||||
* <code title="class PlanStep">PlanStep.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">is_ready</a>(completed_steps: List[str]) -> bool</code>
|
||||
* <code title="class PlanStep">PlanStep.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">mark_complete</a>() -> None</code>
|
||||
* <code title="class PlanStep">PlanStep.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">mark_in_progress</a>() -> None</code>
|
||||
* <code title="class PlanStep">PlanStep.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">mark_skipped</a>() -> None</code>
|
||||
* <code title="class PlanStep">PlanStep.<a href="./src/praisonai-agents/praisonaiagents/planning/plan.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class PlanStorage">PlanStorage.<a href="./src/praisonai-agents/praisonaiagents/planning/storage.py">cleanup_old_plans</a>(keep_count: int = 10) -> int</code>
|
||||
* <code title="class PlanStorage">PlanStorage.<a href="./src/praisonai-agents/praisonaiagents/planning/storage.py">delete_plan</a>(plan_id: str) -> bool</code>
|
||||
* <code title="class PlanStorage">PlanStorage.<a href="./src/praisonai-agents/praisonaiagents/planning/storage.py">delete_todo</a>(name: str) -> bool</code>
|
||||
* <code title="class PlanStorage">PlanStorage.<a href="./src/praisonai-agents/praisonaiagents/planning/storage.py">get_latest_plan</a>() -> Optional[Plan]</code>
|
||||
* <code title="class PlanStorage">PlanStorage.<a href="./src/praisonai-agents/praisonaiagents/planning/storage.py">list_plans</a>() -> List[Dict[str, Any]]</code>
|
||||
* <code title="class PlanStorage">PlanStorage.<a href="./src/praisonai-agents/praisonaiagents/planning/storage.py">list_todos</a>() -> List[str]</code>
|
||||
* <code title="class PlanStorage">PlanStorage.<a href="./src/praisonai-agents/praisonaiagents/planning/storage.py">load_plan</a>(plan_id: str) -> Optional[Plan]</code>
|
||||
* <code title="class PlanStorage">PlanStorage.<a href="./src/praisonai-agents/praisonaiagents/planning/storage.py">load_plan_from_file</a>(path: str) -> Optional[Plan]</code>
|
||||
* <code title="class PlanStorage">PlanStorage.<a href="./src/praisonai-agents/praisonaiagents/planning/storage.py">load_todo</a>(name: str = 'current') -> Optional[TodoList]</code>
|
||||
* <code title="class PlanStorage">PlanStorage.<a href="./src/praisonai-agents/praisonaiagents/planning/storage.py">save_plan</a>(plan: Plan, filename: Optional[str] = None) -> str</code>
|
||||
* <code title="class PlanStorage">PlanStorage.<a href="./src/praisonai-agents/praisonaiagents/planning/storage.py">save_todo</a>(todo: TodoList, name: str = 'current') -> str</code>
|
||||
* <code title="class PlanningConfig">PlanningConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class TodoItem">TodoItem.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">complete</a>() -> None</code>
|
||||
* <code title="class TodoItem">TodoItem.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">from_dict</a>(data: Dict[str, Any]) -> 'TodoItem'</code>
|
||||
* <code title="class TodoItem">TodoItem.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">is_ready</a>(completed_ids: List[str]) -> bool</code>
|
||||
* <code title="class TodoItem">TodoItem.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">reset</a>() -> None</code>
|
||||
* <code title="class TodoItem">TodoItem.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">start</a>() -> None</code>
|
||||
* <code title="class TodoItem">TodoItem.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class TodoList">TodoList.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">add</a>(item: Union[TodoItem, str]) -> TodoItem</code>
|
||||
* <code title="class TodoList">TodoList.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">complete</a>(item_id: str) -> bool</code>
|
||||
* <code title="class TodoList">TodoList.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">completed</a>() -> List[TodoItem]</code>
|
||||
* <code title="class TodoList">TodoList.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">completed_ids</a>() -> List[str]</code>
|
||||
* <code title="class TodoList">TodoList.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">from_dict</a>(data: Dict[str, Any]) -> 'TodoList'</code>
|
||||
* <code title="class TodoList">TodoList.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">from_json</a>(json_str: str) -> 'TodoList'</code>
|
||||
* <code title="class TodoList">TodoList.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">from_markdown</a>(markdown: str) -> 'TodoList'</code>
|
||||
* <code title="class TodoList">TodoList.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">from_plan</a>(plan: 'Plan') -> 'TodoList'</code>
|
||||
* <code title="class TodoList">TodoList.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">get</a>(item_id: str) -> Optional[TodoItem]</code>
|
||||
* <code title="class TodoList">TodoList.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">get_ready_items</a>() -> List[TodoItem]</code>
|
||||
* <code title="class TodoList">TodoList.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">in_progress</a>() -> List[TodoItem]</code>
|
||||
* <code title="class TodoList">TodoList.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">is_complete</a>() -> bool</code>
|
||||
* <code title="class TodoList">TodoList.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">pending</a>() -> List[TodoItem]</code>
|
||||
* <code title="class TodoList">TodoList.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">progress</a>() -> float</code>
|
||||
* <code title="class TodoList">TodoList.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">remove</a>(item_id: str) -> bool</code>
|
||||
* <code title="class TodoList">TodoList.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">start</a>(item_id: str) -> bool</code>
|
||||
* <code title="class TodoList">TodoList.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">sync_with_plan</a>(plan: 'Plan') -> None</code>
|
||||
* <code title="class TodoList">TodoList.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class TodoList">TodoList.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">to_json</a>() -> str</code>
|
||||
* <code title="class TodoList">TodoList.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">to_markdown</a>() -> str</code>
|
||||
* <code title="class TodoList">TodoList.<a href="./src/praisonai-agents/praisonaiagents/planning/todo.py">update_from_plan</a>(plan: 'Plan') -> None</code>
|
||||
|
||||
# Skills
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import SkillLoader, SkillManager, SkillMetadata, SkillProperties, SkillsConfig
|
||||
```
|
||||
|
||||
Methods:
|
||||
|
||||
* <code title="class SkillLoader">SkillLoader.<a href="./src/praisonai-agents/praisonaiagents/skills/loader.py">activate</a>(skill: LoadedSkill) -> bool</code>
|
||||
* <code title="class SkillLoader">SkillLoader.<a href="./src/praisonai-agents/praisonaiagents/skills/loader.py">load</a>(skill_path: str, activate: bool = False) -> Optional[LoadedSkill]</code>
|
||||
* <code title="class SkillLoader">SkillLoader.<a href="./src/praisonai-agents/praisonaiagents/skills/loader.py">load_all_resources</a>(skill: LoadedSkill) -> None</code>
|
||||
* <code title="class SkillLoader">SkillLoader.<a href="./src/praisonai-agents/praisonaiagents/skills/loader.py">load_assets</a>(skill: LoadedSkill) -> dict</code>
|
||||
* <code title="class SkillLoader">SkillLoader.<a href="./src/praisonai-agents/praisonaiagents/skills/loader.py">load_metadata</a>(skill_path: str) -> Optional[LoadedSkill]</code>
|
||||
* <code title="class SkillLoader">SkillLoader.<a href="./src/praisonai-agents/praisonaiagents/skills/loader.py">load_references</a>(skill: LoadedSkill) -> dict</code>
|
||||
* <code title="class SkillLoader">SkillLoader.<a href="./src/praisonai-agents/praisonaiagents/skills/loader.py">load_scripts</a>(skill: LoadedSkill) -> dict</code>
|
||||
* <code title="class SkillManager">SkillManager.<a href="./src/praisonai-agents/praisonaiagents/skills/manager.py">activate</a>(skill: LoadedSkill) -> bool</code>
|
||||
* <code title="class SkillManager">SkillManager.<a href="./src/praisonai-agents/praisonaiagents/skills/manager.py">activate_by_name</a>(name: str) -> bool</code>
|
||||
* <code title="class SkillManager">SkillManager.<a href="./src/praisonai-agents/praisonaiagents/skills/manager.py">add_skill</a>(skill_path: str) -> Optional[LoadedSkill]</code>
|
||||
* <code title="class SkillManager">SkillManager.<a href="./src/praisonai-agents/praisonaiagents/skills/manager.py">clear</a>() -> None</code>
|
||||
* <code title="class SkillManager">SkillManager.<a href="./src/praisonai-agents/praisonaiagents/skills/manager.py">discover</a>(skill_dirs: Optional[List[str]] = None, include_defaults: bool = True) -> int</code>
|
||||
* <code title="class SkillManager">SkillManager.<a href="./src/praisonai-agents/praisonaiagents/skills/manager.py">get_available_skills</a>() -> List[SkillMetadata]</code>
|
||||
* <code title="class SkillManager">SkillManager.<a href="./src/praisonai-agents/praisonaiagents/skills/manager.py">get_instructions</a>(name: str) -> Optional[str]</code>
|
||||
* <code title="class SkillManager">SkillManager.<a href="./src/praisonai-agents/praisonaiagents/skills/manager.py">get_skill</a>(name: str) -> Optional[LoadedSkill]</code>
|
||||
* <code title="class SkillManager">SkillManager.<a href="./src/praisonai-agents/praisonaiagents/skills/manager.py">load_resources</a>(name: str) -> bool</code>
|
||||
* <code title="class SkillManager">SkillManager.<a href="./src/praisonai-agents/praisonaiagents/skills/manager.py">skill_names</a>() -> List[str]</code>
|
||||
* <code title="class SkillManager">SkillManager.<a href="./src/praisonai-agents/praisonaiagents/skills/manager.py">skills</a>() -> List[LoadedSkill]</code>
|
||||
* <code title="class SkillManager">SkillManager.<a href="./src/praisonai-agents/praisonaiagents/skills/manager.py">to_prompt</a>() -> str</code>
|
||||
* <code title="class SkillMetadata">SkillMetadata.<a href="./src/praisonai-agents/praisonaiagents/skills/models.py">from_properties</a>(props: SkillProperties) -> 'SkillMetadata'</code>
|
||||
* <code title="class SkillProperties">SkillProperties.<a href="./src/praisonai-agents/praisonaiagents/skills/models.py">to_dict</a>() -> dict</code>
|
||||
* <code title="class SkillsConfig">SkillsConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
|
||||
# Session
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import Session
|
||||
```
|
||||
|
||||
Methods:
|
||||
|
||||
* <code title="class Session">Session.<a href="./src/praisonai-agents/praisonaiagents/session/api.py">Agent</a>(name: str, role: str = 'Assistant', instructions: Optional[str] = None, tools: Optional[List[Any]] = None, memory: bool = True, knowledge: Optional[List[str]] = None, **kwargs) -> 'Agent'</code>
|
||||
* <code title="class Session">Session.<a href="./src/praisonai-agents/praisonaiagents/session/api.py">add_knowledge</a>(source: str) -> None</code>
|
||||
* <code title="class Session">Session.<a href="./src/praisonai-agents/praisonaiagents/session/api.py">add_memory</a>(text: str, memory_type: str = 'long', **metadata) -> None</code>
|
||||
* <code title="class Session">Session.<a href="./src/praisonai-agents/praisonaiagents/session/api.py">chat</a>(message: str, **kwargs) -> str</code>
|
||||
* <code title="class Session">Session.<a href="./src/praisonai-agents/praisonaiagents/session/api.py">clear_memory</a>(memory_type: str = 'all') -> None</code>
|
||||
* <code title="class Session">Session.<a href="./src/praisonai-agents/praisonaiagents/session/api.py">create_agent</a>(*args, **kwargs) -> 'Agent'</code>
|
||||
* <code title="class Session">Session.<a href="./src/praisonai-agents/praisonaiagents/session/api.py">get_context</a>(query: str, max_items: int = 3) -> str</code>
|
||||
* <code title="class Session">Session.<a href="./src/praisonai-agents/praisonaiagents/session/api.py">get_state</a>(key: str, default: Any = None) -> Any</code>
|
||||
* <code title="class Session">Session.<a href="./src/praisonai-agents/praisonaiagents/session/api.py">increment_state</a>(key: str, increment: int = 1, default: int = 0) -> None</code>
|
||||
* <code title="class Session">Session.<a href="./src/praisonai-agents/praisonaiagents/session/api.py">knowledge</a>() -> 'Knowledge'</code>
|
||||
* <code title="class Session">Session.<a href="./src/praisonai-agents/praisonaiagents/session/api.py">memory</a>() -> 'Memory'</code>
|
||||
* <code title="class Session">Session.<a href="./src/praisonai-agents/praisonaiagents/session/api.py">restore_state</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class Session">Session.<a href="./src/praisonai-agents/praisonaiagents/session/api.py">save_state</a>(state_data: Dict[str, Any]) -> None</code>
|
||||
* <code title="class Session">Session.<a href="./src/praisonai-agents/praisonaiagents/session/api.py">search_knowledge</a>(query: str, limit: int = 5) -> List[Dict[str, Any]]</code>
|
||||
* <code title="class Session">Session.<a href="./src/praisonai-agents/praisonaiagents/session/api.py">search_memory</a>(query: str, memory_type: str = 'long', limit: int = 5) -> List[Dict[str, Any]]</code>
|
||||
* <code title="class Session">Session.<a href="./src/praisonai-agents/praisonaiagents/session/api.py">send_message</a>(message: str, **kwargs) -> str</code>
|
||||
* <code title="class Session">Session.<a href="./src/praisonai-agents/praisonaiagents/session/api.py">set_state</a>(key: str, value: Any) -> None</code>
|
||||
|
||||
# MCP
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import MCP
|
||||
```
|
||||
|
||||
Methods:
|
||||
|
||||
* <code title="class MCP">MCP.<a href="./src/praisonai-agents/praisonaiagents/mcp/mcp.py">get_tools</a>() -> List[Callable]</code>
|
||||
* <code title="class MCP">MCP.<a href="./src/praisonai-agents/praisonaiagents/mcp/mcp.py">shutdown</a>()</code>
|
||||
* <code title="class MCP">MCP.<a href="./src/praisonai-agents/praisonaiagents/mcp/mcp.py">to_openai_tool</a>()</code>
|
||||
|
||||
# Telemetry
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import MinimalTelemetry, TelemetryCollector, cleanup_telemetry_resources, disable_performance_mode, disable_telemetry, enable_performance_mode, enable_telemetry, get_telemetry
|
||||
```
|
||||
|
||||
Methods:
|
||||
|
||||
* <code title="class MinimalTelemetry">MinimalTelemetry.<a href="./src/praisonai-agents/praisonaiagents/telemetry/telemetry.py">flush</a>()</code>
|
||||
* <code title="class MinimalTelemetry">MinimalTelemetry.<a href="./src/praisonai-agents/praisonaiagents/telemetry/telemetry.py">get_metrics</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class MinimalTelemetry">MinimalTelemetry.<a href="./src/praisonai-agents/praisonaiagents/telemetry/telemetry.py">shutdown</a>()</code>
|
||||
* <code title="class MinimalTelemetry">MinimalTelemetry.<a href="./src/praisonai-agents/praisonaiagents/telemetry/telemetry.py">track_agent_execution</a>(agent_name: str = None, success: bool = True, async_mode: bool = False)</code>
|
||||
* <code title="class MinimalTelemetry">MinimalTelemetry.<a href="./src/praisonai-agents/praisonaiagents/telemetry/telemetry.py">track_error</a>(error_type: str = None)</code>
|
||||
* <code title="class MinimalTelemetry">MinimalTelemetry.<a href="./src/praisonai-agents/praisonaiagents/telemetry/telemetry.py">track_feature_usage</a>(feature_name: str)</code>
|
||||
* <code title="class MinimalTelemetry">MinimalTelemetry.<a href="./src/praisonai-agents/praisonaiagents/telemetry/telemetry.py">track_task_completion</a>(task_name: str = None, success: bool = True)</code>
|
||||
* <code title="class MinimalTelemetry">MinimalTelemetry.<a href="./src/praisonai-agents/praisonaiagents/telemetry/telemetry.py">track_tool_usage</a>(tool_name: str, success: bool = True, execution_time: float = None)</code>
|
||||
* <code title="class TelemetryCollector">TelemetryCollector.<a href="./src/praisonai-agents/praisonaiagents/telemetry/telemetry.py">get_metrics</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class TelemetryCollector">TelemetryCollector.<a href="./src/praisonai-agents/praisonaiagents/telemetry/telemetry.py">record_cost</a>(cost: float, model: str = None)</code>
|
||||
* <code title="class TelemetryCollector">TelemetryCollector.<a href="./src/praisonai-agents/praisonaiagents/telemetry/telemetry.py">record_tokens</a>(prompt_tokens: int, completion_tokens: int, model: str = None)</code>
|
||||
* <code title="class TelemetryCollector">TelemetryCollector.<a href="./src/praisonai-agents/praisonaiagents/telemetry/telemetry.py">start</a>()</code>
|
||||
* <code title="class TelemetryCollector">TelemetryCollector.<a href="./src/praisonai-agents/praisonaiagents/telemetry/telemetry.py">stop</a>()</code>
|
||||
* <code title="class TelemetryCollector">TelemetryCollector.<a href="./src/praisonai-agents/praisonaiagents/telemetry/telemetry.py">trace_agent_execution</a>(agent_name: str, **attributes)</code>
|
||||
* <code title="class TelemetryCollector">TelemetryCollector.<a href="./src/praisonai-agents/praisonaiagents/telemetry/telemetry.py">trace_llm_call</a>(model: str = None, **attributes)</code>
|
||||
* <code title="class TelemetryCollector">TelemetryCollector.<a href="./src/praisonai-agents/praisonaiagents/telemetry/telemetry.py">trace_task_execution</a>(task_name: str, agent_name: str = None, **attributes)</code>
|
||||
* <code title="class TelemetryCollector">TelemetryCollector.<a href="./src/praisonai-agents/praisonaiagents/telemetry/telemetry.py">trace_tool_call</a>(tool_name: str, **attributes)</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/telemetry/__init__.py">cleanup_telemetry_resources</a>()</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/telemetry/__init__.py">disable_performance_mode</a>()</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/telemetry/__init__.py">disable_telemetry</a>()</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/telemetry/__init__.py">enable_performance_mode</a>()</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/telemetry/__init__.py">enable_telemetry</a>()</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/telemetry/__init__.py">get_telemetry</a>() -> 'MinimalTelemetry'</code>
|
||||
|
||||
# Observability
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import FlowDisplay, obs, track_workflow
|
||||
```
|
||||
|
||||
Methods:
|
||||
|
||||
* <code title="class FlowDisplay">FlowDisplay.<a href="./src/praisonai-agents/praisonaiagents/flow_display.py">display</a>()</code>
|
||||
* <code title="class FlowDisplay">FlowDisplay.<a href="./src/praisonai-agents/praisonaiagents/flow_display.py">start</a>()</code>
|
||||
* <code title="class FlowDisplay">FlowDisplay.<a href="./src/praisonai-agents/praisonaiagents/flow_display.py">stop</a>()</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/flow_display.py">track_workflow</a>()</code>
|
||||
|
||||
# Context
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import ContextManager, ManagerConfig
|
||||
```
|
||||
|
||||
Methods:
|
||||
|
||||
* <code title="class ContextManager">ContextManager.<a href="./src/praisonai-agents/praisonaiagents/context/manager.py">capture_llm_boundary</a>(messages: List[Dict[str, Any]], tools: List[Dict[str, Any]]) -> SnapshotHookData</code>
|
||||
* <code title="class ContextManager">ContextManager.<a href="./src/praisonai-agents/praisonaiagents/context/manager.py">emergency_truncate</a>(messages: List[Dict[str, Any]], target_tokens: int) -> List[Dict[str, Any]]</code>
|
||||
* <code title="class ContextManager">ContextManager.<a href="./src/praisonai-agents/praisonaiagents/context/manager.py">estimate_tokens</a>(text: str, validate: bool = False) -> Tuple[int, Optional[EstimationMetrics]]</code>
|
||||
* <code title="class ContextManager">ContextManager.<a href="./src/praisonai-agents/praisonaiagents/context/manager.py">get_history</a>() -> List[Dict[str, Any]]</code>
|
||||
* <code title="class ContextManager">ContextManager.<a href="./src/praisonai-agents/praisonaiagents/context/manager.py">get_last_snapshot_hook</a>() -> Optional[SnapshotHookData]</code>
|
||||
* <code title="class ContextManager">ContextManager.<a href="./src/praisonai-agents/praisonaiagents/context/manager.py">get_resolved_config</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class ContextManager">ContextManager.<a href="./src/praisonai-agents/praisonaiagents/context/manager.py">get_stats</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class ContextManager">ContextManager.<a href="./src/praisonai-agents/praisonaiagents/context/manager.py">get_tool_budget</a>(tool_name: str) -> int</code>
|
||||
* <code title="class ContextManager">ContextManager.<a href="./src/praisonai-agents/praisonaiagents/context/manager.py">process</a>(messages: List[Dict[str, Any]], system_prompt: str = '', tools: Optional[List[Dict[str, Any]]] = None, trigger: Literal['turn', 'tool_call', 'manual', 'overflow'] = 'turn') -> Dict[str, Any]</code>
|
||||
* <code title="class ContextManager">ContextManager.<a href="./src/praisonai-agents/praisonaiagents/context/manager.py">register_snapshot_callback</a>(callback: Callable[[SnapshotHookData], None]) -> None</code>
|
||||
* <code title="class ContextManager">ContextManager.<a href="./src/praisonai-agents/praisonaiagents/context/manager.py">reset</a>() -> None</code>
|
||||
* <code title="class ContextManager">ContextManager.<a href="./src/praisonai-agents/praisonaiagents/context/manager.py">set_tool_budget</a>(tool_name: str, max_tokens: int, protected: bool = False) -> None</code>
|
||||
* <code title="class ContextManager">ContextManager.<a href="./src/praisonai-agents/praisonaiagents/context/manager.py">truncate_tool_output</a>(tool_name: str, output: str) -> str</code>
|
||||
* <code title="class ManagerConfig">ManagerConfig.<a href="./src/praisonai-agents/praisonaiagents/context/manager.py">from_env</a>() -> 'ManagerConfig'</code>
|
||||
* <code title="class ManagerConfig">ManagerConfig.<a href="./src/praisonai-agents/praisonaiagents/context/manager.py">merge</a>(**overrides) -> 'ManagerConfig'</code>
|
||||
* <code title="class ManagerConfig">ManagerConfig.<a href="./src/praisonai-agents/praisonaiagents/context/manager.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
|
||||
# Config
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import AutonomyConfig, AutonomyLevel, CachingConfig, ExecutionConfig, ExecutionPreset, GuardrailConfig, HooksConfig, KnowledgeConfig, MemoryConfig, MultiAgentExecutionConfig, MultiAgentHooksConfig, MultiAgentMemoryConfig, MultiAgentOutputConfig, MultiAgentPlanningConfig, OutputConfig, OutputPreset, PlanningConfig, ReflectionConfig, SkillsConfig, TemplateConfig, WebConfig, WebSearchProvider
|
||||
```
|
||||
|
||||
Methods:
|
||||
|
||||
* <code title="class AutonomyConfig">AutonomyConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class CachingConfig">CachingConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class ExecutionConfig">ExecutionConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class GuardrailConfig">GuardrailConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class HooksConfig">HooksConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class KnowledgeConfig">KnowledgeConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class MemoryConfig">MemoryConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class MultiAgentExecutionConfig">MultiAgentExecutionConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class MultiAgentHooksConfig">MultiAgentHooksConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class MultiAgentMemoryConfig">MultiAgentMemoryConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class MultiAgentOutputConfig">MultiAgentOutputConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class MultiAgentPlanningConfig">MultiAgentPlanningConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class OutputConfig">OutputConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class PlanningConfig">PlanningConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class ReflectionConfig">ReflectionConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class SkillsConfig">SkillsConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class TemplateConfig">TemplateConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
* <code title="class WebConfig">WebConfig.<a href="./src/praisonai-agents/praisonaiagents/config/feature_configs.py">to_dict</a>() -> Dict[str, Any]</code>
|
||||
|
||||
# Display
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import async_display_callbacks, clean_triple_backticks, display_error, display_generating, display_instruction, display_interaction, display_self_reflection, display_tool_call, error_logs, register_display_callback, sync_display_callbacks
|
||||
```
|
||||
|
||||
Methods:
|
||||
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/main.py">clean_triple_backticks</a>(text: str) -> str</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/main.py">display_error</a>(message: str, console = None)</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/main.py">display_generating</a>(content: str = '', start_time: Optional[float] = None)</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/main.py">display_instruction</a>(message: str, console = None, agent_name: str = None, agent_role: str = None, agent_tools: List[str] = None)</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/main.py">display_interaction</a>(message, response, markdown = True, generation_time = None, console = None, agent_name = None, agent_role = None, agent_tools = None, task_name = None, task_description = None, task_id = None, metrics = None)</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/main.py">display_self_reflection</a>(message: str, console = None)</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/main.py">display_tool_call</a>(message: str, console = None, tool_name: str = None, tool_input: dict = None, tool_output: str = None, elapsed_time: float = None, success: bool = True)</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/main.py">register_display_callback</a>(display_type: str, callback_fn, is_async: bool = False)</code>
|
||||
|
||||
# Utilities
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import ArrayMode, is_policy_string, parse_policy_string, resolve, resolve_autonomy, resolve_caching, resolve_context, resolve_execution, resolve_guardrail_policies, resolve_guardrails, resolve_hooks, resolve_knowledge, resolve_memory, resolve_output, resolve_planning, resolve_reflection, resolve_routing, resolve_skills, resolve_web
|
||||
```
|
||||
|
||||
Methods:
|
||||
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/config/parse_utils.py">is_policy_string</a>(value: str) -> bool</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/config/parse_utils.py">parse_policy_string</a>(value: str) -> tuple</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/config/param_resolver.py">resolve</a>(value: Any, param_name: str, config_class: Optional[Type] = None, presets: Optional[Dict[str, Any]] = None, default: Any = None, instance_check: Optional[Callable[[Any], bool]] = None, url_schemes: Optional[Dict[str, str]] = None, array_mode: Optional[str] = None, string_mode: Optional[str] = None) -> Any</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/config/param_resolver.py">resolve_autonomy</a>(value: Any, config_class: Type) -> Any</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/config/param_resolver.py">resolve_caching</a>(value: Any, config_class: Type) -> Any</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/config/param_resolver.py">resolve_context</a>(value: Any, config_class: Type) -> Any</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/config/param_resolver.py">resolve_execution</a>(value: Any, config_class: Type) -> Any</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/config/param_resolver.py">resolve_guardrail_policies</a>(policies: list, config_class: Type) -> Any</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/config/param_resolver.py">resolve_guardrails</a>(value: Any, config_class: Type) -> Any</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/config/param_resolver.py">resolve_hooks</a>(value: Any, config_class: Optional[Type] = None) -> Any</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/config/param_resolver.py">resolve_knowledge</a>(value: Any, config_class: Type) -> Any</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/config/param_resolver.py">resolve_memory</a>(value: Any, config_class: Type) -> Any</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/config/param_resolver.py">resolve_output</a>(value: Any, config_class: Type) -> Any</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/config/param_resolver.py">resolve_planning</a>(value: Any, config_class: Type) -> Any</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/config/param_resolver.py">resolve_reflection</a>(value: Any, config_class: Type) -> Any</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/config/param_resolver.py">resolve_routing</a>(value: Any, config_class: Type) -> Any</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/config/param_resolver.py">resolve_skills</a>(value: Any, config_class: Type) -> Any</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/config/param_resolver.py">resolve_web</a>(value: Any, config_class: Type) -> Any</code>
|
||||
|
||||
# Other
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import Task
|
||||
from praisonaiagents import EmbeddingResult, Task, aembedding, aembeddings, embedding, embeddings, get_dimensions
|
||||
```
|
||||
|
||||
Methods:
|
||||
@@ -130,6 +743,11 @@ Methods:
|
||||
* <code title="class Task">Task.<a href="./src/praisonai-agents/praisonaiagents/task/task.py">execute_callback_sync</a>(task_output: TaskOutput) -> None</code>
|
||||
* <code title="class Task">Task.<a href="./src/praisonai-agents/praisonaiagents/task/task.py">initialize_memory</a>()</code>
|
||||
* <code title="class Task">Task.<a href="./src/praisonai-agents/praisonaiagents/task/task.py">store_in_memory</a>(content: str, agent_name: str = None, task_id: str = None)</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/embedding/embed.py">aembedding</a>(input: Union[str, List[str]], model: str = 'text-embedding-3-small', dimensions: Optional[int] = None, encoding_format: str = 'float', timeout: float = 600.0, api_key: Optional[str] = None, api_base: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None, **kwargs) -> EmbeddingResult</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/embedding/embed.py">aembeddings</a>(input: Union[str, List[str]], model: str = 'text-embedding-3-small', dimensions: Optional[int] = None, encoding_format: str = 'float', timeout: float = 600.0, api_key: Optional[str] = None, api_base: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None, **kwargs) -> EmbeddingResult</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/embedding/embed.py">embedding</a>(input: Union[str, List[str]], model: str = 'text-embedding-3-small', dimensions: Optional[int] = None, encoding_format: str = 'float', timeout: float = 600.0, api_key: Optional[str] = None, api_base: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None, **kwargs) -> EmbeddingResult</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/embedding/embed.py">embeddings</a>(input: Union[str, List[str]], model: str = 'text-embedding-3-small', dimensions: Optional[int] = None, encoding_format: str = 'float', timeout: float = 600.0, api_key: Optional[str] = None, api_base: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None, **kwargs) -> EmbeddingResult</code>
|
||||
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/embedding/dimensions.py">get_dimensions</a>(model_name: str) -> int</code>
|
||||
|
||||
# Wrapper (praisonai)
|
||||
|
||||
@@ -148,6 +766,10 @@ Methods:
|
||||
* <code title="cli">praisonai agents info <a href="./src/praisonai/praisonai/cli/commands/agents.py">--help</a></code>
|
||||
* <code title="cli">praisonai agents list <a href="./src/praisonai/praisonai/cli/commands/agents.py">--help</a></code>
|
||||
* <code title="cli">praisonai audit agent-centric <a href="./src/praisonai/praisonai/cli/commands/audit.py">--help</a></code>
|
||||
* <code title="cli">praisonai batch batch-run <a href="./src/praisonai/praisonai/cli/commands/batch.py">--help</a></code>
|
||||
* <code title="cli">praisonai batch list <a href="./src/praisonai/praisonai/cli/commands/batch.py">--help</a></code>
|
||||
* <code title="cli">praisonai batch report <a href="./src/praisonai/praisonai/cli/commands/batch.py">--help</a></code>
|
||||
* <code title="cli">praisonai batch stats <a href="./src/praisonai/praisonai/cli/commands/batch.py">--help</a></code>
|
||||
* <code title="cli">praisonai benchmark agent <a href="./src/praisonai/praisonai/cli/commands/benchmark.py">--help</a></code>
|
||||
* <code title="cli">praisonai benchmark benchmark-callback <a href="./src/praisonai/praisonai/cli/commands/benchmark.py">--help</a></code>
|
||||
* <code title="cli">praisonai benchmark cli <a href="./src/praisonai/praisonai/cli/commands/benchmark.py">--help</a></code>
|
||||
@@ -216,6 +838,8 @@ Methods:
|
||||
* <code title="cli">praisonai environment doctor <a href="./src/praisonai/praisonai/cli/commands/environment.py">--help</a></code>
|
||||
* <code title="cli">praisonai environment view <a href="./src/praisonai/praisonai/cli/commands/environment.py">--help</a></code>
|
||||
* <code title="cli">praisonai eval accuracy <a href="./src/praisonai/praisonai/cli/commands/eval.py">--help</a></code>
|
||||
* <code title="cli">praisonai eval judge <a href="./src/praisonai/praisonai/cli/commands/eval.py">--help</a></code>
|
||||
* <code title="cli">praisonai eval list-judges <a href="./src/praisonai/praisonai/cli/commands/eval.py">--help</a></code>
|
||||
* <code title="cli">praisonai eval performance <a href="./src/praisonai/praisonai/cli/commands/eval.py">--help</a></code>
|
||||
* <code title="cli">praisonai examples info <a href="./src/praisonai/praisonai/cli/commands/examples.py">--help</a></code>
|
||||
* <code title="cli">praisonai examples list <a href="./src/praisonai/praisonai/cli/commands/examples.py">--help</a></code>
|
||||
@@ -230,14 +854,18 @@ Methods:
|
||||
* <code title="cli">praisonai knowledge index <a href="./src/praisonai/praisonai/cli/commands/knowledge.py">--help</a></code>
|
||||
* <code title="cli">praisonai knowledge list <a href="./src/praisonai/praisonai/cli/commands/knowledge.py">--help</a></code>
|
||||
* <code title="cli">praisonai knowledge search <a href="./src/praisonai/praisonai/cli/commands/knowledge.py">--help</a></code>
|
||||
* <code title="cli">praisonai loop help <a href="./src/praisonai/praisonai/cli/commands/loop.py">--help</a></code>
|
||||
* <code title="cli">praisonai loop loop-main <a href="./src/praisonai/praisonai/cli/commands/loop.py">--help</a></code>
|
||||
* <code title="cli">praisonai lsp logs <a href="./src/praisonai/praisonai/cli/commands/lsp.py">--help</a></code>
|
||||
* <code title="cli">praisonai lsp lsp-callback <a href="./src/praisonai/praisonai/cli/commands/lsp.py">--help</a></code>
|
||||
* <code title="cli">praisonai lsp start <a href="./src/praisonai/praisonai/cli/commands/lsp.py">--help</a></code>
|
||||
* <code title="cli">praisonai lsp status <a href="./src/praisonai/praisonai/cli/commands/lsp.py">--help</a></code>
|
||||
* <code title="cli">praisonai lsp stop <a href="./src/praisonai/praisonai/cli/commands/lsp.py">--help</a></code>
|
||||
* <code title="cli">praisonai mcp add <a href="./src/praisonai/praisonai/cli/commands/mcp.py">--help</a></code>
|
||||
* <code title="cli">praisonai mcp auth <a href="./src/praisonai/praisonai/cli/commands/mcp.py">--help</a></code>
|
||||
* <code title="cli">praisonai mcp describe <a href="./src/praisonai/praisonai/cli/commands/mcp.py">--help</a></code>
|
||||
* <code title="cli">praisonai mcp list <a href="./src/praisonai/praisonai/cli/commands/mcp.py">--help</a></code>
|
||||
* <code title="cli">praisonai mcp logout <a href="./src/praisonai/praisonai/cli/commands/mcp.py">--help</a></code>
|
||||
* <code title="cli">praisonai mcp mcp-callback <a href="./src/praisonai/praisonai/cli/commands/mcp.py">--help</a></code>
|
||||
* <code title="cli">praisonai mcp remove <a href="./src/praisonai/praisonai/cli/commands/mcp.py">--help</a></code>
|
||||
* <code title="cli">praisonai mcp run <a href="./src/praisonai/praisonai/cli/commands/mcp.py">--help</a></code>
|
||||
@@ -266,11 +894,24 @@ Methods:
|
||||
* <code title="cli">praisonai rag query <a href="./src/praisonai/praisonai/cli/commands/rag.py">--help</a></code>
|
||||
* <code title="cli">praisonai rag serve <a href="./src/praisonai/praisonai/cli/commands/rag.py">--help</a></code>
|
||||
* <code title="cli">praisonai realtime realtime-main <a href="./src/praisonai/praisonai/cli/commands/realtime.py">--help</a></code>
|
||||
* <code title="cli">praisonai recipe apply <a href="./src/praisonai/praisonai/cli/commands/recipe.py">--help</a></code>
|
||||
* <code title="cli">praisonai recipe create <a href="./src/praisonai/praisonai/cli/commands/recipe.py">--help</a></code>
|
||||
* <code title="cli">praisonai recipe info <a href="./src/praisonai/praisonai/cli/commands/recipe.py">--help</a></code>
|
||||
* <code title="cli">praisonai recipe install <a href="./src/praisonai/praisonai/cli/commands/recipe.py">--help</a></code>
|
||||
* <code title="cli">praisonai recipe judge <a href="./src/praisonai/praisonai/cli/commands/recipe.py">--help</a></code>
|
||||
* <code title="cli">praisonai recipe list <a href="./src/praisonai/praisonai/cli/commands/recipe.py">--help</a></code>
|
||||
* <code title="cli">praisonai recipe optimize <a href="./src/praisonai/praisonai/cli/commands/recipe.py">--help</a></code>
|
||||
* <code title="cli">praisonai recipe run <a href="./src/praisonai/praisonai/cli/commands/recipe.py">--help</a></code>
|
||||
* <code title="cli">praisonai recipe serve <a href="./src/praisonai/praisonai/cli/commands/recipe.py">--help</a></code>
|
||||
* <code title="cli">praisonai registry list <a href="./src/praisonai/praisonai/cli/commands/registry.py">--help</a></code>
|
||||
* <code title="cli">praisonai registry serve <a href="./src/praisonai/praisonai/cli/commands/registry.py">--help</a></code>
|
||||
* <code title="cli">praisonai replay cleanup <a href="./src/praisonai/praisonai/cli/commands/replay.py">--help</a></code>
|
||||
* <code title="cli">praisonai replay context <a href="./src/praisonai/praisonai/cli/commands/replay.py">--help</a></code>
|
||||
* <code title="cli">praisonai replay dashboard <a href="./src/praisonai/praisonai/cli/commands/replay.py">--help</a></code>
|
||||
* <code title="cli">praisonai replay delete <a href="./src/praisonai/praisonai/cli/commands/replay.py">--help</a></code>
|
||||
* <code title="cli">praisonai replay flow <a href="./src/praisonai/praisonai/cli/commands/replay.py">--help</a></code>
|
||||
* <code title="cli">praisonai replay list <a href="./src/praisonai/praisonai/cli/commands/replay.py">--help</a></code>
|
||||
* <code title="cli">praisonai replay show <a href="./src/praisonai/praisonai/cli/commands/replay.py">--help</a></code>
|
||||
* <code title="cli">praisonai research research-main <a href="./src/praisonai/praisonai/cli/commands/research.py">--help</a></code>
|
||||
* <code title="cli">praisonai retrieval index <a href="./src/praisonai/praisonai/cli/commands/retrieval.py">--help</a></code>
|
||||
* <code title="cli">praisonai retrieval query <a href="./src/praisonai/praisonai/cli/commands/retrieval.py">--help</a></code>
|
||||
@@ -289,10 +930,24 @@ Methods:
|
||||
* <code title="cli">praisonai schedule start <a href="./src/praisonai/praisonai/cli/commands/schedule.py">--help</a></code>
|
||||
* <code title="cli">praisonai schedule stats <a href="./src/praisonai/praisonai/cli/commands/schedule.py">--help</a></code>
|
||||
* <code title="cli">praisonai schedule stop <a href="./src/praisonai/praisonai/cli/commands/schedule.py">--help</a></code>
|
||||
* <code title="cli">praisonai serve a2a <a href="./src/praisonai/praisonai/cli/commands/serve.py">--help</a></code>
|
||||
* <code title="cli">praisonai serve a2u <a href="./src/praisonai/praisonai/cli/commands/serve.py">--help</a></code>
|
||||
* <code title="cli">praisonai serve acp <a href="./src/praisonai/praisonai/cli/commands/serve.py">--help</a></code>
|
||||
* <code title="cli">praisonai serve agents <a href="./src/praisonai/praisonai/cli/commands/serve.py">--help</a></code>
|
||||
* <code title="cli">praisonai serve docs <a href="./src/praisonai/praisonai/cli/commands/serve.py">--help</a></code>
|
||||
* <code title="cli">praisonai serve gateway <a href="./src/praisonai/praisonai/cli/commands/serve.py">--help</a></code>
|
||||
* <code title="cli">praisonai serve lsp <a href="./src/praisonai/praisonai/cli/commands/serve.py">--help</a></code>
|
||||
* <code title="cli">praisonai serve mcp <a href="./src/praisonai/praisonai/cli/commands/serve.py">--help</a></code>
|
||||
* <code title="cli">praisonai serve rag <a href="./src/praisonai/praisonai/cli/commands/serve.py">--help</a></code>
|
||||
* <code title="cli">praisonai serve recipe <a href="./src/praisonai/praisonai/cli/commands/serve.py">--help</a></code>
|
||||
* <code title="cli">praisonai serve registry <a href="./src/praisonai/praisonai/cli/commands/serve.py">--help</a></code>
|
||||
* <code title="cli">praisonai serve scheduler <a href="./src/praisonai/praisonai/cli/commands/serve.py">--help</a></code>
|
||||
* <code title="cli">praisonai serve serve-callback <a href="./src/praisonai/praisonai/cli/commands/serve.py">--help</a></code>
|
||||
* <code title="cli">praisonai serve start <a href="./src/praisonai/praisonai/cli/commands/serve.py">--help</a></code>
|
||||
* <code title="cli">praisonai serve status <a href="./src/praisonai/praisonai/cli/commands/serve.py">--help</a></code>
|
||||
* <code title="cli">praisonai serve stop <a href="./src/praisonai/praisonai/cli/commands/serve.py">--help</a></code>
|
||||
* <code title="cli">praisonai serve ui <a href="./src/praisonai/praisonai/cli/commands/serve.py">--help</a></code>
|
||||
* <code title="cli">praisonai serve unified <a href="./src/praisonai/praisonai/cli/commands/serve.py">--help</a></code>
|
||||
* <code title="cli">praisonai session delete <a href="./src/praisonai/praisonai/cli/commands/session.py">--help</a></code>
|
||||
* <code title="cli">praisonai session export <a href="./src/praisonai/praisonai/cli/commands/session.py">--help</a></code>
|
||||
* <code title="cli">praisonai session import <a href="./src/praisonai/praisonai/cli/commands/session.py">--help</a></code>
|
||||
@@ -320,11 +975,16 @@ Methods:
|
||||
* <code title="cli">praisonai tools info <a href="./src/praisonai/praisonai/cli/commands/tools.py">--help</a></code>
|
||||
* <code title="cli">praisonai tools list <a href="./src/praisonai/praisonai/cli/commands/tools.py">--help</a></code>
|
||||
* <code title="cli">praisonai tools test <a href="./src/praisonai/praisonai/cli/commands/tools.py">--help</a></code>
|
||||
* <code title="cli">praisonai tools validate <a href="./src/praisonai/praisonai/cli/commands/tools.py">--help</a></code>
|
||||
* <code title="cli">praisonai traces disable <a href="./src/praisonai/praisonai/cli/commands/traces.py">--help</a></code>
|
||||
* <code title="cli">praisonai traces enable <a href="./src/praisonai/praisonai/cli/commands/traces.py">--help</a></code>
|
||||
* <code title="cli">praisonai traces list <a href="./src/praisonai/praisonai/cli/commands/traces.py">--help</a></code>
|
||||
* <code title="cli">praisonai traces status <a href="./src/praisonai/praisonai/cli/commands/traces.py">--help</a></code>
|
||||
* <code title="cli">praisonai train train-main <a href="./src/praisonai/praisonai/cli/commands/train.py">--help</a></code>
|
||||
* <code title="cli">praisonai train agents <a href="./src/praisonai/praisonai/cli/commands/train.py">--help</a></code>
|
||||
* <code title="cli">praisonai train list <a href="./src/praisonai/praisonai/cli/commands/train.py">--help</a></code>
|
||||
* <code title="cli">praisonai train llm <a href="./src/praisonai/praisonai/cli/commands/train.py">--help</a></code>
|
||||
* <code title="cli">praisonai train show <a href="./src/praisonai/praisonai/cli/commands/train.py">--help</a></code>
|
||||
* <code title="cli">praisonai train train-callback <a href="./src/praisonai/praisonai/cli/commands/train.py">--help</a></code>
|
||||
* <code title="cli">praisonai ui chat <a href="./src/praisonai/praisonai/cli/commands/ui.py">--help</a></code>
|
||||
* <code title="cli">praisonai ui code <a href="./src/praisonai/praisonai/cli/commands/ui.py">--help</a></code>
|
||||
* <code title="cli">praisonai ui gradio <a href="./src/praisonai/praisonai/cli/commands/ui.py">--help</a></code>
|
||||
@@ -343,6 +1003,8 @@ Types/Exports:
|
||||
```ts
|
||||
export { Agent, Agents, PraisonAIAgents, Router } from "./agent";
|
||||
export type { PraisonAIAgentsConfig, SimpleAgentConfig, SimpleRouteConfig, SimpleRouterConfig } from "./agent";
|
||||
export { AudioAgent, createAudioAgent } from "./agent/audio";
|
||||
export type { AudioAgentConfig, AudioProvider, AudioSpeakOptions, AudioSpeakResult, AudioTranscribeOptions, AudioTranscribeResult } from "./agent/audio";
|
||||
export { ContextAgent, createContextAgent } from "./agent/context";
|
||||
export { Handoff, handoff, handoffFilters } from "./agent/handoff";
|
||||
export { ImageAgent, createImageAgent } from "./agent/image";
|
||||
@@ -364,7 +1026,7 @@ export { // Agent loop
|
||||
configureTelemetry, // Tool Approval (AI SDK v6 parity)
|
||||
ApprovalManager, // Tools
|
||||
defineTool, // UI Message (AI SDK v6 parity)
|
||||
convertToModelMessages, AIAgentStep, AIEmbedManyResult, AIEmbedOptions, AIEmbedResult, AIFilePart, AIGenerateImageOptions, AIGenerateImageResult, AIGenerateObjectOptions, AIGenerateObjectResult, AIGenerateTextOptions, AIGenerateTextResult, AIImagePart, AIMiddleware, AIMiddlewareConfig, AIModelMessage, AISpan, AISpanKind, AISpanOptions, AISpanStatus, AIStreamObjectOptions, AIStreamObjectResult, AIStreamTextOptions, AIStreamTextResult, AITelemetryEvent, AITelemetrySettings, AITextPart, AIToolDefinition, AITracer, AgentLoop, DANGEROUS_PATTERNS, MODEL_ALIASES, SPEECH_MODELS, TRANSCRIPTION_MODELS, ToolApprovalDeniedError, ToolApprovalTimeoutError, aiEmbed, aiEmbedMany, aiGenerateImage, aiGenerateObject, aiGenerateText, aiStreamObject, aiStreamText, applyMiddleware, autoEnableDevTools, base64ToUint8Array, clearAICache, clearEvents, closeAllMCPClients, closeMCPClient, convertToUIMessages, createAILoggingMiddleware, createAISpan, createApprovalResponse, createDangerousPatternChecker, createDevToolsMiddleware, createExpressHandler, createFastifyHandler, createFilePart, createHonoHandler, createMultimodalMessage, createNestHandler, createPagesHandler, createPdfPart, createSystemMessage, createTelemetryMiddleware, createTelemetrySettings, createTextMessage, createTextPart, createToolSet, disableAITelemetry, disableDevTools, enableAITelemetry, functionToTool, getAICacheStats, getApprovalManager, getDevToolsState, getDevToolsUrl, getEvents, getMCPClient, getModel, getTelemetrySettings, getToolsNeedingApproval, getTracer, hasModelAlias, hasPendingApprovals, initOpenTelemetry, isDangerous, isDataUrl, isDevToolsEnabled, isTelemetryEnabled, isUrl, listModelAliases, mcpToolsToAITools, parseModel, pipeUIMessageStreamToResponse, recordEvent, resolveModelAlias, safeValidateUIMessages, setApprovalManager, stopAfterSteps, stopWhen, stopWhenNoToolCalls, toMessageContent, toUIMessageStreamResponse, transcribe, uint8ArrayToBase64, validateUIMessages, withApproval, withSpan, wrapModel } from "./ai";
|
||||
convertToModelMessages, AIAgentStep, AIEmbedManyResult, AIEmbedOptions, AIEmbedResult, AIFilePart, AIGenerateImageOptions, AIGenerateImageResult, AIGenerateObjectOptions, AIGenerateObjectResult, AIGenerateTextOptions, AIGenerateTextResult, AIImagePart, AIMiddleware, AIMiddlewareConfig, AIModelMessage, AISpan, AISpanKind, AISpanOptions, AISpanStatus, AIStreamObjectOptions, AIStreamObjectResult, AIStreamTextOptions, AIStreamTextResult, AITelemetryEvent, AITelemetrySettings, AITextPart, AIToolDefinition, AITracer, AgentLoop, DANGEROUS_PATTERNS, MCPClientType, MODEL_ALIASES, SPEECH_MODELS, TRANSCRIPTION_MODELS, ToolApprovalDeniedError, ToolApprovalTimeoutError, aiEmbed, aiEmbedMany, aiGenerateImage, aiGenerateObject, aiGenerateText, aiStreamObject, aiStreamText, applyMiddleware, autoEnableDevTools, base64ToUint8Array, clearAICache, clearEvents, closeAllMCPClients, closeMCPClient, convertToUIMessages, createAILoggingMiddleware, createAISpan, createApprovalResponse, createDangerousPatternChecker, createDevToolsMiddleware, createExpressHandler, createFastifyHandler, createFilePart, createHonoHandler, createMultimodalMessage, createNestHandler, createPagesHandler, createPdfPart, createSystemMessage, createTelemetryMiddleware, createTelemetrySettings, createTextMessage, createTextPart, createToolSet, disableAITelemetry, disableDevTools, enableAITelemetry, functionToTool, getAICacheStats, getApprovalManager, getDevToolsState, getDevToolsUrl, getEvents, getMCPClient, getModel, getTelemetrySettings, getToolsNeedingApproval, getTracer, hasModelAlias, hasPendingApprovals, initOpenTelemetry, isDangerous, isDataUrl, isDevToolsEnabled, isTelemetryEnabled, isUrl, listModelAliases, mcpToolsToAITools, parseModel, pipeUIMessageStreamToResponse, recordEvent, resolveModelAlias, safeValidateUIMessages, setApprovalManager, stopAfterSteps, stopWhen, stopWhenNoToolCalls, toMessageContent, toUIMessageStreamResponse, transcribe, uint8ArrayToBase64, validateUIMessages, withApproval, withSpan, wrapModel } from "./ai";
|
||||
export { AutoAgents, createAutoAgents } from "./auto";
|
||||
export { BaseCache, FileCache, MemoryCache, createFileCache, createMemoryCache } from "./cache";
|
||||
export { CLI_SPEC_VERSION, executeCommand, parseArgs } from "./cli";
|
||||
@@ -388,9 +1050,11 @@ export type { DbAdapter, DbConfig, DbMessage, DbRun, DbTrace } from "./db";
|
||||
export { MemoryPostgresAdapter, NeonPostgresAdapter, PostgresSessionStorage, createMemoryPostgres, createNeonPostgres, createPostgresSessionStorage } from "./db/postgres";
|
||||
export { MemoryRedisAdapter, UpstashRedisAdapter, createMemoryRedis, createUpstashRedis } from "./db/redis";
|
||||
export { SQLiteAdapter, createSQLiteAdapter } from "./db/sqlite";
|
||||
export { EvalSuite, accuracyEval, performanceEval, reliabilityEval } from "./eval";
|
||||
export { // LLM-as-Judge
|
||||
Judge, AccuracyJudge, CriteriaJudge, EvalResults, EvalSuite, Evaluator, RecipeJudge, accuracyEval, addJudge, addOptimizationRule, containsKeywordsCriterion, createDefaultEvaluator, createEvalResults, createEvaluator, getJudge, getOptimizationRule, lengthCriterion, listJudges, listOptimizationRules, noHarmfulContentCriterion, parseJudgeResponse, performanceEval, relevanceCriterion, reliabilityEval, removeJudge, removeOptimizationRule } from "./eval";
|
||||
export { AgentEventBus, AgentEvents, EventEmitterPubSub, PubSub, createEventBus, createPubSub } from "./events";
|
||||
export { LLMGuardrail, createLLMGuardrail } from "./guardrails/llm-guardrail";
|
||||
export { DisplayTypes, HooksManager, WorkflowHooksExecutor, clearAllCallbacks, clearApprovalCallback, createHooksManager, createLoggingOperationHooks, createLoggingWorkflowHooks, createTimingWorkflowHooks, createValidationOperationHooks, createWorkflowHooks, executeCallback, executeSyncCallback, getRegisteredDisplayTypes, hasApprovalCallback, registerApprovalCallback, registerDisplayCallback, requestApproval, unregisterDisplayCallback } from "./hooks";
|
||||
export { // Computer Use
|
||||
createComputerUse, ComputerUseClient, createCLIApprovalPrompt, createComputerUseAgent } from "./integrations/computer-use";
|
||||
export { BaseObservabilityProvider, ConsoleObservabilityProvider, LangfuseObservabilityProvider, MemoryObservabilityProvider, ObservabilityTraceContext, createConsoleObservability, createLangfuseObservability, createMemoryObservability } from "./integrations/observability";
|
||||
@@ -408,10 +1072,14 @@ export { // Provider classes
|
||||
ProviderRegistry, // Types
|
||||
type LLMProvider, AnthropicProvider, BaseProvider, GoogleProvider, ProviderMessage, ProviderToolDefinition, createProviderRegistry, getAvailableProviders, getDefaultProvider, getDefaultRegistry, hasProvider, isProviderAvailable, listProviders, parseModelString, registerBuiltinProviders, registerProvider, unregisterProvider } from "./llm/providers";
|
||||
export { ADAPTERS, AISDK_PROVIDERS, COMMUNITY_PROVIDERS, PROVIDER_ALIASES } from "./llm/providers/ai-sdk/types";
|
||||
export { MCPClient, MCPSecurity, MCPServer, MCPSessionManager, createApiKeyPolicy, createMCPClient, createMCPSecurity, createMCPServer, createMCPSession, createRateLimitPolicy, getMCPTools } from "./mcp";
|
||||
export { AutoMemory, AutoMemoryKnowledgeBase, AutoMemoryVectorStore, DEFAULT_POLICIES, createAutoMemory, createLLMSummarizer } from "./memory/auto-memory";
|
||||
export { DocsManager, createDocsManager } from "./memory/docs-manager";
|
||||
export { FileMemory, createFileMemory } from "./memory/file-memory";
|
||||
export { MemoryHooks, createEncryptionHooks, createLoggingHooks, createMemoryHooks, createValidationHooks } from "./memory/hooks";
|
||||
export { Memory, createMemory } from "./memory/memory";
|
||||
export type { MemoryConfig, MemoryEntry } from "./memory/memory";
|
||||
export { RulesManager, createRulesManager, createSafetyRules } from "./memory/rules-manager";
|
||||
export { // Adapters
|
||||
NoopObservabilityAdapter, // Constants
|
||||
OBSERVABILITY_TOOLS, // Global adapter management
|
||||
@@ -419,14 +1087,17 @@ export { // Adapters
|
||||
type SpanKind, ConsoleObservabilityAdapter, MemoryObservabilityAdapter, clearAdapterCache, createConsoleAdapter, createMemoryAdapter, createObservabilityAdapter, getObservabilityAdapter, getObservabilityToolInfo, hasObservabilityToolEnvVar, listObservabilityTools, noopAdapter, resetObservabilityAdapter, trace } from "./observability";
|
||||
export { Plan, PlanStep, PlanStorage, PlanningAgent, TaskAgent, TodoItem, TodoList, createPlan, createPlanStorage, createPlanningAgent, createTaskAgent, createTodoList } from "./planning";
|
||||
export { SkillManager, createSkillManager, parseSkillFile } from "./skills";
|
||||
export { AgentTelemetry, TelemetryCollector, cleanupTelemetry, createAgentTelemetry, disableTelemetry, enableTelemetry, getTelemetry } from "./telemetry";
|
||||
export { BaseTool, FunctionTool, ToolRegistry, ToolResult, ToolValidationError, createTool, getRegistry, getTool, registerTool, tool, validateTool } from "./tools";
|
||||
export { AgentTelemetry, PerformanceMonitor, TelemetryCollector, TelemetryIntegration, cleanupTelemetry, createAgentTelemetry, createConsoleSink, createHTTPSink, createPerformanceMonitor, createTelemetryIntegration, disableTelemetry, enableTelemetry, getTelemetry } from "./telemetry";
|
||||
export { // Subagent Tool (agent-as-tool pattern)
|
||||
SubagentTool, BaseTool, FunctionTool, ToolRegistry, ToolResult, ToolValidationError, createDelegator, createSubagentTool, createSubagentTools, createTool, getRegistry, getTool, registerTool, tool, validateTool } from "./tools";
|
||||
export { airweaveSearch, bedrockBrowserClick, bedrockBrowserFill, bedrockBrowserNavigate, bedrockCodeInterpreter, codeExecution, codeMode, createCustomTool, exaSearch, firecrawlCrawl, firecrawlScrape, parallelSearch, perplexitySearch, registerCustomTool, registerLocalTool, registerNpmTool, superagentGuard, superagentRedact, superagentVerify, tavilyCrawl, tavilyExtract, tavilySearch, valyuBioSearch, valyuCompanyResearch, valyuEconomicsSearch, valyuFinanceSearch, valyuPaperSearch, valyuPatentSearch, valyuSecSearch, valyuWebSearch } from "./tools/builtins";
|
||||
export { MissingDependencyError, MissingEnvVarError, ToolsRegistry, composeMiddleware, createLoggingMiddleware, createRateLimitMiddleware, createRedactionMiddleware, createRetryMiddleware, createTimeoutMiddleware, createToolsRegistry, createTracingMiddleware, createValidationMiddleware, getToolsRegistry, resetToolsRegistry } from "./tools/registry";
|
||||
export type { InstallHints, PraisonTool, RedactionHooks, RegisteredTool, ToolCapabilities, ToolExecutionContext, ToolExecutionResult, ToolFactory, ToolHooks, ToolInstallStatus, ToolLimits, ToolLogger, ToolMetadata, ToolMiddleware, ToolParameterProperty, ToolParameterSchema } from "./tools/registry";
|
||||
export { registerBuiltinTools, tools } from "./tools/tools";
|
||||
export { Workflow, loop, parallel, repeat, route } from "./workflows";
|
||||
export type { StepResult, WorkflowContext, WorkflowStep } from "./workflows";
|
||||
export { // New: Python-parity Loop and Repeat classes
|
||||
Loop, // WorkflowStep class
|
||||
WorkflowStep, Repeat, Workflow, loop, loopPattern, parallel, repeat, repeatPattern, route } from "./workflows";
|
||||
export type { LoopConfig, LoopResult, RepeatConfig, RepeatContext, RepeatResult, StepContextConfig, StepExecutionConfig, StepOutputConfig, StepResult, StepRoutingConfig, WorkflowContext, WorkflowStepConfig } from "./workflows";
|
||||
export { createWorkflowFromYAML, loadWorkflowFromFile, parseYAMLWorkflow, validateWorkflowDefinition } from "./workflows/yaml-parser";
|
||||
```
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
|
||||
# Install Python packages (using latest versions)
|
||||
RUN pip install --no-cache-dir \
|
||||
praisonai_tools \
|
||||
"praisonai>=3.9.2" \
|
||||
"praisonai>=3.11.2" \
|
||||
"praisonai[chat]" \
|
||||
"embedchain[github,youtube]"
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ RUN mkdir -p /root/.praison
|
||||
# Install Python packages (using latest versions)
|
||||
RUN pip install --no-cache-dir \
|
||||
praisonai_tools \
|
||||
"praisonai>=3.9.2" \
|
||||
"praisonai>=3.11.2" \
|
||||
"praisonai[ui]" \
|
||||
"praisonai[chat]" \
|
||||
"praisonai[realtime]" \
|
||||
|
||||
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
|
||||
# Install Python packages (using latest versions)
|
||||
RUN pip install --no-cache-dir \
|
||||
praisonai_tools \
|
||||
"praisonai>=3.9.2" \
|
||||
"praisonai>=3.11.2" \
|
||||
"praisonai[ui]" \
|
||||
"praisonai[crewai]"
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ def run_quick_comparison():
|
||||
prompt="What is 2+2?",
|
||||
iterations=2,
|
||||
paths=["openai_sdk", "praisonai_agent"],
|
||||
verbose=True
|
||||
output="verbose"
|
||||
)
|
||||
|
||||
# Print comparison table
|
||||
@@ -56,7 +56,7 @@ def run_full_benchmark():
|
||||
report = handler.run_full_benchmark(
|
||||
prompt="Hi",
|
||||
iterations=3,
|
||||
verbose=True
|
||||
output="verbose"
|
||||
)
|
||||
|
||||
# Print full report
|
||||
@@ -78,7 +78,7 @@ def run_agent_benchmark():
|
||||
prompt="Explain Python in one sentence",
|
||||
iterations=3,
|
||||
paths=["openai_sdk", "praisonai_agent"],
|
||||
verbose=True
|
||||
output="verbose"
|
||||
)
|
||||
|
||||
# Show timeline diagrams
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
Embeddings Capability Example
|
||||
|
||||
Demonstrates text embedding generation using PraisonAI capabilities.
|
||||
Both `embed` and `embedding` work identically - use whichever you prefer.
|
||||
"""
|
||||
|
||||
from praisonai.capabilities import embed
|
||||
from praisonai import embed, embedding # Both work from top-level
|
||||
# Or: from praisonai.capabilities import embed, embedding
|
||||
|
||||
# Single text embedding
|
||||
print("=== Single Text Embedding ===")
|
||||
# Single text embedding using embed()
|
||||
print("=== Single Text Embedding (using embed) ===")
|
||||
result = embed(
|
||||
input="Hello, world!",
|
||||
model="text-embedding-3-small"
|
||||
@@ -16,6 +18,14 @@ print(f"Embedding dimensions: {len(result.embeddings[0])}")
|
||||
print(f"First 5 values: {result.embeddings[0][:5]}")
|
||||
print(f"Usage: {result.usage}")
|
||||
|
||||
# Same thing using embedding() alias
|
||||
print("\n=== Single Text Embedding (using embedding alias) ===")
|
||||
result = embedding(
|
||||
input="Hello, world!",
|
||||
model="text-embedding-3-small"
|
||||
)
|
||||
print(f"Embedding dimensions: {len(result.embeddings[0])}")
|
||||
|
||||
# Multiple text embeddings
|
||||
print("\n=== Multiple Text Embeddings ===")
|
||||
result = embed(
|
||||
@@ -25,3 +35,12 @@ result = embed(
|
||||
print(f"Number of embeddings: {len(result.embeddings)}")
|
||||
for i, emb in enumerate(result.embeddings):
|
||||
print(f" Text {i+1}: {len(emb)} dimensions")
|
||||
|
||||
# With custom dimensions (for models that support it)
|
||||
print("\n=== Custom Dimensions ===")
|
||||
result = embed(
|
||||
input="Hello world",
|
||||
model="text-embedding-3-large",
|
||||
dimensions=256
|
||||
)
|
||||
print(f"Reduced dimensions: {len(result.embeddings[0])}")
|
||||
@@ -22,7 +22,7 @@ custom_modes = {
|
||||
}
|
||||
|
||||
# Create handler with verbose output
|
||||
handler = CompareHandler(verbose=True)
|
||||
handler = CompareHandler(output="verbose")
|
||||
|
||||
# Example: Manually create comparison results for analysis
|
||||
# (useful for testing without API calls)
|
||||
|
||||
@@ -22,7 +22,7 @@ modes = parse_modes("basic,tools,planning")
|
||||
print(f"\nParsed modes: {modes}")
|
||||
|
||||
# Create compare handler
|
||||
handler = CompareHandler(verbose=True)
|
||||
handler = CompareHandler(output="verbose")
|
||||
|
||||
# Compare modes (this will run actual agent calls)
|
||||
# Uncomment to run:
|
||||
|
||||
File renamed without changes.
@@ -32,7 +32,7 @@ workflow = Workflow(
|
||||
),
|
||||
],
|
||||
# Workflow-level consolidated params
|
||||
output=WorkflowOutputConfig(verbose=True, stream=True),
|
||||
output=WorkflowOutputConfig(output="verbose", stream=True),
|
||||
planning=WorkflowPlanningConfig(enabled=True, reasoning=True),
|
||||
memory=WorkflowMemoryConfig(backend="file"),
|
||||
# Agent-like params
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
"""
|
||||
Basic Memory Example - Agent-Centric API
|
||||
|
||||
Demonstrates the simplest memory usage with consolidated params.
|
||||
"""
|
||||
|
||||
"""Basic memory example - minimal usage."""
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Basic: Enable memory with preset
|
||||
# Simple enable (uses default file-based memory)
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant with memory.",
|
||||
memory="sqlite", # Preset: sqlite, redis, postgres, file
|
||||
memory=True,
|
||||
)
|
||||
|
||||
# Run a simple task
|
||||
response = agent.start("Remember that my favorite color is blue.")
|
||||
print(response)
|
||||
# With preset
|
||||
agent_redis = Agent(
|
||||
instructions="You are a helpful assistant.",
|
||||
memory="redis", # Uses redis preset
|
||||
)
|
||||
|
||||
# Follow-up to test memory
|
||||
response = agent.start("What is my favorite color?")
|
||||
print(response)
|
||||
# With URL
|
||||
agent_postgres = Agent(
|
||||
instructions="You are a helpful assistant.",
|
||||
memory="postgresql://localhost/mydb", # URL auto-detected
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
response = agent.chat("Remember that my favorite color is blue.")
|
||||
print(response)
|
||||
File renamed without changes.
@@ -1,26 +1,22 @@
|
||||
"""
|
||||
Basic Workflow Example - Agent-Centric API
|
||||
|
||||
Demonstrates minimal workflow with consolidated params.
|
||||
"""
|
||||
|
||||
"""Basic workflow example with consolidated params."""
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.workflows import Workflow, WorkflowStep
|
||||
|
||||
# Create a simple workflow
|
||||
# Create agents
|
||||
writer = Agent(instructions="You are a content writer.")
|
||||
editor = Agent(instructions="You are an editor.")
|
||||
|
||||
# Create workflow with consolidated params
|
||||
workflow = Workflow(
|
||||
name="simple_workflow",
|
||||
output="verbose", # Workflow-level output preset
|
||||
name="Content Pipeline",
|
||||
steps=[
|
||||
WorkflowStep(name="write", agent=writer, action="Write about {{topic}}"),
|
||||
WorkflowStep(name="edit", agent=editor, action="Edit the content", context=["write"]),
|
||||
],
|
||||
output="verbose",
|
||||
planning=True,
|
||||
)
|
||||
|
||||
# Add a step
|
||||
step = WorkflowStep(
|
||||
name="writer",
|
||||
action="Write a haiku about programming",
|
||||
agent=Agent(instructions="You are a creative poet."),
|
||||
output="result.txt", # Save output to file
|
||||
)
|
||||
|
||||
# Note: This is a structural example - actual execution requires workflow.run()
|
||||
print("Workflow created with output preset:", workflow.output)
|
||||
print("Step output file:", step.output_file)
|
||||
if __name__ == "__main__":
|
||||
result = workflow.run(variables={"topic": "AI agents"})
|
||||
print(result)
|
||||
@@ -0,0 +1,59 @@
|
||||
"""
|
||||
Basic Context Management Example
|
||||
|
||||
Demonstrates enabling context management with ContextConfig.
|
||||
This manages token budgets, auto-compaction, and prevents context overflow.
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.context import ContextConfig, OptimizerStrategy
|
||||
|
||||
# Example 1: Enable context with defaults
|
||||
agent_basic = Agent(
|
||||
name="Assistant",
|
||||
instructions="You are a helpful assistant",
|
||||
context=True # Auto-compact at 80% utilization
|
||||
)
|
||||
|
||||
# Example 2: Custom configuration
|
||||
agent_custom = Agent(
|
||||
name="CustomAgent",
|
||||
instructions="You are a helpful assistant with custom context settings",
|
||||
context=ContextConfig(
|
||||
auto_compact=True,
|
||||
compact_threshold=0.8, # Trigger at 80% utilization
|
||||
strategy=OptimizerStrategy.SMART,
|
||||
output_reserve=8000, # Reserve tokens for output
|
||||
keep_recent_turns=5, # Always keep last 5 turns
|
||||
tool_output_max=10000, # Max tokens per tool output
|
||||
)
|
||||
)
|
||||
|
||||
# Example 3: Sliding window strategy
|
||||
agent_sliding = Agent(
|
||||
name="SlidingAgent",
|
||||
instructions="You are a helpful assistant using sliding window",
|
||||
context=ContextConfig(
|
||||
strategy=OptimizerStrategy.SLIDING_WINDOW,
|
||||
keep_recent_turns=10, # Keep last 10 turns
|
||||
)
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=== Basic Context Example ===")
|
||||
print("Context management is automatically enabled.")
|
||||
print()
|
||||
|
||||
# Test basic agent
|
||||
result = agent_basic.chat("Hello! What is 2 + 2?")
|
||||
print(f"Response: {result}")
|
||||
print()
|
||||
|
||||
# Show context config
|
||||
print("=== Context Configuration ===")
|
||||
config = ContextConfig(
|
||||
auto_compact=True,
|
||||
compact_threshold=0.8,
|
||||
strategy=OptimizerStrategy.SMART,
|
||||
)
|
||||
print(f"Config: {config.to_dict()}")
|
||||
@@ -0,0 +1,71 @@
|
||||
"""
|
||||
Session Tracking Example
|
||||
|
||||
Demonstrates tracking conversation state (goal, plan, progress) across turns.
|
||||
Inspired by Agno's SessionContextStore pattern.
|
||||
"""
|
||||
|
||||
from praisonaiagents.context import SessionContextTracker
|
||||
|
||||
# Create session tracker
|
||||
tracker = SessionContextTracker(
|
||||
session_id="user123",
|
||||
track_summary=True,
|
||||
track_goal=True,
|
||||
track_plan=True,
|
||||
track_progress=True,
|
||||
)
|
||||
|
||||
# Set the user's goal
|
||||
tracker.update_goal("Build a Python web application with Flask")
|
||||
|
||||
# Define the plan
|
||||
tracker.update_plan([
|
||||
"Create Flask project structure",
|
||||
"Add routes for API endpoints",
|
||||
"Implement database models",
|
||||
"Add authentication",
|
||||
"Write tests",
|
||||
"Deploy to cloud"
|
||||
])
|
||||
|
||||
# Mark completed steps
|
||||
tracker.add_progress("Created Flask project structure")
|
||||
tracker.add_progress("Added routes for API endpoints")
|
||||
|
||||
# Update summary
|
||||
tracker.update_summary(
|
||||
"User is building a Flask web app. Completed project setup and API routes. "
|
||||
"Next: implement database models."
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=== Session Tracking Example ===")
|
||||
print()
|
||||
|
||||
# Show current state
|
||||
print(f"Session ID: {tracker.session_id}")
|
||||
print(f"Goal: {tracker.goal}")
|
||||
print(f"Plan: {tracker.plan}")
|
||||
print(f"Progress: {tracker.progress}")
|
||||
print()
|
||||
|
||||
# Get context string (simple format)
|
||||
print("=== Context String ===")
|
||||
print(tracker.to_context_string())
|
||||
print()
|
||||
|
||||
# Get system prompt section (XML format with guidelines)
|
||||
print("=== System Prompt Section ===")
|
||||
print(tracker.to_system_prompt_section())
|
||||
print()
|
||||
|
||||
# Export to dict for persistence
|
||||
print("=== Export as Dict ===")
|
||||
data = tracker.to_dict()
|
||||
print(f"Exported: {data.keys()}")
|
||||
print()
|
||||
|
||||
# Recreate from dict
|
||||
new_tracker = SessionContextTracker.from_dict(data)
|
||||
print(f"Restored goal: {new_tracker.goal}")
|
||||
@@ -0,0 +1,81 @@
|
||||
"""
|
||||
Multi-Memory Aggregation Example
|
||||
|
||||
Demonstrates concurrent fetching from multiple context sources.
|
||||
Inspired by CrewAI's ContextualMemory pattern.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
from praisonaiagents.context import ContextAggregator, create_aggregator_from_config
|
||||
|
||||
# Example 1: Basic aggregator with mock sources
|
||||
def mock_memory_search(query: str) -> str:
|
||||
"""Mock memory search - returns recent conversation context."""
|
||||
return f"[Memory] User previously asked about: {query}. They prefer Python."
|
||||
|
||||
def mock_knowledge_search(query: str) -> str:
|
||||
"""Mock knowledge search - returns facts from knowledge base."""
|
||||
return f"[Knowledge] Relevant facts: Python is a high-level programming language."
|
||||
|
||||
def mock_rag_retrieve(query: str) -> str:
|
||||
"""Mock RAG retrieval - returns document chunks."""
|
||||
return f"[RAG] Retrieved: Documentation about {query} from the codebase."
|
||||
|
||||
# Create aggregator
|
||||
aggregator = ContextAggregator(
|
||||
max_tokens=4000,
|
||||
separator="\n\n---\n\n",
|
||||
include_source_labels=True
|
||||
)
|
||||
|
||||
# Register sources with priorities (lower = higher priority)
|
||||
aggregator.register_source("memory", mock_memory_search, priority=10)
|
||||
aggregator.register_source("knowledge", mock_knowledge_search, priority=20)
|
||||
aggregator.register_source("rag", mock_rag_retrieve, priority=30)
|
||||
|
||||
async def demo_async():
|
||||
"""Demo async aggregation."""
|
||||
print("=== Async Aggregation ===")
|
||||
result = await aggregator.aggregate("Python web development")
|
||||
print(f"Sources used: {result.sources_used}")
|
||||
print(f"Tokens used: {result.tokens_used}")
|
||||
print(f"Fetch times: {result.fetch_times}")
|
||||
print()
|
||||
print("Context:")
|
||||
print(result.context)
|
||||
return result
|
||||
|
||||
def demo_sync():
|
||||
"""Demo sync aggregation."""
|
||||
print("=== Sync Aggregation ===")
|
||||
result = aggregator.aggregate_sync("Flask API development")
|
||||
print(f"Sources used: {result.sources_used}")
|
||||
print(f"Tokens used: {result.tokens_used}")
|
||||
print()
|
||||
print("Context:")
|
||||
print(result.context)
|
||||
return result
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=== Multi-Memory Aggregation Example ===")
|
||||
print()
|
||||
|
||||
# Show registered sources
|
||||
print(f"Registered sources: {aggregator.sources}")
|
||||
print()
|
||||
|
||||
# Demo sync aggregation
|
||||
demo_sync()
|
||||
print()
|
||||
|
||||
# Demo async aggregation
|
||||
asyncio.run(demo_async())
|
||||
print()
|
||||
|
||||
# Demo selective sources
|
||||
print("=== Selective Sources ===")
|
||||
result = aggregator.aggregate_sync(
|
||||
"Find database info",
|
||||
sources=["memory", "knowledge"] # Only use these
|
||||
)
|
||||
print(f"Sources used: {result.sources_used}")
|
||||
@@ -37,7 +37,7 @@ def main():
|
||||
name="CodeAssistant",
|
||||
instructions="You are a helpful code assistant.",
|
||||
context=config,
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
print(f" Agent name: {agent.name}")
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
"""
|
||||
Compaction Strategies Example
|
||||
|
||||
Demonstrates different context compaction strategies.
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.context import ContextConfig, OptimizerStrategy
|
||||
|
||||
# Strategy 1: TRUNCATE - Fast, removes oldest messages
|
||||
agent_truncate = Agent(
|
||||
name="TruncateAgent",
|
||||
instructions="You are a helpful assistant",
|
||||
context=ContextConfig(
|
||||
strategy=OptimizerStrategy.TRUNCATE,
|
||||
compact_threshold=0.8,
|
||||
)
|
||||
)
|
||||
|
||||
# Strategy 2: SLIDING_WINDOW - Keeps recent N turns
|
||||
agent_sliding = Agent(
|
||||
name="SlidingAgent",
|
||||
instructions="You are a helpful assistant",
|
||||
context=ContextConfig(
|
||||
strategy=OptimizerStrategy.SLIDING_WINDOW,
|
||||
keep_recent_turns=10,
|
||||
)
|
||||
)
|
||||
|
||||
# Strategy 3: SMART - Importance-based (default)
|
||||
agent_smart = Agent(
|
||||
name="SmartAgent",
|
||||
instructions="You are a helpful assistant",
|
||||
context=ContextConfig(
|
||||
strategy=OptimizerStrategy.SMART, # Default
|
||||
compact_threshold=0.8,
|
||||
)
|
||||
)
|
||||
|
||||
# Strategy 4: PRUNE_TOOLS - Truncate old tool outputs
|
||||
agent_prune = Agent(
|
||||
name="PruneAgent",
|
||||
instructions="You are a helpful assistant with tools",
|
||||
context=ContextConfig(
|
||||
strategy=OptimizerStrategy.PRUNE_TOOLS,
|
||||
tool_output_max=5000, # Max tokens per tool output
|
||||
)
|
||||
)
|
||||
|
||||
# Strategy 5: NON_DESTRUCTIVE - Only prune tools, keep all history
|
||||
agent_safe = Agent(
|
||||
name="SafeAgent",
|
||||
instructions="You are a helpful assistant (safety-critical)",
|
||||
context=ContextConfig(
|
||||
strategy=OptimizerStrategy.NON_DESTRUCTIVE,
|
||||
)
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=== Compaction Strategies Example ===")
|
||||
print()
|
||||
|
||||
strategies = [
|
||||
("TRUNCATE", OptimizerStrategy.TRUNCATE, "Remove oldest messages"),
|
||||
("SLIDING_WINDOW", OptimizerStrategy.SLIDING_WINDOW, "Keep last N turns"),
|
||||
("SMART", OptimizerStrategy.SMART, "Importance-based (default)"),
|
||||
("PRUNE_TOOLS", OptimizerStrategy.PRUNE_TOOLS, "Truncate tool outputs"),
|
||||
("NON_DESTRUCTIVE", OptimizerStrategy.NON_DESTRUCTIVE, "Only prune tools"),
|
||||
]
|
||||
|
||||
for name, strategy, description in strategies:
|
||||
print(f" {name:20} - {description}")
|
||||
|
||||
print()
|
||||
print("Usage:")
|
||||
print(" context=ContextConfig(strategy=OptimizerStrategy.SLIDING_WINDOW)")
|
||||
@@ -0,0 +1,85 @@
|
||||
"""
|
||||
Context Monitoring Example
|
||||
|
||||
Demonstrates monitoring context usage with logging and metrics.
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.context import ContextConfig, MonitorConfig, OptimizerStrategy
|
||||
|
||||
# Example 1: Human-readable monitoring
|
||||
agent_human = Agent(
|
||||
name="MonitoredAgent",
|
||||
instructions="You are a helpful assistant",
|
||||
context=ContextConfig(
|
||||
auto_compact=True,
|
||||
monitor=MonitorConfig(
|
||||
enabled=True,
|
||||
path="./context_logs/",
|
||||
format="human", # Human-readable format
|
||||
frequency="turn", # Log on every turn
|
||||
redact_sensitive=True, # Redact sensitive data
|
||||
multi_agent_files=True, # Separate files per agent
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
# Example 2: JSON monitoring (for parsing)
|
||||
agent_json = Agent(
|
||||
name="JSONMonitorAgent",
|
||||
instructions="You are a helpful assistant",
|
||||
context=ContextConfig(
|
||||
monitor=MonitorConfig(
|
||||
enabled=True,
|
||||
path="./context_logs/",
|
||||
format="json", # JSON format for parsing
|
||||
frequency="tool_call", # Log on tool calls
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
# Example 3: Overflow-only monitoring
|
||||
agent_overflow = Agent(
|
||||
name="OverflowAgent",
|
||||
instructions="You are a helpful assistant",
|
||||
context=ContextConfig(
|
||||
monitor=MonitorConfig(
|
||||
enabled=True,
|
||||
path="./context_logs/",
|
||||
format="human",
|
||||
frequency="overflow", # Only log on overflow
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=== Context Monitoring Example ===")
|
||||
print()
|
||||
|
||||
# Show monitor configuration
|
||||
config = MonitorConfig(
|
||||
enabled=True,
|
||||
path="./context_logs/",
|
||||
format="human",
|
||||
frequency="turn",
|
||||
redact_sensitive=True,
|
||||
)
|
||||
|
||||
print("Monitor Config:")
|
||||
print(f" enabled: {config.enabled}")
|
||||
print(f" path: {config.path}")
|
||||
print(f" format: {config.format}")
|
||||
print(f" frequency: {config.frequency}")
|
||||
print(f" redact_sensitive: {config.redact_sensitive}")
|
||||
print()
|
||||
|
||||
print("Frequency options:")
|
||||
print(" 'turn' - Log on every conversation turn")
|
||||
print(" 'tool_call' - Log when tools are called")
|
||||
print(" 'manual' - Manual logging only")
|
||||
print(" 'overflow' - Log only when context overflows")
|
||||
print()
|
||||
|
||||
print("Format options:")
|
||||
print(" 'human' - Human-readable format")
|
||||
print(" 'json' - JSON format for parsing")
|
||||
@@ -0,0 +1,274 @@
|
||||
"""
|
||||
Example 15: Recursive Context Pattern
|
||||
|
||||
Demonstrates the RLM (Recursive Language Model) pattern for handling large context:
|
||||
- Store large documents as artifacts (not in LLM context)
|
||||
- Agent uses tools (grep/head/tail/chunk) to explore artifacts
|
||||
- Dramatically reduces token usage (~2K vs ~10K+)
|
||||
|
||||
This pattern solves "context rot" by treating context as programmatically
|
||||
explorable data instead of dumping everything into the LLM's context window.
|
||||
"""
|
||||
|
||||
import tempfile
|
||||
import os
|
||||
from praisonaiagents import Agent
|
||||
from praisonai.context import FileSystemArtifactStore
|
||||
from praisonai.context.queue import create_artifact_tools
|
||||
from praisonaiagents.context.artifacts import ArtifactMetadata
|
||||
|
||||
|
||||
def create_sample_document():
|
||||
"""Create a sample large document for testing."""
|
||||
# Simulate a research paper / large document
|
||||
content = """
|
||||
# Attention Is All You Need
|
||||
|
||||
## Abstract
|
||||
|
||||
The dominant sequence transduction models are based on complex recurrent or
|
||||
convolutional neural networks that include an encoder and a decoder. The best
|
||||
performing models also connect the encoder and decoder through an attention
|
||||
mechanism. We propose a new simple network architecture, the Transformer,
|
||||
based solely on attention mechanisms, dispensing with recurrence and convolutions
|
||||
entirely.
|
||||
|
||||
## Introduction
|
||||
|
||||
Recurrent neural networks, long short-term memory and gated recurrent neural
|
||||
networks in particular, have been firmly established as state of the art
|
||||
approaches in sequence modeling and transduction problems such as language
|
||||
modeling and machine translation.
|
||||
|
||||
## Background
|
||||
|
||||
The goal of reducing sequential computation also forms the foundation of the
|
||||
Extended Neural GPU, ByteNet and ConvS2S, all of which use convolutional neural
|
||||
networks as basic building block.
|
||||
|
||||
## Model Architecture
|
||||
|
||||
### Encoder and Decoder Stacks
|
||||
|
||||
The encoder is composed of a stack of N = 6 identical layers. Each layer has
|
||||
two sub-layers. The first is a multi-head self-attention mechanism, and the
|
||||
second is a simple, position-wise fully connected feed-forward network.
|
||||
|
||||
### Attention
|
||||
|
||||
An attention function can be described as mapping a query and a set of key-value
|
||||
pairs to an output, where the query, keys, values, and output are all vectors.
|
||||
|
||||
#### Scaled Dot-Product Attention
|
||||
|
||||
We call our particular attention "Scaled Dot-Product Attention". The input
|
||||
consists of queries and keys of dimension dk, and values of dimension dv.
|
||||
|
||||
The formula is: Attention(Q, K, V) = softmax(QK^T / sqrt(d_k))V
|
||||
|
||||
### Multi-Head Attention
|
||||
|
||||
Multi-head attention allows the model to jointly attend to information from
|
||||
different representation subspaces at different positions.
|
||||
|
||||
## Results
|
||||
|
||||
### Machine Translation
|
||||
|
||||
On the WMT 2014 English-to-German translation task, the big transformer model
|
||||
outperforms the best previously reported models including ensembles.
|
||||
|
||||
The model achieved a BLEU score of 28.4 on the WMT 2014 English-to-German
|
||||
translation task, improving over the existing best results by over 2 BLEU.
|
||||
|
||||
On the WMT 2014 English-to-French translation task, our big model achieves
|
||||
a BLEU score of 41.8, outperforming all published single models.
|
||||
|
||||
### Training
|
||||
|
||||
Training took 3.5 days on 8 P100 GPUs. The big model was trained for 300,000
|
||||
steps (3.5 days) at a cost of approximately $1000 in cloud compute.
|
||||
|
||||
## Model Variations
|
||||
|
||||
| Model | Parameters | BLEU EN-DE | BLEU EN-FR |
|
||||
|-------|------------|------------|------------|
|
||||
| Base | 65M | 27.3 | 38.1 |
|
||||
| Big | 213M | 28.4 | 41.8 |
|
||||
|
||||
The base model has 65 million parameters (65 × 10^6).
|
||||
The big model has 213 million parameters.
|
||||
|
||||
## Conclusion
|
||||
|
||||
In this work, we presented the Transformer, the first sequence transduction
|
||||
model based entirely on attention, replacing the recurrent layers most commonly
|
||||
used in encoder-decoder architectures with multi-headed self-attention.
|
||||
|
||||
The Transformer can be trained significantly faster than architectures based
|
||||
on recurrent or convolutional layers.
|
||||
|
||||
## Authors
|
||||
|
||||
Ashish Vaswani (Google Brain)
|
||||
Noam Shazeer (Google Brain)
|
||||
Niki Parmar (Google Research)
|
||||
Jakob Uszkoreit (Google Research)
|
||||
Llion Jones (Google Research)
|
||||
Aidan N. Gomez (University of Toronto)
|
||||
Łukasz Kaiser (Google Brain)
|
||||
Illia Polosukhin
|
||||
|
||||
## References
|
||||
|
||||
[1] Neural Machine Translation by Jointly Learning to Align and Translate
|
||||
[2] Sequence to Sequence Learning with Neural Networks
|
||||
[3] Learning Phrase Representations using RNN Encoder-Decoder
|
||||
"""
|
||||
# Repeat content to make it larger
|
||||
full_content = (content + "\n\n") * 10 # ~35KB
|
||||
return full_content
|
||||
|
||||
|
||||
def main():
|
||||
print("=" * 70)
|
||||
print("Recursive Context Pattern - Token Efficiency Demo")
|
||||
print("=" * 70)
|
||||
|
||||
# Track token usage across methods
|
||||
token_stats = {
|
||||
"traditional": {"input": 0, "output": 0},
|
||||
"recursive": {"input": 0, "output": 0},
|
||||
}
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
# 1. Create artifact store and tools
|
||||
store = FileSystemArtifactStore(base_dir=tmpdir)
|
||||
artifact_tools = create_artifact_tools(store=store)
|
||||
|
||||
print(f"\n1. Created FileSystemArtifactStore")
|
||||
print(f" Location: {tmpdir}")
|
||||
print(f" Tools available: {[t.__name__ for t in artifact_tools]}")
|
||||
|
||||
# 2. Create sample document and store as artifact
|
||||
document = create_sample_document()
|
||||
doc_size = len(document)
|
||||
doc_tokens = doc_size // 4 # Rough estimate: 4 chars per token
|
||||
|
||||
metadata = ArtifactMetadata(
|
||||
agent_id="research_agent",
|
||||
run_id="demo_run",
|
||||
tool_name="document_loader",
|
||||
turn_id=1
|
||||
)
|
||||
|
||||
ref = store.store(document, metadata)
|
||||
|
||||
print(f"\n2. Stored document as artifact")
|
||||
print(f" Size: {doc_size:,} chars (~{doc_tokens:,} tokens)")
|
||||
print(f" Path: {ref.path}")
|
||||
print(f" Summary: {ref.summary[:80]}...")
|
||||
|
||||
# 3. Create agent WITH artifact tools (Recursive Context approach)
|
||||
agent = Agent(
|
||||
instructions="""You are a research paper analyst with access to artifact exploration tools.
|
||||
When given an artifact path, use the tools to explore it efficiently:
|
||||
- artifact_grep: Search for patterns (USE THIS FIRST)
|
||||
- artifact_head: See first N lines
|
||||
- artifact_tail: See last N lines
|
||||
- artifact_chunk: Get specific line ranges
|
||||
|
||||
Be precise and cite line numbers when finding information.""",
|
||||
tools=artifact_tools,
|
||||
output='silent' # Quiet output for cleaner demo
|
||||
)
|
||||
|
||||
print(f"\n3. Created agent with {len(agent.tools)} artifact tools")
|
||||
|
||||
# 4. Query using RECURSIVE CONTEXT (small prompt + tools)
|
||||
print(f"\n4. RECURSIVE CONTEXT APPROACH")
|
||||
print("-" * 40)
|
||||
|
||||
prompt = f"""I have a research paper stored at: {ref.path}
|
||||
|
||||
Find the BLEU score on the WMT 2014 English-to-German translation task.
|
||||
Use artifact_grep to search, then report the answer with line number."""
|
||||
|
||||
prompt_tokens = len(prompt) // 4
|
||||
print(f" Prompt size: {len(prompt)} chars (~{prompt_tokens} tokens)")
|
||||
print(f" Document NOT in prompt context!")
|
||||
|
||||
response = agent.chat(prompt)
|
||||
|
||||
# Estimate output tokens (could use actual LiteLLM response if available)
|
||||
output_tokens = len(response) // 4
|
||||
|
||||
# Calculate recursive approach tokens (prompt + tool calls + response)
|
||||
# Tool call: ~200 tokens for tool desc + call
|
||||
# Tool response: ~300 tokens for grep results
|
||||
estimated_total = prompt_tokens + 200 + 300 + output_tokens
|
||||
token_stats["recursive"]["input"] = estimated_total
|
||||
|
||||
print(f"\n Agent Response:")
|
||||
print(f" {response[:200]}...")
|
||||
print(f"\n Estimated tokens used: ~{estimated_total:,}")
|
||||
|
||||
# 5. Compare with TRADITIONAL approach (full context)
|
||||
print(f"\n5. TRADITIONAL APPROACH (for comparison)")
|
||||
print("-" * 40)
|
||||
|
||||
traditional_prompt_tokens = prompt_tokens + doc_tokens
|
||||
token_stats["traditional"]["input"] = traditional_prompt_tokens
|
||||
|
||||
print(f" If we passed FULL document in prompt:")
|
||||
print(f" Prompt: {prompt_tokens} + Document: {doc_tokens} = {traditional_prompt_tokens:,} tokens")
|
||||
|
||||
# 6. Show token savings
|
||||
print(f"\n6. TOKEN COMPARISON")
|
||||
print("=" * 40)
|
||||
|
||||
savings = token_stats["traditional"]["input"] - token_stats["recursive"]["input"]
|
||||
savings_pct = (savings / token_stats["traditional"]["input"]) * 100
|
||||
|
||||
print(f" Traditional approach: ~{token_stats['traditional']['input']:,} tokens")
|
||||
print(f" Recursive approach: ~{token_stats['recursive']['input']:,} tokens")
|
||||
print(f" -----------------------------------")
|
||||
print(f" SAVINGS: ~{savings:,} tokens ({savings_pct:.0f}%)")
|
||||
|
||||
# 7. Demonstrate other artifact operations
|
||||
print(f"\n7. ARTIFACT OPERATIONS DEMO")
|
||||
print("-" * 40)
|
||||
|
||||
# head
|
||||
head_result = store.head(ref, lines=5)
|
||||
print(f" head(5 lines):")
|
||||
for line in head_result.split('\n')[:3]:
|
||||
print(f" {line[:60]}")
|
||||
|
||||
# grep
|
||||
grep_results = store.grep(ref, pattern=r"BLEU.*\d+", max_matches=3)
|
||||
print(f"\n grep('BLEU.*\\d+'):")
|
||||
for match in grep_results[:2]:
|
||||
print(f" Line {match.line_number}: {match.line_content[:50].strip()}...")
|
||||
|
||||
# chunk
|
||||
chunk_result = store.chunk(ref, start_line=50, end_line=55)
|
||||
print(f"\n chunk(lines 50-55):")
|
||||
for line in chunk_result.split('\n')[:3]:
|
||||
print(f" {line[:60]}")
|
||||
|
||||
print("\n" + "=" * 70)
|
||||
print("CONCLUSION: Recursive Context Pattern")
|
||||
print("=" * 70)
|
||||
print("""
|
||||
The Recursive Context pattern (RLM) provides:
|
||||
✓ Token efficiency: ~{savings_pct:.0f}% reduction in token usage
|
||||
✓ Scalability: Handle documents of any size
|
||||
✓ Precision: Agent searches for exactly what it needs
|
||||
✓ Cost savings: Lower API costs due to fewer tokens
|
||||
✓ Better accuracy: Avoids "context rot" from large contexts
|
||||
""".format(savings_pct=savings_pct))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,145 @@
|
||||
"""
|
||||
Agent-centric Embedding Example
|
||||
|
||||
This example shows how to use embeddings with PraisonAI Agents.
|
||||
Embeddings are used internally by Agent for:
|
||||
- Knowledge retrieval (RAG)
|
||||
- Memory storage and search
|
||||
- Semantic similarity
|
||||
|
||||
You can also use the embedding API directly for custom use cases.
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent, embedding
|
||||
|
||||
# =============================================================================
|
||||
# Example 1: Direct Embedding API
|
||||
# =============================================================================
|
||||
|
||||
def example_direct_embedding():
|
||||
"""Use the embedding API directly."""
|
||||
|
||||
# Single text embedding
|
||||
result = embedding("Hello, world!")
|
||||
print(f"Single embedding: {len(result.embeddings[0])} dimensions")
|
||||
|
||||
# Batch embedding
|
||||
texts = ["AI agents are powerful", "Machine learning is fascinating"]
|
||||
result = embedding(texts, model="text-embedding-3-small")
|
||||
print(f"Batch embeddings: {len(result.embeddings)} vectors")
|
||||
|
||||
# Custom dimensions (for models that support it)
|
||||
result = embedding("Hello", model="text-embedding-3-large", dimensions=256)
|
||||
print(f"Custom dimensions: {len(result.embeddings[0])} dimensions")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Example 2: Agent with Knowledge (uses embeddings internally)
|
||||
# =============================================================================
|
||||
|
||||
def example_agent_with_knowledge():
|
||||
"""Agent with knowledge uses embeddings for RAG."""
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant with knowledge about AI.",
|
||||
knowledge=["AI agents can use tools to accomplish tasks."],
|
||||
knowledge_config={
|
||||
"embedder": {
|
||||
"provider": "openai",
|
||||
"config": {"model": "text-embedding-3-small"}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
# The agent uses embeddings internally for knowledge retrieval
|
||||
response = agent.chat("What can AI agents do?")
|
||||
print(f"Agent response: {response}")
|
||||
|
||||
return agent
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Example 3: Agent with Memory (uses embeddings internally)
|
||||
# =============================================================================
|
||||
|
||||
def example_agent_with_memory():
|
||||
"""Agent with memory uses embeddings for semantic search."""
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant that remembers conversations.",
|
||||
memory=True,
|
||||
memory_config={
|
||||
"embedding_model": "text-embedding-3-small"
|
||||
}
|
||||
)
|
||||
|
||||
# The agent uses embeddings internally for memory storage/retrieval
|
||||
agent.chat("My name is Alice and I love Python programming.")
|
||||
response = agent.chat("What do I love?")
|
||||
print(f"Agent remembered: {response}")
|
||||
|
||||
return agent
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Example 4: Custom Embedding for Similarity Search
|
||||
# =============================================================================
|
||||
|
||||
def example_similarity_search():
|
||||
"""Use embeddings for custom similarity search."""
|
||||
import math
|
||||
|
||||
def cosine_similarity(a, b):
|
||||
dot = sum(x * y for x, y in zip(a, b))
|
||||
norm_a = math.sqrt(sum(x * x for x in a))
|
||||
norm_b = math.sqrt(sum(x * x for x in b))
|
||||
return dot / (norm_a * norm_b) if norm_a and norm_b else 0
|
||||
|
||||
# Embed documents
|
||||
documents = [
|
||||
"Python is a programming language",
|
||||
"JavaScript runs in browsers",
|
||||
"AI agents can automate tasks"
|
||||
]
|
||||
doc_embeddings = embedding(documents)
|
||||
|
||||
# Embed query
|
||||
query = "What language is used for web development?"
|
||||
query_embedding = embedding(query)
|
||||
|
||||
# Find most similar document
|
||||
similarities = [
|
||||
cosine_similarity(query_embedding.embeddings[0], doc_emb)
|
||||
for doc_emb in doc_embeddings.embeddings
|
||||
]
|
||||
|
||||
best_idx = similarities.index(max(similarities))
|
||||
print(f"Most similar document: {documents[best_idx]}")
|
||||
print(f"Similarity score: {similarities[best_idx]:.4f}")
|
||||
|
||||
return similarities
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=" * 60)
|
||||
print("Example 1: Direct Embedding API")
|
||||
print("=" * 60)
|
||||
example_direct_embedding()
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("Example 4: Custom Similarity Search")
|
||||
print("=" * 60)
|
||||
example_similarity_search()
|
||||
|
||||
# Uncomment to run agent examples (requires API key)
|
||||
# print("\n" + "=" * 60)
|
||||
# print("Example 2: Agent with Knowledge")
|
||||
# print("=" * 60)
|
||||
# example_agent_with_knowledge()
|
||||
|
||||
# print("\n" + "=" * 60)
|
||||
# print("Example 3: Agent with Memory")
|
||||
# print("=" * 60)
|
||||
# example_agent_with_memory()
|
||||
@@ -2,32 +2,34 @@
|
||||
"""
|
||||
Basic Hooks Example for PraisonAI Agents.
|
||||
|
||||
This example demonstrates how to use the hooks system to:
|
||||
This example demonstrates the simplified hook API using add_hook():
|
||||
1. Log tool calls before execution
|
||||
2. Block dangerous operations
|
||||
3. Add context to agent responses
|
||||
4. Monitor session lifecycle
|
||||
|
||||
For the simplest example, see simple_hooks.py
|
||||
|
||||
Usage:
|
||||
python basic_hooks.py
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.hooks import (
|
||||
HookRegistry, HookRunner, HookEvent, HookResult,
|
||||
add_hook, remove_hook, has_hook, get_default_registry,
|
||||
HookRunner, HookEvent, HookResult,
|
||||
BeforeToolInput, AfterToolInput
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
# Create a hook registry
|
||||
registry = HookRegistry()
|
||||
# Clear any existing hooks from previous runs
|
||||
get_default_registry().clear()
|
||||
|
||||
# ==========================================================================
|
||||
# Hook 1: Log all tool calls
|
||||
# Hook 1: Log all tool calls (using string event name)
|
||||
# ==========================================================================
|
||||
@registry.on(HookEvent.BEFORE_TOOL)
|
||||
@add_hook('before_tool')
|
||||
def log_tool_calls(event_data: BeforeToolInput) -> HookResult:
|
||||
"""Log every tool call before execution."""
|
||||
print(f"\n📝 [LOG] Tool: {event_data.tool_name}")
|
||||
@@ -35,9 +37,9 @@ def main():
|
||||
return HookResult.allow()
|
||||
|
||||
# ==========================================================================
|
||||
# Hook 2: Block dangerous file operations (using function logic)
|
||||
# Hook 2: Block dangerous file operations
|
||||
# ==========================================================================
|
||||
@registry.on(HookEvent.BEFORE_TOOL)
|
||||
@add_hook('before_tool')
|
||||
def block_delete_operations(event_data: BeforeToolInput) -> HookResult:
|
||||
"""Block any delete or remove operations."""
|
||||
dangerous_keywords = ['delete', 'remove', 'rm', 'unlink']
|
||||
@@ -53,7 +55,7 @@ def main():
|
||||
# ==========================================================================
|
||||
# Hook 3: Require confirmation for write operations
|
||||
# ==========================================================================
|
||||
@registry.on(HookEvent.BEFORE_TOOL)
|
||||
@add_hook('before_tool')
|
||||
def confirm_write_operations(event_data: BeforeToolInput) -> HookResult:
|
||||
"""Request confirmation for write operations."""
|
||||
write_keywords = ['write', 'save', 'create', 'update']
|
||||
@@ -62,14 +64,13 @@ def main():
|
||||
if any(kw in tool_lower for kw in write_keywords):
|
||||
print(f"\n⚠️ [CONFIRM] Write operation: {event_data.tool_name}")
|
||||
# In a real scenario, you might prompt the user here
|
||||
# For this example, we'll auto-approve
|
||||
return HookResult.allow("Auto-approved for demo")
|
||||
return HookResult.allow()
|
||||
|
||||
# ==========================================================================
|
||||
# Hook 4: Add timing information after tool execution
|
||||
# ==========================================================================
|
||||
@registry.on(HookEvent.AFTER_TOOL)
|
||||
@add_hook('after_tool')
|
||||
def log_tool_completion(event_data: AfterToolInput) -> HookResult:
|
||||
"""Log tool completion with timing."""
|
||||
print(f"\n✅ [DONE] Tool: {event_data.tool_name}")
|
||||
@@ -82,10 +83,14 @@ def main():
|
||||
# Test the hooks
|
||||
# ==========================================================================
|
||||
print("=" * 60)
|
||||
print("Testing Hooks System")
|
||||
print("Testing Hooks System (using add_hook API)")
|
||||
print("=" * 60)
|
||||
|
||||
runner = HookRunner(registry)
|
||||
# Check hooks are registered
|
||||
print(f"\nHooks registered for 'before_tool': {has_hook('before_tool')}")
|
||||
print(f"Hooks registered for 'after_tool': {has_hook('after_tool')}")
|
||||
|
||||
runner = HookRunner(get_default_registry())
|
||||
|
||||
# Test 1: Normal tool call (should be logged and allowed)
|
||||
print("\n--- Test 1: Normal read operation ---")
|
||||
@@ -132,7 +137,7 @@ def main():
|
||||
print("\n" + "=" * 60)
|
||||
print("Registered Hooks:")
|
||||
print("=" * 60)
|
||||
for event, hooks in registry.list_hooks().items():
|
||||
for event, hooks in get_default_registry().list_hooks().items():
|
||||
print(f"\n{event}:")
|
||||
for hook in hooks:
|
||||
print(f" - {hook['name']} (matcher: {hook['matcher'] or '*'})")
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Simple Hooks Example for PraisonAI Agents.
|
||||
|
||||
This example shows the SIMPLEST way to use hooks with the add_hook API.
|
||||
Just a few lines of code to intercept tool calls!
|
||||
|
||||
No need to import HookResult - just return None/True to allow,
|
||||
False to deny, or a string to deny with a reason.
|
||||
|
||||
Usage:
|
||||
python simple_hooks.py
|
||||
"""
|
||||
|
||||
from praisonaiagents.hooks import add_hook, has_hook
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Register hooks with simple string event names
|
||||
# =============================================================================
|
||||
|
||||
@add_hook('before_tool')
|
||||
def log_tools(event_data):
|
||||
"""Log every tool call. Return nothing (None) to allow."""
|
||||
print(f"🔧 Tool: {event_data.tool_name}")
|
||||
# No return needed - defaults to allow
|
||||
|
||||
|
||||
@add_hook('before_tool')
|
||||
def block_dangerous(event_data):
|
||||
"""Block delete operations. Return False or string to deny."""
|
||||
if 'delete' in event_data.tool_name.lower():
|
||||
print(f"🚫 Blocked: {event_data.tool_name}")
|
||||
return "Delete operations are not allowed" # String = deny with reason
|
||||
# No return = allow
|
||||
|
||||
|
||||
@add_hook('after_tool')
|
||||
def log_completion(event_data):
|
||||
"""Log tool completion."""
|
||||
print(f"✅ Done: {event_data.tool_name} ({event_data.execution_time_ms:.0f}ms)")
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Test the hooks
|
||||
# =============================================================================
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=" * 50)
|
||||
print("Simple Hooks Example")
|
||||
print("=" * 50)
|
||||
|
||||
# Check hooks are registered
|
||||
print(f"\nHooks registered for 'before_tool': {has_hook('before_tool')}")
|
||||
print(f"Hooks registered for 'after_tool': {has_hook('after_tool')}")
|
||||
|
||||
# You can now create an Agent and the hooks will be applied
|
||||
print("\n💡 Hooks are now globally registered!")
|
||||
print(" Any Agent will automatically use these hooks.")
|
||||
print("\n Example:")
|
||||
print(" from praisonaiagents import Agent")
|
||||
print(" agent = Agent(instructions='You are helpful')")
|
||||
print(" agent.start('Help me with files')")
|
||||
print("\n📝 Hook returns:")
|
||||
print(" - None or True → Allow the operation")
|
||||
print(" - False → Deny the operation")
|
||||
print(" - 'reason' → Deny with a custom message")
|
||||
@@ -105,7 +105,7 @@ def example_agent_with_default_tools():
|
||||
name="InteractiveAgent",
|
||||
instructions="You are a helpful coding assistant with file and code analysis capabilities.",
|
||||
tools=tools,
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
print(f"Agent created with {len(tools)} tools")
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
* AudioAgent Integration Test
|
||||
*
|
||||
* Tests the AudioAgent for TTS and STT using AI SDK.
|
||||
* Requires OPENAI_API_KEY for live tests.
|
||||
*
|
||||
* Run: npx ts-node audio-agent.ts
|
||||
*/
|
||||
|
||||
import { AudioAgent, createAudioAgent } from '../../../src/praisonai-ts/dist';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
async function main() {
|
||||
console.log('=== AudioAgent Integration Test ===\n');
|
||||
|
||||
// Test 1: Create AudioAgent with defaults
|
||||
console.log('1. Testing AudioAgent creation:');
|
||||
const agent = new AudioAgent({
|
||||
name: 'TestAudioAgent',
|
||||
provider: 'openai',
|
||||
voice: 'alloy',
|
||||
verbose: true
|
||||
});
|
||||
console.log(' Agent ID:', agent.id);
|
||||
console.log(' Agent Name:', agent.name);
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 2: Factory function
|
||||
console.log('\n2. Testing createAudioAgent() factory:');
|
||||
const agent2 = createAudioAgent({ provider: 'openai', voice: 'nova' });
|
||||
console.log(' Agent created:', typeof agent2);
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 3: Live TTS (requires API key)
|
||||
if (process.env.OPENAI_API_KEY) {
|
||||
console.log('\n3. Testing Text-to-Speech (live API):');
|
||||
try {
|
||||
const ttsAgent = new AudioAgent({
|
||||
provider: 'openai',
|
||||
voice: 'alloy',
|
||||
verbose: false
|
||||
});
|
||||
|
||||
const result = await ttsAgent.speak('Hello from PraisonAI AudioAgent!');
|
||||
console.log(' Audio format:', result.format);
|
||||
console.log(' Audio size:', result.audio.byteLength || result.audio.length, 'bytes');
|
||||
|
||||
// Optionally save to file
|
||||
const outputPath = path.join(__dirname, 'test-output.mp3');
|
||||
if (result.audio instanceof Buffer) {
|
||||
fs.writeFileSync(outputPath, result.audio);
|
||||
console.log(' Saved to:', outputPath);
|
||||
}
|
||||
console.log(' Success: ✅');
|
||||
} catch (error: any) {
|
||||
console.log(' ⚠️ TTS failed:', error.message);
|
||||
}
|
||||
|
||||
// Test 4: Live Transcription (requires audio file)
|
||||
console.log('\n4. Testing Speech-to-Text (live API):');
|
||||
try {
|
||||
const sttAgent = new AudioAgent({
|
||||
provider: 'openai',
|
||||
verbose: false
|
||||
});
|
||||
|
||||
// Check if we have the test output from TTS
|
||||
const audioPath = path.join(__dirname, 'test-output.mp3');
|
||||
if (fs.existsSync(audioPath)) {
|
||||
const result = await sttAgent.transcribe(audioPath);
|
||||
console.log(' Transcribed text:', result.text);
|
||||
console.log(' Language:', result.language || 'auto-detected');
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Cleanup
|
||||
fs.unlinkSync(audioPath);
|
||||
console.log(' Cleaned up test file');
|
||||
} else {
|
||||
console.log(' Skipped (no test audio file available)');
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.log(' ⚠️ STT failed:', error.message);
|
||||
}
|
||||
|
||||
// Test 5: Chat method (auto-detect mode)
|
||||
console.log('\n5. Testing chat() method:');
|
||||
try {
|
||||
const chatAgent = new AudioAgent({ provider: 'openai', voice: 'echo' });
|
||||
|
||||
// Text input -> TTS
|
||||
const chatResult = await chatAgent.chat('Testing audio chat interface');
|
||||
console.log(' Chat result:', chatResult);
|
||||
console.log(' Success: ✅');
|
||||
} catch (error: any) {
|
||||
console.log(' ⚠️ Chat failed:', error.message);
|
||||
}
|
||||
|
||||
} else {
|
||||
console.log('\n3-5. Live API Tests: Skipped (OPENAI_API_KEY not set)');
|
||||
console.log(' Set OPENAI_API_KEY to run live tests');
|
||||
}
|
||||
|
||||
// Test 6: Different providers (just creation, no live calls)
|
||||
console.log('\n6. Testing provider configurations:');
|
||||
const providers = ['openai', 'elevenlabs', 'groq', 'deepgram'] as const;
|
||||
|
||||
for (const provider of providers) {
|
||||
try {
|
||||
const a = new AudioAgent({ provider });
|
||||
console.log(` ${provider}: ✅ (created)`);
|
||||
} catch (error: any) {
|
||||
console.log(` ${provider}: ⚠️ ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Test 7: Voice options
|
||||
console.log('\n7. Testing OpenAI voice options:');
|
||||
const voices = ['alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer'];
|
||||
for (const voice of voices) {
|
||||
const a = new AudioAgent({ provider: 'openai', voice });
|
||||
console.log(` ${voice}: ✅`);
|
||||
}
|
||||
|
||||
console.log('\n=== AudioAgent Tests Complete ===');
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* ChonkieAdapter Integration Test
|
||||
*
|
||||
* Tests the ChonkieJS adapter for text chunking.
|
||||
* Works without ChonkieJS installed (uses native fallback).
|
||||
*
|
||||
* Run: npx ts-node chonkie-adapter.ts
|
||||
*/
|
||||
|
||||
import {
|
||||
ChonkieAdapter,
|
||||
createChonkieAdapter,
|
||||
hasChonkie,
|
||||
Chunking
|
||||
} from '../../../src/praisonai-ts/dist';
|
||||
|
||||
async function main() {
|
||||
console.log('=== ChonkieAdapter Integration Test ===\n');
|
||||
|
||||
// Test 1: Check ChonkieJS availability
|
||||
console.log('1. Checking ChonkieJS availability:');
|
||||
const chonkieAvailable = await hasChonkie();
|
||||
console.log(` ChonkieJS installed: ${chonkieAvailable ? '✅' : '❌ (using native fallback)'}`);
|
||||
|
||||
// Test 2: Create adapter with default config
|
||||
console.log('\n2. Testing ChonkieAdapter creation:');
|
||||
const adapter = new ChonkieAdapter({
|
||||
strategy: 'token',
|
||||
chunkSize: 100,
|
||||
overlap: 20
|
||||
});
|
||||
console.log(' Adapter created: ✅');
|
||||
console.log(' Info:', adapter.getInfo());
|
||||
|
||||
// Test 3: Chunk text
|
||||
console.log('\n3. Testing text chunking:');
|
||||
const sampleText = `
|
||||
PraisonAI is a high-performance, agentic AI framework designed with minimal client-side API.
|
||||
It features extreme performance sensitivity, lazy loading everywhere, and optional dependencies only.
|
||||
The framework supports clean separation between Core SDK, Wrapper/integrations, and Tools/plugins.
|
||||
All features must have a relevant CLI integration and representation.
|
||||
`.trim();
|
||||
|
||||
const chunks = await adapter.chunk(sampleText);
|
||||
console.log(` Input length: ${sampleText.length} characters`);
|
||||
console.log(` Chunks created: ${chunks.length}`);
|
||||
chunks.forEach((chunk, i) => {
|
||||
console.log(` [${i}]: "${chunk.content.slice(0, 50)}..." (${chunk.content.length} chars)`);
|
||||
});
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 4: Different strategies
|
||||
console.log('\n4. Testing different chunking strategies:');
|
||||
const strategies = ['size', 'sentence', 'paragraph', 'semantic'] as const;
|
||||
|
||||
for (const strategy of strategies) {
|
||||
const strategyAdapter = createChonkieAdapter({ strategy, chunkSize: 80 });
|
||||
const strategyChunks = await strategyAdapter.chunk(sampleText);
|
||||
console.log(` ${strategy}: ${strategyChunks.length} chunks`);
|
||||
}
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 5: Native Chunking class
|
||||
console.log('\n5. Testing native Chunking class:');
|
||||
const nativeChunker = new Chunking({ chunkSize: 100, overlap: 10, strategy: 'sentence' });
|
||||
const nativeChunks = nativeChunker.chunk(sampleText);
|
||||
console.log(` Native chunks: ${nativeChunks.length}`);
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 6: Factory function
|
||||
console.log('\n6. Testing createChunking() factory:');
|
||||
const factoryChunker = createChunking({ chunkSize: 200 });
|
||||
const factoryChunks = factoryChunker.chunk(sampleText);
|
||||
console.log(` Factory chunks: ${factoryChunks.length}`);
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 7: Merge small chunks
|
||||
console.log('\n7. Testing mergeSmallChunks:');
|
||||
const tinyChunker = new Chunking({ chunkSize: 20, overlap: 5 });
|
||||
const tinyChunks = tinyChunker.chunk(sampleText);
|
||||
const mergedChunks = tinyChunker.mergeSmallChunks(tinyChunks, 50);
|
||||
console.log(` Before merge: ${tinyChunks.length} chunks`);
|
||||
console.log(` After merge: ${mergedChunks.length} chunks`);
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 8: Code chunking (if ChonkieJS available)
|
||||
if (chonkieAvailable) {
|
||||
console.log('\n8. Testing code chunking (ChonkieJS):');
|
||||
const codeAdapter = createChonkieAdapter({ strategy: 'code', language: 'typescript' });
|
||||
const codeText = `
|
||||
function hello() {
|
||||
console.log('Hello');
|
||||
}
|
||||
|
||||
class MyClass {
|
||||
constructor() {
|
||||
this.value = 42;
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
`.trim();
|
||||
|
||||
const codeChunks = await codeAdapter.chunk(codeText);
|
||||
console.log(` Code chunks: ${codeChunks.length}`);
|
||||
console.log(' Success: ✅');
|
||||
} else {
|
||||
console.log('\n8. Code chunking: Skipped (ChonkieJS not installed)');
|
||||
}
|
||||
|
||||
// Test 9: Verify adapter info
|
||||
console.log('\n9. Verifying adapter state:');
|
||||
const info = adapter.getInfo();
|
||||
console.log(` Strategy: ${info.strategy}`);
|
||||
console.log(` Using ChonkieJS: ${info.usingChonkie}`);
|
||||
console.log(` Chunk size: ${info.config.chunkSize}`);
|
||||
console.log(' Success: ✅');
|
||||
|
||||
console.log('\n=== ChonkieAdapter Tests Complete ===');
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* QueryEngine Integration Test
|
||||
*
|
||||
* Tests semantic and keyword search for RAG applications.
|
||||
*
|
||||
* Run: npx ts-node query-engine.ts
|
||||
*/
|
||||
|
||||
import {
|
||||
QueryEngine,
|
||||
createQueryEngine,
|
||||
createSimpleQueryEngine
|
||||
} from '../../../src/praisonai-ts/dist';
|
||||
|
||||
async function main() {
|
||||
console.log('=== QueryEngine Integration Test ===\n');
|
||||
|
||||
// Test 1: Simple in-memory engine
|
||||
console.log('1. Testing simple in-memory QueryEngine:');
|
||||
const docs = [
|
||||
{ id: 'doc1', content: 'PraisonAI is a high-performance AI agent framework designed for production use.' },
|
||||
{ id: 'doc2', content: 'TypeScript provides static typing and better tooling for JavaScript projects.' },
|
||||
{ id: 'doc3', content: 'Agents can use tools, memory, and knowledge to complete complex tasks.' },
|
||||
{ id: 'doc4', content: 'RAG (Retrieval-Augmented Generation) improves AI responses with relevant context.' },
|
||||
{ id: 'doc5', content: 'Workflows enable sequential and parallel execution of agent tasks.' }
|
||||
];
|
||||
|
||||
const engine = createSimpleQueryEngine(docs);
|
||||
|
||||
const results1 = await engine.query('agent framework', { topK: 2 });
|
||||
console.log(' Query: "agent framework"');
|
||||
console.log(` Found: ${results1.length} results`);
|
||||
results1.forEach((r, i) => {
|
||||
console.log(` [${i + 1}] ${r.content.slice(0, 50)}... (score: ${r.score.toFixed(2)})`);
|
||||
});
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 2: Different queries
|
||||
console.log('\n2. Testing various queries:');
|
||||
const queries = ['TypeScript', 'RAG', 'workflow', 'tools memory'];
|
||||
|
||||
for (const q of queries) {
|
||||
const results = await engine.query(q, { topK: 1 });
|
||||
console.log(` "${q}" → ${results.length > 0 ? results[0].content.slice(0, 40) + '...' : 'No results'}`);
|
||||
}
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 3: Query for context string
|
||||
console.log('\n3. Testing queryForContext:');
|
||||
const context = await engine.queryForContext('agent tasks', { topK: 2 });
|
||||
console.log(' Context string (preview):');
|
||||
console.log(' ' + context.split('\n')[0]);
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 4: Cache behavior
|
||||
console.log('\n4. Testing caching:');
|
||||
const start = Date.now();
|
||||
await engine.query('agent framework', { topK: 2 });
|
||||
const cachedTime = Date.now() - start;
|
||||
console.log(` Cached query time: ${cachedTime}ms (should be fast)`);
|
||||
|
||||
engine.clearCache();
|
||||
const start2 = Date.now();
|
||||
await engine.query('agent framework', { topK: 2 });
|
||||
const uncachedTime = Date.now() - start2;
|
||||
console.log(` Uncached query time: ${uncachedTime}ms`);
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 5: QueryEngine configuration
|
||||
console.log('\n5. Testing custom QueryEngine configuration:');
|
||||
const customEngine = new QueryEngine({
|
||||
keywordSearch: async (query, options) => {
|
||||
return docs
|
||||
.filter(d => d.content.toLowerCase().includes(query.toLowerCase()))
|
||||
.map(d => ({ id: d.id, content: d.content, score: 0.8 }))
|
||||
.slice(0, options?.topK ?? 5);
|
||||
},
|
||||
defaultOptions: { mode: 'keyword', topK: 3 }
|
||||
});
|
||||
|
||||
const customResults = await customEngine.query('TypeScript');
|
||||
console.log(` Custom engine results: ${customResults.length}`);
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 6: Empty results handling
|
||||
console.log('\n6. Testing empty results:');
|
||||
const emptyResults = await engine.query('nonexistent_query_12345');
|
||||
console.log(` Results for nonsense query: ${emptyResults.length}`);
|
||||
|
||||
const emptyContext = await engine.queryForContext('nonexistent_query_12345');
|
||||
console.log(` Context: "${emptyContext}"`);
|
||||
console.log(' Success: ✅');
|
||||
|
||||
console.log('\n=== QueryEngine Tests Complete ===');
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* MCP Client Integration Test
|
||||
*
|
||||
* Tests the MCP (Model Context Protocol) client.
|
||||
* Note: Requires an MCP server for full integration tests.
|
||||
*
|
||||
* Run: npx ts-node mcp-client.ts
|
||||
*/
|
||||
|
||||
import {
|
||||
MCPClient,
|
||||
createMCPClient,
|
||||
getMCPTools,
|
||||
type MCPClientConfig
|
||||
} from '../../../src/praisonai-ts/dist/mcp';
|
||||
|
||||
async function main() {
|
||||
console.log('=== MCPClient Integration Test ===\n');
|
||||
|
||||
// Test 1: Create MCP client
|
||||
console.log('1. Testing MCPClient creation:');
|
||||
const client = new MCPClient({
|
||||
serverUrl: 'http://localhost:3000',
|
||||
transport: 'http',
|
||||
timeout: 5000,
|
||||
verbose: true
|
||||
});
|
||||
console.log(' Client ID:', client.id);
|
||||
console.log(' Connected:', client.isConnected());
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 2: Factory function
|
||||
console.log('\n2. Testing createMCPClient() factory:');
|
||||
const client2 = createMCPClient({ serverUrl: 'http://localhost:8080' });
|
||||
console.log(' Client created:', typeof client2);
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 3: Transport configurations
|
||||
console.log('\n3. Testing transport configurations:');
|
||||
const transports: MCPClientConfig['transport'][] = ['http', 'websocket', 'sse', 'stdio'];
|
||||
|
||||
for (const transport of transports) {
|
||||
try {
|
||||
const c = new MCPClient({
|
||||
transport,
|
||||
serverUrl: transport !== 'stdio' ? 'http://localhost:3000' : undefined,
|
||||
command: transport === 'stdio' ? 'npx' : undefined,
|
||||
args: transport === 'stdio' ? ['mcp-server'] : undefined
|
||||
});
|
||||
console.log(` ${transport}: ✅ (configured)`);
|
||||
} catch (error: any) {
|
||||
console.log(` ${transport}: ⚠️ ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Test 4: Session info
|
||||
console.log('\n4. Testing session management:');
|
||||
const session = client.getSession();
|
||||
console.log(' Session ID:', session.id);
|
||||
console.log(' Connected:', session.connected);
|
||||
console.log(' Tools:', session.tools.length);
|
||||
console.log(' Resources:', session.resources.length);
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 5: Live connection test (optional - requires running server)
|
||||
const testServerUrl = process.env.MCP_SERVER_URL;
|
||||
if (testServerUrl) {
|
||||
console.log('\n5. Testing live MCP connection:');
|
||||
try {
|
||||
const liveClient = new MCPClient({
|
||||
serverUrl: testServerUrl,
|
||||
transport: 'http',
|
||||
timeout: 10000,
|
||||
verbose: false
|
||||
});
|
||||
|
||||
await liveClient.connect();
|
||||
console.log(' Connected: ✅');
|
||||
|
||||
const tools = await liveClient.listTools();
|
||||
console.log(` Tools discovered: ${tools.length}`);
|
||||
|
||||
for (const tool of tools.slice(0, 3)) {
|
||||
console.log(` - ${tool.name}: ${tool.description || 'No description'}`);
|
||||
}
|
||||
|
||||
// Get tools in AI SDK format
|
||||
const aiTools = await liveClient.getToolsAsAISDK();
|
||||
console.log(` AI SDK tools: ${aiTools.length}`);
|
||||
|
||||
await liveClient.disconnect();
|
||||
console.log(' Disconnected: ✅');
|
||||
} catch (error: any) {
|
||||
console.log(` ⚠️ Connection failed: ${error.message}`);
|
||||
}
|
||||
} else {
|
||||
console.log('\n5. Live connection: Skipped (MCP_SERVER_URL not set)');
|
||||
console.log(' Set MCP_SERVER_URL to test live connections');
|
||||
}
|
||||
|
||||
// Test 6: Mock tool call simulation
|
||||
console.log('\n6. Testing tool call preparation:');
|
||||
const mockTool = {
|
||||
name: 'search',
|
||||
description: 'Search for information',
|
||||
inputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
query: { type: 'string', description: 'Search query' }
|
||||
},
|
||||
required: ['query']
|
||||
}
|
||||
};
|
||||
console.log(' Mock tool:', mockTool.name);
|
||||
console.log(' Schema:', JSON.stringify(mockTool.inputSchema));
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 7: API Key configuration
|
||||
console.log('\n7. Testing API key configuration:');
|
||||
const authClient = new MCPClient({
|
||||
serverUrl: 'http://api.example.com',
|
||||
apiKey: 'test-api-key-12345'
|
||||
});
|
||||
console.log(' Client with API key: ✅');
|
||||
|
||||
// Test 8: getMCPTools helper
|
||||
console.log('\n8. Testing getMCPTools helper signature:');
|
||||
console.log(' getMCPTools function:', typeof getMCPTools);
|
||||
console.log(' Returns: { client, tools }');
|
||||
console.log(' Success: ✅');
|
||||
|
||||
console.log('\n=== MCPClient Tests Complete ===');
|
||||
console.log('\nNote: For full integration tests, run an MCP server and set MCP_SERVER_URL');
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* MemoryHooks Integration Test
|
||||
*
|
||||
* Tests pre/post hooks for memory operations.
|
||||
*
|
||||
* Run: npx ts-node memory-hooks.ts
|
||||
*/
|
||||
|
||||
import {
|
||||
MemoryHooks,
|
||||
createMemoryHooks,
|
||||
createLoggingHooks,
|
||||
createValidationHooks,
|
||||
Memory,
|
||||
createMemory
|
||||
} from '../../../src/praisonai-ts/dist';
|
||||
|
||||
async function main() {
|
||||
console.log('=== MemoryHooks Integration Test ===\n');
|
||||
|
||||
// Test 1: Basic hooks
|
||||
console.log('1. Testing basic MemoryHooks:');
|
||||
const logs: string[] = [];
|
||||
|
||||
const hooks = new MemoryHooks({
|
||||
beforeStore: async (key, value) => {
|
||||
logs.push(`beforeStore: ${key}`);
|
||||
return { key, value };
|
||||
},
|
||||
afterStore: async (key) => {
|
||||
logs.push(`afterStore: ${key}`);
|
||||
},
|
||||
beforeRetrieve: async (key) => {
|
||||
logs.push(`beforeRetrieve: ${key}`);
|
||||
return key;
|
||||
},
|
||||
afterRetrieve: async (key, value) => {
|
||||
logs.push(`afterRetrieve: ${key}`);
|
||||
return value;
|
||||
}
|
||||
});
|
||||
|
||||
await hooks.beforeStore('key1', { data: 'value1' });
|
||||
await hooks.afterStore('key1', { data: 'value1' });
|
||||
await hooks.beforeRetrieve('key1');
|
||||
await hooks.afterRetrieve('key1', { data: 'value1' });
|
||||
|
||||
console.log(' Triggered hooks:', logs);
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 2: Logging hooks
|
||||
console.log('\n2. Testing createLoggingHooks:');
|
||||
const logMessages: string[] = [];
|
||||
const loggingHooks = createLoggingHooks((msg) => logMessages.push(msg));
|
||||
|
||||
await loggingHooks.beforeStore('test', 'data');
|
||||
await loggingHooks.afterStore('test', 'data');
|
||||
await loggingHooks.beforeRetrieve('test');
|
||||
await loggingHooks.afterRetrieve('test', 'data');
|
||||
|
||||
console.log(' Log messages:', logMessages.length);
|
||||
logMessages.forEach(m => console.log(' -', m));
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 3: Validation hooks
|
||||
console.log('\n3. Testing createValidationHooks:');
|
||||
const validationHooks = createValidationHooks((key, value) => {
|
||||
// Only allow non-empty strings
|
||||
if (typeof value !== 'string' || value.length === 0) {
|
||||
return { valid: false, reason: 'Value must be non-empty string' };
|
||||
}
|
||||
return { valid: true };
|
||||
});
|
||||
|
||||
const validResult = await validationHooks.beforeStore('good', 'valid string');
|
||||
console.log(' Valid data allowed:', validResult !== null);
|
||||
|
||||
const invalidResult = await validationHooks.beforeStore('bad', '');
|
||||
console.log(' Invalid data blocked:', invalidResult === null);
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 4: Delete hooks
|
||||
console.log('\n4. Testing delete hooks:');
|
||||
const deleteHooks = new MemoryHooks({
|
||||
beforeDelete: async (key) => {
|
||||
console.log(` [Hook] About to delete: ${key}`);
|
||||
return true; // Allow deletion
|
||||
},
|
||||
afterDelete: async (key, success) => {
|
||||
console.log(` [Hook] Delete ${key}: ${success ? 'succeeded' : 'failed'}`);
|
||||
}
|
||||
});
|
||||
|
||||
const canDelete = await deleteHooks.beforeDelete('item-to-delete');
|
||||
console.log(' Deletion allowed:', canDelete);
|
||||
await deleteHooks.afterDelete('item-to-delete', true);
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 5: Search hooks
|
||||
console.log('\n5. Testing search hooks:');
|
||||
const searchHooks = new MemoryHooks({
|
||||
beforeSearch: async (query, options) => {
|
||||
console.log(` [Hook] Searching: "${query}"`);
|
||||
// Could modify query here
|
||||
return { query: query.toLowerCase(), options };
|
||||
},
|
||||
afterSearch: async (query, results) => {
|
||||
console.log(` [Hook] Found ${results.length} results for "${query}"`);
|
||||
return results;
|
||||
}
|
||||
});
|
||||
|
||||
const searchParams = await searchHooks.beforeSearch('UPPERCASE QUERY');
|
||||
console.log(' Modified query:', searchParams?.query);
|
||||
|
||||
await searchHooks.afterSearch('query', [{ id: '1' }, { id: '2' }]);
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 6: Dynamic hook management
|
||||
console.log('\n6. Testing dynamic hook management:');
|
||||
const dynamicHooks = new MemoryHooks({});
|
||||
|
||||
console.log(' Initial config:', Object.keys(dynamicHooks.getConfig()).length === 0 ? 'empty' : 'has hooks');
|
||||
|
||||
dynamicHooks.addHook('logging', true);
|
||||
dynamicHooks.setLogging(true);
|
||||
|
||||
console.log(' After adding logging:', dynamicHooks.getConfig().logging);
|
||||
|
||||
dynamicHooks.removeHook('logging');
|
||||
console.log(' After removing:', dynamicHooks.getConfig().logging ?? 'undefined');
|
||||
console.log(' Success: ✅');
|
||||
|
||||
console.log('\n=== MemoryHooks Tests Complete ===');
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -0,0 +1,181 @@
|
||||
/**
|
||||
* Feature Parity Integration Test Runner
|
||||
*
|
||||
* Runs all integration tests for the new TypeScript features.
|
||||
* Tests include real API calls when OPENAI_API_KEY is available.
|
||||
*
|
||||
* Run: npx ts-node run-feature-tests.ts
|
||||
*/
|
||||
|
||||
import { execSync, spawn } from 'child_process';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
|
||||
interface TestResult {
|
||||
name: string;
|
||||
passed: boolean;
|
||||
duration: number;
|
||||
output: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
const TEST_FILES = [
|
||||
// Workflow patterns
|
||||
'workflows/loop-pattern.ts',
|
||||
'workflows/repeat-pattern.ts',
|
||||
// Agents
|
||||
'agents/audio-agent.ts',
|
||||
// Knowledge
|
||||
'knowledge/chonkie-adapter.ts',
|
||||
// MCP
|
||||
'mcp/mcp-client-test.ts',
|
||||
];
|
||||
|
||||
async function runTest(testFile: string): Promise<TestResult> {
|
||||
const startTime = Date.now();
|
||||
const fullPath = path.join(__dirname, testFile);
|
||||
const name = path.basename(testFile, '.ts');
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const proc = spawn('npx', ['ts-node', fullPath], {
|
||||
cwd: __dirname,
|
||||
env: { ...process.env },
|
||||
stdio: ['pipe', 'pipe', 'pipe']
|
||||
});
|
||||
|
||||
let stdout = '';
|
||||
let stderr = '';
|
||||
|
||||
proc.stdout.on('data', (data) => {
|
||||
stdout += data.toString();
|
||||
});
|
||||
|
||||
proc.stderr.on('data', (data) => {
|
||||
stderr += data.toString();
|
||||
});
|
||||
|
||||
proc.on('close', (code) => {
|
||||
const duration = Date.now() - startTime;
|
||||
resolve({
|
||||
name,
|
||||
passed: code === 0,
|
||||
duration,
|
||||
output: stdout,
|
||||
error: stderr || undefined
|
||||
});
|
||||
});
|
||||
|
||||
proc.on('error', (error) => {
|
||||
const duration = Date.now() - startTime;
|
||||
resolve({
|
||||
name,
|
||||
passed: false,
|
||||
duration,
|
||||
output: '',
|
||||
error: error.message
|
||||
});
|
||||
});
|
||||
|
||||
// Timeout after 60 seconds
|
||||
setTimeout(() => {
|
||||
proc.kill();
|
||||
resolve({
|
||||
name,
|
||||
passed: false,
|
||||
duration: 60000,
|
||||
output: stdout,
|
||||
error: 'Test timed out after 60 seconds'
|
||||
});
|
||||
}, 60000);
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log('╔════════════════════════════════════════════════════════════╗');
|
||||
console.log('║ PraisonAI TypeScript Feature Parity Integration Tests ║');
|
||||
console.log('╚════════════════════════════════════════════════════════════╝\n');
|
||||
|
||||
// Environment info
|
||||
console.log('Environment:');
|
||||
console.log(` OPENAI_API_KEY: ${process.env.OPENAI_API_KEY ? '✅ Set' : '❌ Not set'}`);
|
||||
console.log(` MCP_SERVER_URL: ${process.env.MCP_SERVER_URL ? '✅ Set' : '❌ Not set'}`);
|
||||
console.log(` Node version: ${process.version}`);
|
||||
console.log('');
|
||||
|
||||
// Check if test files exist
|
||||
console.log('Test Files:');
|
||||
for (const file of TEST_FILES) {
|
||||
const fullPath = path.join(__dirname, file);
|
||||
const exists = fs.existsSync(fullPath);
|
||||
console.log(` ${exists ? '✅' : '❌'} ${file}`);
|
||||
}
|
||||
console.log('');
|
||||
|
||||
// Run tests
|
||||
console.log('Running Tests...\n');
|
||||
console.log('─'.repeat(60));
|
||||
|
||||
const results: TestResult[] = [];
|
||||
for (const testFile of TEST_FILES) {
|
||||
const fullPath = path.join(__dirname, testFile);
|
||||
if (!fs.existsSync(fullPath)) {
|
||||
results.push({
|
||||
name: path.basename(testFile, '.ts'),
|
||||
passed: false,
|
||||
duration: 0,
|
||||
output: '',
|
||||
error: 'File not found'
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
console.log(`\n▶ Running: ${testFile}`);
|
||||
const result = await runTest(testFile);
|
||||
results.push(result);
|
||||
|
||||
if (result.passed) {
|
||||
console.log(` ✅ PASSED (${result.duration}ms)`);
|
||||
} else {
|
||||
console.log(` ❌ FAILED (${result.duration}ms)`);
|
||||
if (result.error) {
|
||||
console.log(` Error: ${result.error.slice(0, 200)}...`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\n' + '─'.repeat(60));
|
||||
|
||||
// Summary
|
||||
const passed = results.filter(r => r.passed).length;
|
||||
const failed = results.filter(r => !r.passed).length;
|
||||
const totalDuration = results.reduce((sum, r) => sum + r.duration, 0);
|
||||
|
||||
console.log('\n╔════════════════════════════════════════════════════════════╗');
|
||||
console.log('║ TEST SUMMARY ║');
|
||||
console.log('╚════════════════════════════════════════════════════════════╝');
|
||||
console.log(` Total Tests: ${results.length}`);
|
||||
console.log(` Passed: ${passed} ✅`);
|
||||
console.log(` Failed: ${failed} ${failed > 0 ? '❌' : ''}`);
|
||||
console.log(` Duration: ${(totalDuration / 1000).toFixed(2)}s`);
|
||||
console.log('');
|
||||
|
||||
// Detailed results
|
||||
if (failed > 0) {
|
||||
console.log('Failed Tests:');
|
||||
for (const result of results.filter(r => !r.passed)) {
|
||||
console.log(` ❌ ${result.name}`);
|
||||
if (result.error) {
|
||||
console.log(` ${result.error.slice(0, 100)}`);
|
||||
}
|
||||
}
|
||||
console.log('');
|
||||
}
|
||||
|
||||
// Exit with appropriate code
|
||||
process.exit(failed > 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error('Test runner failed:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* SubagentTool Integration Test
|
||||
*
|
||||
* Tests the agent-as-tool pattern with real agents.
|
||||
*
|
||||
* Run: npx ts-node subagent-tool.ts
|
||||
* Requires: OPENAI_API_KEY
|
||||
*/
|
||||
|
||||
import {
|
||||
Agent,
|
||||
SubagentTool,
|
||||
createSubagentTool,
|
||||
createSubagentTools,
|
||||
createDelegator
|
||||
} from '../../../src/praisonai-ts/dist';
|
||||
|
||||
async function main() {
|
||||
console.log('=== SubagentTool Integration Test ===\n');
|
||||
|
||||
// Test 1: Create SubagentTool
|
||||
console.log('1. Testing SubagentTool creation:');
|
||||
const mockAgent = {
|
||||
name: 'MockAgent',
|
||||
chat: async (input: string) => `Echo: ${input}`
|
||||
};
|
||||
|
||||
const tool = new SubagentTool(mockAgent, {
|
||||
name: 'echo',
|
||||
description: 'Echo the input'
|
||||
});
|
||||
|
||||
console.log(' Tool name:', tool.name);
|
||||
console.log(' Tool ID:', tool.id);
|
||||
console.log(' Schema:', JSON.stringify(tool.getSchema()));
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 2: Execute tool with mock agent
|
||||
console.log('\n2. Testing tool execution:');
|
||||
const mockResult = await tool.execute({ input: 'Hello World' });
|
||||
console.log(' Input: "Hello World"');
|
||||
console.log(' Output:', mockResult);
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 3: Factory function
|
||||
console.log('\n3. Testing createSubagentTool factory:');
|
||||
const factoryTool = createSubagentTool(mockAgent, { name: 'factory_echo' });
|
||||
console.log(' Tool name:', factoryTool.name);
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 4: Multiple subagent tools
|
||||
console.log('\n4. Testing createSubagentTools (batch):');
|
||||
const agents = [
|
||||
{ name: 'Agent1', chat: async (i: string) => `A1: ${i}` },
|
||||
{ name: 'Agent2', chat: async (i: string) => `A2: ${i}` }
|
||||
];
|
||||
const tools = createSubagentTools(agents);
|
||||
console.log(' Created tools:', tools.length);
|
||||
tools.forEach(t => console.log(' -', t.name));
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 5: AI SDK format conversion
|
||||
console.log('\n5. Testing AI SDK format conversion:');
|
||||
const aiTool = tool.toAISDKTool();
|
||||
console.log(' Type:', aiTool.type);
|
||||
console.log(' Function name:', aiTool.function.name);
|
||||
console.log(' Has execute:', typeof aiTool.execute === 'function');
|
||||
console.log(' Success: ✅');
|
||||
|
||||
// Test 6: Live test with real agent
|
||||
if (process.env.OPENAI_API_KEY) {
|
||||
console.log('\n6. Testing with real Agent (live API):');
|
||||
try {
|
||||
const researcher = new Agent({
|
||||
name: 'QuickResearcher',
|
||||
instructions: 'Answer in exactly 5 words.',
|
||||
llm: 'openai/gpt-4o-mini'
|
||||
});
|
||||
|
||||
const researchTool = createSubagentTool(researcher, {
|
||||
name: 'quick_research',
|
||||
description: 'Get a quick 5-word answer'
|
||||
});
|
||||
|
||||
const result = await researchTool.execute({ input: 'What is AI?' });
|
||||
console.log(' Question: "What is AI?"');
|
||||
console.log(' Answer:', result);
|
||||
console.log(' Success: ✅');
|
||||
} catch (error: any) {
|
||||
console.log(' Error:', error.message);
|
||||
}
|
||||
} else {
|
||||
console.log('\n6. Live test: Skipped (OPENAI_API_KEY not set)');
|
||||
}
|
||||
|
||||
// Test 7: Input/Output transforms
|
||||
console.log('\n7. Testing transforms:');
|
||||
const transformTool = createSubagentTool(mockAgent, {
|
||||
name: 'transform_echo',
|
||||
inputTransform: (input) => input.toUpperCase(),
|
||||
outputTransform: (output) => `[TRANSFORMED] ${output}`
|
||||
});
|
||||
|
||||
const transformResult = await transformTool.execute({ input: 'hello' });
|
||||
console.log(' Input: "hello"');
|
||||
console.log(' Output:', transformResult);
|
||||
console.log(' Success: ✅');
|
||||
|
||||
console.log('\n=== SubagentTool Tests Complete ===');
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* Loop Pattern Integration Test
|
||||
*
|
||||
* Tests the Loop workflow pattern with real data.
|
||||
*
|
||||
* Run: npx ts-node loop-pattern.ts
|
||||
*/
|
||||
|
||||
import { Loop, loopPattern, Agent, Workflow } from '../../../src/praisonai-ts/dist';
|
||||
|
||||
async function main() {
|
||||
console.log('=== Loop Pattern Integration Test ===\n');
|
||||
|
||||
// Test 1: Basic Loop with array
|
||||
console.log('1. Testing Loop with array iteration:');
|
||||
const items = ['apple', 'banana', 'cherry'];
|
||||
|
||||
const processor = (item: string) => `Processed: ${item.toUpperCase()}`;
|
||||
const arrayLoop = new Loop(processor, { over: 'items' });
|
||||
|
||||
const result1 = await arrayLoop.run({ items });
|
||||
console.log(' Results:', result1.results);
|
||||
console.log(' Iterations:', result1.iterations);
|
||||
console.log(' Success:', result1.success ? '✅' : '❌');
|
||||
|
||||
// Test 2: Loop with convenience function
|
||||
console.log('\n2. Testing loop() convenience function:');
|
||||
const doubler = (n: number) => n * 2;
|
||||
const numberLoop = loopPattern(doubler, { over: 'numbers' });
|
||||
|
||||
const result2 = await numberLoop.run({ numbers: [1, 2, 3, 4, 5] });
|
||||
console.log(' Input: [1, 2, 3, 4, 5]');
|
||||
console.log(' Output:', result2.results);
|
||||
console.log(' Success:', result2.success ? '✅' : '❌');
|
||||
|
||||
// Test 3: Loop with Agent (requires OPENAI_API_KEY)
|
||||
if (process.env.OPENAI_API_KEY) {
|
||||
console.log('\n3. Testing Loop with Agent (live API):');
|
||||
try {
|
||||
const agent = new Agent({
|
||||
name: 'Summarizer',
|
||||
instructions: 'Summarize the given topic in one sentence.',
|
||||
llm: 'openai/gpt-4o-mini'
|
||||
});
|
||||
|
||||
const topics = ['AI', 'TypeScript'];
|
||||
const agentLoop = new Loop(agent, { over: 'topics', varName: 'topic' });
|
||||
|
||||
console.log(' Processing topics:', topics);
|
||||
const result3 = await agentLoop.run({ topics });
|
||||
|
||||
result3.results.forEach((res, i) => {
|
||||
console.log(` [${topics[i]}]: ${res.slice(0, 80)}...`);
|
||||
});
|
||||
console.log(' Success:', result3.success ? '✅' : '❌');
|
||||
} catch (error: any) {
|
||||
console.log(' ⚠️ Agent test failed:', error.message);
|
||||
}
|
||||
} else {
|
||||
console.log('\n3. Agent Loop Test: Skipped (OPENAI_API_KEY not set)');
|
||||
}
|
||||
|
||||
// Test 4: Loop with error handling
|
||||
console.log('\n4. Testing Loop with continueOnError:');
|
||||
const errorProneProcessor = (item: string) => {
|
||||
if (item === 'fail') throw new Error('Intentional failure');
|
||||
return `OK: ${item}`;
|
||||
};
|
||||
|
||||
const errorLoop = new Loop(errorProneProcessor, {
|
||||
over: 'items',
|
||||
continueOnError: true
|
||||
});
|
||||
|
||||
const result4 = await errorLoop.run({ items: ['a', 'fail', 'b'] });
|
||||
console.log(' Results:', result4.results);
|
||||
console.log(' Errors:', result4.errors.length);
|
||||
console.log(' Success:', result4.success ? '✅' : '❌ (expected - has errors)');
|
||||
|
||||
// Test 5: Loop type exports
|
||||
console.log('\n5. Verifying exports:');
|
||||
console.log(' Loop class:', typeof Loop);
|
||||
console.log(' loop function:', typeof loopPattern);
|
||||
|
||||
console.log('\n=== Loop Pattern Tests Complete ===');
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* Repeat Pattern Integration Test
|
||||
*
|
||||
* Tests the Repeat workflow pattern for evaluator-optimizer loops.
|
||||
*
|
||||
* Run: npx ts-node repeat-pattern.ts
|
||||
*/
|
||||
|
||||
import { Repeat, repeatPattern, Agent } from '../../../src/praisonai-ts/dist';
|
||||
|
||||
async function main() {
|
||||
console.log('=== Repeat Pattern Integration Test ===\n');
|
||||
|
||||
// Test 1: Basic repeat until condition
|
||||
console.log('1. Testing Repeat with condition:');
|
||||
let counter = 0;
|
||||
const incrementer = () => {
|
||||
counter++;
|
||||
return `Iteration ${counter}`;
|
||||
};
|
||||
|
||||
const repeat1 = new Repeat(incrementer, {
|
||||
until: (ctx) => ctx.iteration >= 3,
|
||||
maxIterations: 10
|
||||
});
|
||||
|
||||
const result1 = await repeat1.run('start');
|
||||
console.log(' Results:', result1.iterations);
|
||||
console.log(' Final:', result1.result);
|
||||
console.log(' Condition met:', result1.conditionMet ? '✅' : '❌');
|
||||
console.log(' Max reached:', result1.maxReached ? '⚠️' : 'No');
|
||||
|
||||
// Test 2: Repeat with content condition
|
||||
console.log('\n2. Testing Repeat with content-based condition:');
|
||||
let quality = 0;
|
||||
const improver = (input: string, prev: string | null) => {
|
||||
quality += 25;
|
||||
return `Quality: ${quality}% - ${prev || input}`;
|
||||
};
|
||||
|
||||
const repeat2 = new Repeat(improver, {
|
||||
until: (ctx) => ctx.lastResult?.includes('100%') ?? false,
|
||||
maxIterations: 5
|
||||
});
|
||||
|
||||
quality = 0; // Reset
|
||||
const result2 = await repeat2.run('Initial draft');
|
||||
console.log(' Iterations:', result2.count);
|
||||
console.log(' Final:', result2.result);
|
||||
console.log(' Condition met:', result2.conditionMet ? '✅' : '❌');
|
||||
|
||||
// Test 3: Repeat reaching max iterations
|
||||
console.log('\n3. Testing Repeat hitting max iterations:');
|
||||
const neverDone = () => 'still working...';
|
||||
|
||||
const repeat3 = new Repeat(neverDone, {
|
||||
until: () => false, // Never satisfied
|
||||
maxIterations: 3
|
||||
});
|
||||
|
||||
const result3 = await repeat3.run('start');
|
||||
console.log(' Iterations:', result3.count);
|
||||
console.log(' Max reached:', result3.maxReached ? '✅ (expected)' : '❌');
|
||||
|
||||
// Test 4: Repeat with Agent (requires OPENAI_API_KEY)
|
||||
if (process.env.OPENAI_API_KEY) {
|
||||
console.log('\n4. Testing Repeat with Agent (live API):');
|
||||
try {
|
||||
const agent = new Agent({
|
||||
name: 'Optimizer',
|
||||
instructions: 'Improve the given text. Add more detail and clarity. Say "DONE" when satisfied.',
|
||||
llm: 'openai/gpt-4o-mini'
|
||||
});
|
||||
|
||||
const repeat4 = new Repeat(agent, {
|
||||
until: (ctx) => ctx.lastResult?.includes('DONE') ?? false,
|
||||
maxIterations: 3
|
||||
});
|
||||
|
||||
const result4 = await repeat4.run('Make this better: Hello world');
|
||||
console.log(' Iterations:', result4.count);
|
||||
console.log(' Final (truncated):', result4.result.slice(0, 100) + '...');
|
||||
console.log(' Condition met:', result4.conditionMet ? '✅' : 'Max reached');
|
||||
} catch (error: any) {
|
||||
console.log(' ⚠️ Agent test failed:', error.message);
|
||||
}
|
||||
} else {
|
||||
console.log('\n4. Agent Repeat Test: Skipped (OPENAI_API_KEY not set)');
|
||||
}
|
||||
|
||||
// Test 5: Convenience function
|
||||
console.log('\n5. Testing repeatPattern() convenience function:');
|
||||
let seq = 0;
|
||||
const sequencer = () => `seq-${++seq}`;
|
||||
|
||||
const repeat5 = repeatPattern(sequencer, {
|
||||
until: (ctx) => ctx.iteration >= 2,
|
||||
maxIterations: 5
|
||||
});
|
||||
|
||||
seq = 0; // Reset
|
||||
const result5 = await repeat5.run('');
|
||||
console.log(' Results:', result5.iterations);
|
||||
console.log(' Success:', result5.conditionMet ? '✅' : '❌');
|
||||
|
||||
// Test 6: Verify exports
|
||||
console.log('\n6. Verifying exports:');
|
||||
console.log(' Repeat class:', typeof Repeat);
|
||||
console.log(' repeatPattern function:', typeof repeatPattern);
|
||||
|
||||
console.log('\n=== Repeat Pattern Tests Complete ===');
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -68,7 +68,7 @@ Answer questions based ONLY on the provided knowledge context.
|
||||
If the answer is not in the context, say 'I don't have that information.'
|
||||
Be precise and quote exact values when asked about codes or numbers.""",
|
||||
knowledge=[temp_dir],
|
||||
user_id="demo_user",
|
||||
memory={"user_id": "demo_user"},
|
||||
output="verbose",
|
||||
)
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ Only authorized personnel with code WRENCH-992 may access this project.
|
||||
instructions="You ingest and store knowledge.",
|
||||
knowledge=[temp_dir],
|
||||
user_id="user_alice", # Scoped to Alice
|
||||
verbose=False,
|
||||
output="silent",
|
||||
)
|
||||
|
||||
# Ensure knowledge is processed
|
||||
@@ -104,7 +104,7 @@ Only authorized personnel with code WRENCH-992 may access this project.
|
||||
instructions="Answer questions based on the provided knowledge. If you don't have the information, say so.",
|
||||
knowledge=[temp_dir],
|
||||
user_id="user_alice", # Same scope as Agent A
|
||||
verbose=False,
|
||||
output="silent",
|
||||
)
|
||||
|
||||
response = agent_b.chat("What is the secret access code for Project PHOENIX?")
|
||||
|
||||
@@ -74,7 +74,7 @@ def example_agent_locks():
|
||||
agent = Agent(
|
||||
name="LockTestAgent",
|
||||
instructions="Test agent",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
# Check for locks
|
||||
@@ -112,7 +112,7 @@ def example_concurrent_real_api():
|
||||
name="ConcurrentAgent",
|
||||
instructions="Reply with one word only.",
|
||||
llm="gpt-4o-mini",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
results = []
|
||||
|
||||
@@ -51,7 +51,7 @@ agent = Agent(
|
||||
name="KnowledgeAssistant",
|
||||
instructions="You are a helpful assistant with access to technical documentation.",
|
||||
knowledge=[doc_path],
|
||||
knowledge_config={
|
||||
knowledge={
|
||||
"vector_store": "qdrant",
|
||||
"url": "http://localhost:6333"
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ agent = Agent(
|
||||
instructions="You are a helpful assistant. Keep responses brief.",
|
||||
db=db_instance,
|
||||
session_id="demo-session-001", # Same session_id = resume conversation
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
# Chat with persistence
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
from praisonaiagents import AudioAgent
|
||||
|
||||
# Text to Speech
|
||||
tts = AudioAgent(llm="openai/tts-1")
|
||||
tts.say("Hello!", output="hello.mp3")
|
||||
|
||||
# Speech to Text
|
||||
stt = AudioAgent(llm="openai/whisper-1")
|
||||
text = stt.listen("hello.mp3")
|
||||
print(text)
|
||||
@@ -0,0 +1,7 @@
|
||||
from praisonaiagents import AudioAgent
|
||||
|
||||
agent = AudioAgent(llm="groq/whisper-large-v3") # 10x faster
|
||||
text = agent.transcribe("audio.mp3", language="en")
|
||||
print(text)
|
||||
|
||||
# Models: openai/whisper-1, groq/whisper-large-v3, deepgram/nova-2
|
||||
@@ -0,0 +1,8 @@
|
||||
# Speech-to-Text with Groq (fastest)
|
||||
# Requires: export GROQ_API_KEY=your-key
|
||||
|
||||
from praisonaiagents import AudioAgent
|
||||
|
||||
agent = AudioAgent(llm="groq/whisper-large-v3")
|
||||
text = agent.listen("audio.mp3") # Replace with your audio file
|
||||
print(text)
|
||||
@@ -0,0 +1,5 @@
|
||||
from praisonaiagents import AudioAgent
|
||||
|
||||
agent = AudioAgent(llm="deepgram/nova-2")
|
||||
text = agent.listen("audio.mp3")
|
||||
print(text)
|
||||
@@ -0,0 +1,5 @@
|
||||
from praisonaiagents import AudioAgent
|
||||
|
||||
agent = AudioAgent(llm="groq/whisper-large-v3")
|
||||
text = agent.listen("audio.mp3")
|
||||
print(text)
|
||||
@@ -0,0 +1,5 @@
|
||||
from praisonaiagents import AudioAgent
|
||||
|
||||
agent = AudioAgent(llm="openai/whisper-1")
|
||||
text = agent.listen("audio.mp3")
|
||||
print(text)
|
||||
@@ -0,0 +1,7 @@
|
||||
from praisonaiagents import AudioAgent
|
||||
|
||||
agent = AudioAgent(llm="openai/tts-1-hd")
|
||||
agent.speech("Hello!", voice="nova", speed=1.2, output="hello.mp3")
|
||||
|
||||
# Voices: alloy, echo, fable, onyx, nova, shimmer
|
||||
# Models: openai/tts-1, openai/tts-1-hd, openai/gpt-4o-mini-tts
|
||||
@@ -0,0 +1,8 @@
|
||||
# Text-to-Speech with OpenAI
|
||||
# Requires: export OPENAI_API_KEY=your-key
|
||||
|
||||
from praisonaiagents import AudioAgent
|
||||
|
||||
agent = AudioAgent(llm="openai/tts-1")
|
||||
agent.say("Hello world!", output="hello.mp3")
|
||||
print("Saved to hello.mp3")
|
||||
@@ -0,0 +1,4 @@
|
||||
from praisonaiagents import AudioAgent
|
||||
|
||||
agent = AudioAgent(llm="elevenlabs/eleven_multilingual_v2")
|
||||
agent.say("Hello world!", output="hello.mp3")
|
||||
@@ -0,0 +1,4 @@
|
||||
from praisonaiagents import AudioAgent
|
||||
|
||||
agent = AudioAgent(llm="gemini/gemini-2.5-flash-preview-tts")
|
||||
agent.say("Hello world!", output="hello.mp3", voice="leda")
|
||||
@@ -0,0 +1,4 @@
|
||||
from praisonaiagents import AudioAgent
|
||||
|
||||
agent = AudioAgent(llm="openai/tts-1")
|
||||
agent.say("Hello world!", output="hello.mp3")
|
||||
@@ -0,0 +1,76 @@
|
||||
"""
|
||||
Messaging Bot Example - Deploy Agents to Telegram, Discord, Slack
|
||||
|
||||
This example demonstrates how to configure bots for different
|
||||
messaging platforms.
|
||||
"""
|
||||
|
||||
import os
|
||||
from praisonaiagents import Agent, BotConfig
|
||||
|
||||
# Telegram Bot Configuration
|
||||
telegram_config = BotConfig(
|
||||
token=os.environ.get("TELEGRAM_BOT_TOKEN", ""),
|
||||
command_prefix="/",
|
||||
mention_required=True,
|
||||
typing_indicator=True,
|
||||
max_message_length=4096,
|
||||
metadata={"platform": "telegram"}
|
||||
)
|
||||
|
||||
# Discord Bot Configuration
|
||||
discord_config = BotConfig(
|
||||
token=os.environ.get("DISCORD_BOT_TOKEN", ""),
|
||||
command_prefix="!",
|
||||
mention_required=True,
|
||||
typing_indicator=True,
|
||||
metadata={
|
||||
"platform": "discord",
|
||||
"guild_ids": [] # Add your guild IDs here
|
||||
}
|
||||
)
|
||||
|
||||
# Slack Bot Configuration
|
||||
slack_config = BotConfig(
|
||||
token=os.environ.get("SLACK_BOT_TOKEN", ""),
|
||||
command_prefix="/",
|
||||
mention_required=True,
|
||||
typing_indicator=True,
|
||||
metadata={
|
||||
"platform": "slack",
|
||||
"app_token": os.environ.get("SLACK_APP_TOKEN", "")
|
||||
}
|
||||
)
|
||||
|
||||
# Create the agent that will handle messages
|
||||
assistant = Agent(
|
||||
name="assistant",
|
||||
instructions="""You are a helpful assistant that responds to messages
|
||||
from users on messaging platforms. Be friendly and concise.""",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Bot Configurations:")
|
||||
print()
|
||||
|
||||
print("Telegram Config:")
|
||||
print(f" Token configured: {bool(telegram_config.token)}")
|
||||
print(f" Command prefix: {telegram_config.command_prefix}")
|
||||
print(f" Mention required: {telegram_config.mention_required}")
|
||||
print()
|
||||
|
||||
print("Discord Config:")
|
||||
print(f" Token configured: {bool(discord_config.token)}")
|
||||
print(f" Command prefix: {discord_config.command_prefix}")
|
||||
print()
|
||||
|
||||
print("Slack Config:")
|
||||
print(f" Token configured: {bool(slack_config.token)}")
|
||||
print(f" Command prefix: {slack_config.command_prefix}")
|
||||
print()
|
||||
|
||||
print("To start a bot, use the CLI:")
|
||||
print(" praisonai bot telegram --token $TELEGRAM_BOT_TOKEN")
|
||||
print(" praisonai bot discord --token $DISCORD_BOT_TOKEN")
|
||||
print(" praisonai bot slack --token $SLACK_BOT_TOKEN")
|
||||
@@ -8,7 +8,7 @@ Docs: https://docs.praison.ai/cli/git-integration
|
||||
from praisonai.cli.features import GitIntegrationHandler
|
||||
|
||||
# Initialize
|
||||
handler = GitIntegrationHandler(verbose=True)
|
||||
handler = GitIntegrationHandler(output="verbose")
|
||||
git = handler.initialize(repo_path=".")
|
||||
|
||||
# Check if it's a git repo
|
||||
|
||||
@@ -8,7 +8,7 @@ Docs: https://docs.praison.ai/cli/repo-map
|
||||
from praisonai.cli.features import RepoMapHandler
|
||||
|
||||
# Initialize with current directory
|
||||
handler = RepoMapHandler(verbose=True)
|
||||
handler = RepoMapHandler(output="verbose")
|
||||
repo_map = handler.initialize(root=".")
|
||||
|
||||
# Get the repository map
|
||||
|
||||
@@ -9,7 +9,7 @@ from praisonai.cli.features import SandboxExecutorHandler
|
||||
from praisonai.cli.features.sandbox_executor import SandboxMode
|
||||
|
||||
# Initialize with basic sandbox
|
||||
handler = SandboxExecutorHandler(verbose=True)
|
||||
handler = SandboxExecutorHandler(output="verbose")
|
||||
sandbox = handler.initialize(mode="basic")
|
||||
|
||||
print(f"Sandbox mode: {handler.get_mode()}")
|
||||
|
||||
@@ -26,7 +26,7 @@ pdf_agent = Agent(
|
||||
backstory="You are an expert at reading, analyzing, and answering questions about PDF documents. You provide accurate, detailed answers based on the document content.",
|
||||
instructions="Read the provided PDF document and answer questions about its content. Be specific and cite relevant sections when possible.",
|
||||
knowledge=["document.pdf"], # Replace with your PDF file path
|
||||
knowledge_config=config,
|
||||
knowledge=config,
|
||||
reflection=True,
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ knowledge_agent = Agent(
|
||||
goal="Store and retrieve knowledge efficiently",
|
||||
backstory="Expert in managing and utilizing stored knowledge",
|
||||
knowledge=["sample.pdf"],
|
||||
knowledge_config=config)
|
||||
knowledge=config)
|
||||
|
||||
# Define a task for the agent
|
||||
knowledge_task = Task(
|
||||
|
||||
@@ -13,8 +13,7 @@ config = {
|
||||
agent = Agent(
|
||||
name="Knowledge Agent",
|
||||
instructions="You answer questions based on the provided knowledge.",
|
||||
knowledge=["small.pdf"],
|
||||
knowledge_config=config
|
||||
knowledge=["small.pdf"]
|
||||
)
|
||||
|
||||
agent.start("What is KAG in one line?")
|
||||
@@ -139,7 +139,7 @@ def main():
|
||||
name="AI Research Assistant",
|
||||
instructions="You are an AI research assistant. Use your knowledge base to answer questions about artificial intelligence topics.",
|
||||
knowledge=sample_documents, # Will use default knowledge config
|
||||
knowledge_config=rerank_config, # Use reranking config
|
||||
knowledge=rerank_config, # Use reranking config
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,391 @@
|
||||
"""
|
||||
Conditional Branching Example - PraisonAI Agents
|
||||
|
||||
This example demonstrates the `if:` pattern for conditional workflow execution:
|
||||
1. Basic if/then/else branching
|
||||
2. Numeric condition evaluation (>, <, >=, <=, ==, !=)
|
||||
3. String condition evaluation (==, !=)
|
||||
4. Contains condition (in, contains)
|
||||
5. Combining if: with loop: for per-item decisions
|
||||
|
||||
The if: pattern enables dynamic workflow paths based on
|
||||
runtime conditions and variable values.
|
||||
"""
|
||||
|
||||
from praisonaiagents import Workflow, WorkflowContext, StepResult
|
||||
from praisonaiagents.workflows import if_, loop
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Example 1: Basic If/Then/Else - Score-Based Routing
|
||||
# =============================================================================
|
||||
|
||||
def basic_if_example():
|
||||
"""
|
||||
Route to different handlers based on a score threshold.
|
||||
"""
|
||||
print("\n" + "="*60)
|
||||
print("Example 1: Basic If/Then/Else - Score Routing")
|
||||
print("="*60)
|
||||
|
||||
def approve(ctx: WorkflowContext) -> StepResult:
|
||||
score = ctx.variables.get("score", 0)
|
||||
print(f" ✅ APPROVED: Score {score} meets threshold")
|
||||
return StepResult(output="Application approved")
|
||||
|
||||
def reject(ctx: WorkflowContext) -> StepResult:
|
||||
score = ctx.variables.get("score", 0)
|
||||
print(f" ❌ REJECTED: Score {score} below threshold")
|
||||
return StepResult(output="Application rejected")
|
||||
|
||||
# Test with passing score
|
||||
workflow_pass = Workflow(
|
||||
steps=[
|
||||
if_(
|
||||
condition="{{score}} >= 70",
|
||||
then_steps=[approve],
|
||||
else_steps=[reject]
|
||||
)
|
||||
],
|
||||
variables={"score": 85}
|
||||
)
|
||||
|
||||
print("\nTest 1: Score = 85")
|
||||
workflow_pass.start("Evaluate application")
|
||||
|
||||
# Test with failing score
|
||||
workflow_fail = Workflow(
|
||||
steps=[
|
||||
if_(
|
||||
condition="{{score}} >= 70",
|
||||
then_steps=[approve],
|
||||
else_steps=[reject]
|
||||
)
|
||||
],
|
||||
variables={"score": 55}
|
||||
)
|
||||
|
||||
print("\nTest 2: Score = 55")
|
||||
workflow_fail.start("Evaluate application")
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Example 2: String Condition - Status-Based Processing
|
||||
# =============================================================================
|
||||
|
||||
def string_condition_example():
|
||||
"""
|
||||
Branch based on string equality.
|
||||
"""
|
||||
print("\n" + "="*60)
|
||||
print("Example 2: String Condition - Status Processing")
|
||||
print("="*60)
|
||||
|
||||
def process_active(ctx: WorkflowContext) -> StepResult:
|
||||
print(" 🟢 Processing ACTIVE user")
|
||||
return StepResult(output="Active user processed")
|
||||
|
||||
def process_inactive(ctx: WorkflowContext) -> StepResult:
|
||||
print(" 🔴 Processing INACTIVE user")
|
||||
return StepResult(output="Inactive user archived")
|
||||
|
||||
# Test with active status
|
||||
workflow = Workflow(
|
||||
steps=[
|
||||
if_(
|
||||
condition="{{status}} == active",
|
||||
then_steps=[process_active],
|
||||
else_steps=[process_inactive]
|
||||
)
|
||||
],
|
||||
variables={"status": "active"}
|
||||
)
|
||||
|
||||
print("\nTest: status = 'active'")
|
||||
workflow.start("Process user")
|
||||
|
||||
# Test with inactive status
|
||||
workflow2 = Workflow(
|
||||
steps=[
|
||||
if_(
|
||||
condition="{{status}} == active",
|
||||
then_steps=[process_active],
|
||||
else_steps=[process_inactive]
|
||||
)
|
||||
],
|
||||
variables={"status": "inactive"}
|
||||
)
|
||||
|
||||
print("\nTest: status = 'inactive'")
|
||||
workflow2.start("Process user")
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Example 3: Contains Condition - Content Filtering
|
||||
# =============================================================================
|
||||
|
||||
def contains_condition_example():
|
||||
"""
|
||||
Branch based on whether a string contains a substring.
|
||||
"""
|
||||
print("\n" + "="*60)
|
||||
print("Example 3: Contains Condition - Content Filtering")
|
||||
print("="*60)
|
||||
|
||||
def flag_content(ctx: WorkflowContext) -> StepResult:
|
||||
print(" 🚨 FLAGGED: Message contains sensitive content")
|
||||
return StepResult(output="Content flagged for review")
|
||||
|
||||
def approve_content(ctx: WorkflowContext) -> StepResult:
|
||||
print(" ✅ APPROVED: Message is clean")
|
||||
return StepResult(output="Content approved")
|
||||
|
||||
# Test with flagged content
|
||||
workflow1 = Workflow(
|
||||
steps=[
|
||||
if_(
|
||||
condition="error in {{message}}",
|
||||
then_steps=[flag_content],
|
||||
else_steps=[approve_content]
|
||||
)
|
||||
],
|
||||
variables={"message": "System error: connection failed"}
|
||||
)
|
||||
|
||||
print("\nTest 1: Message contains 'error'")
|
||||
workflow1.start("Filter content")
|
||||
|
||||
# Test with clean content
|
||||
workflow2 = Workflow(
|
||||
steps=[
|
||||
if_(
|
||||
condition="error in {{message}}",
|
||||
then_steps=[flag_content],
|
||||
else_steps=[approve_content]
|
||||
)
|
||||
],
|
||||
variables={"message": "Operation completed successfully"}
|
||||
)
|
||||
|
||||
print("\nTest 2: Message is clean")
|
||||
workflow2.start("Filter content")
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Example 4: If Inside Loop - Per-Item Decisions
|
||||
# =============================================================================
|
||||
|
||||
def if_inside_loop_example():
|
||||
"""
|
||||
Make decisions for each item in a collection.
|
||||
Combines iteration with conditional branching.
|
||||
"""
|
||||
print("\n" + "="*60)
|
||||
print("Example 4: If Inside Loop - Per-Item Decisions")
|
||||
print("="*60)
|
||||
|
||||
results = {"premium": [], "standard": []}
|
||||
|
||||
def premium_service(ctx: WorkflowContext) -> StepResult:
|
||||
customer = ctx.variables.get("customer", {})
|
||||
name = customer.get("name", "Unknown")
|
||||
results["premium"].append(name)
|
||||
print(f" ⭐ {name}: Premium service activated")
|
||||
return StepResult(output=f"Premium service for {name}")
|
||||
|
||||
def standard_service(ctx: WorkflowContext) -> StepResult:
|
||||
customer = ctx.variables.get("customer", {})
|
||||
name = customer.get("name", "Unknown")
|
||||
results["standard"].append(name)
|
||||
print(f" 📦 {name}: Standard service activated")
|
||||
return StepResult(output=f"Standard service for {name}")
|
||||
|
||||
workflow = Workflow(
|
||||
steps=[
|
||||
loop(
|
||||
steps=[
|
||||
if_(
|
||||
condition="{{customer.tier}} == premium",
|
||||
then_steps=[premium_service],
|
||||
else_steps=[standard_service]
|
||||
)
|
||||
],
|
||||
over="customers",
|
||||
var_name="customer"
|
||||
)
|
||||
],
|
||||
variables={
|
||||
"customers": [
|
||||
{"name": "Alice", "tier": "premium"},
|
||||
{"name": "Bob", "tier": "standard"},
|
||||
{"name": "Charlie", "tier": "premium"},
|
||||
{"name": "Diana", "tier": "standard"}
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
print("\nProcessing customers:")
|
||||
workflow.start("Assign service tiers")
|
||||
|
||||
print(f"\nSummary:")
|
||||
print(f" Premium customers: {results['premium']}")
|
||||
print(f" Standard customers: {results['standard']}")
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Example 5: Nested Conditions - Multi-Level Decision Tree
|
||||
# =============================================================================
|
||||
|
||||
def nested_conditions_example():
|
||||
"""
|
||||
Demonstrate nested if conditions for complex decision trees.
|
||||
"""
|
||||
print("\n" + "="*60)
|
||||
print("Example 5: Nested Conditions - Decision Tree")
|
||||
print("="*60)
|
||||
|
||||
def vip_treatment(ctx: WorkflowContext) -> StepResult:
|
||||
print(" 👑 VIP Treatment: Dedicated support + Priority queue")
|
||||
return StepResult(output="VIP treatment applied") # noqa: ARG001
|
||||
|
||||
def regular_premium(ctx: WorkflowContext) -> StepResult:
|
||||
print(" ⭐ Premium: Priority support")
|
||||
return StepResult(output="Premium support applied")
|
||||
|
||||
def basic_support(ctx: WorkflowContext) -> StepResult:
|
||||
print(" 📞 Basic: Standard support queue")
|
||||
return StepResult(output="Basic support applied")
|
||||
|
||||
# Outer condition: Is premium?
|
||||
# Inner condition (if premium): Is VIP?
|
||||
workflow = Workflow(
|
||||
steps=[
|
||||
if_(
|
||||
condition="{{tier}} == premium",
|
||||
then_steps=[
|
||||
if_(
|
||||
condition="{{spend}} > 10000",
|
||||
then_steps=[vip_treatment],
|
||||
else_steps=[regular_premium]
|
||||
)
|
||||
],
|
||||
else_steps=[basic_support]
|
||||
)
|
||||
],
|
||||
variables={"tier": "premium", "spend": 15000}
|
||||
)
|
||||
|
||||
print("\nTest 1: Premium tier, high spend")
|
||||
workflow.start("Determine support level")
|
||||
|
||||
workflow2 = Workflow(
|
||||
steps=[
|
||||
if_(
|
||||
condition="{{tier}} == premium",
|
||||
then_steps=[
|
||||
if_(
|
||||
condition="{{spend}} > 10000",
|
||||
then_steps=[vip_treatment],
|
||||
else_steps=[regular_premium]
|
||||
)
|
||||
],
|
||||
else_steps=[basic_support]
|
||||
)
|
||||
],
|
||||
variables={"tier": "premium", "spend": 5000}
|
||||
)
|
||||
|
||||
print("\nTest 2: Premium tier, low spend")
|
||||
workflow2.start("Determine support level")
|
||||
|
||||
workflow3 = Workflow(
|
||||
steps=[
|
||||
if_(
|
||||
condition="{{tier}} == premium",
|
||||
then_steps=[
|
||||
if_(
|
||||
condition="{{spend}} > 10000",
|
||||
then_steps=[vip_treatment],
|
||||
else_steps=[regular_premium]
|
||||
)
|
||||
],
|
||||
else_steps=[basic_support]
|
||||
)
|
||||
],
|
||||
variables={"tier": "basic", "spend": 20000}
|
||||
)
|
||||
|
||||
print("\nTest 3: Basic tier (regardless of spend)")
|
||||
workflow3.start("Determine support level")
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Example 6: No Else Branch - Optional Processing
|
||||
# =============================================================================
|
||||
|
||||
def no_else_example():
|
||||
"""
|
||||
If condition without else branch - only execute if true.
|
||||
"""
|
||||
print("\n" + "="*60)
|
||||
print("Example 6: No Else Branch - Optional Processing")
|
||||
print("="*60)
|
||||
|
||||
def send_notification(ctx: WorkflowContext) -> StepResult:
|
||||
print(" 📧 Notification sent!")
|
||||
return StepResult(output="Notification sent")
|
||||
|
||||
def continue_processing(ctx: WorkflowContext) -> StepResult:
|
||||
print(" ➡️ Continuing with main workflow...")
|
||||
return StepResult(output="Continued")
|
||||
|
||||
# Only send notification if opted in
|
||||
workflow = Workflow(
|
||||
steps=[
|
||||
if_(
|
||||
condition="{{notify}} == true",
|
||||
then_steps=[send_notification]
|
||||
# No else_steps - just skip if false
|
||||
),
|
||||
continue_processing
|
||||
],
|
||||
variables={"notify": "true"}
|
||||
)
|
||||
|
||||
print("\nTest 1: notify = true")
|
||||
workflow.start("Process with notification")
|
||||
|
||||
workflow2 = Workflow(
|
||||
steps=[
|
||||
if_(
|
||||
condition="{{notify}} == true",
|
||||
then_steps=[send_notification]
|
||||
),
|
||||
continue_processing
|
||||
],
|
||||
variables={"notify": "false"}
|
||||
)
|
||||
|
||||
print("\nTest 2: notify = false")
|
||||
workflow2.start("Process without notification")
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Main - Run All Examples
|
||||
# =============================================================================
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("\n" + "="*60)
|
||||
print("PraisonAI Conditional Branching Examples")
|
||||
print("="*60)
|
||||
|
||||
basic_if_example()
|
||||
string_condition_example()
|
||||
contains_condition_example()
|
||||
if_inside_loop_example()
|
||||
nested_conditions_example()
|
||||
no_else_example()
|
||||
|
||||
print("\n" + "="*60)
|
||||
print("All conditional branching examples completed!")
|
||||
print("="*60)
|
||||
@@ -16,7 +16,7 @@ def example_dict_output_config():
|
||||
"""Example: Using dict for output configuration."""
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Dict shorthand - equivalent to OutputConfig(verbose=True, stream=False)
|
||||
# Dict shorthand - equivalent to OutputConfig(output="verbose", stream=False)
|
||||
agent = Agent(
|
||||
name="Assistant",
|
||||
instructions="You are a helpful assistant.",
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
"""Example: Merge Strategies for Multi-Agent Workflows
|
||||
|
||||
This example demonstrates how to use and create custom merge strategies
|
||||
for combining outputs from parallel agent executions.
|
||||
"""
|
||||
from praisonaiagents.agents import (
|
||||
MergeStrategyProtocol,
|
||||
FirstWinsMerge,
|
||||
ConcatMerge,
|
||||
DictMerge,
|
||||
)
|
||||
|
||||
|
||||
def example_first_wins_merge():
|
||||
"""Demonstrate FirstWinsMerge strategy."""
|
||||
print("=" * 50)
|
||||
print("FirstWinsMerge Examples")
|
||||
print("=" * 50)
|
||||
|
||||
merge = FirstWinsMerge()
|
||||
|
||||
# 1. Basic usage - returns first non-None
|
||||
print("\n1. Basic Usage:")
|
||||
outputs = [None, "Agent 2 response", "Agent 3 response"]
|
||||
result = merge.merge(outputs)
|
||||
print(f" Inputs: {outputs}")
|
||||
print(f" Result: {result}")
|
||||
|
||||
# 2. All None returns None
|
||||
print("\n2. All None:")
|
||||
outputs = [None, None, None]
|
||||
result = merge.merge(outputs)
|
||||
print(f" Inputs: {outputs}")
|
||||
print(f" Result: {result}")
|
||||
|
||||
# 3. First value wins
|
||||
print("\n3. First Value Wins:")
|
||||
outputs = ["Fast agent", "Slow agent", "Slowest agent"]
|
||||
result = merge.merge(outputs)
|
||||
print(f" Inputs: {outputs}")
|
||||
print(f" Result: {result}")
|
||||
|
||||
# 4. Works with any type
|
||||
print("\n4. Various Types:")
|
||||
print(f" Dict: {merge.merge([None, {'key': 'value'}])}")
|
||||
print(f" List: {merge.merge([None, [1, 2, 3]])}")
|
||||
print(f" Number: {merge.merge([None, 42])}")
|
||||
|
||||
|
||||
def example_concat_merge():
|
||||
"""Demonstrate ConcatMerge strategy."""
|
||||
print("\n" + "=" * 50)
|
||||
print("ConcatMerge Examples")
|
||||
print("=" * 50)
|
||||
|
||||
# 1. Default separator (double newline)
|
||||
print("\n1. Default Separator:")
|
||||
merge = ConcatMerge()
|
||||
outputs = ["Part 1: Introduction", "Part 2: Analysis", "Part 3: Conclusion"]
|
||||
result = merge.merge(outputs)
|
||||
print(f" Result:\n{result}")
|
||||
|
||||
# 2. Custom separator
|
||||
print("\n2. Custom Separator:")
|
||||
merge = ConcatMerge(separator=" | ")
|
||||
outputs = ["Alice", "Bob", "Charlie"]
|
||||
result = merge.merge(outputs)
|
||||
print(f" Result: {result}")
|
||||
|
||||
# 3. Skips None values
|
||||
print("\n3. Skips None:")
|
||||
merge = ConcatMerge(separator=", ")
|
||||
outputs = ["A", None, "C", None, "E"]
|
||||
result = merge.merge(outputs)
|
||||
print(f" Inputs: {outputs}")
|
||||
print(f" Result: {result}")
|
||||
|
||||
# 4. Converts non-strings
|
||||
print("\n4. Converts Non-Strings:")
|
||||
merge = ConcatMerge(separator=" + ")
|
||||
outputs = [1, 2, 3]
|
||||
result = merge.merge(outputs)
|
||||
print(f" Inputs: {outputs}")
|
||||
print(f" Result: {result}")
|
||||
|
||||
|
||||
def example_dict_merge():
|
||||
"""Demonstrate DictMerge strategy."""
|
||||
print("\n" + "=" * 50)
|
||||
print("DictMerge Examples")
|
||||
print("=" * 50)
|
||||
|
||||
# 1. Basic shallow merge
|
||||
print("\n1. Shallow Merge (default):")
|
||||
merge = DictMerge()
|
||||
outputs = [
|
||||
{"name": "Alice", "score": 10},
|
||||
{"name": "Bob", "level": 5},
|
||||
{"score": 20, "rank": 1}
|
||||
]
|
||||
result = merge.merge(outputs)
|
||||
print(f" Inputs: {outputs}")
|
||||
print(f" Result: {result}")
|
||||
|
||||
# 2. Later values override
|
||||
print("\n2. Override Behavior:")
|
||||
merge = DictMerge()
|
||||
outputs = [
|
||||
{"status": "pending"},
|
||||
{"status": "processing"},
|
||||
{"status": "complete"}
|
||||
]
|
||||
result = merge.merge(outputs)
|
||||
print(f" Result: {result}")
|
||||
|
||||
# 3. Deep merge for nested dicts
|
||||
print("\n3. Deep Merge:")
|
||||
merge = DictMerge(deep=True)
|
||||
outputs = [
|
||||
{"config": {"a": 1, "b": 2}},
|
||||
{"config": {"b": 3, "c": 4}},
|
||||
{"config": {"d": 5}}
|
||||
]
|
||||
result = merge.merge(outputs)
|
||||
print(f" Inputs: {outputs}")
|
||||
print(f" Result: {result}")
|
||||
|
||||
# 4. Skips non-dict values
|
||||
print("\n4. Skips Non-Dict Values:")
|
||||
merge = DictMerge()
|
||||
outputs = [{"a": 1}, "not a dict", None, {"b": 2}]
|
||||
result = merge.merge(outputs)
|
||||
print(f" Inputs: {outputs}")
|
||||
print(f" Result: {result}")
|
||||
|
||||
|
||||
def example_custom_merge():
|
||||
"""Demonstrate creating custom merge strategies."""
|
||||
print("\n" + "=" * 50)
|
||||
print("Custom Merge Strategy Examples")
|
||||
print("=" * 50)
|
||||
|
||||
# 1. Longest output merge
|
||||
class LongestOutputMerge:
|
||||
"""Returns the longest output."""
|
||||
def merge(self, outputs, context=None):
|
||||
valid = [o for o in outputs if o is not None]
|
||||
if not valid:
|
||||
return None
|
||||
return max(valid, key=lambda x: len(str(x)))
|
||||
|
||||
print("\n1. LongestOutputMerge:")
|
||||
merge = LongestOutputMerge()
|
||||
outputs = ["short", "medium length", "this is the longest response"]
|
||||
result = merge.merge(outputs)
|
||||
print(f" Inputs: {outputs}")
|
||||
print(f" Result: {result}")
|
||||
|
||||
# 2. Majority vote merge
|
||||
class MajorityVoteMerge:
|
||||
"""Returns the most common output."""
|
||||
def merge(self, outputs, context=None):
|
||||
from collections import Counter
|
||||
valid = [o for o in outputs if o is not None]
|
||||
if not valid:
|
||||
return None
|
||||
counts = Counter(valid)
|
||||
return counts.most_common(1)[0][0]
|
||||
|
||||
print("\n2. MajorityVoteMerge:")
|
||||
merge = MajorityVoteMerge()
|
||||
outputs = ["yes", "yes", "no", "yes", "no"]
|
||||
result = merge.merge(outputs)
|
||||
print(f" Inputs: {outputs}")
|
||||
print(f" Result: {result} (3 votes)")
|
||||
|
||||
# 3. Weighted merge
|
||||
class WeightedMerge:
|
||||
"""Merges with agent weights from context."""
|
||||
def merge(self, outputs, context=None):
|
||||
weights = context.get("weights", [1] * len(outputs)) if context else [1] * len(outputs)
|
||||
best_idx = 0
|
||||
best_weight = 0
|
||||
for i, (output, weight) in enumerate(zip(outputs, weights)):
|
||||
if output is not None and weight > best_weight:
|
||||
best_idx = i
|
||||
best_weight = weight
|
||||
return outputs[best_idx] if outputs else None
|
||||
|
||||
print("\n3. WeightedMerge:")
|
||||
merge = WeightedMerge()
|
||||
outputs = ["junior answer", "senior answer", "expert answer"]
|
||||
context = {"weights": [1, 5, 10]}
|
||||
result = merge.merge(outputs, context=context)
|
||||
print(f" Inputs: {outputs}")
|
||||
print(f" Weights: {context['weights']}")
|
||||
print(f" Result: {result}")
|
||||
|
||||
# 4. Protocol compliance
|
||||
print("\n4. Protocol Compliance:")
|
||||
print(f" LongestOutputMerge: {isinstance(LongestOutputMerge(), MergeStrategyProtocol)}")
|
||||
print(f" MajorityVoteMerge: {isinstance(MajorityVoteMerge(), MergeStrategyProtocol)}")
|
||||
print(f" WeightedMerge: {isinstance(WeightedMerge(), MergeStrategyProtocol)}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
example_first_wins_merge()
|
||||
example_concat_merge()
|
||||
example_dict_merge()
|
||||
example_custom_merge()
|
||||
|
||||
print("\n" + "=" * 50)
|
||||
print("All examples completed!")
|
||||
print("=" * 50)
|
||||
@@ -0,0 +1,174 @@
|
||||
"""Example: Retry Policies and Fallback Chains
|
||||
|
||||
This example demonstrates how to configure retry behavior with
|
||||
exponential backoff, jitter, and fallback chains.
|
||||
"""
|
||||
from praisonaiagents.tools import (
|
||||
RetryPolicy,
|
||||
FallbackChain,
|
||||
ToolExecutionConfig,
|
||||
)
|
||||
|
||||
|
||||
def example_retry_policy():
|
||||
"""Demonstrate RetryPolicy configuration and usage."""
|
||||
print("=" * 50)
|
||||
print("RetryPolicy Examples")
|
||||
print("=" * 50)
|
||||
|
||||
# 1. Default policy
|
||||
print("\n1. Default RetryPolicy:")
|
||||
policy = RetryPolicy()
|
||||
print(f" max_attempts: {policy.max_attempts}")
|
||||
print(f" backoff_factor: {policy.backoff_factor}")
|
||||
print(f" initial_delay_ms: {policy.initial_delay_ms}")
|
||||
print(f" max_delay_ms: {policy.max_delay_ms}")
|
||||
print(f" retry_on: {policy.retry_on}")
|
||||
|
||||
# 2. Exponential backoff calculation
|
||||
print("\n2. Exponential Backoff (no jitter):")
|
||||
policy = RetryPolicy(
|
||||
initial_delay_ms=1000,
|
||||
backoff_factor=2.0,
|
||||
max_delay_ms=30000,
|
||||
jitter=False
|
||||
)
|
||||
for attempt in range(5):
|
||||
delay = policy.get_delay_ms(attempt)
|
||||
print(f" Attempt {attempt}: delay = {delay}ms")
|
||||
|
||||
# 3. With jitter for production
|
||||
print("\n3. With Jitter (production-ready):")
|
||||
policy = RetryPolicy(
|
||||
initial_delay_ms=1000,
|
||||
backoff_factor=2.0,
|
||||
jitter=True,
|
||||
jitter_factor=0.25 # ±25%
|
||||
)
|
||||
print(" Delays for attempt 0 (10 samples):")
|
||||
delays = [policy.get_delay_ms(0) for _ in range(10)]
|
||||
print(f" {delays}")
|
||||
print(f" Range: {min(delays)} - {max(delays)} (expected: 750-1250)")
|
||||
|
||||
# 4. should_retry logic
|
||||
print("\n4. should_retry Logic:")
|
||||
policy = RetryPolicy(max_attempts=3, retry_on={"timeout", "rate_limit"})
|
||||
|
||||
test_cases = [
|
||||
("timeout", 0),
|
||||
("timeout", 2),
|
||||
("timeout", 3), # At max_attempts
|
||||
("unknown_error", 0), # Not in retry_on
|
||||
]
|
||||
for error_type, attempt in test_cases:
|
||||
result = policy.should_retry(error_type, attempt)
|
||||
print(f" should_retry('{error_type}', {attempt}) = {result}")
|
||||
|
||||
# 5. Custom error types
|
||||
print("\n5. Custom Error Types:")
|
||||
policy = RetryPolicy(retry_on={"api_error", "network_error", "throttled"})
|
||||
print(f" Retries on: {policy.retry_on}")
|
||||
print(f" should_retry('api_error', 0) = {policy.should_retry('api_error', 0)}")
|
||||
print(f" should_retry('timeout', 0) = {policy.should_retry('timeout', 0)}")
|
||||
|
||||
|
||||
def example_fallback_chain():
|
||||
"""Demonstrate FallbackChain configuration."""
|
||||
print("\n" + "=" * 50)
|
||||
print("FallbackChain Examples")
|
||||
print("=" * 50)
|
||||
|
||||
# 1. Basic chain
|
||||
print("\n1. Basic FallbackChain:")
|
||||
chain = FallbackChain(
|
||||
tools=["web_search", "cached_search", "default_response"]
|
||||
)
|
||||
print(f" Tools: {chain.tools}")
|
||||
print(f" Length: {len(chain)}")
|
||||
print(f" stop_on_success: {chain.stop_on_success}")
|
||||
|
||||
# 2. Iteration
|
||||
print("\n2. Iterating over chain:")
|
||||
for i, tool in enumerate(chain):
|
||||
print(f" {i+1}. {tool}")
|
||||
|
||||
# 3. Try all (don't stop on success)
|
||||
print("\n3. Try All Mode:")
|
||||
chain = FallbackChain(
|
||||
tools=["validator_1", "validator_2", "validator_3"],
|
||||
stop_on_success=False
|
||||
)
|
||||
print(f" stop_on_success: {chain.stop_on_success}")
|
||||
print(" (All tools will be tried regardless of success)")
|
||||
|
||||
|
||||
def example_tool_execution_config():
|
||||
"""Demonstrate ToolExecutionConfig combining retry and fallback."""
|
||||
print("\n" + "=" * 50)
|
||||
print("ToolExecutionConfig Examples")
|
||||
print("=" * 50)
|
||||
|
||||
# 1. Default config
|
||||
print("\n1. Default Config:")
|
||||
config = ToolExecutionConfig()
|
||||
print(f" retry_policy: {config.retry_policy}")
|
||||
print(f" fallback_chain: {config.fallback_chain}")
|
||||
print(f" timeout_ms: {config.timeout_ms}")
|
||||
|
||||
# 2. Using default() factory
|
||||
print("\n2. Default Factory:")
|
||||
config = ToolExecutionConfig.default()
|
||||
print(f" retry_policy.max_attempts: {config.retry_policy.max_attempts}")
|
||||
|
||||
# 3. Full configuration
|
||||
print("\n3. Full Configuration:")
|
||||
config = ToolExecutionConfig(
|
||||
retry_policy=RetryPolicy(
|
||||
max_attempts=5,
|
||||
backoff_factor=1.5,
|
||||
initial_delay_ms=500,
|
||||
jitter=True
|
||||
),
|
||||
fallback_chain=FallbackChain(
|
||||
tools=["primary_api", "backup_api", "cache"]
|
||||
),
|
||||
timeout_ms=10000
|
||||
)
|
||||
print(f" retry_policy.max_attempts: {config.retry_policy.max_attempts}")
|
||||
print(f" retry_policy.jitter: {config.retry_policy.jitter}")
|
||||
print(f" fallback_chain tools: {config.fallback_chain.tools}")
|
||||
print(f" timeout_ms: {config.timeout_ms}")
|
||||
|
||||
|
||||
def example_validation():
|
||||
"""Demonstrate validation of RetryPolicy parameters."""
|
||||
print("\n" + "=" * 50)
|
||||
print("Validation Examples")
|
||||
print("=" * 50)
|
||||
|
||||
invalid_configs = [
|
||||
("max_attempts=0", {"max_attempts": 0}),
|
||||
("backoff_factor=0.5", {"backoff_factor": 0.5}),
|
||||
("initial_delay_ms=-1", {"initial_delay_ms": -1}),
|
||||
("max_delay < initial", {"initial_delay_ms": 1000, "max_delay_ms": 500}),
|
||||
("jitter_factor=1.5", {"jitter_factor": 1.5}),
|
||||
]
|
||||
|
||||
for name, kwargs in invalid_configs:
|
||||
try:
|
||||
RetryPolicy(**kwargs)
|
||||
print(f"\n {name}: No error (unexpected!)")
|
||||
except ValueError as e:
|
||||
print(f"\n {name}:")
|
||||
print(f" → ValueError: {e}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
example_retry_policy()
|
||||
example_fallback_chain()
|
||||
example_tool_execution_config()
|
||||
example_validation()
|
||||
|
||||
print("\n" + "=" * 50)
|
||||
print("All examples completed!")
|
||||
print("=" * 50)
|
||||
@@ -0,0 +1,163 @@
|
||||
"""Example: Tool Validation with Custom Validators
|
||||
|
||||
This example demonstrates how to use ValidationResult and implement
|
||||
custom validators using the ToolValidatorProtocol.
|
||||
"""
|
||||
from praisonaiagents.tools import (
|
||||
ValidationResult,
|
||||
ToolValidatorProtocol,
|
||||
PassthroughValidator,
|
||||
)
|
||||
|
||||
|
||||
def example_validation_result():
|
||||
"""Demonstrate ValidationResult usage."""
|
||||
print("=" * 50)
|
||||
print("ValidationResult Examples")
|
||||
print("=" * 50)
|
||||
|
||||
# 1. Success factory
|
||||
success = ValidationResult.success()
|
||||
print(f"\n1. Success: valid={success.valid}, bool={bool(success)}")
|
||||
|
||||
# 2. Failure factory
|
||||
failure = ValidationResult.failure(
|
||||
errors=["Query cannot be empty", "Missing required field"],
|
||||
remediation="Provide a non-empty query string"
|
||||
)
|
||||
print(f"\n2. Failure: valid={failure.valid}")
|
||||
print(f" Errors: {failure.errors}")
|
||||
print(f" Remediation: {failure.remediation}")
|
||||
|
||||
# 3. Fluent API - building incrementally
|
||||
result = ValidationResult(valid=True)
|
||||
result.add_warning("Query is very long, may be slow")
|
||||
result.add_warning("Consider using pagination")
|
||||
print(f"\n3. With warnings: valid={result.valid}, warnings={result.warnings}")
|
||||
|
||||
# 4. Adding errors changes validity
|
||||
result.add_error("Rate limit exceeded")
|
||||
print(f"\n4. After error: valid={result.valid}, errors={result.errors}")
|
||||
|
||||
|
||||
class InputLengthValidator:
|
||||
"""Custom validator that checks string input lengths."""
|
||||
|
||||
def __init__(self, max_length: int = 100):
|
||||
self.max_length = max_length
|
||||
|
||||
def validate_args(self, tool_name, args, context=None):
|
||||
"""Validate that string arguments don't exceed max length."""
|
||||
for key, value in args.items():
|
||||
if isinstance(value, str) and len(value) > self.max_length:
|
||||
return ValidationResult.failure(
|
||||
errors=[f"Argument '{key}' ({len(value)} chars) exceeds limit ({self.max_length})"],
|
||||
remediation=f"Truncate '{key}' to {self.max_length} characters or less"
|
||||
)
|
||||
return ValidationResult.success()
|
||||
|
||||
def validate_result(self, tool_name, result, context=None):
|
||||
"""Validate tool results."""
|
||||
return ValidationResult.success()
|
||||
|
||||
|
||||
class TypeValidator:
|
||||
"""Custom validator that checks argument types."""
|
||||
|
||||
def __init__(self, type_specs: dict):
|
||||
"""
|
||||
Args:
|
||||
type_specs: Dict mapping arg names to expected types
|
||||
e.g., {"query": str, "limit": int}
|
||||
"""
|
||||
self.type_specs = type_specs
|
||||
|
||||
def validate_args(self, tool_name, args, context=None):
|
||||
result = ValidationResult(valid=True)
|
||||
|
||||
for arg_name, expected_type in self.type_specs.items():
|
||||
if arg_name in args:
|
||||
actual_value = args[arg_name]
|
||||
if not isinstance(actual_value, expected_type):
|
||||
result.add_error(
|
||||
f"Argument '{arg_name}' must be {expected_type.__name__}, "
|
||||
f"got {type(actual_value).__name__}"
|
||||
)
|
||||
|
||||
if not result.valid:
|
||||
result.remediation = "Check argument types and try again"
|
||||
|
||||
return result
|
||||
|
||||
def validate_result(self, tool_name, result, context=None):
|
||||
return ValidationResult.success()
|
||||
|
||||
|
||||
def example_custom_validators():
|
||||
"""Demonstrate custom validator implementations."""
|
||||
print("\n" + "=" * 50)
|
||||
print("Custom Validator Examples")
|
||||
print("=" * 50)
|
||||
|
||||
# 1. InputLengthValidator
|
||||
print("\n1. InputLengthValidator:")
|
||||
validator = InputLengthValidator(max_length=50)
|
||||
|
||||
# Valid input
|
||||
result = validator.validate_args("search", {"query": "short query"})
|
||||
print(f" Short query: valid={result.valid}")
|
||||
|
||||
# Invalid input
|
||||
long_query = "x" * 100
|
||||
result = validator.validate_args("search", {"query": long_query})
|
||||
print(f" Long query: valid={result.valid}")
|
||||
print(f" Error: {result.errors[0]}")
|
||||
print(f" Fix: {result.remediation}")
|
||||
|
||||
# 2. TypeValidator
|
||||
print("\n2. TypeValidator:")
|
||||
validator = TypeValidator({"query": str, "limit": int, "offset": int})
|
||||
|
||||
# Valid types
|
||||
result = validator.validate_args("search", {"query": "test", "limit": 10})
|
||||
print(f" Correct types: valid={result.valid}")
|
||||
|
||||
# Invalid types
|
||||
result = validator.validate_args("search", {"query": 123, "limit": "ten"})
|
||||
print(f" Wrong types: valid={result.valid}")
|
||||
for error in result.errors:
|
||||
print(f" - {error}")
|
||||
|
||||
# 3. Protocol compliance check
|
||||
print("\n3. Protocol Compliance:")
|
||||
print(f" InputLengthValidator: {isinstance(InputLengthValidator(), ToolValidatorProtocol)}")
|
||||
print(f" TypeValidator: {isinstance(TypeValidator({}), ToolValidatorProtocol)}")
|
||||
print(f" PassthroughValidator: {isinstance(PassthroughValidator(), ToolValidatorProtocol)}")
|
||||
|
||||
|
||||
def example_passthrough_validator():
|
||||
"""Demonstrate the default PassthroughValidator."""
|
||||
print("\n" + "=" * 50)
|
||||
print("PassthroughValidator Example")
|
||||
print("=" * 50)
|
||||
|
||||
validator = PassthroughValidator()
|
||||
|
||||
# Always returns valid
|
||||
result = validator.validate_args("any_tool", {"any": "args"})
|
||||
print(f"\nvalidate_args: valid={result.valid}")
|
||||
|
||||
result = validator.validate_result("any_tool", {"any": "result"})
|
||||
print(f"validate_result: valid={result.valid}")
|
||||
|
||||
print("\nPassthroughValidator is useful as a default when no validation is needed.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
example_validation_result()
|
||||
example_custom_validators()
|
||||
example_passthrough_validator()
|
||||
|
||||
print("\n" + "=" * 50)
|
||||
print("All examples completed!")
|
||||
print("=" * 50)
|
||||
@@ -0,0 +1,170 @@
|
||||
"""
|
||||
Model Failover Example - Automatic Provider Switching
|
||||
|
||||
This example demonstrates how to configure model failover
|
||||
for reliability and cost optimization.
|
||||
"""
|
||||
|
||||
import os
|
||||
from praisonaiagents import (
|
||||
AuthProfile,
|
||||
FailoverConfig,
|
||||
FailoverManager,
|
||||
)
|
||||
|
||||
# Create auth profiles for different providers
|
||||
openai_profile = AuthProfile(
|
||||
name="openai-primary",
|
||||
provider="openai",
|
||||
api_key=os.environ.get("OPENAI_API_KEY", "sk-..."),
|
||||
priority=1, # Highest priority
|
||||
rate_limit=100,
|
||||
)
|
||||
|
||||
anthropic_profile = AuthProfile(
|
||||
name="anthropic-backup",
|
||||
provider="anthropic",
|
||||
api_key=os.environ.get("ANTHROPIC_API_KEY", "sk-ant-..."),
|
||||
priority=2, # Second priority
|
||||
rate_limit=50,
|
||||
)
|
||||
|
||||
groq_profile = AuthProfile(
|
||||
name="groq-fallback",
|
||||
provider="groq",
|
||||
api_key=os.environ.get("GROQ_API_KEY", "gsk-..."),
|
||||
priority=3, # Third priority (fast but limited)
|
||||
rate_limit=30,
|
||||
)
|
||||
|
||||
# Configure failover behavior
|
||||
failover_config = FailoverConfig(
|
||||
max_retries=3,
|
||||
retry_delay=1.0,
|
||||
exponential_backoff=True,
|
||||
max_retry_delay=60.0,
|
||||
failover_on_rate_limit=True,
|
||||
failover_on_timeout=True,
|
||||
failover_on_error=True,
|
||||
)
|
||||
|
||||
# Create failover manager
|
||||
manager = FailoverManager(failover_config)
|
||||
manager.add_profile(openai_profile)
|
||||
manager.add_profile(anthropic_profile)
|
||||
manager.add_profile(groq_profile)
|
||||
|
||||
def demonstrate_failover():
|
||||
"""Demonstrate failover functionality."""
|
||||
|
||||
print("Failover Manager Status:")
|
||||
print()
|
||||
|
||||
# Get current status
|
||||
status = manager.status()
|
||||
for name, info in status.items():
|
||||
print(f" {name}:")
|
||||
print(f" Status: {info.get('status', 'unknown')}")
|
||||
print(f" Priority: {info.get('priority', 'N/A')}")
|
||||
print(f" Failures: {info.get('failure_count', 0)}")
|
||||
print()
|
||||
|
||||
# Get next available profile
|
||||
next_profile = manager.get_next_profile()
|
||||
if next_profile:
|
||||
print(f"Next profile to use: {next_profile.name}")
|
||||
print(f" Provider: {next_profile.provider}")
|
||||
print(f" Priority: {next_profile.priority}")
|
||||
print()
|
||||
|
||||
# Simulate marking a failure
|
||||
print("Simulating failure on primary provider...")
|
||||
manager.mark_failure("openai-primary", "Rate limit exceeded")
|
||||
|
||||
# Get next profile after failure
|
||||
next_profile = manager.get_next_profile()
|
||||
if next_profile:
|
||||
print(f"After failure, next profile: {next_profile.name}")
|
||||
print()
|
||||
|
||||
# Get retry delay
|
||||
delay = manager.get_retry_delay("openai-primary")
|
||||
print(f"Retry delay for openai-primary: {delay}s")
|
||||
print()
|
||||
|
||||
# Reset all providers
|
||||
print("Resetting all providers...")
|
||||
manager.reset_all()
|
||||
|
||||
next_profile = manager.get_next_profile()
|
||||
if next_profile:
|
||||
print(f"After reset, next profile: {next_profile.name}")
|
||||
|
||||
def cost_optimization_example():
|
||||
"""Example of cost-optimized failover."""
|
||||
|
||||
print("\nCost Optimization Example:")
|
||||
print("-" * 40)
|
||||
|
||||
# Create cost-optimized manager
|
||||
cost_manager = FailoverManager()
|
||||
|
||||
# Cheaper model first
|
||||
cost_manager.add_profile(AuthProfile(
|
||||
name="gpt-4o-mini",
|
||||
provider="openai",
|
||||
api_key=os.environ.get("OPENAI_API_KEY", ""),
|
||||
priority=1,
|
||||
metadata={"model": "gpt-4o-mini", "cost_per_1k": 0.00015}
|
||||
))
|
||||
|
||||
# Premium model as fallback
|
||||
cost_manager.add_profile(AuthProfile(
|
||||
name="gpt-4o",
|
||||
provider="openai",
|
||||
api_key=os.environ.get("OPENAI_API_KEY", ""),
|
||||
priority=2,
|
||||
metadata={"model": "gpt-4o", "cost_per_1k": 0.005}
|
||||
))
|
||||
|
||||
# Most expensive as last resort
|
||||
cost_manager.add_profile(AuthProfile(
|
||||
name="claude-opus",
|
||||
provider="anthropic",
|
||||
api_key=os.environ.get("ANTHROPIC_API_KEY", ""),
|
||||
priority=3,
|
||||
metadata={"model": "claude-3-opus", "cost_per_1k": 0.015}
|
||||
))
|
||||
|
||||
print("Cost-optimized failover chain:")
|
||||
for profile in [
|
||||
cost_manager.get_profile("gpt-4o-mini"),
|
||||
cost_manager.get_profile("gpt-4o"),
|
||||
cost_manager.get_profile("claude-opus"),
|
||||
]:
|
||||
if profile:
|
||||
cost = profile.metadata.get("cost_per_1k", "N/A")
|
||||
print(f" {profile.priority}. {profile.name} (${cost}/1K tokens)")
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Model Failover Configuration")
|
||||
print("=" * 40)
|
||||
print()
|
||||
|
||||
print("Failover Config:")
|
||||
print(f" Max retries: {failover_config.max_retries}")
|
||||
print(f" Initial delay: {failover_config.retry_delay}s")
|
||||
print(f" Exponential backoff: {failover_config.exponential_backoff}")
|
||||
print(f" Max delay: {failover_config.max_retry_delay}s")
|
||||
print()
|
||||
|
||||
print("Auth Profiles:")
|
||||
for profile in [openai_profile, anthropic_profile, groq_profile]:
|
||||
print(f" {profile.name}:")
|
||||
print(f" Provider: {profile.provider}")
|
||||
print(f" Priority: {profile.priority}")
|
||||
print(f" Rate limit: {profile.rate_limit} req/min")
|
||||
print()
|
||||
|
||||
demonstrate_failover()
|
||||
cost_optimization_example()
|
||||
File renamed without changes.
@@ -0,0 +1,47 @@
|
||||
"""
|
||||
Gateway Example - Multi-Agent Coordination
|
||||
|
||||
This example demonstrates how to use the Gateway for coordinating
|
||||
multiple agents and managing real-time communication.
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent, GatewayConfig, SessionConfig
|
||||
|
||||
# Configure the gateway
|
||||
gateway_config = GatewayConfig(
|
||||
host="127.0.0.1",
|
||||
port=8765,
|
||||
max_connections=100,
|
||||
heartbeat_interval=30,
|
||||
session_config=SessionConfig(
|
||||
timeout=3600, # 1 hour session timeout
|
||||
max_messages=500,
|
||||
)
|
||||
)
|
||||
|
||||
# Create specialized agents
|
||||
researcher = Agent(
|
||||
name="researcher",
|
||||
instructions="You research topics thoroughly and provide detailed information.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
writer = Agent(
|
||||
name="writer",
|
||||
instructions="You write clear, engaging content based on research.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Example: Simple agent interaction
|
||||
if __name__ == "__main__":
|
||||
print("Gateway Configuration:")
|
||||
print(f" Host: {gateway_config.host}")
|
||||
print(f" Port: {gateway_config.port}")
|
||||
print(f" WebSocket URL: {gateway_config.ws_url}")
|
||||
print(f" Max Connections: {gateway_config.max_connections}")
|
||||
print()
|
||||
|
||||
# Test agent
|
||||
response = researcher.start("What are the key benefits of multi-agent systems?")
|
||||
print("Researcher Response:")
|
||||
print(response)
|
||||
@@ -104,11 +104,13 @@ def main():
|
||||
agents = Agents(
|
||||
agents=[researcher, retriever],
|
||||
tasks=[store_task, verify_task, query_task, query_both_task], # Use same verbose level as memory
|
||||
memory=True,
|
||||
embedder={
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small"
|
||||
memory={
|
||||
"provider": "rag",
|
||||
"embedder": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small"
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
from praisonaiagents import ImageAgent
|
||||
|
||||
agent = ImageAgent(llm="openai/dall-e-3", style="vivid")
|
||||
|
||||
# Generate with options
|
||||
result = agent.generate("A futuristic city", size="1792x1024", quality="hd")
|
||||
print(result.data[0].url)
|
||||
|
||||
# Edit image (dall-e-2 only)
|
||||
agent2 = ImageAgent(llm="openai/dall-e-2")
|
||||
edited = agent2.edit("photo.png", "Add a rainbow")
|
||||
print(edited.data[0].url)
|
||||
|
||||
# Generate variations
|
||||
variations = agent2.variation("photo.png", n=3)
|
||||
for img in variations.data:
|
||||
print(img.url)
|
||||
@@ -0,0 +1,8 @@
|
||||
# Image Generation with DALL-E
|
||||
# Requires: export OPENAI_API_KEY=your-key
|
||||
|
||||
from praisonaiagents import ImageAgent
|
||||
|
||||
agent = ImageAgent(llm="openai/dall-e-3")
|
||||
result = agent.generate("A sunset over mountains")
|
||||
print(result.data[0].url)
|
||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,72 @@
|
||||
"""
|
||||
MCP Auth Storage Example
|
||||
|
||||
This example demonstrates how to use the MCPAuthStorage class
|
||||
to manage OAuth tokens for remote MCP servers.
|
||||
"""
|
||||
|
||||
from praisonaiagents.mcp import (
|
||||
MCPAuthStorage,
|
||||
generate_state,
|
||||
generate_code_verifier,
|
||||
generate_code_challenge,
|
||||
get_redirect_url
|
||||
)
|
||||
import time
|
||||
|
||||
# Initialize auth storage
|
||||
storage = MCPAuthStorage()
|
||||
print(f"Auth storage path: {storage.filepath}")
|
||||
|
||||
# Generate PKCE parameters for OAuth flow
|
||||
state = generate_state()
|
||||
verifier = generate_code_verifier()
|
||||
challenge = generate_code_challenge(verifier)
|
||||
redirect_url = get_redirect_url()
|
||||
|
||||
print("\n=== PKCE Parameters ===")
|
||||
print(f"State: {state[:30]}...")
|
||||
print(f"Verifier: {verifier[:30]}...")
|
||||
print(f"Challenge: {challenge[:30]}...")
|
||||
print(f"Redirect URL: {redirect_url}")
|
||||
|
||||
# Store tokens (simulating OAuth callback)
|
||||
print("\n=== Storing Tokens ===")
|
||||
storage.set_tokens("example-server", {
|
||||
"access_token": "example_access_token_12345",
|
||||
"refresh_token": "example_refresh_token_67890",
|
||||
"expires_at": time.time() + 3600, # 1 hour from now
|
||||
"scope": "read write"
|
||||
}, server_url="https://mcp.example.com/mcp")
|
||||
print("Tokens stored successfully")
|
||||
|
||||
# Retrieve tokens
|
||||
entry = storage.get("example-server")
|
||||
print("\n=== Retrieved Entry ===")
|
||||
print(f"Server URL: {entry['server_url']}")
|
||||
print(f"Access Token: {entry['tokens']['access_token'][:20]}...")
|
||||
print(f"Expires At: {entry['tokens']['expires_at']}")
|
||||
|
||||
# Check token expiration
|
||||
is_expired = storage.is_token_expired("example-server")
|
||||
print("\n=== Token Status ===")
|
||||
print(f"Is Expired: {is_expired}")
|
||||
|
||||
# URL validation
|
||||
print("\n=== URL Validation ===")
|
||||
valid = storage.get_for_url("example-server", "https://mcp.example.com/mcp")
|
||||
print(f"Same URL: {valid is not None}")
|
||||
|
||||
invalid = storage.get_for_url("example-server", "https://different.url/mcp")
|
||||
print(f"Different URL: {invalid is None}")
|
||||
|
||||
# List all entries
|
||||
print("\n=== All Entries ===")
|
||||
all_entries = storage.all()
|
||||
for name, entry in all_entries.items():
|
||||
print(f" {name}: {entry.get('server_url', 'N/A')}")
|
||||
|
||||
# Cleanup
|
||||
storage.remove("example-server")
|
||||
print("\n=== Cleanup ===")
|
||||
print("Removed example-server entry")
|
||||
@@ -0,0 +1,32 @@
|
||||
"""
|
||||
Remote MCP Server with OAuth Authentication Example
|
||||
|
||||
This example shows how to connect to a remote MCP server
|
||||
that requires OAuth 2.1 authentication.
|
||||
|
||||
Prerequisites:
|
||||
1. Configure the remote server in ~/.praison/config.yaml
|
||||
2. Run: praisonai mcp auth <server-name>
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent, MCP
|
||||
from praisonaiagents.mcp import MCPAuthStorage
|
||||
|
||||
# Check if authenticated
|
||||
storage = MCPAuthStorage()
|
||||
entry = storage.get("my-remote-server")
|
||||
|
||||
if not entry or not entry.get("tokens"):
|
||||
print("Not authenticated. Run: praisonai mcp auth my-remote-server")
|
||||
exit(1)
|
||||
|
||||
# Create agent with remote MCP server
|
||||
agent = Agent(
|
||||
name="Remote Assistant",
|
||||
instructions="You help with tasks using the remote MCP server.",
|
||||
llm="gpt-4o-mini",
|
||||
tools=MCP("https://mcp.example.com/mcp")
|
||||
)
|
||||
|
||||
# Start the agent
|
||||
agent.start("What tools are available?")
|
||||
File renamed without changes.
@@ -61,7 +61,7 @@ agents_system = Agents(
|
||||
agents=[knowledge_agent],
|
||||
tasks=[build_task, query_task],
|
||||
memory=True,
|
||||
memory_config=memory_config, output="verbose"
|
||||
memory=memory_config, output="verbose"
|
||||
)
|
||||
|
||||
print("Starting graph memory demonstration...")
|
||||
|
||||
@@ -62,7 +62,7 @@ agents_system = Agents(
|
||||
agents=[research_agent],
|
||||
tasks=[build_memory_task, search_task],
|
||||
memory=True,
|
||||
memory_config=memory_config, output="verbose"
|
||||
memory=memory_config, output="verbose"
|
||||
)
|
||||
|
||||
print("Starting memory search optimization demonstration...")
|
||||
|
||||
@@ -85,13 +85,13 @@ def main():
|
||||
agents = Agents(
|
||||
agents=[researcher, retriever],
|
||||
tasks=[store_task, retrieve_task],
|
||||
memory=True,
|
||||
embedder={
|
||||
"provider": "gemini",
|
||||
"config": {
|
||||
"model": "text-embedding-004",
|
||||
# Optional: specify task type for better results
|
||||
# "task_type": "RETRIEVAL_DOCUMENT"
|
||||
memory={
|
||||
"provider": "rag",
|
||||
"embedder": {
|
||||
"provider": "gemini",
|
||||
"config": {
|
||||
"model": "text-embedding-004",
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -153,7 +153,7 @@ def main():
|
||||
agents=[researcher],
|
||||
tasks=[build_knowledge_task, query_knowledge_task, expand_knowledge_task],
|
||||
memory=True,
|
||||
memory_config=memory_config
|
||||
memory=memory_config
|
||||
)
|
||||
|
||||
print("\n🚀 Starting graph memory demonstration...")
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
"""
|
||||
Example: Memory with Tracing
|
||||
|
||||
This example demonstrates how to use memory with context tracing enabled.
|
||||
When tracing is enabled, memory operations (store/search) emit trace events
|
||||
that can be used for debugging and analysis with the LLM Judge.
|
||||
|
||||
Usage:
|
||||
python memory_with_tracing_example.py
|
||||
|
||||
To judge the trace:
|
||||
praisonai recipe judge <trace_id> --memory
|
||||
"""
|
||||
|
||||
from praisonaiagents.memory import Memory
|
||||
from praisonaiagents.trace.context_events import (
|
||||
ContextTraceEmitter,
|
||||
ContextListSink,
|
||||
set_context_emitter,
|
||||
reset_context_emitter,
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
# Set up trace emitter to capture events
|
||||
sink = ContextListSink()
|
||||
emitter = ContextTraceEmitter(sink=sink, session_id="memory-demo", enabled=True)
|
||||
token = set_context_emitter(emitter)
|
||||
|
||||
try:
|
||||
# Create memory instance
|
||||
memory = Memory(config={
|
||||
"provider": "rag",
|
||||
"use_embedding": False,
|
||||
"agent_name": "demo_agent", # Used in trace events
|
||||
})
|
||||
|
||||
# Store some memories
|
||||
print("Storing memories...")
|
||||
memory.store_short_term("The user's name is Alice")
|
||||
memory.store_short_term("Alice likes Python programming")
|
||||
memory.store_long_term("Important: Alice prefers dark mode in all applications")
|
||||
|
||||
# Search memories
|
||||
print("\nSearching memories...")
|
||||
results = memory.search_short_term("Alice", limit=5)
|
||||
print(f"Found {len(results)} short-term memories")
|
||||
|
||||
results = memory.search_long_term("preferences", limit=5)
|
||||
print(f"Found {len(results)} long-term memories")
|
||||
|
||||
# Print captured trace events
|
||||
events = sink.get_events()
|
||||
print(f"\n--- Captured {len(events)} trace events ---")
|
||||
for event in events:
|
||||
print(f" {event.event_type.value}: {event.data}")
|
||||
|
||||
# Filter memory-specific events
|
||||
memory_events = [e for e in events if 'memory' in e.event_type.value]
|
||||
print(f"\n--- Memory-specific events: {len(memory_events)} ---")
|
||||
for event in memory_events:
|
||||
print(f" {event.event_type.value}:")
|
||||
print(f" agent: {event.agent_name}")
|
||||
print(f" data: {event.data}")
|
||||
|
||||
finally:
|
||||
reset_context_emitter(token)
|
||||
print("\nTrace emitter reset.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -33,7 +33,7 @@ def init_agent():
|
||||
name="Knowledge Agent",
|
||||
instructions="You answer questions based on the provided knowledge.",
|
||||
knowledge=["kag-research-paper.pdf"],
|
||||
knowledge_config=config,
|
||||
knowledge=config,
|
||||
user_id="user1",
|
||||
llm="deepseek-r1"
|
||||
)
|
||||
|
||||
@@ -31,7 +31,7 @@ agent = Agent(
|
||||
name="Knowledge Agent",
|
||||
instructions="You answer questions based on the provided knowledge.",
|
||||
knowledge=["kag-research-paper.pdf"], # Indexing
|
||||
knowledge_config=config,
|
||||
knowledge=config,
|
||||
user_id="user1",
|
||||
llm="deepseek-r1"
|
||||
)
|
||||
|
||||
@@ -81,7 +81,7 @@ def main():
|
||||
backstory="""You are a knowledge management specialist who excels at
|
||||
organizing, categorizing, and retrieving information from the knowledge base.
|
||||
You ensure that knowledge is properly stored, indexed, and accessible.""",
|
||||
knowledge_config=mongodb_knowledge_config,
|
||||
knowledge=mongodb_knowledge_config,
|
||||
memory=True,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
@@ -107,7 +107,7 @@ def main():
|
||||
backstory="""You are a customer service representative who uses the
|
||||
knowledge base and customer data to provide excellent support. You can
|
||||
access customer history, product information, and troubleshooting guides.""",
|
||||
knowledge_config=mongodb_knowledge_config,
|
||||
knowledge=mongodb_knowledge_config,
|
||||
tools=[mongodb_tools],
|
||||
memory=True,
|
||||
llm="gpt-4o-mini"
|
||||
@@ -190,7 +190,7 @@ def main():
|
||||
agents=[data_manager, knowledge_curator, business_analyst, customer_service],
|
||||
tasks=business_tasks,
|
||||
memory=True,
|
||||
memory_config=mongodb_memory_config, output="verbose"
|
||||
memory=mongodb_memory_config, output="verbose"
|
||||
)
|
||||
|
||||
# Execute the comprehensive business pipeline
|
||||
|
||||
@@ -55,7 +55,7 @@ def main():
|
||||
retrieve information from a comprehensive MongoDB knowledge base. You excel
|
||||
at finding relevant information, synthesizing knowledge from multiple sources,
|
||||
and providing accurate, context-aware responses.""",
|
||||
knowledge_config=mongodb_knowledge_config,
|
||||
knowledge=mongodb_knowledge_config,
|
||||
knowledge=[os.path.join(os.path.dirname(__file__), "llms.md")],
|
||||
memory=True,
|
||||
llm="gpt-4o-mini"
|
||||
|
||||
@@ -94,7 +94,7 @@ def main():
|
||||
agents=[research_agent],
|
||||
tasks=research_tasks,
|
||||
memory=True,
|
||||
memory_config=mongodb_memory_config, output="verbose"
|
||||
memory=mongodb_memory_config, output="verbose"
|
||||
)
|
||||
|
||||
# Execute the research pipeline
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
"""
|
||||
Nested Workflows Example - PraisonAI Agents
|
||||
|
||||
This example demonstrates how to use nested workflow patterns:
|
||||
1. Loop inside Loop (nested iteration)
|
||||
2. Parallel inside Loop (concurrent processing per item)
|
||||
3. Route inside Loop (conditional routing per item)
|
||||
4. Depth limit protection (prevents infinite recursion)
|
||||
|
||||
These patterns enable complex data processing pipelines
|
||||
while maintaining clean, readable workflow definitions.
|
||||
"""
|
||||
|
||||
from praisonaiagents import Workflow, WorkflowContext, StepResult
|
||||
from praisonaiagents.workflows import loop, parallel, route
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Example 1: Nested Loops - Process Matrix Data
|
||||
# =============================================================================
|
||||
|
||||
def nested_loop_example():
|
||||
"""
|
||||
Process a 2D matrix using nested loops.
|
||||
Outer loop iterates rows, inner loop iterates columns.
|
||||
"""
|
||||
print("\n" + "="*60)
|
||||
print("Example 1: Nested Loops - Matrix Processing")
|
||||
print("="*60)
|
||||
|
||||
results = []
|
||||
|
||||
def process_cell(ctx: WorkflowContext) -> StepResult:
|
||||
row = ctx.variables.get("row", {})
|
||||
col = ctx.variables.get("col", "")
|
||||
row_name = row.get("name", "?")
|
||||
results.append(f"{row_name}-{col}")
|
||||
return StepResult(output=f"Processed cell {row_name}-{col}")
|
||||
|
||||
# Inner loop processes columns for each row
|
||||
inner_loop = loop(
|
||||
process_cell,
|
||||
over="columns",
|
||||
var_name="col"
|
||||
)
|
||||
|
||||
# Outer loop iterates through rows
|
||||
outer_loop = loop(
|
||||
steps=[inner_loop],
|
||||
over="rows",
|
||||
var_name="row"
|
||||
)
|
||||
|
||||
workflow = Workflow(
|
||||
steps=[outer_loop],
|
||||
variables={
|
||||
"rows": [
|
||||
{"name": "Row1"},
|
||||
{"name": "Row2"}
|
||||
],
|
||||
"columns": ["A", "B", "C"]
|
||||
}
|
||||
)
|
||||
|
||||
workflow.start("Process matrix")
|
||||
print(f"Processed cells: {results}")
|
||||
# Output: ['Row1-A', 'Row1-B', 'Row1-C', 'Row2-A', 'Row2-B', 'Row2-C']
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Example 2: Parallel Inside Loop - Concurrent Task Processing
|
||||
# =============================================================================
|
||||
|
||||
def parallel_inside_loop_example():
|
||||
"""
|
||||
For each project, run multiple analysis tasks in parallel.
|
||||
Combines iteration with concurrent execution.
|
||||
"""
|
||||
print("\n" + "="*60)
|
||||
print("Example 2: Parallel Inside Loop - Concurrent Analysis")
|
||||
print("="*60)
|
||||
|
||||
results = []
|
||||
|
||||
def security_scan(ctx: WorkflowContext) -> StepResult:
|
||||
project = ctx.variables.get("project", "unknown")
|
||||
results.append(f"security:{project}")
|
||||
return StepResult(output=f"Security scan complete for {project}")
|
||||
|
||||
def performance_test(ctx: WorkflowContext) -> StepResult:
|
||||
project = ctx.variables.get("project", "unknown")
|
||||
results.append(f"performance:{project}")
|
||||
return StepResult(output=f"Performance test complete for {project}")
|
||||
|
||||
def code_review(ctx: WorkflowContext) -> StepResult:
|
||||
project = ctx.variables.get("project", "unknown")
|
||||
results.append(f"review:{project}")
|
||||
return StepResult(output=f"Code review complete for {project}")
|
||||
|
||||
# Parallel tasks run concurrently for each project
|
||||
parallel_analysis = parallel([security_scan, performance_test, code_review])
|
||||
|
||||
# Loop through projects, running parallel analysis for each
|
||||
workflow = Workflow(
|
||||
steps=[
|
||||
loop(
|
||||
steps=[parallel_analysis],
|
||||
over="projects",
|
||||
var_name="project"
|
||||
)
|
||||
],
|
||||
variables={
|
||||
"projects": ["frontend", "backend", "api"]
|
||||
}
|
||||
)
|
||||
|
||||
workflow.start("Analyze all projects")
|
||||
print(f"Analysis results: {sorted(results)}")
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Example 3: Route Inside Loop - Conditional Processing Per Item
|
||||
# =============================================================================
|
||||
|
||||
def route_inside_loop_example():
|
||||
"""
|
||||
Process items differently based on their type.
|
||||
Each item in the loop is routed to the appropriate handler.
|
||||
"""
|
||||
print("\n" + "="*60)
|
||||
print("Example 3: Route Inside Loop - Type-Based Processing")
|
||||
print("="*60)
|
||||
|
||||
results = []
|
||||
|
||||
def process_image(ctx: WorkflowContext) -> StepResult:
|
||||
item = ctx.variables.get("item", {})
|
||||
results.append(f"image:{item.get('name')}")
|
||||
return StepResult(output=f"Processed image: {item.get('name')}")
|
||||
|
||||
def process_video(ctx: WorkflowContext) -> StepResult:
|
||||
item = ctx.variables.get("item", {})
|
||||
results.append(f"video:{item.get('name')}")
|
||||
return StepResult(output=f"Processed video: {item.get('name')}")
|
||||
|
||||
def process_document(ctx: WorkflowContext) -> StepResult:
|
||||
item = ctx.variables.get("item", {})
|
||||
results.append(f"document:{item.get('name')}")
|
||||
return StepResult(output=f"Processed document: {item.get('name')}")
|
||||
|
||||
# Route based on item type
|
||||
type_router = route({
|
||||
"image": [process_image],
|
||||
"video": [process_video],
|
||||
"document": [process_document]
|
||||
})
|
||||
|
||||
# First, determine the type, then route
|
||||
def get_type(ctx: WorkflowContext) -> StepResult:
|
||||
item = ctx.variables.get("item", {})
|
||||
item_type = item.get("type", "unknown")
|
||||
return StepResult(output=item_type)
|
||||
|
||||
workflow = Workflow(
|
||||
steps=[
|
||||
loop(
|
||||
steps=[get_type, type_router],
|
||||
over="files",
|
||||
var_name="item"
|
||||
)
|
||||
],
|
||||
variables={
|
||||
"files": [
|
||||
{"name": "photo.jpg", "type": "image"},
|
||||
{"name": "movie.mp4", "type": "video"},
|
||||
{"name": "report.pdf", "type": "document"},
|
||||
{"name": "logo.png", "type": "image"}
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
workflow.start("Process all files")
|
||||
print(f"Processing results: {results}")
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Example 4: Three-Level Nesting - Complex Data Pipeline
|
||||
# =============================================================================
|
||||
|
||||
def three_level_nesting_example():
|
||||
"""
|
||||
Demonstrate three levels of nesting:
|
||||
Department -> Team -> Member
|
||||
"""
|
||||
print("\n" + "="*60)
|
||||
print("Example 4: Three-Level Nesting - Organization Processing")
|
||||
print("="*60)
|
||||
|
||||
results = []
|
||||
|
||||
def process_member(ctx: WorkflowContext) -> StepResult:
|
||||
dept = ctx.variables.get("dept", {}).get("name", "?")
|
||||
team = ctx.variables.get("team", {}).get("name", "?")
|
||||
member = ctx.variables.get("member", "?")
|
||||
results.append(f"{dept}/{team}/{member}")
|
||||
return StepResult(output=f"Processed {member}")
|
||||
|
||||
# Level 3: Process each member
|
||||
member_loop = loop(process_member, over="members", var_name="member")
|
||||
|
||||
# Level 2: Process each team (contains member loop)
|
||||
team_loop = loop(steps=[member_loop], over="teams", var_name="team")
|
||||
|
||||
# Level 1: Process each department (contains team loop)
|
||||
dept_loop = loop(steps=[team_loop], over="departments", var_name="dept")
|
||||
|
||||
workflow = Workflow(
|
||||
steps=[dept_loop],
|
||||
variables={
|
||||
"departments": [
|
||||
{"name": "Engineering"},
|
||||
{"name": "Marketing"}
|
||||
],
|
||||
"teams": [
|
||||
{"name": "Frontend", "members": ["Alice", "Bob"]},
|
||||
{"name": "Backend", "members": ["Charlie"]}
|
||||
],
|
||||
"members": ["Member1", "Member2"] # Simplified for demo
|
||||
}
|
||||
)
|
||||
|
||||
workflow.start("Process organization")
|
||||
print(f"Processed paths: {results}")
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Main - Run All Examples
|
||||
# =============================================================================
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("\n" + "="*60)
|
||||
print("PraisonAI Nested Workflows Examples")
|
||||
print("="*60)
|
||||
|
||||
nested_loop_example()
|
||||
parallel_inside_loop_example()
|
||||
route_inside_loop_example()
|
||||
three_level_nesting_example()
|
||||
|
||||
print("\n" + "="*60)
|
||||
print("All nested workflow examples completed!")
|
||||
print("="*60)
|
||||
@@ -0,0 +1,12 @@
|
||||
from praisonaiagents import OCRAgent
|
||||
|
||||
agent = OCRAgent()
|
||||
|
||||
# Extract with page selection (pages is 0-indexed)
|
||||
result = agent.extract("https://arxiv.org/pdf/2201.04234", pages=[0, 1])
|
||||
for page in result.pages:
|
||||
print(f"Page {page.index}: {page.markdown[:200]}")
|
||||
|
||||
# Quick read - just get the text
|
||||
text = agent.read("https://arxiv.org/pdf/2201.04234")
|
||||
print(f"Total length: {len(text)} chars")
|
||||
@@ -0,0 +1,9 @@
|
||||
# OCR with Mistral
|
||||
# Requires: export MISTRAL_API_KEY=your-key
|
||||
# Note: Source must be a URL (https://) or base64
|
||||
|
||||
from praisonaiagents import OCRAgent
|
||||
|
||||
agent = OCRAgent()
|
||||
text = agent.read("https://arxiv.org/pdf/2201.04234")
|
||||
print(text[:500]) # First 500 chars
|
||||
@@ -0,0 +1,5 @@
|
||||
from praisonaiagents import OCRAgent
|
||||
|
||||
agent = OCRAgent(llm="mistral/mistral-ocr-latest")
|
||||
text = agent.read("https://arxiv.org/pdf/2201.04234")
|
||||
print(text[:500]) # First 500 chars
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,155 +1,155 @@
|
||||
{
|
||||
"timestamp": "2025-12-31T18:45:38.187539Z",
|
||||
"timestamp": "2026-01-16T05:23:04.919943Z",
|
||||
"metadata": {
|
||||
"python_version": "3.12.11",
|
||||
"platform": "macOS-15.7.4-arm64-arm-64bit",
|
||||
"praisonai_version": "2.9.2",
|
||||
"timestamp": "2025-12-31T18:45:38.226558Z"
|
||||
"platform": "macOS-26.3-arm64-arm-64bit",
|
||||
"praisonai_version": "3.9.2",
|
||||
"timestamp": "2026-01-16T05:23:04.932474Z"
|
||||
},
|
||||
"startup": {
|
||||
"cold_ms": 80.9305000002496,
|
||||
"warm_ms": 55.266541996388696
|
||||
"cold_ms": 27.866583000104583,
|
||||
"warm_ms": 27.75670800019725
|
||||
},
|
||||
"import_analysis": [
|
||||
{
|
||||
"module": "praisonaiagents",
|
||||
"self_us": 2419,
|
||||
"cumulative_us": 1645390,
|
||||
"self_ms": 2.419,
|
||||
"cumulative_ms": 1645.39
|
||||
"self_us": 403,
|
||||
"cumulative_us": 188329,
|
||||
"self_ms": 0.403,
|
||||
"cumulative_ms": 188.329
|
||||
},
|
||||
{
|
||||
"module": "praisonaiagents.workflows",
|
||||
"self_us": 670,
|
||||
"cumulative_us": 1375919,
|
||||
"self_ms": 0.67,
|
||||
"cumulative_ms": 1375.919
|
||||
"self_us": 106,
|
||||
"cumulative_us": 112180,
|
||||
"self_ms": 0.106,
|
||||
"cumulative_ms": 112.18
|
||||
},
|
||||
{
|
||||
"module": "praisonaiagents.workflows.yaml_parser",
|
||||
"self_us": 775,
|
||||
"cumulative_us": 1369435,
|
||||
"self_ms": 0.775,
|
||||
"cumulative_ms": 1369.435
|
||||
"self_us": 217,
|
||||
"cumulative_us": 107210,
|
||||
"self_ms": 0.217,
|
||||
"cumulative_ms": 107.21
|
||||
},
|
||||
{
|
||||
"module": "praisonaiagents.agent.agent",
|
||||
"self_us": 19,
|
||||
"cumulative_us": 1349174,
|
||||
"self_ms": 0.019,
|
||||
"cumulative_ms": 1349.174
|
||||
"self_us": 15,
|
||||
"cumulative_us": 98811,
|
||||
"self_ms": 0.015,
|
||||
"cumulative_ms": 98.811
|
||||
},
|
||||
{
|
||||
"module": "praisonaiagents.agent",
|
||||
"self_us": 537,
|
||||
"cumulative_us": 1349155,
|
||||
"self_ms": 0.537,
|
||||
"cumulative_ms": 1349.155
|
||||
"self_us": 146,
|
||||
"cumulative_us": 98796,
|
||||
"self_ms": 0.146,
|
||||
"cumulative_ms": 98.796
|
||||
},
|
||||
{
|
||||
"module": "praisonaiagents.agent.agent",
|
||||
"self_us": 1453,
|
||||
"cumulative_us": 1285299,
|
||||
"self_ms": 1.453,
|
||||
"cumulative_ms": 1285.299
|
||||
},
|
||||
{
|
||||
"module": "praisonaiagents.llm.openai_client",
|
||||
"self_us": 7887,
|
||||
"cumulative_us": 1123578,
|
||||
"self_ms": 7.887,
|
||||
"cumulative_ms": 1123.578
|
||||
},
|
||||
{
|
||||
"module": "openai",
|
||||
"self_us": 1083,
|
||||
"cumulative_us": 1115692,
|
||||
"self_ms": 1.083,
|
||||
"cumulative_ms": 1115.692
|
||||
},
|
||||
{
|
||||
"module": "openai.types",
|
||||
"self_us": 2606,
|
||||
"cumulative_us": 957990,
|
||||
"self_ms": 2.606,
|
||||
"cumulative_ms": 957.99
|
||||
},
|
||||
{
|
||||
"module": "openai.types.batch",
|
||||
"self_us": 1787,
|
||||
"cumulative_us": 485667,
|
||||
"self_ms": 1.787,
|
||||
"cumulative_ms": 485.667
|
||||
},
|
||||
{
|
||||
"module": "openai._models",
|
||||
"self_us": 13423,
|
||||
"cumulative_us": 450798,
|
||||
"self_ms": 13.423,
|
||||
"cumulative_ms": 450.798
|
||||
},
|
||||
{
|
||||
"module": "openai.types.eval_create_params",
|
||||
"self_us": 644,
|
||||
"cumulative_us": 393275,
|
||||
"self_ms": 0.644,
|
||||
"cumulative_ms": 393.275
|
||||
},
|
||||
{
|
||||
"module": "openai.types.graders.grader_inputs_param",
|
||||
"self_us": 17,
|
||||
"cumulative_us": 359515,
|
||||
"self_ms": 0.017,
|
||||
"cumulative_ms": 359.515
|
||||
},
|
||||
{
|
||||
"module": "openai.types.graders",
|
||||
"self_us": 392,
|
||||
"cumulative_us": 359498,
|
||||
"self_ms": 0.392,
|
||||
"cumulative_ms": 359.498
|
||||
},
|
||||
{
|
||||
"module": "openai.types.graders.multi_grader",
|
||||
"self_us": 3847,
|
||||
"cumulative_us": 351251,
|
||||
"self_ms": 3.847,
|
||||
"cumulative_ms": 351.251
|
||||
},
|
||||
{
|
||||
"module": "openai.types.graders.label_model_grader",
|
||||
"self_us": 5450,
|
||||
"cumulative_us": 337291,
|
||||
"self_ms": 5.45,
|
||||
"cumulative_ms": 337.291
|
||||
},
|
||||
{
|
||||
"module": "openai.types.graders.grader_inputs",
|
||||
"self_us": 545,
|
||||
"cumulative_us": 331841,
|
||||
"self_ms": 0.545,
|
||||
"cumulative_ms": 331.841
|
||||
},
|
||||
{
|
||||
"module": "openai.types.responses.response_input_text",
|
||||
"self_us": 21,
|
||||
"cumulative_us": 331297,
|
||||
"self_ms": 0.021,
|
||||
"cumulative_ms": 331.297
|
||||
},
|
||||
{
|
||||
"module": "openai.types.responses",
|
||||
"self_us": 1301,
|
||||
"cumulative_us": 331277,
|
||||
"self_ms": 1.301,
|
||||
"cumulative_ms": 331.277
|
||||
"self_us": 1027,
|
||||
"cumulative_us": 86223,
|
||||
"self_ms": 1.027,
|
||||
"cumulative_ms": 86.223
|
||||
},
|
||||
{
|
||||
"module": "rich.logging",
|
||||
"self_us": 1066,
|
||||
"cumulative_us": 238256,
|
||||
"self_ms": 1.066,
|
||||
"cumulative_ms": 238.256
|
||||
"self_us": 282,
|
||||
"cumulative_us": 53009,
|
||||
"self_ms": 0.282,
|
||||
"cumulative_ms": 53.009
|
||||
},
|
||||
{
|
||||
"module": "praisonaiagents.main",
|
||||
"self_us": 18784,
|
||||
"cumulative_us": 45759,
|
||||
"self_ms": 18.784,
|
||||
"cumulative_ms": 45.759
|
||||
},
|
||||
{
|
||||
"module": "praisonaiagents.llm.openai_client",
|
||||
"self_us": 2470,
|
||||
"cumulative_us": 28251,
|
||||
"self_ms": 2.47,
|
||||
"cumulative_ms": 28.251
|
||||
},
|
||||
{
|
||||
"module": "rich.traceback",
|
||||
"self_us": 1478,
|
||||
"cumulative_us": 18788,
|
||||
"self_ms": 1.478,
|
||||
"cumulative_ms": 18.788
|
||||
},
|
||||
{
|
||||
"module": "rich.console",
|
||||
"self_us": 1737,
|
||||
"cumulative_us": 18587,
|
||||
"self_ms": 1.737,
|
||||
"cumulative_ms": 18.587
|
||||
},
|
||||
{
|
||||
"module": "pygments.lexers",
|
||||
"self_us": 242,
|
||||
"cumulative_us": 15427,
|
||||
"self_ms": 0.242,
|
||||
"cumulative_ms": 15.427
|
||||
},
|
||||
{
|
||||
"module": "rich.markdown",
|
||||
"self_us": 409,
|
||||
"cumulative_us": 13987,
|
||||
"self_ms": 0.409,
|
||||
"cumulative_ms": 13.987
|
||||
},
|
||||
{
|
||||
"module": "pygments.plugin",
|
||||
"self_us": 85,
|
||||
"cumulative_us": 13503,
|
||||
"self_ms": 0.085,
|
||||
"cumulative_ms": 13.503
|
||||
},
|
||||
{
|
||||
"module": "importlib.metadata",
|
||||
"self_us": 637,
|
||||
"cumulative_us": 13419,
|
||||
"self_ms": 0.637,
|
||||
"cumulative_ms": 13.419
|
||||
},
|
||||
{
|
||||
"module": "rich._log_render",
|
||||
"self_us": 145,
|
||||
"cumulative_us": 13380,
|
||||
"self_ms": 0.145,
|
||||
"cumulative_ms": 13.38
|
||||
},
|
||||
{
|
||||
"module": "markdown_it",
|
||||
"self_us": 172,
|
||||
"cumulative_us": 13339,
|
||||
"self_ms": 0.172,
|
||||
"cumulative_ms": 13.339
|
||||
},
|
||||
{
|
||||
"module": "rich.text",
|
||||
"self_us": 582,
|
||||
"cumulative_us": 13236,
|
||||
"self_ms": 0.582,
|
||||
"cumulative_ms": 13.236
|
||||
},
|
||||
{
|
||||
"module": "markdown_it.main",
|
||||
"self_us": 298,
|
||||
"cumulative_us": 13168,
|
||||
"self_ms": 0.298,
|
||||
"cumulative_ms": 13.168
|
||||
},
|
||||
{
|
||||
"module": "pydantic",
|
||||
"self_us": 223,
|
||||
"cumulative_us": 11119,
|
||||
"self_ms": 0.223,
|
||||
"cumulative_ms": 11.119
|
||||
}
|
||||
],
|
||||
"scenarios": [
|
||||
@@ -162,28 +162,22 @@
|
||||
"iterations": 2
|
||||
},
|
||||
"import_time_stats": {
|
||||
"mean": 0.008833496394800022,
|
||||
"min": 0.005916997906751931,
|
||||
"max": 0.011749994882848114,
|
||||
"stdev": 0.0041245517164382375,
|
||||
"median": 0.008833496394800022
|
||||
"mean": 0,
|
||||
"min": 0,
|
||||
"max": 0,
|
||||
"stdev": 0,
|
||||
"median": 0
|
||||
},
|
||||
"total_time_stats": {
|
||||
"mean": 1727.4090415012324,
|
||||
"min": 1367.2264170018025,
|
||||
"max": 2087.5916660006624,
|
||||
"stdev": 509.3751524982296,
|
||||
"median": 1727.4090415012324
|
||||
"mean": 0,
|
||||
"min": 0,
|
||||
"max": 0,
|
||||
"stdev": 0,
|
||||
"median": 0
|
||||
},
|
||||
"first_token_stats": null,
|
||||
"raw_import_times_ms": [
|
||||
0.011749994882848114,
|
||||
0.005916997906751931
|
||||
],
|
||||
"raw_total_times_ms": [
|
||||
1367.2264170018025,
|
||||
2087.5916660006624
|
||||
]
|
||||
"raw_import_times_ms": [],
|
||||
"raw_total_times_ms": []
|
||||
},
|
||||
{
|
||||
"name": "simple_stream",
|
||||
@@ -194,34 +188,22 @@
|
||||
"iterations": 2
|
||||
},
|
||||
"import_time_stats": {
|
||||
"mean": 0.008792001608526334,
|
||||
"min": 0.006375004886649549,
|
||||
"max": 0.01120899833040312,
|
||||
"stdev": 0.0034181495442894613,
|
||||
"median": 0.008792001608526334
|
||||
"mean": 0,
|
||||
"min": 0,
|
||||
"max": 0,
|
||||
"stdev": 0,
|
||||
"median": 0
|
||||
},
|
||||
"total_time_stats": {
|
||||
"mean": 2321.0982290001994,
|
||||
"min": 1697.1089580038097,
|
||||
"max": 2945.087499996589,
|
||||
"stdev": 882.4540898183949,
|
||||
"median": 2321.0982290001994
|
||||
"mean": 0,
|
||||
"min": 0,
|
||||
"max": 0,
|
||||
"stdev": 0,
|
||||
"median": 0
|
||||
},
|
||||
"first_token_stats": {
|
||||
"mean": 2312.8511880022415,
|
||||
"min": 1681.2440420035273,
|
||||
"max": 2944.458334000956,
|
||||
"stdev": 893.2273919631452,
|
||||
"median": 2312.8511880022415
|
||||
},
|
||||
"raw_import_times_ms": [
|
||||
0.01120899833040312,
|
||||
0.006375004886649549
|
||||
],
|
||||
"raw_total_times_ms": [
|
||||
2945.087499996589,
|
||||
1697.1089580038097
|
||||
]
|
||||
"first_token_stats": null,
|
||||
"raw_import_times_ms": [],
|
||||
"raw_total_times_ms": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
"""
|
||||
Sandbox Example - Secure Code Execution
|
||||
|
||||
This example demonstrates how to configure and use sandboxes
|
||||
for safe code execution.
|
||||
"""
|
||||
|
||||
from praisonaiagents import (
|
||||
SandboxConfig,
|
||||
ResourceLimits,
|
||||
SandboxResult,
|
||||
SandboxStatus
|
||||
)
|
||||
from praisonaiagents.sandbox import SecurityPolicy
|
||||
|
||||
# Minimal sandbox for untrusted code
|
||||
minimal_sandbox = SandboxConfig(
|
||||
sandbox_type="subprocess",
|
||||
resource_limits=ResourceLimits.minimal(),
|
||||
security_policy=SecurityPolicy.strict(),
|
||||
)
|
||||
|
||||
# Standard sandbox for general use
|
||||
standard_sandbox = SandboxConfig(
|
||||
sandbox_type="subprocess",
|
||||
resource_limits=ResourceLimits.standard(),
|
||||
security_policy=SecurityPolicy.standard(),
|
||||
)
|
||||
|
||||
# Docker sandbox for full isolation
|
||||
docker_sandbox = SandboxConfig.docker(image="python:3.11-slim")
|
||||
|
||||
# Custom sandbox configuration
|
||||
custom_sandbox = SandboxConfig(
|
||||
sandbox_type="subprocess",
|
||||
working_dir="/tmp/sandbox",
|
||||
resource_limits=ResourceLimits(
|
||||
memory_mb=256,
|
||||
cpu_percent=50,
|
||||
timeout_seconds=30,
|
||||
network_enabled=False,
|
||||
max_processes=5,
|
||||
),
|
||||
security_policy=SecurityPolicy(
|
||||
allow_network=False,
|
||||
allow_file_write=True,
|
||||
allow_subprocess=False,
|
||||
blocked_imports=["subprocess", "os.system", "eval"],
|
||||
),
|
||||
auto_cleanup=True,
|
||||
)
|
||||
|
||||
def demonstrate_result_handling():
|
||||
"""Show how to handle sandbox results."""
|
||||
|
||||
# Simulated successful result
|
||||
success_result = SandboxResult(
|
||||
status=SandboxStatus.COMPLETED,
|
||||
exit_code=0,
|
||||
stdout="Hello, World!\n",
|
||||
stderr="",
|
||||
duration_seconds=0.1,
|
||||
)
|
||||
|
||||
# Simulated timeout result
|
||||
timeout_result = SandboxResult(
|
||||
status=SandboxStatus.TIMEOUT,
|
||||
exit_code=None,
|
||||
stdout="Partial output...",
|
||||
stderr="",
|
||||
error="Execution timed out after 30 seconds",
|
||||
duration_seconds=30.0,
|
||||
)
|
||||
|
||||
# Simulated error result
|
||||
error_result = SandboxResult(
|
||||
status=SandboxStatus.FAILED,
|
||||
exit_code=1,
|
||||
stdout="",
|
||||
stderr="NameError: name 'undefined_var' is not defined",
|
||||
error="Execution failed",
|
||||
)
|
||||
|
||||
print("Result Handling Examples:")
|
||||
print()
|
||||
|
||||
for name, result in [
|
||||
("Success", success_result),
|
||||
("Timeout", timeout_result),
|
||||
("Error", error_result)
|
||||
]:
|
||||
print(f"{name} Result:")
|
||||
print(f" Status: {result.status.name}")
|
||||
print(f" Success: {result.success}")
|
||||
if result.stdout:
|
||||
print(f" Output: {result.stdout.strip()}")
|
||||
if result.stderr:
|
||||
print(f" Error: {result.stderr.strip()}")
|
||||
if result.error:
|
||||
print(f" Message: {result.error}")
|
||||
print()
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Sandbox Configurations:")
|
||||
print()
|
||||
|
||||
print("Minimal Sandbox (for untrusted code):")
|
||||
print(f" Type: {minimal_sandbox.sandbox_type}")
|
||||
print(f" Memory: {minimal_sandbox.resource_limits.memory_mb}MB")
|
||||
print(f" Timeout: {minimal_sandbox.resource_limits.timeout_seconds}s")
|
||||
print(f" Network: {minimal_sandbox.resource_limits.network_enabled}")
|
||||
print()
|
||||
|
||||
print("Standard Sandbox:")
|
||||
print(f" Type: {standard_sandbox.sandbox_type}")
|
||||
print(f" Memory: {standard_sandbox.resource_limits.memory_mb}MB")
|
||||
print(f" Timeout: {standard_sandbox.resource_limits.timeout_seconds}s")
|
||||
print()
|
||||
|
||||
print("Docker Sandbox:")
|
||||
print(f" Type: {docker_sandbox.sandbox_type}")
|
||||
print(f" Image: {docker_sandbox.image}")
|
||||
print()
|
||||
|
||||
print("Custom Sandbox:")
|
||||
print(f" Type: {custom_sandbox.sandbox_type}")
|
||||
print(f" Working Dir: {custom_sandbox.working_dir}")
|
||||
print(f" Memory: {custom_sandbox.resource_limits.memory_mb}MB")
|
||||
print(f" Max Processes: {custom_sandbox.resource_limits.max_processes}")
|
||||
print()
|
||||
|
||||
demonstrate_result_handling()
|
||||
|
||||
print("To run code in sandbox via CLI:")
|
||||
print(" praisonai sandbox run \"print('Hello, World!')\"")
|
||||
print(" praisonai sandbox run --file script.py")
|
||||
print(" praisonai sandbox shell")
|
||||
@@ -0,0 +1,22 @@
|
||||
"""
|
||||
Example 1: Save Agent Output Using write_file Tool
|
||||
|
||||
The agent decides when and what to save based on the task.
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.tools import write_file
|
||||
|
||||
# Create agent with write_file tool
|
||||
agent = Agent(
|
||||
name="ContentWriter",
|
||||
role="Technical Writer",
|
||||
goal="Create and save technical documentation",
|
||||
tools=[write_file]
|
||||
)
|
||||
|
||||
# Agent will use write_file tool to save the content
|
||||
result = agent.start("Write a short poem about coding and save it to poem.txt")
|
||||
|
||||
print("✅ Task completed!")
|
||||
print(f"Result: {result}")
|
||||
@@ -0,0 +1,30 @@
|
||||
"""
|
||||
Example 2: Save Agent Output Using Task.output_file
|
||||
|
||||
Task output is automatically saved to the specified file.
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent, Task, Agents
|
||||
|
||||
# Create agent
|
||||
writer = Agent(
|
||||
name="ContentWriter",
|
||||
role="Writer",
|
||||
goal="Create engaging content"
|
||||
)
|
||||
|
||||
# Task with output_file - auto-saves result
|
||||
task = Task(
|
||||
description="Write a short blog post about the benefits of AI assistants",
|
||||
expected_output="A well-structured blog post in markdown format",
|
||||
agent=writer,
|
||||
output_file="blog_post.md",
|
||||
create_directory=True
|
||||
)
|
||||
|
||||
# Run
|
||||
agents = Agents(agents=[writer], tasks=[task])
|
||||
result = agents.start()
|
||||
|
||||
print("✅ Task completed!")
|
||||
print("Output saved to: blog_post.md")
|
||||
@@ -0,0 +1,41 @@
|
||||
"""
|
||||
Example 3: Save Agent Output Using Workflow output_file
|
||||
|
||||
Workflow step output is automatically saved with variable substitution.
|
||||
"""
|
||||
|
||||
from praisonaiagents import Workflow
|
||||
|
||||
# Define workflow with output_file
|
||||
workflow_config = {
|
||||
"metadata": {
|
||||
"name": "content-generator",
|
||||
"version": "1.0"
|
||||
},
|
||||
"variables": {
|
||||
"output_dir": "generated",
|
||||
"topic": "Python programming"
|
||||
},
|
||||
"agents": {
|
||||
"writer": {
|
||||
"role": "Content Writer",
|
||||
"goal": "Create engaging content",
|
||||
"llm": "gpt-4o-mini"
|
||||
}
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"agent": "writer",
|
||||
"action": "Write a short tutorial about Python basics",
|
||||
"expected_output": "A beginner-friendly tutorial",
|
||||
"output_file": "{{output_dir}}/tutorial.md"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# Run workflow
|
||||
workflow = Workflow(config=workflow_config)
|
||||
result = workflow.run()
|
||||
|
||||
print("✅ Workflow completed!")
|
||||
print("Output saved to: generated/tutorial.md")
|
||||
@@ -0,0 +1,27 @@
|
||||
"""
|
||||
Example 4: Save Agent Output Manually
|
||||
|
||||
Capture the response and save it with full control.
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
from pathlib import Path
|
||||
|
||||
# Create agent
|
||||
agent = Agent(
|
||||
name="StoryWriter",
|
||||
instructions="You are a creative writer who writes short stories."
|
||||
)
|
||||
|
||||
# Get response
|
||||
response = agent.start("Write a very short story about a robot learning to paint")
|
||||
|
||||
# Save manually with error handling
|
||||
output_path = Path("stories/robot_story.txt")
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
try:
|
||||
output_path.write_text(response)
|
||||
print(f"✅ Saved to {output_path}")
|
||||
except IOError as e:
|
||||
print(f"❌ Failed to save: {e}")
|
||||
@@ -0,0 +1,49 @@
|
||||
"""
|
||||
Example: Auto-save agent output to file
|
||||
|
||||
This example demonstrates how to automatically save agent responses to files.
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.config import OutputConfig
|
||||
|
||||
# Method 1: Simplest - just pass a file path string
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
output="output/response.txt" # Just a string path!
|
||||
)
|
||||
|
||||
# When you call start(), the response is automatically saved
|
||||
# result = agent.start("Write a short greeting")
|
||||
# Prints: ✅ Output saved to output/response.txt
|
||||
|
||||
# Method 2: With template formatting using OutputConfig
|
||||
agent_with_template = Agent(
|
||||
instructions="You are a blog writer",
|
||||
output=OutputConfig(
|
||||
output_file="output/blog_post.md",
|
||||
template="""# {{title}}
|
||||
|
||||
{{content}}
|
||||
|
||||
---
|
||||
*Generated by AI*
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
# The agent will format its response according to the template
|
||||
# result = agent_with_template.start("Write about Python programming")
|
||||
|
||||
# Method 3: Combine with other output settings
|
||||
agent_verbose = Agent(
|
||||
instructions="You are a researcher",
|
||||
output=OutputConfig(
|
||||
verbose=True, # Show rich output in terminal
|
||||
output_file="output/research.md", # Also save to file
|
||||
template="## Research Summary\n\n{{content}}"
|
||||
)
|
||||
)
|
||||
|
||||
print("Examples ready! Uncomment agent.start() calls to run.")
|
||||
print("Output will be saved to the specified files automatically.")
|
||||
@@ -0,0 +1,35 @@
|
||||
# Save Agent Output Examples
|
||||
|
||||
Examples demonstrating different methods to save agent output to files.
|
||||
|
||||
## Examples
|
||||
|
||||
| File | Method | Description |
|
||||
|------|--------|-------------|
|
||||
| `01_write_file_tool.py` | write_file Tool | Agent decides when/what to save |
|
||||
| `02_task_output_file.py` | Task.output_file | Auto-save task result |
|
||||
| `03_workflow_output_file.py` | Workflow output_file | Save workflow step output |
|
||||
| `04_manual_save.py` | Manual | Full control over saving |
|
||||
|
||||
## Setup
|
||||
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
export OPENAI_API_KEY="your-key"
|
||||
```
|
||||
|
||||
## Run Examples
|
||||
|
||||
```bash
|
||||
python 01_write_file_tool.py
|
||||
python 02_task_output_file.py
|
||||
python 03_workflow_output_file.py
|
||||
python 04_manual_save.py
|
||||
```
|
||||
|
||||
## Which Method to Use?
|
||||
|
||||
- **write_file Tool**: When agent needs to decide what to save
|
||||
- **Task.output_file**: For task-based workflows with auto-save
|
||||
- **Workflow output_file**: For YAML workflows with variable substitution
|
||||
- **Manual**: When you need full control over the saving process
|
||||
Loaded 100 of 625 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user