mirror of
https://github.com/MervinPraison/PraisonAI.git
synced 2026-11-07 12:47:55 -10:00
Release v3.4.0
This commit is contained in:
1 parent
304952e84d
commit
be1e4b3424
72 files changed
+961
-1049
No files matched your search
@@ -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.3.1" \
|
||||
"praisonai>=3.4.0" \
|
||||
"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.3.1" \
|
||||
"praisonai>=3.4.0" \
|
||||
"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.3.1" \
|
||||
"praisonai>=3.4.0" \
|
||||
"praisonai[ui]" \
|
||||
"praisonai[crewai]"
|
||||
|
||||
|
||||
@@ -1,203 +0,0 @@
|
||||
# Profiling CLI
|
||||
|
||||
PraisonAI provides unified profiling capabilities for performance analysis and debugging, with **full visibility from ENTER to first response**.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Basic profiling
|
||||
praisonai "What is 2+2?" --profile
|
||||
|
||||
# Deep profiling with call graph, decision trace, and module breakdown
|
||||
praisonai "What is 2+2?" --profile --profile-deep
|
||||
|
||||
# JSON output format
|
||||
praisonai "What is 2+2?" --profile --profile-format json
|
||||
```
|
||||
|
||||
## Time to First Response (TTFR)
|
||||
|
||||
**TTFR** is the key user-perceived latency metric. It measures the time from when you press ENTER until the first visible output appears.
|
||||
|
||||
### What contributes to TTFR?
|
||||
|
||||
1. **CLI Entry** - Time to reach the CLI entry point
|
||||
2. **CLI Parse** - Argparse/Typer routing time
|
||||
3. **Routing** - Command routing to handler
|
||||
4. **Imports** - Loading required modules
|
||||
5. **Agent Init** - Initializing the agent
|
||||
6. **Network Request** - Sending request to LLM API
|
||||
7. **First Token** - Receiving first token (streaming)
|
||||
8. **First Output** - Rendering first visible output
|
||||
|
||||
### How to reduce TTFR
|
||||
|
||||
1. **Warm runs** - Imports are cached after first run
|
||||
2. **Streaming mode** - See output as tokens arrive
|
||||
3. **Lighter models** - Faster response times
|
||||
4. **Local models** - Eliminate network latency
|
||||
|
||||
## CLI Flags
|
||||
|
||||
| Flag | Description | Default |
|
||||
|------|-------------|---------|
|
||||
| `--profile` | Enable profiling with timing breakdown | Disabled |
|
||||
| `--profile-deep` | Enable deep profiling with call graph (higher overhead) | Disabled |
|
||||
| `--profile-format` | Output format: `text` or `json` | `text` |
|
||||
|
||||
## Profile Command
|
||||
|
||||
For more detailed profiling options, use the `profile` subcommand:
|
||||
|
||||
```bash
|
||||
# Profile a query
|
||||
praisonai profile query "What is 2+2?"
|
||||
|
||||
# With deep call tracing
|
||||
praisonai profile query "Hello" --deep
|
||||
|
||||
# Limit functions shown
|
||||
praisonai profile query "Test" --limit 20
|
||||
|
||||
# Save artifacts to directory
|
||||
praisonai profile query "Test" --save ./profile_results
|
||||
|
||||
# JSON output
|
||||
praisonai profile query "Test" --format json
|
||||
```
|
||||
|
||||
### Profile Query Options
|
||||
|
||||
| Option | Description | Default |
|
||||
|--------|-------------|---------|
|
||||
| `--model, -m` | Model to use | Default model |
|
||||
| `--stream/--no-stream` | Use streaming mode | No stream |
|
||||
| `--deep` | Enable deep call tracing | Disabled |
|
||||
| `--limit, -n` | Top N functions to show | 30 |
|
||||
| `--sort, -s` | Sort by: `cumulative` or `tottime` | `cumulative` |
|
||||
| `--show-callers` | Show caller functions | Disabled |
|
||||
| `--show-callees` | Show callee functions | Disabled |
|
||||
| `--save` | Save artifacts to path | None |
|
||||
| `--format, -f` | Output format: `text` or `json` | `text` |
|
||||
|
||||
## Other Profile Commands
|
||||
|
||||
```bash
|
||||
# Profile module import times
|
||||
praisonai profile imports
|
||||
|
||||
# Profile CLI startup time
|
||||
praisonai profile startup
|
||||
|
||||
# Run comprehensive profiling suite
|
||||
praisonai profile suite
|
||||
|
||||
# Create performance snapshots for comparison
|
||||
praisonai profile snapshot --baseline
|
||||
praisonai profile snapshot current --compare
|
||||
|
||||
# Configure performance optimizations
|
||||
praisonai profile optimize --show
|
||||
```
|
||||
|
||||
## Output Format
|
||||
|
||||
### Text Report
|
||||
|
||||
```
|
||||
======================================================================
|
||||
PraisonAI Profile Report
|
||||
======================================================================
|
||||
|
||||
Run ID: abc12345
|
||||
Timestamp: 2024-01-02T12:00:00.000000Z
|
||||
Method: cli_direct
|
||||
Version: 3.0.1
|
||||
|
||||
## Execution Timeline
|
||||
---------------------------------------------
|
||||
Imports : 500.00 ms
|
||||
Agent Init : 0.50 ms
|
||||
Execution : 2000.00 ms
|
||||
───────────────────────────────────────────
|
||||
⏱ Time to First Response : 2500.50 ms
|
||||
TOTAL : 2500.50 ms
|
||||
|
||||
## Timing Breakdown
|
||||
----------------------------------------
|
||||
Imports: 500.00 ms
|
||||
Agent Init: 0.50 ms
|
||||
Execution: 2000.00 ms
|
||||
─────────────────────────────────────
|
||||
TOTAL: 2500.50 ms
|
||||
|
||||
## Decision Trace (deep profile only)
|
||||
----------------------------------------
|
||||
Agent Config: default
|
||||
Model: gpt-4
|
||||
Streaming: disabled
|
||||
Profile Layer: 2
|
||||
|
||||
## Top Functions by Cumulative Time
|
||||
----------------------------------------------------------------------
|
||||
Function Calls Cumul (ms)
|
||||
----------------------------------------------------------------------
|
||||
request 1 1800.00
|
||||
send 1 1750.00
|
||||
...
|
||||
```
|
||||
|
||||
### JSON Report
|
||||
|
||||
```json
|
||||
{
|
||||
"schema_version": "1.0",
|
||||
"run_id": "abc12345",
|
||||
"timestamp": "2024-01-02T12:00:00.000000Z",
|
||||
"invocation": {
|
||||
"method": "cli_direct",
|
||||
"flags": {"layer": 1, "stream": false, "model": null},
|
||||
"praisonai_version": "3.0.1",
|
||||
"python_version": "3.12.0"
|
||||
},
|
||||
"timing": {
|
||||
"total_ms": 2500.5,
|
||||
"imports_ms": 500.0,
|
||||
"agent_init_ms": 0.5,
|
||||
"execution_ms": 2000.0
|
||||
},
|
||||
"functions": [...],
|
||||
"response_preview": "four"
|
||||
}
|
||||
```
|
||||
|
||||
## Profiling Layers
|
||||
|
||||
| Layer | Overhead | Features |
|
||||
|-------|----------|----------|
|
||||
| 0 | < 1ms | Wall-clock phases only |
|
||||
| 1 | ~5% | + cProfile function stats |
|
||||
| 2 | ~15% | + Call graph (callers/callees) |
|
||||
|
||||
- `--profile` uses Layer 1
|
||||
- `--profile --profile-deep` uses Layer 2
|
||||
|
||||
## Performance Tips
|
||||
|
||||
1. **Use Layer 0 for production monitoring** - minimal overhead
|
||||
2. **Use Layer 1 for development profiling** - good balance
|
||||
3. **Use Layer 2 only for deep debugging** - higher overhead
|
||||
|
||||
## Observational Equivalence
|
||||
|
||||
The following commands produce equivalent profile reports:
|
||||
|
||||
```bash
|
||||
# CLI direct
|
||||
praisonai "prompt" --profile
|
||||
|
||||
# Profile command
|
||||
praisonai profile query "prompt"
|
||||
```
|
||||
|
||||
Both use the same unified profiling architecture and produce identical schema output.
|
||||
@@ -1,257 +0,0 @@
|
||||
# Profiling Module
|
||||
|
||||
PraisonAI provides a unified profiling module for programmatic performance analysis.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```python
|
||||
from praisonai.cli.execution import (
|
||||
ExecutionRequest,
|
||||
Profiler,
|
||||
ProfilerConfig,
|
||||
)
|
||||
|
||||
# Create execution request
|
||||
request = ExecutionRequest(prompt="What is 2+2?")
|
||||
|
||||
# Configure profiler
|
||||
config = ProfilerConfig(layer=1)
|
||||
|
||||
# Run with profiling
|
||||
profiler = Profiler(config)
|
||||
result, report = profiler.profile_sync(request)
|
||||
|
||||
# Access results
|
||||
print(f"Output: {result.output}")
|
||||
print(f"Total time: {report.timing.total_ms}ms")
|
||||
```
|
||||
|
||||
## ExecutionRequest
|
||||
|
||||
Immutable request descriptor for execution.
|
||||
|
||||
```python
|
||||
from praisonai.cli.execution import ExecutionRequest
|
||||
|
||||
# Basic request
|
||||
request = ExecutionRequest(prompt="Hello")
|
||||
|
||||
# With model
|
||||
request = ExecutionRequest(
|
||||
prompt="Hello",
|
||||
model="gpt-4",
|
||||
agent_name="MyAgent",
|
||||
)
|
||||
|
||||
# With streaming
|
||||
request = ExecutionRequest(
|
||||
prompt="Hello",
|
||||
stream=True,
|
||||
)
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| `prompt` | str | Required | The prompt to execute |
|
||||
| `agent_name` | str | "Assistant" | Name of the agent |
|
||||
| `agent_instructions` | str | None | Custom instructions |
|
||||
| `model` | str | None | Model to use |
|
||||
| `stream` | bool | False | Enable streaming |
|
||||
| `tools` | tuple | () | Tools to provide |
|
||||
|
||||
## ProfilerConfig
|
||||
|
||||
Configuration for profiling behavior.
|
||||
|
||||
```python
|
||||
from praisonai.cli.execution import ProfilerConfig
|
||||
|
||||
# Layer 0: Wall-clock only (< 1ms overhead)
|
||||
config = ProfilerConfig(layer=0)
|
||||
|
||||
# Layer 1: + cProfile stats (~5% overhead)
|
||||
config = ProfilerConfig(layer=1)
|
||||
|
||||
# Layer 2: + Call graph (~15% overhead)
|
||||
config = ProfilerConfig(
|
||||
layer=2,
|
||||
show_callers=True,
|
||||
show_callees=True,
|
||||
)
|
||||
|
||||
# From CLI flags
|
||||
config = ProfilerConfig.from_flags(
|
||||
profile=True,
|
||||
deep=True,
|
||||
network=False,
|
||||
)
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| `layer` | int | 1 | Profiling layer (0, 1, or 2) |
|
||||
| `limit` | int | 30 | Max functions to show |
|
||||
| `sort_by` | str | "cumulative" | Sort by: cumulative, time, calls |
|
||||
| `show_callers` | bool | False | Show caller functions |
|
||||
| `show_callees` | bool | False | Show callee functions |
|
||||
| `track_network` | bool | False | Track network requests |
|
||||
| `output_format` | str | "text" | Output format: text, json |
|
||||
| `save_path` | str | None | Path to save artifacts |
|
||||
|
||||
## Profiler
|
||||
|
||||
The main profiler class that wraps execution.
|
||||
|
||||
```python
|
||||
from praisonai.cli.execution import Profiler, ProfilerConfig, ExecutionRequest
|
||||
|
||||
config = ProfilerConfig(layer=1)
|
||||
profiler = Profiler(config)
|
||||
|
||||
request = ExecutionRequest(prompt="Hello")
|
||||
result, report = profiler.profile_sync(request, invocation_method="api")
|
||||
```
|
||||
|
||||
### Methods
|
||||
|
||||
#### `profile_sync(request, invocation_method="profile_command")`
|
||||
|
||||
Profile synchronous execution.
|
||||
|
||||
**Parameters:**
|
||||
- `request`: ExecutionRequest - The execution request
|
||||
- `invocation_method`: str - How this was invoked (for report)
|
||||
|
||||
**Returns:** Tuple of (ExecutionResult, ProfileReport)
|
||||
|
||||
## ProfileReport
|
||||
|
||||
The canonical profile report with timing and statistics.
|
||||
|
||||
```python
|
||||
# Access timing breakdown
|
||||
print(f"Total: {report.timing.total_ms}ms")
|
||||
print(f"Imports: {report.timing.imports_ms}ms")
|
||||
print(f"Agent Init: {report.timing.agent_init_ms}ms")
|
||||
print(f"Execution: {report.timing.execution_ms}ms")
|
||||
|
||||
# Access function stats (layer 1+)
|
||||
if report.functions:
|
||||
for func in report.functions[:5]:
|
||||
print(f"{func.name}: {func.cumulative_time_ms}ms")
|
||||
|
||||
# Access call graph (layer 2)
|
||||
if report.call_graph:
|
||||
print(f"Edges: {len(report.call_graph.edges)}")
|
||||
|
||||
# Export formats
|
||||
json_str = report.to_json()
|
||||
text_str = report.to_text()
|
||||
dict_data = report.to_dict()
|
||||
```
|
||||
|
||||
### Schema Version
|
||||
|
||||
The report uses schema version `1.0`. Schema is frozen after release - new fields are always optional with defaults.
|
||||
|
||||
### Mandatory Fields
|
||||
|
||||
- `schema_version`: str
|
||||
- `run_id`: str
|
||||
- `timestamp`: str (ISO 8601)
|
||||
- `invocation`: InvocationInfo
|
||||
- `timing`: TimingBreakdown
|
||||
- `response_preview`: str
|
||||
|
||||
### Optional Fields
|
||||
|
||||
- `functions`: List[FunctionStat] (layer 1+)
|
||||
- `call_graph`: CallGraph (layer 2)
|
||||
- `network`: List[RequestTiming] (if track_network)
|
||||
|
||||
## ExecutionResult
|
||||
|
||||
Result of execution with output and metadata.
|
||||
|
||||
```python
|
||||
# Access output
|
||||
print(result.output)
|
||||
print(result.success)
|
||||
print(result.run_id)
|
||||
|
||||
# Check for errors
|
||||
if result.error:
|
||||
print(f"Error: {result.error}")
|
||||
|
||||
# Duration
|
||||
print(f"Duration: {result.duration_ms}ms")
|
||||
```
|
||||
|
||||
## Data Bounds
|
||||
|
||||
Profile data is strictly bounded to prevent memory issues:
|
||||
|
||||
| Data Type | Maximum |
|
||||
|-----------|---------|
|
||||
| Function stats | 1000 |
|
||||
| Call graph edges | 5000 |
|
||||
| Network requests | 100 |
|
||||
|
||||
## Example: Full Profiling Workflow
|
||||
|
||||
```python
|
||||
from praisonai.cli.execution import (
|
||||
ExecutionRequest,
|
||||
Profiler,
|
||||
ProfilerConfig,
|
||||
)
|
||||
|
||||
# Configure deep profiling
|
||||
config = ProfilerConfig(
|
||||
layer=2,
|
||||
limit=50,
|
||||
show_callers=True,
|
||||
show_callees=True,
|
||||
)
|
||||
|
||||
# Create request
|
||||
request = ExecutionRequest(
|
||||
prompt="Explain quantum computing in simple terms",
|
||||
model="gpt-4",
|
||||
)
|
||||
|
||||
# Profile execution
|
||||
profiler = Profiler(config)
|
||||
result, report = profiler.profile_sync(request)
|
||||
|
||||
# Print text report
|
||||
print(report.to_text())
|
||||
|
||||
# Save JSON report
|
||||
with open("profile.json", "w") as f:
|
||||
f.write(report.to_json())
|
||||
|
||||
# Analyze timing
|
||||
print(f"\nTiming Analysis:")
|
||||
print(f" Import overhead: {report.timing.imports_ms / report.timing.total_ms * 100:.1f}%")
|
||||
print(f" Execution time: {report.timing.execution_ms / report.timing.total_ms * 100:.1f}%")
|
||||
|
||||
# Top 5 hotspots
|
||||
if report.functions:
|
||||
print(f"\nTop 5 Hotspots:")
|
||||
for func in report.functions[:5]:
|
||||
print(f" {func.name}: {func.cumulative_time_ms:.2f}ms ({func.calls} calls)")
|
||||
```
|
||||
|
||||
## Invariants
|
||||
|
||||
The profiling module guarantees:
|
||||
|
||||
1. **Output Equivalence**: Profiled execution produces identical output to non-profiled execution
|
||||
2. **Schema Stability**: Schema version 1.0 is frozen; new fields are always optional
|
||||
3. **Bounded Data**: All profile data respects maximum bounds
|
||||
4. **Zero Overhead When Disabled**: No profiling code runs unless explicitly enabled
|
||||
@@ -1,53 +0,0 @@
|
||||
# Templates CLI
|
||||
|
||||
```bash
|
||||
praisonai templates list
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai templates search video
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai templates info ai-video-editor
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai templates run ai-video-editor --input video.mp4 --output edited.mp4
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai templates run ai-video-editor --input video.mp4 --output edited.mp4 --offline
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai templates run ai-video-editor --input video.mp4 --output edited.mp4 --strict-tools
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai templates run ai-video-editor --input video.mp4 --tools ./my_tools.py
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai templates run ai-video-editor --input video.mp4 --tools-dir ./tools
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai templates run ai-video-editor --input video.mp4 --tools-source praisonai_tools.video
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai templates run ai-video-editor --input video.mp4 --no-template-tools-py
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai templates init my-project --template ai-video-editor
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai templates cache clear
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai templates cache list
|
||||
```
|
||||
@@ -1,104 +0,0 @@
|
||||
# Templates Module
|
||||
|
||||
## Loading Templates
|
||||
|
||||
```python
|
||||
from praisonai.templates.loader import TemplateLoader
|
||||
|
||||
loader = TemplateLoader()
|
||||
|
||||
# Load from local path
|
||||
template = loader.load("./my-template")
|
||||
|
||||
# Load from URI
|
||||
template = loader.load("ai-video-editor")
|
||||
|
||||
# Load offline
|
||||
template = loader.load("ai-video-editor", offline=True)
|
||||
|
||||
# Check requirements
|
||||
missing = loader.check_requirements(template)
|
||||
```
|
||||
|
||||
## Template Discovery
|
||||
|
||||
```python
|
||||
from praisonai.templates.discovery import TemplateDiscovery
|
||||
|
||||
discovery = TemplateDiscovery(
|
||||
include_package=True,
|
||||
include_defaults=True,
|
||||
)
|
||||
|
||||
# Find template
|
||||
result = discovery.find_template("ai-video-editor")
|
||||
|
||||
# List all templates
|
||||
templates = discovery.list_templates()
|
||||
```
|
||||
|
||||
## Template Config
|
||||
|
||||
```python
|
||||
from praisonai.templates.loader import TemplateConfig
|
||||
|
||||
# Access template properties
|
||||
template.name
|
||||
template.description
|
||||
template.version
|
||||
template.author
|
||||
template.requires
|
||||
template.workflow_file
|
||||
template.agents_file
|
||||
template.path
|
||||
```
|
||||
|
||||
## Tool Override Integration
|
||||
|
||||
```python
|
||||
from praisonai.templates.tool_override import (
|
||||
create_tool_registry_with_overrides,
|
||||
resolve_tools,
|
||||
)
|
||||
|
||||
# Build registry with template sources
|
||||
tools_sources = template.requires.get("tools_sources", [])
|
||||
|
||||
registry = create_tool_registry_with_overrides(
|
||||
tools_sources=tools_sources,
|
||||
template_dir=str(template.path),
|
||||
include_defaults=True,
|
||||
)
|
||||
|
||||
# Resolve tool names
|
||||
tools = resolve_tools(["shell_tool"], registry=registry)
|
||||
```
|
||||
|
||||
## TEMPLATE.yaml Schema
|
||||
|
||||
```yaml
|
||||
name: my-template
|
||||
version: "1.0.0"
|
||||
description: Template description
|
||||
|
||||
requires:
|
||||
tools: [shell_tool]
|
||||
packages: [praisonai-tools]
|
||||
env: [OPENAI_API_KEY]
|
||||
tools_sources:
|
||||
- praisonai_tools.video
|
||||
- ./local_tools.py
|
||||
|
||||
workflow: workflow.yaml
|
||||
agents: agents.yaml
|
||||
|
||||
config:
|
||||
input:
|
||||
type: string
|
||||
required: true
|
||||
output:
|
||||
type: string
|
||||
|
||||
defaults:
|
||||
preset: podcast
|
||||
```
|
||||
@@ -1,65 +0,0 @@
|
||||
# Tools CLI
|
||||
|
||||
```bash
|
||||
praisonai tools list
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai tools info shell_tool
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai tools info internet_search
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai tools search "web"
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai tools search "file"
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai tools doctor
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai tools doctor --json
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai tools resolve shell_tool
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai tools resolve internet_search --template ai-video-editor
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai tools resolve my_tool --tools ./my_tools.py
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai tools resolve my_tool --tools-dir ./tools
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai tools discover
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai tools discover --include praisonai_tools.video
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai tools discover --entrypoints
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai tools show-sources
|
||||
```
|
||||
|
||||
```bash
|
||||
praisonai tools show-sources --template ai-video-editor
|
||||
```
|
||||
@@ -1,90 +0,0 @@
|
||||
# Tools Module
|
||||
|
||||
## Tool Registry
|
||||
|
||||
```python
|
||||
from praisonai.templates.tool_override import (
|
||||
create_tool_registry_with_overrides,
|
||||
resolve_tools,
|
||||
)
|
||||
|
||||
# Create registry with defaults
|
||||
registry = create_tool_registry_with_overrides(include_defaults=True)
|
||||
|
||||
# Create registry with overrides
|
||||
registry = create_tool_registry_with_overrides(
|
||||
override_files=["my_tools.py"],
|
||||
override_dirs=["./tools"],
|
||||
include_defaults=True,
|
||||
)
|
||||
|
||||
# Create registry with tools_sources
|
||||
registry = create_tool_registry_with_overrides(
|
||||
tools_sources=["praisonai_tools.video"],
|
||||
template_dir="./my-template",
|
||||
include_defaults=True,
|
||||
)
|
||||
|
||||
# Resolve tool names to callables
|
||||
tools = resolve_tools(
|
||||
["shell_tool", "internet_search"],
|
||||
registry=registry,
|
||||
)
|
||||
```
|
||||
|
||||
## Tool Override Loader
|
||||
|
||||
```python
|
||||
from praisonai.templates.tool_override import ToolOverrideLoader
|
||||
|
||||
loader = ToolOverrideLoader()
|
||||
|
||||
# Load from file
|
||||
tools = loader.load_from_file("my_tools.py")
|
||||
|
||||
# Load from directory
|
||||
tools = loader.load_from_directory("./tools")
|
||||
|
||||
# Load from module
|
||||
tools = loader.load_from_module("praisonai_tools.video")
|
||||
|
||||
# Get default tool directories
|
||||
dirs = loader.get_default_tool_dirs()
|
||||
```
|
||||
|
||||
## Resolution Order
|
||||
|
||||
1. CLI `--tools` files (highest priority)
|
||||
2. CLI `--tools-dir` directories
|
||||
3. Template `tools_sources` (from TEMPLATE.yaml)
|
||||
4. Template-local `tools.py`
|
||||
5. Default dirs (`~/.praison/tools`, `~/.config/praison/tools`)
|
||||
6. Package discovery (`praisonai_tools`)
|
||||
7. Built-in tools (lowest priority)
|
||||
|
||||
## Creating Custom Tools
|
||||
|
||||
```python
|
||||
from praisonai_tools import tool
|
||||
|
||||
@tool
|
||||
def my_custom_tool(query: str) -> str:
|
||||
"""My custom tool description.
|
||||
|
||||
Args:
|
||||
query: The search query
|
||||
"""
|
||||
return f"Result for: {query}"
|
||||
```
|
||||
|
||||
## Template tools_sources
|
||||
|
||||
```yaml
|
||||
# TEMPLATE.yaml
|
||||
requires:
|
||||
tools: [shell_tool]
|
||||
tools_sources:
|
||||
- praisonai_tools.video
|
||||
- ./local_tools.py
|
||||
- ./tools_dir/
|
||||
```
|
||||
@@ -0,0 +1,158 @@
|
||||
"""
|
||||
Agent-Centric API Example
|
||||
|
||||
Demonstrates the new consolidated feature parameters for PraisonAI Agents.
|
||||
These params provide a cleaner, more intuitive API with progressive disclosure.
|
||||
|
||||
New Consolidated Params:
|
||||
- memory: Union[bool, MemoryConfig, MemoryManager] - Memory and session management
|
||||
- knowledge: Union[bool, List[str], KnowledgeConfig, KnowledgeBase] - RAG and retrieval
|
||||
- planning: Union[bool, PlanningConfig] - Planning mode
|
||||
- reflection: Union[bool, ReflectionConfig] - Self-reflection
|
||||
- guardrails: Union[bool, Callable, GuardrailConfig] - Safety validation
|
||||
- web: Union[bool, WebConfig] - Web search and fetch
|
||||
- context: Union[bool, ManagerConfig, ContextManager] - Context management
|
||||
"""
|
||||
|
||||
from praisonaiagents import (
|
||||
Agent,
|
||||
# Config classes for progressive disclosure
|
||||
MemoryConfig,
|
||||
KnowledgeConfig,
|
||||
PlanningConfig,
|
||||
ReflectionConfig,
|
||||
GuardrailConfig,
|
||||
WebConfig,
|
||||
)
|
||||
|
||||
|
||||
def example_simple_enable():
|
||||
"""Example 1: Simple boolean enable (easiest)"""
|
||||
print("\n=== Example 1: Simple Boolean Enable ===")
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
memory=True, # Enable memory with defaults
|
||||
reflection=True, # Enable self-reflection
|
||||
web=True, # Enable web search + fetch
|
||||
)
|
||||
print(f"Agent created with memory={agent._memory_instance is not None}")
|
||||
print(f" self_reflect={agent.self_reflect}")
|
||||
print(f" web_search={agent.web_search}")
|
||||
|
||||
|
||||
def example_with_config():
|
||||
"""Example 2: Using config objects (more control)"""
|
||||
print("\n=== Example 2: Using Config Objects ===")
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a research assistant",
|
||||
memory=MemoryConfig(
|
||||
backend="file",
|
||||
user_id="researcher_001",
|
||||
auto_memory=True,
|
||||
),
|
||||
reflection=ReflectionConfig(
|
||||
min_iterations=1,
|
||||
max_iterations=5,
|
||||
llm="gpt-4o-mini",
|
||||
),
|
||||
web=WebConfig(
|
||||
search=True,
|
||||
fetch=False, # Only search, no full page fetch
|
||||
max_results=3,
|
||||
),
|
||||
)
|
||||
print(f"Agent created with user_id={agent.user_id}")
|
||||
print(f" {agent.max_reflect}")
|
||||
print(f" web_search={agent.web_search}, web_fetch={agent.web_fetch}")
|
||||
|
||||
|
||||
def example_guardrails():
|
||||
"""Example 3: Guardrails with callable or config"""
|
||||
print("\n=== Example 3: Guardrails ===")
|
||||
|
||||
# Option A: Direct callable
|
||||
def my_validator(output):
|
||||
"""Simple validator that checks response length."""
|
||||
is_valid = len(output.raw) < 1000
|
||||
return (is_valid, output if is_valid else "Response too long")
|
||||
|
||||
agent_a = Agent(
|
||||
instructions="Be concise",
|
||||
guardrails=my_validator, # Direct callable
|
||||
)
|
||||
print(f"Agent A: guardrail is callable = {callable(agent_a.guardrail)}")
|
||||
|
||||
# Option B: Using GuardrailConfig
|
||||
agent_b = Agent(
|
||||
instructions="Be helpful and safe",
|
||||
guardrails=GuardrailConfig(
|
||||
llm_validator="Ensure the response is helpful, accurate, and safe",
|
||||
max_retries=3,
|
||||
),
|
||||
)
|
||||
print(f"Agent B: guardrail = {agent_b.guardrail}")
|
||||
print(f" max_retries = {agent_b.max_guardrail_retries}")
|
||||
|
||||
|
||||
def example_planning():
|
||||
"""Example 4: Planning mode"""
|
||||
print("\n=== Example 4: Planning Mode ===")
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a project planner",
|
||||
planning=PlanningConfig(
|
||||
reasoning=True,
|
||||
read_only=True, # Plan mode - only read operations
|
||||
),
|
||||
)
|
||||
print(f"Agent created with planning={agent.planning}")
|
||||
print(f" plan_mode={agent.plan_mode}")
|
||||
print(f" planning_reasoning={agent.planning_reasoning}")
|
||||
|
||||
|
||||
def example_backward_compatible():
|
||||
"""Example 5: Using new consolidated params"""
|
||||
print("\n=== Example 5: Consolidated Params ===")
|
||||
|
||||
# New consolidated params
|
||||
agent = Agent(
|
||||
instructions="Test agent",
|
||||
reflection=True,
|
||||
web=WebConfig(search=True, fetch=False),
|
||||
)
|
||||
print(f"Consolidated params work: self_reflect={agent.self_reflect}")
|
||||
print(f" web_search={agent.web_search}, web_fetch={agent.web_fetch}")
|
||||
|
||||
|
||||
def example_real_chat():
|
||||
"""Example 6: Real chat with new API"""
|
||||
print("\n=== Example 6: Real Chat ===")
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a helpful math tutor. Be concise.",
|
||||
reflection=False,
|
||||
web=False,
|
||||
verbose=False,
|
||||
)
|
||||
|
||||
response = agent.start("What is the square root of 144?")
|
||||
print(f"Response: {response}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=" * 60)
|
||||
print("PraisonAI Agent-Centric API Examples")
|
||||
print("=" * 60)
|
||||
|
||||
example_simple_enable()
|
||||
example_with_config()
|
||||
example_guardrails()
|
||||
example_planning()
|
||||
example_backward_compatible()
|
||||
example_real_chat()
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("All examples completed!")
|
||||
print("=" * 60)
|
||||
@@ -67,7 +67,7 @@ agent = Agent(
|
||||
goal="Summarize web content concisely",
|
||||
instructions="You are a helpful assistant that summarizes web content",
|
||||
llm="gemini/gemini-2.5-flash-lite-preview-06-17",
|
||||
self_reflect=False,
|
||||
reflection=False,
|
||||
verbose=True,
|
||||
tools=[get_url_context] # FIX: tools must be a list, not a single function
|
||||
)
|
||||
@@ -77,7 +77,7 @@ task_with_guardrailresult = Task(
|
||||
name="summarise article with GuardrailResult",
|
||||
description="get the context of this url: https://blog.google/technology/ai/dolphingemma/ and produce a summary below 500 characters",
|
||||
agent=agent,
|
||||
guardrail=validate_length_guardrailresult, # Using GuardrailResult
|
||||
guardrails=validate_length_guardrailresult, # Using GuardrailResult
|
||||
expected_output="summary of the article below 500 characters",
|
||||
max_retries=3 # Will retry up to 3 times if guardrail fails
|
||||
)
|
||||
@@ -87,7 +87,7 @@ task_with_tuple = Task(
|
||||
name="summarise article with tuple",
|
||||
description="get the context of this url: https://blog.google/technology/ai/dolphingemma/ and produce a summary below 500 characters",
|
||||
agent=agent,
|
||||
guardrail=validate_length_tuple, # Using Tuple[bool, Any]
|
||||
guardrails=validate_length_tuple, # Using Tuple[bool, Any]
|
||||
expected_output="summary of the article below 500 characters",
|
||||
max_retries=3
|
||||
)
|
||||
@@ -97,7 +97,7 @@ task_with_llm_guardrail = Task(
|
||||
name="summarise with LLM guardrail",
|
||||
description="get the context of this url: https://blog.google/technology/ai/dolphingemma/ and produce a summary",
|
||||
agent=agent,
|
||||
guardrail="Ensure the summary is professional, factual, and between 100-500 characters",
|
||||
guardrails="Ensure the summary is professional, factual, and between 100-500 characters",
|
||||
expected_output="professional summary of the article"
|
||||
)
|
||||
|
||||
|
||||
@@ -32,9 +32,9 @@ code_writer = Agent(
|
||||
goal="Write clean, efficient, and well-documented Python code",
|
||||
backstory="You are a senior Python developer with 10+ years of experience in writing production-quality code.",
|
||||
instructions="Write Python code that follows PEP 8 standards, includes proper error handling, and has clear documentation.",
|
||||
self_reflect=True,
|
||||
min_reflect=2,
|
||||
max_reflect=5
|
||||
reflection=True,
|
||||
|
||||
|
||||
)
|
||||
|
||||
code_reviewer = Agent(
|
||||
@@ -108,9 +108,9 @@ general_code_agent = Agent(
|
||||
4. Refactor code for better performance
|
||||
5. Add tests and documentation""",
|
||||
tools=[code_interpreter, analyze_code_complexity],
|
||||
self_reflect=True,
|
||||
min_reflect=1,
|
||||
max_reflect=3
|
||||
reflection=True,
|
||||
|
||||
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -14,7 +14,7 @@ image_agent = Agent(
|
||||
backstory="""You are an expert in computer vision and image analysis.
|
||||
You excel at describing images, detecting objects, and understanding visual content.""",
|
||||
llm="gpt-5-nano",
|
||||
self_reflect=False
|
||||
reflection=False
|
||||
)
|
||||
|
||||
# 1. Task with Image URL
|
||||
|
||||
@@ -14,7 +14,7 @@ image_agent = Agent(
|
||||
backstory="""You are an expert in computer vision and image analysis.
|
||||
You excel at describing images, detecting objects, and understanding visual content.""",
|
||||
llm="gpt-5-nano",
|
||||
self_reflect=False
|
||||
reflection=False
|
||||
)
|
||||
|
||||
# 1. Task with Image URL
|
||||
|
||||
@@ -65,9 +65,9 @@ calculation_agent = Agent(
|
||||
backstory="You are an expert mathematician who can handle complex calculations with precision.",
|
||||
instructions="Perform the requested calculations step by step, showing your work clearly.",
|
||||
tools=[basic_calculator, solve_quadratic, calculate_statistics],
|
||||
self_reflect=True,
|
||||
min_reflect=1,
|
||||
max_reflect=2
|
||||
reflection=True,
|
||||
|
||||
|
||||
)
|
||||
|
||||
problem_solver_agent = Agent(
|
||||
@@ -81,9 +81,9 @@ problem_solver_agent = Agent(
|
||||
3. Determine what needs to be found
|
||||
4. Show each step of the solution
|
||||
5. Verify the answer makes sense""",
|
||||
self_reflect=True,
|
||||
min_reflect=2,
|
||||
max_reflect=4
|
||||
reflection=True,
|
||||
|
||||
|
||||
)
|
||||
|
||||
math_tutor_agent = Agent(
|
||||
@@ -148,9 +148,9 @@ math_assistant = Agent(
|
||||
|
||||
Always show your work step by step.""",
|
||||
tools=[basic_calculator, solve_quadratic, calculate_statistics],
|
||||
self_reflect=True,
|
||||
min_reflect=1,
|
||||
max_reflect=3
|
||||
reflection=True,
|
||||
|
||||
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents import Agent, Tools, ReflectionConfig
|
||||
from praisonaiagents.tools import execute_code, analyze_code, format_code, lint_code, disassemble_code # Code Tools
|
||||
from praisonaiagents.tools import execute_command, list_processes, kill_process, get_system_info # Shell Tools
|
||||
from praisonaiagents.tools import duckduckgo # Web Search Tool
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a Programming Agent", self_reflect=True, min_reflect=5, max_reflect=10,
|
||||
instructions="You are a Programming Agent",
|
||||
reflection=ReflectionConfig(min_iterations=5, max_iterations=10),
|
||||
tools=[execute_code, analyze_code, format_code, lint_code, disassemble_code, execute_command, list_processes, kill_process, get_system_info, duckduckgo]
|
||||
)
|
||||
agent.start(
|
||||
|
||||
@@ -8,7 +8,7 @@ video_agent = Agent(
|
||||
backstory="""You are an expert in computer vision and image analysis.
|
||||
You excel at describing images, detecting objects, and understanding visual content.""",
|
||||
llm="gpt-5-nano",
|
||||
self_reflect=False
|
||||
reflection=False
|
||||
)
|
||||
|
||||
# Task with Video File
|
||||
|
||||
@@ -4,9 +4,9 @@ from praisonaiagents.tools import wiki_search, wiki_summary, wiki_page, wiki_ran
|
||||
agent = Agent(
|
||||
instructions="You are a Wikipedia Agent",
|
||||
tools=[wiki_search, wiki_summary, wiki_page, wiki_random, wiki_language],
|
||||
self_reflect=True,
|
||||
min_reflect=3,
|
||||
max_reflect=5,
|
||||
reflection=True,
|
||||
|
||||
|
||||
)
|
||||
agent.start(
|
||||
"What is the history of AI?"
|
||||
|
||||
@@ -27,9 +27,9 @@ pdf_agent = Agent(
|
||||
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,
|
||||
self_reflect=True,
|
||||
min_reflect=1,
|
||||
max_reflect=3
|
||||
reflection=True,
|
||||
|
||||
|
||||
)
|
||||
|
||||
# Example usage
|
||||
|
||||
@@ -49,9 +49,9 @@ cot_agent = Agent(
|
||||
6. Assess your confidence level
|
||||
|
||||
Always make your thinking process explicit and transparent.""",
|
||||
self_reflect=True,
|
||||
min_reflect=2,
|
||||
max_reflect=3
|
||||
reflection=True,
|
||||
|
||||
|
||||
)
|
||||
|
||||
# Example 2: Reasoning Extractor Agent
|
||||
@@ -224,7 +224,7 @@ pattern_reasoning_agent = Agent(
|
||||
3. Counterfactual: Explore what-if scenarios
|
||||
4. Systems thinking: Consider interconnections
|
||||
5. Probabilistic: Assess likelihoods""",
|
||||
self_reflect=True
|
||||
reflection=True
|
||||
)
|
||||
|
||||
# Example 8: Interactive Reasoning Extraction
|
||||
|
||||
@@ -208,7 +208,7 @@ dynamic_router = Agent(
|
||||
5. Current system load
|
||||
|
||||
Provide clear routing decisions with reasoning.""",
|
||||
self_reflect=True
|
||||
reflection=True
|
||||
)
|
||||
|
||||
def dynamic_routing_example():
|
||||
|
||||
@@ -24,9 +24,9 @@ basic_reflection_agent = Agent(
|
||||
3. Identify areas for improvement
|
||||
4. Revise and enhance
|
||||
5. Repeat until satisfied""",
|
||||
self_reflect=True, # Enable self-reflection
|
||||
min_reflect=1, # Minimum 1 reflection iteration
|
||||
max_reflect=3 # Maximum 3 reflection iterations
|
||||
reflection=True, # Enable self-reflection
|
||||
# Minimum 1 reflection iteration
|
||||
# Maximum 3 reflection iterations
|
||||
)
|
||||
|
||||
# Example 2: Advanced Reflection with Different Strategies
|
||||
@@ -41,9 +41,9 @@ quality_focused_agent = Agent(
|
||||
- Clarity of presentation
|
||||
- Logical flow
|
||||
- Supporting evidence""",
|
||||
self_reflect=True,
|
||||
min_reflect=3, # Higher minimum for quality
|
||||
max_reflect=5 # Allow more iterations
|
||||
reflection=True,
|
||||
# Higher minimum for quality
|
||||
# Allow more iterations
|
||||
)
|
||||
|
||||
efficiency_balanced_agent = Agent(
|
||||
@@ -52,9 +52,9 @@ efficiency_balanced_agent = Agent(
|
||||
goal="Achieve good quality with reasonable reflection time",
|
||||
backstory="You balance quality with efficiency, knowing when good enough is sufficient.",
|
||||
instructions="Create good content with 1-2 rounds of improvement.",
|
||||
self_reflect=True,
|
||||
min_reflect=1,
|
||||
max_reflect=2 # Limit iterations for efficiency
|
||||
reflection=True,
|
||||
|
||||
# Limit iterations for efficiency
|
||||
)
|
||||
|
||||
# Example 3: No Reflection for Comparison
|
||||
@@ -64,7 +64,7 @@ no_reflection_agent = Agent(
|
||||
goal="Provide immediate responses without reflection",
|
||||
backstory="You provide quick, first-draft responses.",
|
||||
instructions="Respond immediately with your first thought.",
|
||||
self_reflect=False # Disable reflection
|
||||
reflection=False # Disable reflection
|
||||
)
|
||||
|
||||
# Demonstration function to show reflection in action
|
||||
@@ -113,9 +113,9 @@ def reflection_workflow_example():
|
||||
role="Initial content creator",
|
||||
goal="Create first draft with self-improvement",
|
||||
backstory="You create initial drafts and refine them through reflection.",
|
||||
self_reflect=True,
|
||||
min_reflect=2,
|
||||
max_reflect=3
|
||||
reflection=True,
|
||||
|
||||
|
||||
)
|
||||
|
||||
# Reviewer without reflection (provides feedback)
|
||||
@@ -124,7 +124,7 @@ def reflection_workflow_example():
|
||||
role="Content reviewer",
|
||||
goal="Provide constructive feedback",
|
||||
backstory="You review content and provide specific improvement suggestions.",
|
||||
self_reflect=False # No reflection needed for reviewing
|
||||
reflection=False # No reflection needed for reviewing
|
||||
)
|
||||
|
||||
# Final polisher with reflection
|
||||
@@ -133,9 +133,9 @@ def reflection_workflow_example():
|
||||
role="Final content polisher",
|
||||
goal="Perfect the content based on feedback",
|
||||
backstory="You take feedback and create the final, polished version.",
|
||||
self_reflect=True,
|
||||
min_reflect=1,
|
||||
max_reflect=2
|
||||
reflection=True,
|
||||
|
||||
|
||||
)
|
||||
|
||||
# Workflow tasks
|
||||
@@ -202,9 +202,9 @@ custom_reflection_agent = Agent(
|
||||
backstory="You adapt your reflection process based on content quality.",
|
||||
instructions="""Create content and reflect on it.
|
||||
Continue improving until quality standards are met or maximum iterations reached.""",
|
||||
self_reflect=True,
|
||||
min_reflect=1,
|
||||
max_reflect=5
|
||||
reflection=True,
|
||||
|
||||
|
||||
)
|
||||
|
||||
# Example 6: Reflection Impact Analysis
|
||||
|
||||
@@ -17,10 +17,10 @@ reflection_agent = Agent(
|
||||
goal="Demonstrate self-reflection and iterative improvement patterns",
|
||||
backstory="Expert researcher with strong self-reflection and continuous improvement capabilities",
|
||||
tools=[internet_search],
|
||||
self_reflect=True,
|
||||
min_reflect=2,
|
||||
max_reflect=4,
|
||||
reflect_llm="gpt-5-nano",
|
||||
reflection=True,
|
||||
|
||||
|
||||
|
||||
verbose=True
|
||||
)
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ sync_agent = Agent(
|
||||
goal="Perform synchronous searches and return structured results",
|
||||
backstory="Expert in sync operations and data organization",
|
||||
tools=[sync_search_tool],
|
||||
self_reflect=False,
|
||||
reflection=False,
|
||||
verbose=True,
|
||||
markdown=True
|
||||
)
|
||||
@@ -109,7 +109,7 @@ async_agent = Agent(
|
||||
goal="Perform asynchronous searches and return structured results",
|
||||
backstory="Expert in async operations and data organization",
|
||||
tools=[async_search_tool],
|
||||
self_reflect=False,
|
||||
reflection=False,
|
||||
verbose=True,
|
||||
markdown=True
|
||||
)
|
||||
|
||||
@@ -53,7 +53,7 @@ async_agent = Agent(
|
||||
goal="Perform fast parallel searches with structured results",
|
||||
backstory="Expert in efficient data retrieval and parallel search operations",
|
||||
tools=[async_search_tool],
|
||||
self_reflect=False,
|
||||
reflection=False,
|
||||
verbose=True,
|
||||
markdown=True
|
||||
)
|
||||
@@ -63,7 +63,7 @@ summary_agent = Agent(
|
||||
role="Research Synthesizer",
|
||||
goal="Create concise summaries from multiple search results",
|
||||
backstory="Expert in analyzing and synthesizing information from multiple sources",
|
||||
self_reflect=True,
|
||||
reflection=True,
|
||||
verbose=True,
|
||||
markdown=True
|
||||
)
|
||||
|
||||
@@ -60,7 +60,7 @@ async_agent = Agent(
|
||||
goal="Perform fast and efficient asynchronous searches with structured results",
|
||||
backstory="Expert in parallel search operations and data retrieval",
|
||||
tools=[async_search_tool],
|
||||
self_reflect=False,
|
||||
reflection=False,
|
||||
verbose=True,
|
||||
markdown=True
|
||||
)
|
||||
@@ -72,7 +72,7 @@ summary_agent = Agent(
|
||||
backstory="""Expert in analyzing and synthesizing information from multiple sources.
|
||||
Skilled at identifying patterns, trends, and connections between different topics.
|
||||
Specializes in creating clear, structured summaries that highlight key insights.""",
|
||||
self_reflect=True, # Enable self-reflection for better summary quality
|
||||
reflection=True, # Enable self-reflection for better summary quality
|
||||
verbose=True,
|
||||
markdown=True
|
||||
)
|
||||
|
||||
@@ -25,13 +25,13 @@ code_agent = Agent(
|
||||
name="code_agent",
|
||||
llm="gpt-5-nano",
|
||||
backstory="Expert in writing Python scripts",
|
||||
self_reflect=False
|
||||
reflection=False
|
||||
)
|
||||
execution_agent = Agent(
|
||||
name="execution_agent",
|
||||
llm="gpt-5-nano",
|
||||
backstory="Expert in executing Python scripts",
|
||||
self_reflect=False,
|
||||
reflection=False,
|
||||
tools=[code_interpreter]
|
||||
)
|
||||
|
||||
|
||||
@@ -129,9 +129,9 @@ def main():
|
||||
tools=[internet_search_tool],
|
||||
llm="gpt-5-nano",
|
||||
markdown=True,
|
||||
reflect_llm="gpt-5-nano",
|
||||
min_reflect=2,
|
||||
max_reflect=4
|
||||
|
||||
|
||||
|
||||
)
|
||||
|
||||
writer = Agent(
|
||||
|
||||
@@ -112,7 +112,7 @@ data_agent = Agent(
|
||||
goal="Perform internet searches to collect relevant information.",
|
||||
backstory="Expert in finding and organizing internet data from multiple sources.",
|
||||
tools=[internet_search_tool, youtube_search_tool, wikipedia_search_tool],
|
||||
self_reflect=False
|
||||
reflection=False
|
||||
)
|
||||
|
||||
# 3. Tasks
|
||||
|
||||
@@ -41,9 +41,9 @@ researcher = Agent(
|
||||
tools=[internet_search_tool],
|
||||
llm="gpt-5-nano",
|
||||
markdown=True,
|
||||
reflect_llm="gpt-5-nano",
|
||||
min_reflect=2,
|
||||
max_reflect=4
|
||||
|
||||
|
||||
|
||||
)
|
||||
writer = Agent(
|
||||
name="Writer",
|
||||
|
||||
@@ -9,7 +9,7 @@ agent = Agent(
|
||||
goal="Search for information from multiple sources",
|
||||
backstory="I am an AI assistant that can search YouTube and Wikipedia.",
|
||||
tools=[YouTubeSearchTool, WikipediaAPIWrapper],
|
||||
self_reflect=False
|
||||
reflection=False
|
||||
)
|
||||
|
||||
# Create tasks to demonstrate both tools
|
||||
|
||||
@@ -8,7 +8,7 @@ vision_agent = Agent(
|
||||
backstory="""You are an expert in computer vision and image analysis.
|
||||
You excel at describing images, detecting objects, and understanding visual content.""",
|
||||
llm="gpt-5-nano",
|
||||
self_reflect=False
|
||||
reflection=False
|
||||
)
|
||||
|
||||
# 1. Task with Image URL
|
||||
|
||||
@@ -15,7 +15,7 @@ researcher = Agent(
|
||||
verbose=True,
|
||||
llm="gpt-5-nano",
|
||||
tools=[Tools.internet_search],
|
||||
self_reflect=False
|
||||
reflection=False
|
||||
)
|
||||
|
||||
# Create an analyst agent
|
||||
@@ -26,7 +26,7 @@ analyst = Agent(
|
||||
backstory="Senior data analyst with expertise in pattern recognition",
|
||||
verbose=True,
|
||||
llm="gpt-5-nano",
|
||||
self_reflect=False
|
||||
reflection=False
|
||||
)
|
||||
|
||||
# Define structured tasks
|
||||
|
||||
@@ -33,7 +33,7 @@ def get_structured_analysis(query: str, verbose: bool = True) -> AnalysisReport:
|
||||
goal="Analyze topics and provide structured reports",
|
||||
backstory="Expert at gathering information and providing structured analysis",
|
||||
verbose=verbose,
|
||||
self_reflect=True, # Enable self-reflection for better quality
|
||||
reflection=True, # Enable self-reflection for better quality
|
||||
markdown=True,
|
||||
llm="gpt-5-nano"
|
||||
)
|
||||
|
||||
@@ -94,7 +94,7 @@ agent = Agent(
|
||||
goal="Search for information about 'AI Agents Framework'",
|
||||
backstory="I am an AI assistant that can search GitHub.",
|
||||
tools=[EXASearchTool],
|
||||
self_reflect=False
|
||||
reflection=False
|
||||
)
|
||||
|
||||
# Create tasks to demonstrate both tools
|
||||
|
||||
@@ -8,7 +8,7 @@ news_agent = Agent(
|
||||
goal="Collect and analyze news articles from various sources.",
|
||||
backstory="Expert in news gathering and content analysis.",
|
||||
tools=[get_article, get_news_sources, get_articles_from_source, get_trending_topics],
|
||||
self_reflect=False
|
||||
reflection=False
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ data_agent = Agent(
|
||||
goal="Perform internet searches to collect relevant information.",
|
||||
backstory="Expert in finding and organising internet data.",
|
||||
tools=[internet_search_tool],
|
||||
self_reflect=False
|
||||
reflection=False
|
||||
)
|
||||
|
||||
# 3. Tasks
|
||||
|
||||
@@ -158,7 +158,7 @@ data_agent = Agent(
|
||||
goal="Collect and validate data about individuals",
|
||||
backstory="Expert in gathering and validating demographic data",
|
||||
tools=[random_data_of_individuals],
|
||||
self_reflect=False
|
||||
reflection=False
|
||||
)
|
||||
|
||||
process_agent = Agent(
|
||||
@@ -167,7 +167,7 @@ process_agent = Agent(
|
||||
goal="Process and categorize individual data",
|
||||
backstory="Expert in data analysis and categorization",
|
||||
tools=[process_data_of_individuals],
|
||||
self_reflect=False
|
||||
reflection=False
|
||||
)
|
||||
|
||||
# Modify tasks to use Pydantic models
|
||||
|
||||
@@ -125,7 +125,7 @@ email_task = Task(
|
||||
description="Write a business proposal for a new software project, including contact information",
|
||||
expected_output="Professional business proposal with contact email addresses",
|
||||
agent=email_agent,
|
||||
guardrail=email_format_guardrail,
|
||||
guardrails=email_format_guardrail,
|
||||
max_retries=3
|
||||
)
|
||||
|
||||
@@ -135,7 +135,7 @@ content_task = Task(
|
||||
description="Write an analysis of cloud computing benefits for small businesses",
|
||||
expected_output="Comprehensive analysis of cloud computing benefits (minimum 50 words)",
|
||||
agent=content_agent,
|
||||
guardrail=word_count_guardrail,
|
||||
guardrails=word_count_guardrail,
|
||||
max_retries=3
|
||||
)
|
||||
|
||||
@@ -145,7 +145,7 @@ business_task = Task(
|
||||
description="Provide advice on handling difficult client relationships",
|
||||
expected_output="Professional advice maintaining appropriate business tone",
|
||||
agent=business_agent,
|
||||
guardrail=professional_tone_guardrail,
|
||||
guardrails=professional_tone_guardrail,
|
||||
max_retries=3
|
||||
)
|
||||
|
||||
@@ -155,7 +155,7 @@ research_task = Task(
|
||||
description="Analyze the impact of artificial intelligence on job markets",
|
||||
expected_output="Research-backed analysis with citations and evidence",
|
||||
agent=research_agent,
|
||||
guardrail=factual_accuracy_guardrail,
|
||||
guardrails=factual_accuracy_guardrail,
|
||||
max_retries=3
|
||||
)
|
||||
|
||||
@@ -176,7 +176,7 @@ llm_guardrail_task = Task(
|
||||
agent=llm_guardrail_agent,
|
||||
|
||||
# LLM-based guardrail using natural language validation
|
||||
guardrail="Validate that this marketing content is: 1) Factually accurate with no false claims, 2) Compliant with advertising standards (no misleading statements), 3) Engaging and professional in tone, 4) Includes a clear call-to-action. If any criteria are not met, explain what needs to be improved.",
|
||||
guardrails="Validate that this marketing content is: 1) Factually accurate with no false claims, 2) Compliant with advertising standards (no misleading statements), 3) Engaging and professional in tone, 4) Includes a clear call-to-action. If any criteria are not met, explain what needs to be improved.",
|
||||
max_retries=2
|
||||
)
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ production_agent = Agent(
|
||||
goal="Generate safe, compliant content for production use",
|
||||
backstory="Production-ready agent with built-in safety and compliance checks",
|
||||
tools=[internet_search],
|
||||
guardrail=content_guardrail,
|
||||
guardrails=content_guardrail,
|
||||
max_retries=3,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
@@ -40,7 +40,7 @@ class DynamicAgentSystem:
|
||||
goal=f"Conduct {inputs['depth']} research on {inputs['topic']} in {inputs['language']}",
|
||||
backstory=f"Multilingual expert specializing in {inputs['depth']} analysis",
|
||||
tools=[duckduckgo],
|
||||
self_reflect=inputs['depth'] == 'detailed',
|
||||
reflection=inputs['depth'] == 'detailed',
|
||||
llm=self.llm_config
|
||||
)
|
||||
agents.append(research_agent)
|
||||
|
||||
@@ -19,7 +19,7 @@ search_agent = Agent(
|
||||
goal=f"Find {num_results} relevant results about {topic}",
|
||||
backstory="Expert in internet research and data collection",
|
||||
tools=[duckduckgo],
|
||||
self_reflect=False
|
||||
reflection=False
|
||||
)
|
||||
|
||||
# Create analysis agent
|
||||
|
||||
@@ -34,9 +34,7 @@ agent = Agent(
|
||||
llm=llm_config, # Pass the detailed configuration
|
||||
verbose=True, # Enable detailed output
|
||||
markdown=True, # Format responses in markdown
|
||||
self_reflect=True, # Enable self-reflection
|
||||
max_reflect=3, # Maximum reflection iterations
|
||||
min_reflect=1 # Minimum reflection iterations
|
||||
reflection=True # Enable self-reflection
|
||||
)
|
||||
|
||||
# Test the agent
|
||||
|
||||
@@ -4,7 +4,7 @@ from praisonaiagents import Agent
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
llm="gemini/gemini-1.5-flash-8b",
|
||||
self_reflect=True,
|
||||
reflection=True,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ from praisonaiagents import Agent
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
llm="gemini/gemini-1.5-flash-8b",
|
||||
self_reflect=True,
|
||||
reflection=True,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ def main():
|
||||
and technology. You provide concise, accurate summaries of important news.""",
|
||||
tools=[search_tool],
|
||||
verbose=True,
|
||||
self_reflect=False # Disable reflection for faster execution
|
||||
reflection=False # Disable reflection for faster execution
|
||||
)
|
||||
|
||||
# Define the task
|
||||
|
||||
@@ -113,7 +113,7 @@ initial_research = Task(
|
||||
description="Research the current state of renewable energy adoption in the business sector, including trends, challenges, and opportunities",
|
||||
expected_output="Comprehensive research report on renewable energy adoption in business",
|
||||
agent=research_agent,
|
||||
guardrail=data_quality_validator,
|
||||
guardrails=data_quality_validator,
|
||||
max_retries=3
|
||||
)
|
||||
|
||||
@@ -124,7 +124,7 @@ quality_check = Task(
|
||||
expected_output="Quality assessment report with go/no-go decision for proceeding to analysis",
|
||||
agent=quality_checker,
|
||||
context=[initial_research],
|
||||
guardrail=completeness_validator,
|
||||
guardrails=completeness_validator,
|
||||
max_retries=2
|
||||
)
|
||||
|
||||
@@ -153,7 +153,7 @@ additional_research = Task(
|
||||
agent=research_agent,
|
||||
context=[initial_research, quality_check],
|
||||
tools=[duckduckgo],
|
||||
guardrail=data_quality_validator,
|
||||
guardrails=data_quality_validator,
|
||||
max_retries=2
|
||||
)
|
||||
|
||||
@@ -190,7 +190,7 @@ final_report = Task(
|
||||
expected_output="Executive report with strategic recommendations for renewable energy adoption",
|
||||
agent=report_writer,
|
||||
context=[initial_research, quality_check, data_analysis, decision_task],
|
||||
guardrail=completeness_validator,
|
||||
guardrails=completeness_validator,
|
||||
max_retries=2
|
||||
)
|
||||
|
||||
|
||||
@@ -34,8 +34,7 @@ system_ops_agent = Agent(
|
||||
backstory="""You are an expert system administrator with deep knowledge of Unix/Linux systems.
|
||||
You excel at running complex system commands, managing processes, and handling system operations.
|
||||
You always validate commands before execution and ensure they are safe to run.""",
|
||||
min_reflect=6,
|
||||
max_reflect=10,
|
||||
reflection=True,
|
||||
tools=[run_terminal_command, save_to_file],
|
||||
llm="gpt-5-nano"
|
||||
)
|
||||
|
||||
@@ -53,8 +53,7 @@ web_scraper_agent = Agent(
|
||||
role="Web Scraper",
|
||||
goal="Extract URLs from https://news.ycombinator.com/",
|
||||
backstory="An expert in data extraction from websites, adept at navigating and retrieving detailed information and saving it to a file. and just check if the file is created using run_terminal_command tool",
|
||||
min_reflect=3,
|
||||
max_reflect=5,
|
||||
reflection=True,
|
||||
tools=[code_interpret, save_to_file, run_terminal_command],
|
||||
llm="gpt-5-nano"
|
||||
)
|
||||
|
||||
@@ -28,7 +28,7 @@ hackathon_judge = Agent(
|
||||
You excel at evaluating innovation, technical implementation, and presentation quality.
|
||||
You provide constructive feedback and identify both strengths and areas for improvement.""",
|
||||
llm="gpt-5-nano", # Using vision-capable model
|
||||
self_reflect=False,
|
||||
reflection=False,
|
||||
knowledge=""
|
||||
)
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ def get_hackathon_judge():
|
||||
You excel at evaluating innovation, technical implementation, and presentation quality.
|
||||
You provide constructive feedback and identify both strengths and areas for improvement.""",
|
||||
llm="gpt-5-nano", # Using vision-capable model
|
||||
self_reflect=False,
|
||||
reflection=False,
|
||||
knowledge=""
|
||||
)
|
||||
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Auto-generate CLI reference documentation from --help output.
|
||||
|
||||
Usage:
|
||||
python scripts/generate_cli_docs.py > docs/cli/reference.mdx
|
||||
python scripts/generate_cli_docs.py --output docs/cli/reference.mdx
|
||||
|
||||
This script runs `praisonai <cmd> --help` for key commands and generates
|
||||
deterministic markdown documentation.
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
# Commands to document
|
||||
COMMANDS = [
|
||||
# Top-level
|
||||
("praisonai", "--help"),
|
||||
# Knowledge
|
||||
("praisonai knowledge", "--help"),
|
||||
("praisonai knowledge index", "--help"),
|
||||
("praisonai knowledge search", "--help"),
|
||||
("praisonai knowledge add", "--help"),
|
||||
("praisonai knowledge list", "--help"),
|
||||
# RAG
|
||||
("praisonai rag", "--help"),
|
||||
("praisonai rag index", "--help"),
|
||||
("praisonai rag query", "--help"),
|
||||
("praisonai rag chat", "--help"),
|
||||
("praisonai rag eval", "--help"),
|
||||
("praisonai rag serve", "--help"),
|
||||
# Run
|
||||
("praisonai run", "--help"),
|
||||
# Chat
|
||||
("praisonai chat", "--help"),
|
||||
]
|
||||
|
||||
|
||||
def run_help(cmd: str, flag: str = "--help") -> str:
|
||||
"""Run a command with --help and capture output."""
|
||||
full_cmd = f"{cmd} {flag}"
|
||||
try:
|
||||
result = subprocess.run(
|
||||
full_cmd.split(),
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30,
|
||||
)
|
||||
return result.stdout or result.stderr or "(no output)"
|
||||
except subprocess.TimeoutExpired:
|
||||
return "(timeout)"
|
||||
except FileNotFoundError:
|
||||
return "(command not found)"
|
||||
except Exception as e:
|
||||
return f"(error: {e})"
|
||||
|
||||
|
||||
def generate_markdown() -> str:
|
||||
"""Generate markdown documentation."""
|
||||
lines = [
|
||||
"---",
|
||||
"title: CLI Reference",
|
||||
"description: Auto-generated CLI command reference",
|
||||
"---",
|
||||
"",
|
||||
"# PraisonAI CLI Reference",
|
||||
"",
|
||||
"This page is auto-generated from `--help` output.",
|
||||
"",
|
||||
f"Generated: {datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')} UTC",
|
||||
"",
|
||||
]
|
||||
|
||||
for cmd, flag in COMMANDS:
|
||||
# Section header
|
||||
cmd_name = cmd.replace("praisonai ", "").replace(" ", "-") or "main"
|
||||
lines.append(f"## `{cmd}`")
|
||||
lines.append("")
|
||||
lines.append("```")
|
||||
|
||||
# Get help output
|
||||
output = run_help(cmd, flag)
|
||||
lines.append(output.strip())
|
||||
|
||||
lines.append("```")
|
||||
lines.append("")
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Generate CLI docs from --help")
|
||||
parser.add_argument(
|
||||
"--output", "-o",
|
||||
type=Path,
|
||||
help="Output file path (default: stdout)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--check",
|
||||
action="store_true",
|
||||
help="Check if output matches existing file (for CI)",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
content = generate_markdown()
|
||||
|
||||
if args.check and args.output:
|
||||
if args.output.exists():
|
||||
existing = args.output.read_text()
|
||||
# Compare ignoring timestamp line
|
||||
existing_lines = [l for l in existing.split("\n") if not l.startswith("Generated:")]
|
||||
new_lines = [l for l in content.split("\n") if not l.startswith("Generated:")]
|
||||
if existing_lines != new_lines:
|
||||
print(f"ERROR: {args.output} is out of date. Run: python scripts/generate_cli_docs.py -o {args.output}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
print(f"OK: {args.output} is up to date")
|
||||
sys.exit(0)
|
||||
else:
|
||||
print(f"ERROR: {args.output} does not exist", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if args.output:
|
||||
args.output.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.output.write_text(content)
|
||||
print(f"Written to {args.output}")
|
||||
else:
|
||||
print(content)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -372,6 +372,26 @@ def __getattr__(name):
|
||||
except ImportError:
|
||||
return None
|
||||
|
||||
# Feature Config classes (agent-centric API)
|
||||
elif name in ("MemoryConfig", "KnowledgeConfig", "PlanningConfig",
|
||||
"ReflectionConfig", "GuardrailConfig", "WebConfig",
|
||||
"MemoryBackend", "ChunkingStrategy", "GuardrailAction",
|
||||
"WebSearchProvider"):
|
||||
from .config import feature_configs
|
||||
result = getattr(feature_configs, name)
|
||||
_lazy_cache[name] = result
|
||||
return result
|
||||
|
||||
# Context management config (already exists)
|
||||
elif name == "ManagerConfig":
|
||||
from .context.manager import ManagerConfig
|
||||
_lazy_cache[name] = ManagerConfig
|
||||
return ManagerConfig
|
||||
elif name == "ContextManager":
|
||||
from .context.manager import ContextManager
|
||||
_lazy_cache[name] = ContextManager
|
||||
return ContextManager
|
||||
|
||||
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
||||
|
||||
|
||||
@@ -527,4 +547,18 @@ __all__ = [
|
||||
'RAGConfig',
|
||||
'RAGResult',
|
||||
'RAGCitation',
|
||||
# Feature Configs (agent-centric API)
|
||||
'MemoryConfig',
|
||||
'KnowledgeConfig',
|
||||
'PlanningConfig',
|
||||
'ReflectionConfig',
|
||||
'GuardrailConfig',
|
||||
'WebConfig',
|
||||
'MemoryBackend',
|
||||
'ChunkingStrategy',
|
||||
'GuardrailAction',
|
||||
'WebSearchProvider',
|
||||
# Context Management
|
||||
'ManagerConfig',
|
||||
'ContextManager',
|
||||
]
|
||||
@@ -268,35 +268,22 @@ class Agent:
|
||||
allow_code_execution: Optional[bool] = False,
|
||||
max_retry_limit: int = 2,
|
||||
code_execution_mode: Literal["safe", "unsafe"] = "safe",
|
||||
embedder_config: Optional[Dict[str, Any]] = None,
|
||||
knowledge: Optional[Union[List[str], Any]] = None,
|
||||
knowledge: Optional[Union[bool, List[str], Any]] = None,
|
||||
retrieval_config: Optional[Union[Dict[str, Any], Any]] = None,
|
||||
knowledge_config: Optional[Dict[str, Any]] = None,
|
||||
rag_config: Optional[Dict[str, Any]] = None,
|
||||
embedder_config: Optional[Dict[str, Any]] = None,
|
||||
user_id: Optional[str] = None,
|
||||
use_system_prompt: Optional[bool] = True,
|
||||
markdown: bool = True,
|
||||
stream: bool = False,
|
||||
metrics: bool = False,
|
||||
self_reflect: bool = False,
|
||||
max_reflect: int = 3,
|
||||
min_reflect: int = 1,
|
||||
reflect_llm: Optional[str] = None,
|
||||
reflect_prompt: Optional[str] = None,
|
||||
user_id: Optional[str] = None,
|
||||
reasoning_steps: bool = False,
|
||||
guardrail: Optional[Union[Callable[['TaskOutput'], Tuple[bool, Any]], str]] = None,
|
||||
max_guardrail_retries: int = 3,
|
||||
handoffs: Optional[List[Union['Agent', 'Handoff']]] = None,
|
||||
base_url: Optional[str] = None,
|
||||
api_key: Optional[str] = None,
|
||||
web_search: Optional[Union[bool, Dict[str, Any]]] = None,
|
||||
web_fetch: Optional[Union[bool, Dict[str, Any]]] = None,
|
||||
prompt_caching: Optional[bool] = None,
|
||||
claude_memory: Optional[Union[bool, Any]] = None,
|
||||
plan_mode: bool = False,
|
||||
planning: bool = False,
|
||||
planning_tools: Optional[List[Any]] = None,
|
||||
planning_reasoning: bool = False,
|
||||
planning: Optional[Union[bool, Any]] = False,
|
||||
auto_save: Optional[str] = None,
|
||||
skills: Optional[List[str]] = None,
|
||||
skills_dirs: Optional[List[str]] = None,
|
||||
@@ -313,7 +300,12 @@ class Agent:
|
||||
output_style: Optional[Any] = None,
|
||||
thinking_budget: Optional[Any] = None,
|
||||
# Context management (single param for all context features)
|
||||
context: Optional[Union[bool, Any]] = False
|
||||
context: Optional[Union[bool, Any]] = False,
|
||||
# NEW: Consolidated feature params (agent-centric API)
|
||||
# These take precedence over individual params when provided
|
||||
reflection: Optional[Union[bool, Any]] = None, # Union[bool, ReflectionConfig]
|
||||
guardrails: Optional[Union[bool, Callable, Any]] = None, # Union[bool, Callable, GuardrailConfig]
|
||||
web: Optional[Union[bool, Any]] = None, # Union[bool, WebConfig]
|
||||
):
|
||||
"""Initialize an Agent instance.
|
||||
|
||||
@@ -429,6 +421,178 @@ class Agent:
|
||||
Agent._configure_logging()
|
||||
Agent._logging_configured = True
|
||||
|
||||
# ============================================================
|
||||
# CONSOLIDATED PARAMS EXTRACTION (agent-centric API)
|
||||
# New consolidated params take precedence over individual params
|
||||
# Initialize removed params with defaults before extraction
|
||||
# ============================================================
|
||||
|
||||
# Initialize removed params with defaults (these were removed from signature)
|
||||
claude_memory = None
|
||||
self_reflect = False
|
||||
max_reflect = 3
|
||||
min_reflect = 1
|
||||
reflect_llm = None
|
||||
reflect_prompt = None
|
||||
guardrail = None
|
||||
max_guardrail_retries = 3
|
||||
web_search = None
|
||||
web_fetch = None
|
||||
plan_mode = False
|
||||
planning_tools = None
|
||||
planning_reasoning = False
|
||||
|
||||
# Extract memory settings from consolidated 'memory' param
|
||||
# memory can be: False, True, MemoryConfig, or MemoryManager instance
|
||||
_memory_user_id = user_id # Default from param
|
||||
_memory_session_id = session_id # Default from param
|
||||
_memory_db = db # Default from param
|
||||
_memory_auto_memory = auto_memory # Default from param
|
||||
_memory_claude_memory = claude_memory # Default from param
|
||||
|
||||
if memory is not None and memory is not False:
|
||||
if hasattr(memory, 'user_id') and hasattr(memory, 'backend'):
|
||||
# It's a MemoryConfig
|
||||
if memory.user_id:
|
||||
_memory_user_id = memory.user_id
|
||||
if memory.session_id:
|
||||
_memory_session_id = memory.session_id
|
||||
if memory.db:
|
||||
_memory_db = memory.db
|
||||
_memory_auto_memory = memory.auto_memory
|
||||
_memory_claude_memory = memory.claude_memory
|
||||
# Convert MemoryConfig to appropriate memory init value
|
||||
if memory.backend == "file" or (hasattr(memory.backend, 'value') and memory.backend.value == "file"):
|
||||
memory = True # Use FileMemory
|
||||
elif memory.config:
|
||||
memory = memory.config # Use config dict
|
||||
else:
|
||||
backend_val = memory.backend.value if hasattr(memory.backend, 'value') else memory.backend
|
||||
memory = backend_val # Use backend string
|
||||
|
||||
# Apply extracted memory values
|
||||
user_id = _memory_user_id
|
||||
session_id = _memory_session_id
|
||||
db = _memory_db
|
||||
auto_memory = _memory_auto_memory
|
||||
claude_memory = _memory_claude_memory
|
||||
|
||||
# Extract knowledge settings from consolidated 'knowledge' param
|
||||
# knowledge can be: False, True, List[str], KnowledgeConfig, or KnowledgeBase instance
|
||||
_knowledge_sources = None
|
||||
_knowledge_retrieval_config = retrieval_config
|
||||
_knowledge_embedder_config = embedder_config
|
||||
|
||||
if knowledge is not None and knowledge is not False:
|
||||
if isinstance(knowledge, list):
|
||||
# It's a list of sources - use directly
|
||||
_knowledge_sources = knowledge
|
||||
elif hasattr(knowledge, 'search') and hasattr(knowledge, 'add'):
|
||||
# It's a Knowledge/KnowledgeBase instance - pass through unchanged
|
||||
# Don't modify knowledge, let the existing logic handle it
|
||||
pass
|
||||
elif hasattr(knowledge, 'sources') and hasattr(knowledge, 'embedder'):
|
||||
# It's a KnowledgeConfig (has sources list and embedder string)
|
||||
_knowledge_sources = knowledge.sources
|
||||
_knowledge_embedder_config = knowledge.embedder_config or embedder_config
|
||||
# Build retrieval config from KnowledgeConfig
|
||||
if knowledge.config:
|
||||
_knowledge_retrieval_config = knowledge.config
|
||||
else:
|
||||
_knowledge_retrieval_config = {
|
||||
'top_k': knowledge.retrieval_k,
|
||||
'threshold': knowledge.retrieval_threshold,
|
||||
'rerank': knowledge.rerank,
|
||||
'rerank_model': knowledge.rerank_model,
|
||||
}
|
||||
# Update knowledge to be the sources list for internal processing
|
||||
knowledge = _knowledge_sources if _knowledge_sources else None
|
||||
elif knowledge is True:
|
||||
# Enable knowledge but no sources provided yet
|
||||
knowledge = None
|
||||
|
||||
# Apply extracted knowledge values
|
||||
retrieval_config = _knowledge_retrieval_config
|
||||
embedder_config = _knowledge_embedder_config
|
||||
|
||||
# Extract planning settings from consolidated 'planning' param
|
||||
# planning can be: False, True, or PlanningConfig
|
||||
_planning_enabled = planning
|
||||
_plan_mode = plan_mode
|
||||
_planning_tools = planning_tools
|
||||
_planning_reasoning = planning_reasoning
|
||||
|
||||
if planning is not None:
|
||||
if planning is True:
|
||||
_planning_enabled = True
|
||||
elif planning is False:
|
||||
_planning_enabled = False
|
||||
elif hasattr(planning, 'reasoning'):
|
||||
# It's a PlanningConfig
|
||||
_planning_enabled = True
|
||||
_planning_tools = planning.tools
|
||||
_planning_reasoning = planning.reasoning
|
||||
_plan_mode = planning.read_only
|
||||
# planning param becomes True for internal use
|
||||
planning = True
|
||||
|
||||
# Apply extracted planning values
|
||||
plan_mode = _plan_mode
|
||||
planning_tools = _planning_tools
|
||||
planning_reasoning = _planning_reasoning
|
||||
|
||||
# Extract reflection settings from consolidated 'reflection' param
|
||||
if reflection is not None:
|
||||
if reflection is True:
|
||||
# Enable with defaults
|
||||
self_reflect = True
|
||||
elif reflection is False:
|
||||
self_reflect = False
|
||||
elif hasattr(reflection, 'min_iterations'):
|
||||
# It's a ReflectionConfig
|
||||
self_reflect = True
|
||||
min_reflect = reflection.min_iterations
|
||||
max_reflect = reflection.max_iterations
|
||||
reflect_llm = reflection.llm
|
||||
reflect_prompt = reflection.prompt
|
||||
|
||||
# Extract guardrail settings from consolidated 'guardrails' param
|
||||
if guardrails is not None:
|
||||
if guardrails is True:
|
||||
# Enable with defaults (no-op, user must provide validator)
|
||||
pass
|
||||
elif guardrails is False:
|
||||
guardrail = None
|
||||
elif callable(guardrails):
|
||||
# Direct validator function
|
||||
guardrail = guardrails
|
||||
elif hasattr(guardrails, 'validator'):
|
||||
# It's a GuardrailConfig
|
||||
if guardrails.validator:
|
||||
guardrail = guardrails.validator
|
||||
elif guardrails.llm_validator:
|
||||
guardrail = guardrails.llm_validator
|
||||
max_guardrail_retries = guardrails.max_retries
|
||||
|
||||
# Extract web settings from consolidated 'web' param
|
||||
if web is not None:
|
||||
if web is True:
|
||||
# Enable both search and fetch with defaults
|
||||
web_search = True
|
||||
web_fetch = True
|
||||
elif web is False:
|
||||
web_search = False
|
||||
web_fetch = False
|
||||
elif hasattr(web, 'search'):
|
||||
# It's a WebConfig
|
||||
web_search = web.search
|
||||
web_fetch = web.fetch
|
||||
# Could also extract search_config, fetch_config if needed
|
||||
|
||||
# ============================================================
|
||||
# END CONSOLIDATED PARAMS EXTRACTION
|
||||
# ============================================================
|
||||
|
||||
# If instructions are provided, use them to set role, goal, and backstory
|
||||
if instructions:
|
||||
self.name = name or "Agent"
|
||||
|
||||
@@ -127,7 +127,34 @@ def process_task_context(context_item, verbose=0, user_id=None):
|
||||
return str(context_item) # Fallback for unknown types
|
||||
|
||||
class PraisonAIAgents:
|
||||
def __init__(self, agents, tasks=None, verbose=0, completion_checker=None, max_retries=5, process="sequential", manager_llm=None, memory=False, memory_config=None, embedder=None, user_id=None, max_iter=10, stream=True, name: Optional[str] = None, planning: bool = False, planning_llm: Optional[str] = None, auto_approve_plan: bool = False, planning_tools: Optional[List] = None, planning_reasoning: bool = False, on_task_start: Optional[Callable] = None, on_task_complete: Optional[Callable] = None, variables: Optional[Dict[str, Any]] = None, context: Optional[Any] = False):
|
||||
def __init__(
|
||||
self,
|
||||
agents,
|
||||
tasks=None,
|
||||
verbose=0,
|
||||
completion_checker=None,
|
||||
max_retries=5,
|
||||
process="sequential",
|
||||
manager_llm=None,
|
||||
# Consolidated feature params (agent-centric API)
|
||||
memory: Optional[Any] = False, # Union[bool, MemoryConfig]
|
||||
planning: Optional[Any] = False, # Union[bool, PlanningConfig]
|
||||
context: Optional[Any] = False, # Union[bool, ManagerConfig, ContextManager]
|
||||
# Legacy params (kept for backward compatibility)
|
||||
memory_config=None,
|
||||
embedder=None,
|
||||
user_id=None,
|
||||
max_iter=10,
|
||||
stream=True,
|
||||
name: Optional[str] = None,
|
||||
planning_llm: Optional[str] = None,
|
||||
auto_approve_plan: bool = False,
|
||||
planning_tools: Optional[List] = None,
|
||||
planning_reasoning: bool = False,
|
||||
on_task_start: Optional[Callable] = None,
|
||||
on_task_complete: Optional[Callable] = None,
|
||||
variables: Optional[Dict[str, Any]] = None,
|
||||
):
|
||||
# Add check at the start if memory is requested
|
||||
if memory:
|
||||
try:
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
"""
|
||||
Configuration Module for PraisonAI Agents.
|
||||
|
||||
Provides feature configuration classes for agent-centric API:
|
||||
- MemoryConfig: Memory and session management
|
||||
- KnowledgeConfig: RAG and knowledge retrieval
|
||||
- PlanningConfig: Planning mode settings
|
||||
- ReflectionConfig: Self-reflection settings
|
||||
- GuardrailConfig: Safety and validation
|
||||
- WebConfig: Web search and fetch
|
||||
|
||||
All imports are lazy-loaded for zero performance impact.
|
||||
"""
|
||||
|
||||
__all__ = [
|
||||
# Enums
|
||||
"MemoryBackend",
|
||||
"ChunkingStrategy",
|
||||
"GuardrailAction",
|
||||
"WebSearchProvider",
|
||||
# Config classes
|
||||
"MemoryConfig",
|
||||
"KnowledgeConfig",
|
||||
"PlanningConfig",
|
||||
"ReflectionConfig",
|
||||
"GuardrailConfig",
|
||||
"WebConfig",
|
||||
# Type aliases
|
||||
"MemoryParam",
|
||||
"KnowledgeParam",
|
||||
"PlanningParam",
|
||||
"ReflectionParam",
|
||||
"GuardrailParam",
|
||||
"WebParam",
|
||||
]
|
||||
|
||||
|
||||
def __getattr__(name: str):
|
||||
"""Lazy load config classes."""
|
||||
if name in __all__:
|
||||
from . import feature_configs
|
||||
return getattr(feature_configs, name)
|
||||
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
||||
@@ -0,0 +1,397 @@
|
||||
"""
|
||||
Feature Configuration Classes for PraisonAI Agents.
|
||||
|
||||
Provides dataclasses for consolidated feature configuration:
|
||||
- MemoryConfig: Memory and session management
|
||||
- KnowledgeConfig: RAG and knowledge retrieval
|
||||
- PlanningConfig: Planning mode settings
|
||||
- ReflectionConfig: Self-reflection settings
|
||||
- GuardrailConfig: Safety and validation
|
||||
- WebConfig: Web search and fetch
|
||||
|
||||
All configs follow the agent-centric pattern:
|
||||
- False: Feature disabled (zero overhead)
|
||||
- True: Feature enabled with safe defaults
|
||||
- Config: Custom configuration
|
||||
- Instance: Pre-configured manager/engine
|
||||
|
||||
Usage:
|
||||
from praisonaiagents import Agent, MemoryConfig, KnowledgeConfig
|
||||
|
||||
# Simple enable
|
||||
agent = Agent(instructions="...", memory=True)
|
||||
|
||||
# With config
|
||||
agent = Agent(
|
||||
instructions="...",
|
||||
memory=MemoryConfig(backend="redis", user_id="user123"),
|
||||
knowledge=KnowledgeConfig(sources=["docs/"], rerank=True),
|
||||
)
|
||||
"""
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Dict, List, Any, Optional, Callable, Tuple, Union
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class MemoryBackend(str, Enum):
|
||||
"""Memory storage backends."""
|
||||
FILE = "file"
|
||||
SQLITE = "sqlite"
|
||||
REDIS = "redis"
|
||||
POSTGRES = "postgres"
|
||||
MEM0 = "mem0"
|
||||
MONGODB = "mongodb"
|
||||
|
||||
|
||||
@dataclass
|
||||
class MemoryConfig:
|
||||
"""
|
||||
Configuration for agent memory and session management.
|
||||
|
||||
Consolidates: memory, auto_memory, claude_memory, user_id, session_id, db
|
||||
|
||||
Usage:
|
||||
# Simple enable (uses FileMemory)
|
||||
Agent(memory=True)
|
||||
|
||||
# With backend
|
||||
Agent(memory=MemoryConfig(backend="redis"))
|
||||
|
||||
# Full config
|
||||
Agent(memory=MemoryConfig(
|
||||
backend="sqlite",
|
||||
user_id="user123",
|
||||
session_id="session456",
|
||||
auto_memory=True,
|
||||
))
|
||||
"""
|
||||
# Backend selection
|
||||
backend: Union[str, MemoryBackend] = MemoryBackend.FILE
|
||||
|
||||
# Session identification
|
||||
user_id: Optional[str] = None
|
||||
session_id: Optional[str] = None
|
||||
|
||||
# Auto-memory extraction
|
||||
auto_memory: bool = False
|
||||
|
||||
# Claude-specific memory (for Anthropic models)
|
||||
claude_memory: bool = False
|
||||
|
||||
# Database adapter (for advanced use)
|
||||
db: Optional[Any] = None
|
||||
|
||||
# Memory configuration dict (for provider-specific settings)
|
||||
config: Optional[Dict[str, Any]] = None
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Convert to dictionary."""
|
||||
return {
|
||||
"backend": self.backend.value if isinstance(self.backend, MemoryBackend) else self.backend,
|
||||
"user_id": self.user_id,
|
||||
"session_id": self.session_id,
|
||||
"auto_memory": self.auto_memory,
|
||||
"claude_memory": self.claude_memory,
|
||||
"config": self.config,
|
||||
}
|
||||
|
||||
|
||||
class ChunkingStrategy(str, Enum):
|
||||
"""Knowledge chunking strategies."""
|
||||
FIXED = "fixed"
|
||||
SEMANTIC = "semantic"
|
||||
SENTENCE = "sentence"
|
||||
PARAGRAPH = "paragraph"
|
||||
|
||||
|
||||
@dataclass
|
||||
class KnowledgeConfig:
|
||||
"""
|
||||
Configuration for RAG and knowledge retrieval.
|
||||
|
||||
Consolidates: knowledge, retrieval_config, knowledge_config, rag_config, embedder_config
|
||||
|
||||
Usage:
|
||||
# Simple enable with sources
|
||||
Agent(knowledge=["docs/", "data.pdf"])
|
||||
|
||||
# With config
|
||||
Agent(knowledge=KnowledgeConfig(
|
||||
sources=["docs/"],
|
||||
embedder="openai",
|
||||
chunking_strategy="semantic",
|
||||
retrieval_k=5,
|
||||
rerank=True,
|
||||
))
|
||||
"""
|
||||
# Knowledge sources (files, directories, URLs)
|
||||
sources: List[str] = field(default_factory=list)
|
||||
|
||||
# Embedder configuration
|
||||
embedder: str = "openai"
|
||||
embedder_config: Optional[Dict[str, Any]] = None
|
||||
|
||||
# Chunking
|
||||
chunking_strategy: Union[str, ChunkingStrategy] = ChunkingStrategy.SEMANTIC
|
||||
chunk_size: int = 1000
|
||||
chunk_overlap: int = 200
|
||||
|
||||
# Retrieval
|
||||
retrieval_k: int = 5
|
||||
retrieval_threshold: float = 0.0
|
||||
|
||||
# Reranking
|
||||
rerank: bool = False
|
||||
rerank_model: Optional[str] = None
|
||||
|
||||
# Auto-retrieval (inject context automatically)
|
||||
auto_retrieve: bool = True
|
||||
|
||||
# Full config dict (for advanced use)
|
||||
config: Optional[Dict[str, Any]] = None
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Convert to dictionary."""
|
||||
return {
|
||||
"sources": self.sources,
|
||||
"embedder": self.embedder,
|
||||
"embedder_config": self.embedder_config,
|
||||
"chunking_strategy": self.chunking_strategy.value if isinstance(self.chunking_strategy, ChunkingStrategy) else self.chunking_strategy,
|
||||
"chunk_size": self.chunk_size,
|
||||
"chunk_overlap": self.chunk_overlap,
|
||||
"retrieval_k": self.retrieval_k,
|
||||
"retrieval_threshold": self.retrieval_threshold,
|
||||
"rerank": self.rerank,
|
||||
"rerank_model": self.rerank_model,
|
||||
"auto_retrieve": self.auto_retrieve,
|
||||
"config": self.config,
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class PlanningConfig:
|
||||
"""
|
||||
Configuration for planning mode.
|
||||
|
||||
Consolidates: planning, plan_mode, planning_tools, planning_reasoning, planning_llm
|
||||
|
||||
Usage:
|
||||
# Simple enable
|
||||
Agent(planning=True)
|
||||
|
||||
# With config
|
||||
Agent(planning=PlanningConfig(
|
||||
llm="gpt-4o",
|
||||
tools=[search_tool],
|
||||
reasoning=True,
|
||||
auto_approve=False,
|
||||
))
|
||||
"""
|
||||
# Planning LLM (if different from main)
|
||||
llm: Optional[str] = None
|
||||
|
||||
# Tools available during planning
|
||||
tools: Optional[List[Any]] = None
|
||||
|
||||
# Enable reasoning during planning
|
||||
reasoning: bool = False
|
||||
|
||||
# Auto-approve plans without user confirmation
|
||||
auto_approve: bool = False
|
||||
|
||||
# Read-only mode (plan_mode) - only read operations allowed
|
||||
read_only: bool = False
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Convert to dictionary."""
|
||||
return {
|
||||
"llm": self.llm,
|
||||
"tools": [str(t) for t in (self.tools or [])],
|
||||
"reasoning": self.reasoning,
|
||||
"auto_approve": self.auto_approve,
|
||||
"read_only": self.read_only,
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class ReflectionConfig:
|
||||
"""
|
||||
Configuration for self-reflection.
|
||||
|
||||
Consolidates: self_reflect, max_reflect, min_reflect, reflect_llm, reflect_prompt
|
||||
|
||||
Usage:
|
||||
# Simple enable
|
||||
Agent(reflection=True)
|
||||
|
||||
# With config
|
||||
Agent(reflection=ReflectionConfig(
|
||||
min_iterations=1,
|
||||
max_iterations=3,
|
||||
llm="gpt-4o",
|
||||
prompt="Evaluate your response for accuracy...",
|
||||
))
|
||||
"""
|
||||
# Iteration limits
|
||||
min_iterations: int = 1
|
||||
max_iterations: int = 3
|
||||
|
||||
# Reflection LLM (if different from main)
|
||||
llm: Optional[str] = None
|
||||
|
||||
# Custom reflection prompt
|
||||
prompt: Optional[str] = None
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Convert to dictionary."""
|
||||
return {
|
||||
"min_iterations": self.min_iterations,
|
||||
"max_iterations": self.max_iterations,
|
||||
"llm": self.llm,
|
||||
"prompt": self.prompt,
|
||||
}
|
||||
|
||||
|
||||
class GuardrailAction(str, Enum):
|
||||
"""Action to take when guardrail fails."""
|
||||
RETRY = "retry"
|
||||
SKIP = "skip"
|
||||
RAISE = "raise"
|
||||
|
||||
|
||||
@dataclass
|
||||
class GuardrailConfig:
|
||||
"""
|
||||
Configuration for guardrails and safety validation.
|
||||
|
||||
Consolidates: guardrail, max_guardrail_retries, policy
|
||||
|
||||
Usage:
|
||||
# With validator function
|
||||
Agent(guardrails=my_validator_fn)
|
||||
|
||||
# With config
|
||||
Agent(guardrails=GuardrailConfig(
|
||||
validator=my_validator_fn,
|
||||
max_retries=3,
|
||||
on_fail="retry",
|
||||
))
|
||||
|
||||
# With LLM-based validation
|
||||
Agent(guardrails=GuardrailConfig(
|
||||
llm_validator="Ensure response is helpful and safe",
|
||||
max_retries=2,
|
||||
))
|
||||
"""
|
||||
# Validator function: (TaskOutput) -> Tuple[bool, Any]
|
||||
validator: Optional[Callable[..., Tuple[bool, Any]]] = None
|
||||
|
||||
# LLM-based validation prompt
|
||||
llm_validator: Optional[str] = None
|
||||
|
||||
# Retry settings
|
||||
max_retries: int = 3
|
||||
on_fail: Union[str, GuardrailAction] = GuardrailAction.RETRY
|
||||
|
||||
# Policy engine (for advanced use)
|
||||
policy: Optional[Any] = None
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Convert to dictionary."""
|
||||
return {
|
||||
"validator": str(self.validator) if self.validator else None,
|
||||
"llm_validator": self.llm_validator,
|
||||
"max_retries": self.max_retries,
|
||||
"on_fail": self.on_fail.value if isinstance(self.on_fail, GuardrailAction) else self.on_fail,
|
||||
}
|
||||
|
||||
|
||||
class WebSearchProvider(str, Enum):
|
||||
"""Web search providers."""
|
||||
DUCKDUCKGO = "duckduckgo"
|
||||
GOOGLE = "google"
|
||||
BING = "bing"
|
||||
TAVILY = "tavily"
|
||||
SERPER = "serper"
|
||||
|
||||
|
||||
@dataclass
|
||||
class WebConfig:
|
||||
"""
|
||||
Configuration for web search and fetch capabilities.
|
||||
|
||||
Consolidates: web_search, web_fetch
|
||||
|
||||
Usage:
|
||||
# Simple enable
|
||||
Agent(web=True)
|
||||
|
||||
# With config
|
||||
Agent(web=WebConfig(
|
||||
search=True,
|
||||
fetch=True,
|
||||
search_provider="duckduckgo",
|
||||
max_results=5,
|
||||
))
|
||||
"""
|
||||
# Enable web search
|
||||
search: bool = True
|
||||
|
||||
# Enable web fetch (retrieve full page content)
|
||||
fetch: bool = True
|
||||
|
||||
# Search provider
|
||||
search_provider: Union[str, WebSearchProvider] = WebSearchProvider.DUCKDUCKGO
|
||||
|
||||
# Search settings
|
||||
max_results: int = 5
|
||||
|
||||
# Search config dict (for provider-specific settings)
|
||||
search_config: Optional[Dict[str, Any]] = None
|
||||
|
||||
# Fetch config dict
|
||||
fetch_config: Optional[Dict[str, Any]] = None
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Convert to dictionary."""
|
||||
return {
|
||||
"search": self.search,
|
||||
"fetch": self.fetch,
|
||||
"search_provider": self.search_provider.value if isinstance(self.search_provider, WebSearchProvider) else self.search_provider,
|
||||
"max_results": self.max_results,
|
||||
"search_config": self.search_config,
|
||||
"fetch_config": self.fetch_config,
|
||||
}
|
||||
|
||||
|
||||
# Type aliases for Union types used in Agent.__init__
|
||||
MemoryParam = Union[bool, MemoryConfig, Any] # Any = MemoryManager instance
|
||||
KnowledgeParam = Union[bool, List[str], KnowledgeConfig, Any] # Any = KnowledgeBase instance
|
||||
PlanningParam = Union[bool, PlanningConfig]
|
||||
ReflectionParam = Union[bool, ReflectionConfig]
|
||||
GuardrailParam = Union[bool, Callable[..., Tuple[bool, Any]], GuardrailConfig, Any] # Any = GuardrailEngine
|
||||
WebParam = Union[bool, WebConfig]
|
||||
|
||||
|
||||
__all__ = [
|
||||
# Enums
|
||||
"MemoryBackend",
|
||||
"ChunkingStrategy",
|
||||
"GuardrailAction",
|
||||
"WebSearchProvider",
|
||||
# Config classes
|
||||
"MemoryConfig",
|
||||
"KnowledgeConfig",
|
||||
"PlanningConfig",
|
||||
"ReflectionConfig",
|
||||
"GuardrailConfig",
|
||||
"WebConfig",
|
||||
# Type aliases
|
||||
"MemoryParam",
|
||||
"KnowledgeParam",
|
||||
"PlanningParam",
|
||||
"ReflectionParam",
|
||||
"GuardrailParam",
|
||||
"WebParam",
|
||||
]
|
||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "praisonaiagents"
|
||||
version = "0.8.1"
|
||||
version = "0.9.0"
|
||||
description = "Praison AI agents for completing complex tasks with Self Reflection Agents"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
|
||||
Generated
+1
-1
@@ -2422,7 +2422,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "praisonaiagents"
|
||||
version = "0.8.1"
|
||||
version = "0.9.0"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "aiohttp" },
|
||||
|
||||
@@ -3,8 +3,8 @@ class Praisonai < Formula
|
||||
|
||||
desc "AI tools for various AI applications"
|
||||
homepage "https://github.com/MervinPraison/PraisonAI"
|
||||
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v3.3.1.tar.gz"
|
||||
sha256 `curl -sL https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v3.3.1.tar.gz | shasum -a 256`.split.first
|
||||
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v3.4.0.tar.gz"
|
||||
sha256 `curl -sL https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v3.4.0.tar.gz | shasum -a 256`.split.first
|
||||
license "MIT"
|
||||
|
||||
depends_on "[email protected]"
|
||||
|
||||
@@ -57,7 +57,7 @@ class CloudDeployer:
|
||||
file.write("FROM python:3.11-slim\n")
|
||||
file.write("WORKDIR /app\n")
|
||||
file.write("COPY . .\n")
|
||||
file.write("RUN pip install flask praisonai==3.3.1 gunicorn markdown\n")
|
||||
file.write("RUN pip install flask praisonai==3.4.0 gunicorn markdown\n")
|
||||
file.write("EXPOSE 8080\n")
|
||||
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "3.3.1"
|
||||
__version__ = "3.4.0"
|
||||
@@ -12,7 +12,7 @@ dependencies = [
|
||||
"rich>=13.7",
|
||||
"markdown>=3.5",
|
||||
"pyparsing>=3.0.0",
|
||||
"praisonaiagents>=0.8.1",
|
||||
"praisonaiagents>=0.9.0",
|
||||
"python-dotenv>=0.19.0",
|
||||
"instructor>=1.3.3",
|
||||
"PyYAML>=6.0",
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Generated
+4
-4
@@ -4276,7 +4276,7 @@ requires-dist = [
|
||||
{ name = "praisonai-tools", marker = "extra == 'autogen'", specifier = ">=0.1.0" },
|
||||
{ name = "praisonai-tools", marker = "extra == 'autogen-v4'", specifier = ">=0.1.0" },
|
||||
{ name = "praisonai-tools", marker = "extra == 'crewai'", specifier = ">=0.1.0" },
|
||||
{ name = "praisonaiagents", specifier = ">=0.8.1" },
|
||||
{ name = "praisonaiagents", specifier = ">=0.9.0" },
|
||||
{ name = "pyautogen", marker = "extra == 'autogen'", specifier = "==0.2.29" },
|
||||
{ name = "pydantic", marker = "extra == 'chat'", specifier = "<=2.10.1" },
|
||||
{ name = "pydantic", marker = "extra == 'code'", specifier = "<=2.10.1" },
|
||||
@@ -4324,7 +4324,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "praisonaiagents"
|
||||
version = "0.8.1"
|
||||
version = "0.9.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "aiohttp" },
|
||||
@@ -4333,9 +4333,9 @@ dependencies = [
|
||||
{ name = "pydantic" },
|
||||
{ name = "rich" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d1/a1/3577e22f24fd64c870d1b5e0cb56f7addd88c45d0c2fbb649a63cbf509d5/praisonaiagents-0.8.1.tar.gz", hash = "sha256:f17f6e8bdecdebb7c0c234ebc7103070c4546b31d41e878572208c75e6ef19ef", size = 897661, upload-time = "2026-01-08T12:24:08.607Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f5/a8/c2e09f15cc54dec0afe91c69ad75fc8a1634de9ae2701d08c1e7cd64a4b5/praisonaiagents-0.9.0.tar.gz", hash = "sha256:a1f1e38676f723e7fbc1d8fa9314e63d1884fb8a069fbafa5ea028ec4fb9bf66", size = 902419, upload-time = "2026-01-08T13:23:10.826Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/71/01/d0afaf98e78da1d1293f6f1a53e6b2f7b14c8ba1908b70eed16e5b138427/praisonaiagents-0.8.1-py3-none-any.whl", hash = "sha256:b898f8f1f38ae8d010dfba69f443f146faa2d685c997aa5a4992e786dc115654", size = 866252, upload-time = "2026-01-08T12:24:05.975Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3f/da/341d32c829f9928ad858ffaf736e10a84ca3710fe3811e714a0d2cd576a2/praisonaiagents-0.9.0-py3-none-any.whl", hash = "sha256:1de58782b547ef5f2ec9df1ab3a41a9fb7b990fd3b0769eea5a47d9544ecf7f8", size = 871844, upload-time = "2026-01-08T13:23:08.584Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
Reference in new issue
Block a user