mirror of
https://github.com/MervinPraison/PraisonAI.git
synced 2026-11-07 17:33:33 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
657fd93743 | ||
|
|
f0a2936b7f | ||
|
|
58778492ca | ||
|
|
08c444f3a8 | ||
|
|
34c1b39e95 | ||
|
|
5e4c58a9ac | ||
|
|
19a30ff3d9 | ||
|
|
50f12c7682 | ||
|
|
5a70b8abb9 | ||
|
|
b7d4d219b9 | ||
|
|
ff2d83ffdf | ||
|
|
2d58caa741 | ||
|
|
d31cf379e5 | ||
|
|
719ef04e7c | ||
|
|
4fb25a99d5 | ||
|
|
0fdacff2cf | ||
|
|
6a1fa19c6e | ||
|
|
a4725a027a | ||
|
|
dc9a8f3443 | ||
|
|
9421e28c8a | ||
|
|
c3d60c82ca | ||
|
|
8c509b439f | ||
|
|
3fbf1a353e | ||
|
|
e0f3a49e41 | ||
|
|
987b43877f | ||
|
|
ebb383208e | ||
|
|
c9e4f0738a | ||
|
|
db0a24555d | ||
|
|
e3fe35e2b6 | ||
|
|
74a7322b83 | ||
|
|
7ceb7f8cb9 | ||
|
|
84e5b6c693 | ||
|
|
5f00ddbc7c | ||
|
|
db551c5d65 | ||
|
|
aed6027256 | ||
|
|
a9d709645a |
No files matched your search
@@ -0,0 +1,204 @@
|
||||
name: Windows Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, develop]
|
||||
pull_request:
|
||||
branches: [main, develop]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
test-windows:
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 5
|
||||
env:
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
OPENAI_MODEL_NAME: gpt-4o-mini
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python 3.11
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
|
||||
- name: Install praisonaiagents
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
cd src/praisonai-agents
|
||||
pip install .
|
||||
shell: bash
|
||||
|
||||
- name: Install praisonai wrapper
|
||||
run: |
|
||||
cd src/praisonai
|
||||
pip install .[dev]
|
||||
shell: bash
|
||||
|
||||
# ==================== CORE IMPORTS ====================
|
||||
- name: Test core imports
|
||||
run: |
|
||||
python -c "from praisonaiagents import Agent, Agents, Workflow; print('Core imports OK')"
|
||||
python -c "from praisonaiagents import tool, Tools; print('Tool imports OK')"
|
||||
python -c "from praisonaiagents import Task, WorkflowStep; print('Task/Step imports OK')"
|
||||
|
||||
# ==================== AGENT FEATURES ====================
|
||||
- name: Test Agent instantiation
|
||||
run: |
|
||||
python -c "
|
||||
from praisonaiagents import Agent
|
||||
a = Agent(name='Test', instructions='You are helpful')
|
||||
print('Agent created:', a.name)
|
||||
a2 = Agent(name='ToolAgent', instructions='Use tools', tools=[])
|
||||
print('Agent with tools:', a2.name)
|
||||
"
|
||||
|
||||
- name: Test Agents orchestration
|
||||
run: |
|
||||
python -c "
|
||||
from praisonaiagents import Agent, Agents, Task
|
||||
a1 = Agent(name='Agent1', instructions='First agent')
|
||||
a2 = Agent(name='Agent2', instructions='Second agent')
|
||||
t = Task(description='Do something', agent=a1)
|
||||
agents = Agents(agents=[a1, a2], tasks=[t])
|
||||
print('Agents:', len(agents.agents), 'Tasks:', len(agents.tasks))
|
||||
"
|
||||
|
||||
# ==================== WORKFLOW FEATURES ====================
|
||||
- name: Test Workflow and WorkflowStep
|
||||
run: |
|
||||
python -c "
|
||||
from praisonaiagents import Workflow, WorkflowStep
|
||||
from praisonaiagents.workflows import WorkflowOutputConfig
|
||||
|
||||
w = Workflow(name='test')
|
||||
s1 = WorkflowStep(name='step1')
|
||||
s2 = WorkflowStep(name='step2', context=['step1'])
|
||||
print('Workflow:', w.name)
|
||||
print('Steps:', s1.name, s2.name)
|
||||
|
||||
cfg = WorkflowOutputConfig(verbose=True, stream=False)
|
||||
w2 = Workflow(name='configured', output=cfg)
|
||||
print('Configured workflow verbose:', w2.verbose)
|
||||
"
|
||||
|
||||
# ==================== MEMORY FEATURES ====================
|
||||
- name: Test Memory classes
|
||||
run: |
|
||||
python -c "
|
||||
from praisonaiagents.memory import FileMemory
|
||||
from praisonaiagents.config import MemoryConfig
|
||||
|
||||
cfg = MemoryConfig(backend='file', user_id='test_user')
|
||||
print('MemoryConfig backend:', cfg.backend)
|
||||
|
||||
mem = FileMemory(user_id='test_user', base_path='.praison/test_memory')
|
||||
print('FileMemory user:', mem.user_id)
|
||||
"
|
||||
|
||||
# ==================== TOOL DECORATOR ====================
|
||||
- name: Test tool decorator
|
||||
run: |
|
||||
python -c "
|
||||
from praisonaiagents import tool
|
||||
|
||||
@tool
|
||||
def my_tool(query: str) -> str:
|
||||
'''A test tool'''
|
||||
return f'Echo: {query}'
|
||||
|
||||
result = my_tool('hello')
|
||||
print('Tool result:', result)
|
||||
"
|
||||
|
||||
# ==================== CONFIG CLASSES ====================
|
||||
- name: Test config classes
|
||||
run: |
|
||||
python -c "
|
||||
from praisonaiagents.config import OutputConfig, ExecutionConfig, PlanningConfig
|
||||
|
||||
out_cfg = OutputConfig(verbose=True, stream=True)
|
||||
print('OutputConfig verbose:', out_cfg.verbose)
|
||||
|
||||
exec_cfg = ExecutionConfig(max_iter=50, max_retry_limit=5)
|
||||
print('ExecutionConfig max_iter:', exec_cfg.max_iter)
|
||||
|
||||
plan_cfg = PlanningConfig(reasoning=True, auto_approve=False)
|
||||
print('PlanningConfig reasoning:', plan_cfg.reasoning)
|
||||
"
|
||||
# ==================== HANDOFF ====================
|
||||
- name: Test Handoff
|
||||
run: |
|
||||
python -c "
|
||||
from praisonaiagents import Handoff, handoff, Agent
|
||||
|
||||
a1 = Agent(name='Agent1', instructions='First')
|
||||
a2 = Agent(name='Agent2', instructions='Second')
|
||||
|
||||
# Using Handoff class directly
|
||||
h = Handoff(agent=a2)
|
||||
print('Handoff tool name:', h.tool_name)
|
||||
|
||||
# Using handoff function
|
||||
h2 = handoff(a1, tool_name_override='custom_handoff')
|
||||
print('Custom handoff name:', h2.tool_name)
|
||||
"
|
||||
|
||||
|
||||
# ==================== ASYNC FEATURES ====================
|
||||
- name: Test async imports
|
||||
run: |
|
||||
python -c "
|
||||
import asyncio
|
||||
from praisonaiagents import Agent
|
||||
|
||||
async def test_async():
|
||||
agent = Agent(name='AsyncAgent', instructions='Test')
|
||||
assert hasattr(agent, 'arun'), 'Missing arun'
|
||||
assert hasattr(agent, 'astart'), 'Missing astart'
|
||||
print('Async methods available')
|
||||
|
||||
asyncio.run(test_async())
|
||||
"
|
||||
|
||||
# ==================== CLI COMMANDS ====================
|
||||
- name: Test CLI help
|
||||
run: praisonai --help
|
||||
|
||||
- name: Test CLI session list
|
||||
run: praisonai session list
|
||||
continue-on-error: true
|
||||
|
||||
- name: Test CLI queue list
|
||||
run: praisonai queue list
|
||||
continue-on-error: true
|
||||
|
||||
# ==================== REAL API TESTS ====================
|
||||
- name: Real API test - Agent run
|
||||
if: env.OPENAI_API_KEY != ''
|
||||
run: |
|
||||
python -c "
|
||||
from praisonaiagents import Agent
|
||||
agent = Agent(name='TestAgent', instructions='Reply with exactly: WINDOWS_OK', llm='gpt-4o-mini')
|
||||
result = agent.run('Say WINDOWS_OK')
|
||||
print('Result:', result)
|
||||
print('Real API test passed')
|
||||
"
|
||||
|
||||
- name: Real API test - Multi-agent
|
||||
if: env.OPENAI_API_KEY != ''
|
||||
run: |
|
||||
python -c "
|
||||
from praisonaiagents import Agent, Agents, Task
|
||||
|
||||
researcher = Agent(name='Researcher', instructions='You research topics', llm='gpt-4o-mini')
|
||||
writer = Agent(name='Writer', instructions='You write content', llm='gpt-4o-mini')
|
||||
|
||||
task = Task(description='Say hello world', agent=researcher)
|
||||
|
||||
agents = Agents(agents=[researcher, writer], tasks=[task])
|
||||
result = agents.start()
|
||||
print('Multi-agent result type:', type(result))
|
||||
print('Multi-agent test passed')
|
||||
"
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
PraisonAI is a production-ready Multi-AI Agents framework with self-reflection, designed to create AI Agents to automate and solve problems ranging from simple tasks to complex challenges. By integrating PraisonAI Agents, AG2 (Formerly AutoGen), and CrewAI into a low-code solution, it streamlines the building and management of multi-agent LLM systems, emphasising simplicity, customisation, and effective human-agent collaboration.
|
||||
PraisonAI is a production-ready Multi-AI Agents framework with self-reflection, designed to create AI Agents to automate and solve problems ranging from simple tasks to complex challenges. It provides a low-code solution to streamline the building and management of multi-agent LLM systems, emphasising simplicity, customisation, and effective human-agent collaboration.
|
||||
|
||||
<div align="center">
|
||||
<a href="https://docs.praison.ai">
|
||||
|
||||
@@ -12,7 +12,7 @@ from praisonaiagents import Agent, Agents
|
||||
|
||||
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 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 +22,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)</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 +31,18 @@ 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">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_generating</a>(content: str, start_time: float)</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 +56,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>
|
||||
@@ -121,7 +127,7 @@ Methods:
|
||||
|
||||
Types:
|
||||
```python
|
||||
from praisonaiagents import Task
|
||||
from praisonaiagents import EmbeddingResult, Task, aembedding, aembeddings, embedding, embeddings, get_dimensions
|
||||
```
|
||||
|
||||
Methods:
|
||||
@@ -130,6 +136,9 @@ 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">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/dimensions.py">get_dimensions</a>(model_name: str) -> int</code>
|
||||
|
||||
# Wrapper (praisonai)
|
||||
|
||||
@@ -148,6 +157,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>
|
||||
@@ -199,6 +212,7 @@ Methods:
|
||||
* <code title="cli">praisonai docs run-all <a href="./src/praisonai/praisonai/cli/commands/docs.py">--help</a></code>
|
||||
* <code title="cli">praisonai docs serve <a href="./src/praisonai/praisonai/cli/commands/docs.py">--help</a></code>
|
||||
* <code title="cli">praisonai docs stats <a href="./src/praisonai/praisonai/cli/commands/docs.py">--help</a></code>
|
||||
* <code title="cli">praisonai doctor cleanup <a href="./src/praisonai/praisonai/cli/commands/doctor.py">--help</a></code>
|
||||
* <code title="cli">praisonai doctor config <a href="./src/praisonai/praisonai/cli/commands/doctor.py">--help</a></code>
|
||||
* <code title="cli">praisonai doctor db <a href="./src/praisonai/praisonai/cli/commands/doctor.py">--help</a></code>
|
||||
* <code title="cli">praisonai doctor doctor-callback <a href="./src/praisonai/praisonai/cli/commands/doctor.py">--help</a></code>
|
||||
@@ -208,6 +222,7 @@ Methods:
|
||||
* <code title="cli">praisonai doctor performance <a href="./src/praisonai/praisonai/cli/commands/doctor.py">--help</a></code>
|
||||
* <code title="cli">praisonai doctor selftest <a href="./src/praisonai/praisonai/cli/commands/doctor.py">--help</a></code>
|
||||
* <code title="cli">praisonai doctor tools <a href="./src/praisonai/praisonai/cli/commands/doctor.py">--help</a></code>
|
||||
* <code title="cli">praisonai doctor troubleshoot <a href="./src/praisonai/praisonai/cli/commands/doctor.py">--help</a></code>
|
||||
* <code title="cli">praisonai endpoints list <a href="./src/praisonai/praisonai/cli/commands/endpoints.py">--help</a></code>
|
||||
* <code title="cli">praisonai endpoints test <a href="./src/praisonai/praisonai/cli/commands/endpoints.py">--help</a></code>
|
||||
* <code title="cli">praisonai environment check <a href="./src/praisonai/praisonai/cli/commands/environment.py">--help</a></code>
|
||||
@@ -234,10 +249,13 @@ Methods:
|
||||
* <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>
|
||||
* <code title="cli">praisonai mcp status <a href="./src/praisonai/praisonai/cli/commands/mcp.py">--help</a></code>
|
||||
* <code title="cli">praisonai mcp sync <a href="./src/praisonai/praisonai/cli/commands/mcp.py">--help</a></code>
|
||||
* <code title="cli">praisonai mcp test <a href="./src/praisonai/praisonai/cli/commands/mcp.py">--help</a></code>
|
||||
@@ -268,6 +286,12 @@ Methods:
|
||||
* <code title="cli">praisonai recipe run <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 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>
|
||||
@@ -321,7 +345,11 @@ Methods:
|
||||
* <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>
|
||||
@@ -340,6 +368,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";
|
||||
@@ -361,7 +391,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";
|
||||
@@ -385,9 +415,10 @@ 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 { EvalResults, EvalSuite, Evaluator, accuracyEval, containsKeywordsCriterion, createDefaultEvaluator, createEvalResults, createEvaluator, lengthCriterion, noHarmfulContentCriterion, performanceEval, relevanceCriterion, reliabilityEval } 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";
|
||||
@@ -405,10 +436,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
|
||||
@@ -416,14 +451,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.8.11" \
|
||||
"praisonai>=3.10.4" \
|
||||
"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.8.11" \
|
||||
"praisonai>=3.10.4" \
|
||||
"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.8.11" \
|
||||
"praisonai>=3.10.4" \
|
||||
"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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
@@ -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?")
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
"""
|
||||
Multi-Server MCP Example.
|
||||
|
||||
This example demonstrates how to use multiple MCP servers with PraisonAI Agents,
|
||||
including mixing MCP tools with regular Python function tools.
|
||||
|
||||
Requirements:
|
||||
- Node.js and npx installed (or uvx for Python-based servers)
|
||||
- pip install praisonaiagents[mcp]
|
||||
- OPENAI_API_KEY environment variable set
|
||||
|
||||
Usage:
|
||||
python multi_server.py
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent, MCP
|
||||
import os
|
||||
|
||||
|
||||
def calculate(expression: str) -> str:
|
||||
"""
|
||||
A simple calculator tool that evaluates mathematical expressions.
|
||||
|
||||
Args:
|
||||
expression: A mathematical expression to evaluate (e.g., "2 + 2")
|
||||
|
||||
Returns:
|
||||
The result of the calculation
|
||||
"""
|
||||
try:
|
||||
# Safe evaluation of mathematical expressions
|
||||
allowed_chars = set("0123456789+-*/.() ")
|
||||
if not all(c in allowed_chars for c in expression):
|
||||
return "Error: Invalid characters in expression"
|
||||
result = eval(expression)
|
||||
return f"Result: {result}"
|
||||
except Exception as e:
|
||||
return f"Error: {str(e)}"
|
||||
|
||||
|
||||
def main():
|
||||
# Check for API key
|
||||
if not os.environ.get("OPENAI_API_KEY"):
|
||||
print("Please set OPENAI_API_KEY environment variable")
|
||||
return
|
||||
|
||||
print("=" * 60)
|
||||
print("Multi-Server MCP Example")
|
||||
print("=" * 60)
|
||||
|
||||
# Create MCP instance with Time server
|
||||
print("\nInitializing MCP servers...")
|
||||
try:
|
||||
time_mcp = MCP("uvx mcp-server-time", timeout=30)
|
||||
print("✓ Time MCP server initialized")
|
||||
except Exception as e:
|
||||
print(f"✗ Time MCP server failed: {e}")
|
||||
return
|
||||
|
||||
# Create an agent with multiple tool sources
|
||||
agent = Agent(
|
||||
name="MultiToolAgent",
|
||||
instructions="""You are a helpful assistant with access to multiple tools:
|
||||
1. Time tools - for getting current time in different timezones
|
||||
2. Calculator - for mathematical calculations
|
||||
|
||||
Use the appropriate tool based on the user's request.""",
|
||||
llm="openai/gpt-4o-mini",
|
||||
tools=[time_mcp, calculate] # Mix MCP and regular tools
|
||||
)
|
||||
|
||||
# Show available tools
|
||||
print("\nAvailable tools:")
|
||||
formatted_tools = agent._format_tools_for_completion(agent.tools)
|
||||
for tool in formatted_tools:
|
||||
print(f" - {tool['function']['name']}: {tool['function']['description'][:50]}...")
|
||||
|
||||
# Example queries
|
||||
queries = [
|
||||
"What time is it in Tokyo?",
|
||||
"Calculate 15 * 7 + 23",
|
||||
"What's the current time in New York and London?"
|
||||
]
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("Running queries...")
|
||||
print("=" * 60)
|
||||
|
||||
for i, query in enumerate(queries, 1):
|
||||
print(f"\n--- Query {i} ---")
|
||||
print(f"Question: {query}\n")
|
||||
|
||||
try:
|
||||
response = agent.chat(query)
|
||||
print(f"Response:\n{response}")
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
|
||||
print("-" * 40)
|
||||
|
||||
# Clean up
|
||||
time_mcp.shutdown()
|
||||
print("\nDone!")
|
||||
|
||||
|
||||
def demo_multiple_mcp_servers():
|
||||
"""
|
||||
Demonstrate using multiple MCP servers simultaneously.
|
||||
|
||||
This function shows how to create agents with multiple MCP servers,
|
||||
each providing different capabilities.
|
||||
"""
|
||||
print("\n" + "=" * 60)
|
||||
print("Multiple MCP Servers Demo")
|
||||
print("=" * 60)
|
||||
|
||||
# Initialize multiple MCP servers
|
||||
servers = {}
|
||||
|
||||
try:
|
||||
servers['time'] = MCP("uvx mcp-server-time", timeout=30)
|
||||
print("✓ Time server initialized")
|
||||
except Exception as e:
|
||||
print(f"✗ Time server failed: {e}")
|
||||
|
||||
# Create agent with all available servers
|
||||
available_tools = list(servers.values())
|
||||
|
||||
if not available_tools:
|
||||
print("No MCP servers available")
|
||||
return
|
||||
|
||||
agent = Agent(
|
||||
name="MultiServerAgent",
|
||||
instructions="You have access to multiple MCP servers. Use the appropriate tools.",
|
||||
llm="openai/gpt-4o-mini",
|
||||
tools=available_tools
|
||||
)
|
||||
|
||||
print(f"\nAgent created with {len(available_tools)} MCP server(s)")
|
||||
|
||||
# Clean up
|
||||
for server in servers.values():
|
||||
server.shutdown()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,70 @@
|
||||
"""
|
||||
Sequential Thinking MCP Example.
|
||||
|
||||
This example demonstrates how to use the Sequential Thinking MCP server
|
||||
with PraisonAI Agents to break down complex problems step by step.
|
||||
|
||||
Requirements:
|
||||
- Node.js and npx installed
|
||||
- pip install praisonaiagents[mcp]
|
||||
- OPENAI_API_KEY environment variable set
|
||||
|
||||
Usage:
|
||||
python sequential_thinking.py
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent, MCP
|
||||
import os
|
||||
|
||||
|
||||
def main():
|
||||
# Check for API key
|
||||
if not os.environ.get("OPENAI_API_KEY"):
|
||||
print("Please set OPENAI_API_KEY environment variable")
|
||||
return
|
||||
|
||||
# Create MCP instance with Sequential Thinking server
|
||||
# The server provides tools for step-by-step problem analysis
|
||||
sequential_mcp = MCP(
|
||||
"npx -y @modelcontextprotocol/server-sequential-thinking",
|
||||
timeout=60
|
||||
)
|
||||
|
||||
# Create an agent with the Sequential Thinking tools
|
||||
agent = Agent(
|
||||
name="ProblemSolver",
|
||||
instructions="""You are an expert problem solver who breaks down complex problems
|
||||
into manageable steps. When given a problem:
|
||||
1. Use the sequential thinking tool to analyze it step by step
|
||||
2. Provide clear, actionable steps
|
||||
3. Explain your reasoning at each step""",
|
||||
llm="openai/gpt-4o-mini",
|
||||
tools=sequential_mcp
|
||||
)
|
||||
|
||||
# Example problems to solve
|
||||
problems = [
|
||||
"Break down the process of making a cup of tea",
|
||||
"How would you plan a weekend trip to a new city?",
|
||||
"What steps would you take to learn a new programming language?"
|
||||
]
|
||||
|
||||
print("=" * 60)
|
||||
print("Sequential Thinking MCP Example")
|
||||
print("=" * 60)
|
||||
|
||||
for i, problem in enumerate(problems, 1):
|
||||
print(f"\n--- Problem {i} ---")
|
||||
print(f"Question: {problem}\n")
|
||||
|
||||
response = agent.chat(problem)
|
||||
print(f"Response:\n{response}")
|
||||
print("-" * 40)
|
||||
|
||||
# Clean up
|
||||
sequential_mcp.shutdown()
|
||||
print("\nDone!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -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")
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
|
||||
@@ -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.",
|
||||
|
||||
@@ -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)
|
||||
@@ -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?")
|
||||
@@ -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...")
|
||||
|
||||
@@ -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,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
|
||||
@@ -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": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -50,5 +50,5 @@ with st.expander("🔧 Troubleshooting"):
|
||||
**If you still have issues:**
|
||||
- Make sure you have Node.js installed for the MCP server
|
||||
- Set your OpenAI API key: `export OPENAI_API_KEY="your-key"`
|
||||
- Try the debug mode by setting `verbose=True`
|
||||
- Try the debug mode by setting `output="verbose"`
|
||||
""")
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
@@ -265,7 +265,7 @@ agents = Agents(
|
||||
process="hierarchical",
|
||||
manager_llm="gpt-4o-mini",
|
||||
memory=True, # Enable shared memory for domain context
|
||||
memory_config={
|
||||
memory={
|
||||
"provider": "rag",
|
||||
"config": {
|
||||
"collection_name": f"{domain.replace('.', '_')}_security_analysis"
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
from praisonaiagents import VideoAgent
|
||||
|
||||
agent = VideoAgent(llm="gemini/veo-3.1-generate-preview")
|
||||
|
||||
# Generate video
|
||||
video = agent.generate("A sunset timelapse", seconds="8", size="1920x1080")
|
||||
print(f"Started: {video.id}")
|
||||
|
||||
# Wait and download
|
||||
completed = agent.wait_for_completion(video.id)
|
||||
if completed.status == "completed":
|
||||
agent.download(video.id, "sunset.mp4")
|
||||
|
||||
# List all videos
|
||||
videos = agent.list()
|
||||
|
||||
# Models: openai/sora-2, gemini/veo-3.0-generate-preview, azure/sora-2
|
||||
@@ -0,0 +1,5 @@
|
||||
from praisonaiagents import VideoAgent
|
||||
|
||||
agent = VideoAgent(llm="azure/sora-2")
|
||||
video = agent.generate("Mountain landscape")
|
||||
print(video.id)
|
||||
@@ -0,0 +1,9 @@
|
||||
# Video Generation with OpenAI Sora
|
||||
# Requires: export OPENAI_API_KEY=your-key
|
||||
# Note: Sora requires organization verification
|
||||
|
||||
from praisonaiagents import VideoAgent
|
||||
|
||||
agent = VideoAgent(llm="openai/sora-2")
|
||||
video = agent.generate("A cat playing with yarn")
|
||||
print(f"Video ID: {video.id}")
|
||||
@@ -0,0 +1,5 @@
|
||||
from praisonaiagents import VideoAgent
|
||||
|
||||
agent = VideoAgent(llm="gemini/veo-3.1-generate-preview")
|
||||
video = agent.generate("Ocean waves at sunset")
|
||||
print(video.id)
|
||||
@@ -0,0 +1,5 @@
|
||||
from praisonaiagents import VideoAgent
|
||||
|
||||
agent = VideoAgent(llm="openai/sora-2")
|
||||
video = agent.generate("A cat playing with yarn")
|
||||
print(video.id)
|
||||
@@ -0,0 +1,5 @@
|
||||
from praisonaiagents import VideoAgent
|
||||
|
||||
agent = VideoAgent(llm="runwayml/gen4_turbo")
|
||||
video = agent.generate("Animate this forest", size="1280x720", seconds="10")
|
||||
print(video.id)
|
||||
@@ -58,7 +58,7 @@ def auto_rag_basic():
|
||||
|
||||
KNOWLEDGE BASE:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
# Wrap with AutoRagAgent for intelligent retrieval
|
||||
@@ -105,7 +105,7 @@ def auto_rag_with_policies():
|
||||
|
||||
KNOWLEDGE BASE:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
@@ -153,7 +153,7 @@ def auto_rag_config_options():
|
||||
|
||||
KNOWLEDGE BASE:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
|
||||
@@ -79,7 +79,7 @@ def rag_with_query_context():
|
||||
agent = Agent(
|
||||
name="Research Assistant",
|
||||
instructions="You answer questions based on the context provided in each query.",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
# Simulate retrieved context (in real RAG, this comes from vector search)
|
||||
|
||||
@@ -204,7 +204,7 @@ def rag_with_section_chunks():
|
||||
|
||||
PRODUCT DOCUMENTATION:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
queries = [
|
||||
|
||||
@@ -103,7 +103,7 @@ def basic_citations():
|
||||
|
||||
POLICY DOCUMENTS:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
queries = [
|
||||
@@ -146,7 +146,7 @@ def structured_citations():
|
||||
|
||||
POLICY DOCUMENTS:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
query = "What are the requirements for remote work eligibility?"
|
||||
@@ -183,7 +183,7 @@ def inline_citations():
|
||||
|
||||
POLICY DOCUMENTS:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
query = "Summarize the key employee benefits."
|
||||
@@ -267,7 +267,7 @@ def multi_source_synthesis():
|
||||
|
||||
POLICY DOCUMENTS:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
query = "Give me a complete overview of employee benefits and policies."
|
||||
|
||||
@@ -125,7 +125,7 @@ def web_augmented_rag():
|
||||
|
||||
COMPANY KNOWLEDGE:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
# Simulate web-augmented queries
|
||||
@@ -171,7 +171,7 @@ def database_augmented_rag():
|
||||
|
||||
COMPANY KNOWLEDGE:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
queries = [
|
||||
@@ -249,7 +249,7 @@ def hybrid_source_rag():
|
||||
|
||||
COMPANY KNOWLEDGE:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
query = "Give me a complete business briefing for today"
|
||||
|
||||
@@ -156,7 +156,7 @@ def hybrid_rag_example():
|
||||
|
||||
TROUBLESHOOTING KNOWLEDGE BASE:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
# Test with different query types
|
||||
@@ -204,7 +204,7 @@ def compare_retrieval_modes():
|
||||
|
||||
KNOWLEDGE BASE:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
print(f"\n📝 Query: {query}")
|
||||
|
||||
@@ -124,7 +124,7 @@ def graph_aware_rag():
|
||||
|
||||
KNOWLEDGE GRAPH:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
# Relationship-focused queries
|
||||
@@ -167,7 +167,7 @@ def multi_hop_reasoning():
|
||||
|
||||
KNOWLEDGE GRAPH:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
# Multi-hop query requiring traversal
|
||||
@@ -200,7 +200,7 @@ def entity_type_filtering():
|
||||
|
||||
SCIENTISTS:
|
||||
{people_context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
# Filter to only concepts
|
||||
@@ -213,7 +213,7 @@ def entity_type_filtering():
|
||||
|
||||
CONCEPTS:
|
||||
{concepts_context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
query = "Tell me about the major developments in early 20th century physics."
|
||||
|
||||
@@ -112,7 +112,7 @@ def multi_document_rag():
|
||||
|
||||
REPORTS:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
# Questions that require multi-document synthesis
|
||||
@@ -157,7 +157,7 @@ def cross_reference_example():
|
||||
|
||||
REPORTS:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
query = """
|
||||
@@ -185,7 +185,7 @@ def document_filtering():
|
||||
|
||||
POLICY REPORT:
|
||||
{POLICY_REPORT['content']}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
tech_agent = Agent(
|
||||
@@ -194,7 +194,7 @@ def document_filtering():
|
||||
|
||||
TECHNOLOGY REPORT:
|
||||
{TECH_REPORT['content']}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
query = "What progress has been made in addressing climate change?"
|
||||
|
||||
@@ -124,7 +124,7 @@ def main():
|
||||
|
||||
KNOWLEDGE:
|
||||
{SAMPLE_KNOWLEDGE}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
# Get test queries
|
||||
|
||||
@@ -61,7 +61,7 @@ def main():
|
||||
|
||||
KNOWLEDGE BASE:
|
||||
{SHARED_KNOWLEDGE}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
summarizer = Agent(
|
||||
@@ -75,7 +75,7 @@ def main():
|
||||
|
||||
KNOWLEDGE BASE:
|
||||
{SHARED_KNOWLEDGE}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
writer = Agent(
|
||||
@@ -89,7 +89,7 @@ def main():
|
||||
|
||||
KNOWLEDGE BASE:
|
||||
{SHARED_KNOWLEDGE}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
# Define tasks
|
||||
@@ -118,7 +118,7 @@ def main():
|
||||
agents=[researcher, summarizer, writer],
|
||||
tasks=[research_task, summary_task, report_task],
|
||||
process="sequential",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
result = agents.start()
|
||||
|
||||
@@ -67,7 +67,7 @@ def main():
|
||||
|
||||
DOCUMENT:
|
||||
{DOCUMENT_CONTENT}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
query = "What are the main topics covered in this document?"
|
||||
@@ -88,7 +88,7 @@ def main():
|
||||
|
||||
DOCUMENT:
|
||||
{DOCUMENT_CONTENT}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
queries = [
|
||||
@@ -114,7 +114,7 @@ def main():
|
||||
|
||||
DOCUMENT:
|
||||
{DOCUMENT_CONTENT}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
analysis_query = "Compare the benefits vs challenges of remote work based on this study"
|
||||
|
||||
@@ -131,7 +131,7 @@ def rag_with_reranking():
|
||||
|
||||
RESEARCH PAPERS:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
queries = [
|
||||
@@ -170,7 +170,7 @@ def compare_with_without_reranking():
|
||||
|
||||
RESEARCH PAPERS:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
print(f"\n📝 Query: {query}")
|
||||
@@ -196,7 +196,7 @@ def reranking_configuration():
|
||||
agent = Agent(
|
||||
name="My Agent",
|
||||
knowledge=documents,
|
||||
knowledge_config={
|
||||
knowledge={
|
||||
# Enable reranking
|
||||
"rerank": True,
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ def policy_based_retrieval():
|
||||
|
||||
IT SUPPORT DOCS:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
query = "How do I set up VPN?"
|
||||
@@ -217,7 +217,7 @@ def priority_based_retrieval():
|
||||
|
||||
HIGH PRIORITY DOCS:
|
||||
{high_context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
# Full knowledge agent
|
||||
@@ -227,7 +227,7 @@ def priority_based_retrieval():
|
||||
|
||||
IT SUPPORT DOCS:
|
||||
{full_context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
query = "I'm locked out of my account!"
|
||||
|
||||
@@ -110,7 +110,7 @@ def json_output_rag():
|
||||
|
||||
PRODUCT CATALOG:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
# Request structured product info
|
||||
@@ -154,7 +154,7 @@ def pydantic_guided_rag():
|
||||
|
||||
PRODUCT CATALOG:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
query = "Compare the UltraWidget Pro and SmartHome Hub. Which should I buy?"
|
||||
@@ -184,7 +184,7 @@ def table_format_rag():
|
||||
|
||||
PRODUCT CATALOG:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
query = "Show me all products in a table with name, price, and rating."
|
||||
@@ -212,7 +212,7 @@ def list_format_rag():
|
||||
|
||||
PRODUCT CATALOG:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
queries = [
|
||||
@@ -321,7 +321,7 @@ def multi_format_rag():
|
||||
|
||||
PRODUCT CATALOG:
|
||||
{context}""",
|
||||
verbose=False
|
||||
output="silent"
|
||||
)
|
||||
|
||||
response = agent.chat(query)
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
"""
|
||||
Recipe Output Modes Example
|
||||
|
||||
Demonstrates how to use different output modes when running recipes.
|
||||
Output modes control the verbosity and format of execution feedback.
|
||||
|
||||
Available modes:
|
||||
- silent: No output (default, best performance)
|
||||
- status: Shows tool calls inline
|
||||
- trace: Timestamped execution trace
|
||||
- verbose: Full interactive output with panels
|
||||
- debug: Trace + metrics (tokens, cost, model)
|
||||
- json: Machine-readable JSONL events
|
||||
|
||||
CLI Usage:
|
||||
praisonai recipe run my-recipe --output status
|
||||
praisonai recipe run my-recipe --output trace
|
||||
praisonai recipe run my-recipe -v # alias for --output verbose
|
||||
"""
|
||||
|
||||
from praisonai.recipe import run
|
||||
|
||||
|
||||
def example_silent_mode():
|
||||
"""Silent mode - no output, best performance."""
|
||||
print("=== Silent Mode (default) ===")
|
||||
result = run(
|
||||
"my-recipe",
|
||||
input={"query": "Hello"},
|
||||
options={"output": "silent"}
|
||||
)
|
||||
print(f"Result: {result}")
|
||||
|
||||
|
||||
def example_status_mode():
|
||||
"""Status mode - shows tool calls inline."""
|
||||
print("\n=== Status Mode ===")
|
||||
print("Shows: ▸ tool → result ✓")
|
||||
result = run(
|
||||
"my-recipe",
|
||||
input={"query": "Hello"},
|
||||
options={"output": "status"}
|
||||
)
|
||||
print(f"Result: {result}")
|
||||
|
||||
|
||||
def example_trace_mode():
|
||||
"""Trace mode - timestamped execution trace."""
|
||||
print("\n=== Trace Mode ===")
|
||||
print("Shows: [HH:MM:SS] ▸ tool → result [0.2s] ✓")
|
||||
result = run(
|
||||
"my-recipe",
|
||||
input={"query": "Hello"},
|
||||
options={"output": "trace"}
|
||||
)
|
||||
print(f"Result: {result}")
|
||||
|
||||
|
||||
def example_verbose_mode():
|
||||
"""Verbose mode - full interactive output with panels."""
|
||||
print("\n=== Verbose Mode ===")
|
||||
result = run(
|
||||
"my-recipe",
|
||||
input={"query": "Hello"},
|
||||
options={"output": "verbose"}
|
||||
)
|
||||
print(f"Result: {result}")
|
||||
|
||||
|
||||
def example_backward_compat():
|
||||
"""Backward compatibility - verbose flag maps to output='verbose'."""
|
||||
print("\n=== Backward Compatibility ===")
|
||||
print("Using verbose=True (deprecated, use output='verbose' instead)")
|
||||
result = run(
|
||||
"my-recipe",
|
||||
input={"query": "Hello"},
|
||||
options={"verbose": True} # Maps to output="verbose"
|
||||
)
|
||||
print(f"Result: {result}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(__doc__)
|
||||
print("Note: These examples require a recipe named 'my-recipe' to be available.")
|
||||
print("Create one with: praisonai recipe init my-recipe")
|
||||
print()
|
||||
|
||||
# Uncomment to run examples:
|
||||
# example_silent_mode()
|
||||
# example_status_mode()
|
||||
# example_trace_mode()
|
||||
# example_verbose_mode()
|
||||
# example_backward_compat()
|
||||
@@ -0,0 +1,274 @@
|
||||
"""
|
||||
Storage Backends Example for PraisonAI Agents.
|
||||
|
||||
Demonstrates how to use different storage backends (File, SQLite, Redis)
|
||||
for agent data persistence across all supported components.
|
||||
|
||||
Supported Backends:
|
||||
- FileBackend: JSON file-based storage (default, zero dependencies)
|
||||
- SQLiteBackend: SQLite database storage (zero dependencies)
|
||||
- RedisBackend: Redis-based storage (requires redis package)
|
||||
|
||||
Supported Components:
|
||||
- BaseJSONStore: Generic JSON storage
|
||||
- TrainingStorage: Agent training data
|
||||
- SessionManager: CLI session state
|
||||
- RunHistory: Recipe run history
|
||||
- MCPToolIndex: MCP tool schemas
|
||||
|
||||
Usage:
|
||||
python storage_backends_example.py
|
||||
"""
|
||||
|
||||
from praisonaiagents.storage import (
|
||||
FileBackend,
|
||||
SQLiteBackend,
|
||||
BaseJSONStore,
|
||||
get_backend,
|
||||
)
|
||||
|
||||
|
||||
def example_file_backend():
|
||||
"""Example: Using FileBackend for JSON file storage."""
|
||||
print("\n=== FileBackend Example ===")
|
||||
|
||||
# Create file backend
|
||||
backend = FileBackend(storage_dir="/tmp/praison_example")
|
||||
|
||||
# Save data
|
||||
backend.save("agent_state", {
|
||||
"agent_name": "Research Assistant",
|
||||
"messages": ["Hello", "How can I help?"],
|
||||
"context": {"topic": "AI"}
|
||||
})
|
||||
|
||||
# Load data
|
||||
data = backend.load("agent_state")
|
||||
print(f"Loaded: {data}")
|
||||
|
||||
# List keys
|
||||
keys = backend.list_keys()
|
||||
print(f"Keys: {keys}")
|
||||
|
||||
# Check existence
|
||||
print(f"Exists: {backend.exists('agent_state')}")
|
||||
|
||||
# Clean up
|
||||
backend.delete("agent_state")
|
||||
print("Deleted agent_state")
|
||||
|
||||
|
||||
def example_sqlite_backend():
|
||||
"""Example: Using SQLiteBackend for database storage."""
|
||||
print("\n=== SQLiteBackend Example ===")
|
||||
|
||||
# Create SQLite backend (single file, better for concurrent access)
|
||||
backend = SQLiteBackend(db_path="/tmp/praison_example.db")
|
||||
|
||||
# Save multiple sessions
|
||||
for i in range(3):
|
||||
backend.save(f"session_{i}", {
|
||||
"session_id": f"sess-{i}",
|
||||
"messages": [f"Message {j}" for j in range(i + 1)],
|
||||
"timestamp": "2024-01-01T00:00:00Z"
|
||||
})
|
||||
|
||||
# List all sessions
|
||||
keys = backend.list_keys(prefix="session_")
|
||||
print(f"Sessions: {keys}")
|
||||
|
||||
# Load specific session
|
||||
session = backend.load("session_1")
|
||||
print(f"Session 1: {session}")
|
||||
|
||||
# Clean up
|
||||
backend.clear()
|
||||
backend.close()
|
||||
print("Cleaned up SQLite backend")
|
||||
|
||||
|
||||
def example_backend_factory():
|
||||
"""Example: Using get_backend factory function."""
|
||||
print("\n=== Backend Factory Example ===")
|
||||
|
||||
# Easy switching between backends
|
||||
backend_type = "sqlite" # Change to "file" or "redis" as needed
|
||||
|
||||
if backend_type == "file":
|
||||
backend = get_backend("file", storage_dir="/tmp/praison_factory")
|
||||
elif backend_type == "sqlite":
|
||||
backend = get_backend("sqlite", db_path="/tmp/praison_factory.db")
|
||||
# elif backend_type == "redis":
|
||||
# backend = get_backend("redis", url="redis://localhost:6379")
|
||||
|
||||
# Use backend
|
||||
backend.save("config", {"model": "gpt-4", "temperature": 0.7})
|
||||
config = backend.load("config")
|
||||
print(f"Config: {config}")
|
||||
|
||||
# Clean up
|
||||
backend.delete("config")
|
||||
|
||||
|
||||
def example_with_base_json_store():
|
||||
"""Example: Using BaseJSONStore with custom backend."""
|
||||
print("\n=== BaseJSONStore with Backend Example ===")
|
||||
|
||||
# Create a custom store with SQLite backend
|
||||
backend = SQLiteBackend(db_path="/tmp/praison_store.db")
|
||||
|
||||
store = BaseJSONStore(
|
||||
storage_path="/tmp/my_store.json", # Used as key name
|
||||
backend=backend,
|
||||
)
|
||||
|
||||
# Save and load data
|
||||
store.save({"items": [1, 2, 3], "count": 3})
|
||||
data = store.load()
|
||||
print(f"Store data: {data}")
|
||||
|
||||
# Clean up
|
||||
store.delete()
|
||||
backend.close()
|
||||
|
||||
|
||||
def example_training_storage_with_backend():
|
||||
"""Example: Using TrainingStorage with SQLite backend."""
|
||||
print("\n=== TrainingStorage with Backend Example ===")
|
||||
|
||||
try:
|
||||
from praisonai.train.agents.storage import TrainingStorage
|
||||
|
||||
# Create SQLite backend for training data
|
||||
backend = SQLiteBackend(db_path="/tmp/training.db")
|
||||
|
||||
# Use with TrainingStorage
|
||||
storage = TrainingStorage(
|
||||
session_id="train-example-001",
|
||||
backend=backend,
|
||||
)
|
||||
|
||||
print(f"Training storage created with session: {storage.session_id}")
|
||||
print("Training data will be stored in SQLite instead of JSON files")
|
||||
|
||||
backend.close()
|
||||
except ImportError:
|
||||
print("praisonai package not installed, skipping training example")
|
||||
|
||||
|
||||
def example_session_manager_with_backend():
|
||||
"""Example: Using SessionManager with SQLite backend."""
|
||||
print("\n=== SessionManager with Backend Example ===")
|
||||
|
||||
try:
|
||||
from praisonai.cli.state.sessions import SessionManager
|
||||
|
||||
# Create SQLite backend for sessions
|
||||
backend = SQLiteBackend(db_path="/tmp/sessions.db")
|
||||
|
||||
# Use with SessionManager
|
||||
manager = SessionManager(backend=backend)
|
||||
sessions = manager.list(limit=10)
|
||||
|
||||
print(f"SessionManager created with SQLite backend, {len(sessions)} sessions")
|
||||
print("Sessions will be stored in database instead of files")
|
||||
|
||||
backend.close()
|
||||
except ImportError:
|
||||
print("praisonai package not installed, skipping session example")
|
||||
|
||||
|
||||
def example_run_history_with_backend():
|
||||
"""Example: Using RunHistory with SQLite backend."""
|
||||
print("\n=== RunHistory with Backend Example ===")
|
||||
|
||||
try:
|
||||
from praisonai.recipe.history import RunHistory
|
||||
|
||||
# Create SQLite backend for run history
|
||||
backend = SQLiteBackend(db_path="/tmp/runs.db")
|
||||
|
||||
# Use with RunHistory
|
||||
history = RunHistory(backend=backend)
|
||||
runs = history.list()
|
||||
|
||||
print(f"RunHistory created with SQLite backend, {len(runs)} runs")
|
||||
print("Recipe runs will be stored in database instead of files")
|
||||
|
||||
backend.close()
|
||||
except ImportError:
|
||||
print("praisonai package not installed, skipping run history example")
|
||||
|
||||
|
||||
def example_mcp_tool_index_with_backend():
|
||||
"""Example: Using MCPToolIndex with SQLite backend."""
|
||||
print("\n=== MCPToolIndex with Backend Example ===")
|
||||
|
||||
try:
|
||||
from praisonai.mcp_server.tool_index import MCPToolIndex
|
||||
|
||||
# Create SQLite backend for MCP tool index
|
||||
backend = SQLiteBackend(db_path="/tmp/mcp.db")
|
||||
|
||||
# Use with MCPToolIndex
|
||||
index = MCPToolIndex(backend=backend)
|
||||
servers = index.list_servers()
|
||||
|
||||
print(f"MCPToolIndex created with SQLite backend, {len(servers)} servers")
|
||||
print("MCP tool schemas will be stored in database instead of files")
|
||||
|
||||
backend.close()
|
||||
except ImportError:
|
||||
print("praisonai package not installed, skipping MCP example")
|
||||
|
||||
|
||||
def example_redis_backend():
|
||||
"""Example: Using RedisBackend for high-speed caching."""
|
||||
print("\n=== RedisBackend Example ===")
|
||||
|
||||
try:
|
||||
from praisonaiagents.storage import RedisBackend
|
||||
|
||||
# Create Redis backend with TTL
|
||||
backend = RedisBackend(
|
||||
url="redis://localhost:6379",
|
||||
prefix="example:",
|
||||
ttl=3600 # 1 hour TTL
|
||||
)
|
||||
|
||||
# CRUD operations
|
||||
backend.save("test_key", {"data": "value", "count": 42})
|
||||
data = backend.load("test_key")
|
||||
print(f"Loaded from Redis: {data}")
|
||||
|
||||
# List keys
|
||||
keys = backend.list_keys()
|
||||
print(f"Keys: {keys}")
|
||||
|
||||
# Clean up
|
||||
backend.delete("test_key")
|
||||
backend.close()
|
||||
print("RedisBackend example completed")
|
||||
|
||||
except ImportError:
|
||||
print("redis package not installed: pip install redis")
|
||||
except Exception as e:
|
||||
print(f"Redis not available: {e}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("PraisonAI Storage Backends Examples")
|
||||
print("=" * 50)
|
||||
|
||||
example_file_backend()
|
||||
example_sqlite_backend()
|
||||
example_backend_factory()
|
||||
example_with_base_json_store()
|
||||
example_training_storage_with_backend()
|
||||
example_session_manager_with_backend()
|
||||
example_run_history_with_backend()
|
||||
example_mcp_tool_index_with_backend()
|
||||
example_redis_backend()
|
||||
|
||||
print("\n" + "=" * 50)
|
||||
print("All examples completed!")
|
||||
@@ -6,7 +6,7 @@ agent = Agent(
|
||||
name="Assistant",
|
||||
instructions="You are a helpful assistant with access to documents.",
|
||||
knowledge=["./docs/guide.pdf"], # Add your documents here
|
||||
knowledge_config={
|
||||
knowledge={
|
||||
"vector_store": "chroma",
|
||||
"path": "/tmp/chroma_demo"
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ agent = Agent(
|
||||
name="Assistant",
|
||||
instructions="You are a helpful assistant with access to documents.",
|
||||
knowledge=["./docs/guide.pdf"], # Add your documents here
|
||||
knowledge_config={
|
||||
knowledge={
|
||||
"vector_store": "lancedb",
|
||||
"path": "/tmp/lancedb_test"
|
||||
}
|
||||
|
||||
Loaded 100 of 495 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user