Compare commits

..
Author SHA1 Message Date
praisonai-triage-agent[bot]andMervin Praison 76e390fc75 fix: harden batch-2 fixes per reviewer feedback
- runner.py: isolate child process groups (start_new_session) on POSIX so
  timeout killpg cannot target the suite runner; propagate TimeoutError
  metadata + exit_code=-1 in the streaming timeout path
- agent_tools.py: route run_sync via _wrapper_bridge (C7 gate + standalone
  install hint); surface delete apply_plan failures instead of masking them;
  drop unused cwd param on acp_execute_command; B904 chaining; RUF013 Optional
- execution_mixin.py: reset _server_started[port] in finally so a failed or
  exited server can be retried by later launch() calls
- __init__.py: rebind package global db to the callable _LazyDbModule proxy so
  repeated praisonaiagents.db access returns the proxy, not the raw module
- compression_demo.py: derive target_tokens from each ratio so iterations differ
- multi-provider-agent.py: rebind each Task.agent to its RouterAgent wrapper

Co-authored-by: Mervin Praison <[email protected]>
2026-07-22 11:13:58 +00:00
praisonai-triage-agent[bot]andMervin Praison 4447dacb03 fix(code): route run_sync via wrapper bridge to satisfy C7 import gate
agent_tools.py imported `from praisonai._async_bridge import run_sync`
directly, tripping the C7 allowlist enforcement in check_c7_imports.sh
(non-allowlisted wrapper import in praisonai_code/). Load it lazily via
_wrapper_bridge.import_wrapper_module so standalone praisonai-code installs
get a clear install hint and the import-direction gate stays green.

Co-authored-by: Mervin Praison <[email protected]>
2026-07-22 11:05:32 +00:00
607 changed files with 3668 additions and 31365 deletions

No files matched your search

+4 -28
View File
@@ -36,10 +36,8 @@ assert.strictEqual(dayStart.toISOString(), '2026-07-08T00:00:00.000Z');
},
},
};
assert.strictEqual(rg.PATCH_RELEASE_INTERVAL_DAYS, 3);
assert.strictEqual(
await rg.hasSuccessfulReleaseWithinDays(mockGithub, 'o', 'r', noonUtc),
await rg.hasSuccessfulReleaseToday(mockGithub, 'o', 'r', noonUtc),
true
);
@@ -48,34 +46,12 @@ assert.strictEqual(dayStart.toISOString(), '2026-07-08T00:00:00.000Z');
{ headSha: 'abc', isCiTrigger: false, bump: 'patch', now: noonUtc },
null
);
assert.ok(result.reasons.some((r) => r.includes('every 3 days')));
const oldReleaseGithub = {
rest: {
actions: {
listWorkflowRuns: async () => ({
data: {
workflow_runs: [
{
conclusion: 'success',
created_at: '2026-07-04T09:00:00Z',
status: 'completed',
},
],
},
}),
},
},
};
assert.strictEqual(
await rg.hasSuccessfulReleaseWithinDays(oldReleaseGithub, 'o', 'r', noonUtc),
false
);
assert.ok(result.reasons.some((r) => r.includes('already released today')));
console.log('ok: bumpPatch');
console.log('ok: readVersionsFromTree');
console.log('ok: pypiVersionExists missing version');
console.log('ok: utcDayStart');
console.log('ok: hasSuccessfulReleaseWithinDays');
console.log('ok: 3-day dedupe blocks second release');
console.log('ok: hasSuccessfulReleaseToday');
console.log('ok: daily dedupe blocks second release');
})();
+6 -28
View File
@@ -5,8 +5,6 @@
const https = require('https');
const PACKAGE_PATHS = ['src/praisonai', 'src/praisonai-agents', 'src/praisonai-code'];
/** Minimum days between successful patch auto-releases. */
const PATCH_RELEASE_INTERVAL_DAYS = 3;
const ACTIVE_RELEASE_STATUSES = new Set([
'queued', 'in_progress', 'waiting', 'pending', 'requested',
]);
@@ -81,18 +79,8 @@ function utcDayStart(now = new Date()) {
return new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
}
function releaseIntervalStart(now = new Date(), intervalDays = PATCH_RELEASE_INTERVAL_DAYS) {
return new Date(now.getTime() - intervalDays * 24 * 60 * 60 * 1000);
}
async function hasSuccessfulReleaseWithinDays(
github,
owner,
repo,
now = new Date(),
intervalDays = PATCH_RELEASE_INTERVAL_DAYS,
) {
const windowStart = releaseIntervalStart(now, intervalDays);
async function hasSuccessfulReleaseToday(github, owner, repo, now = new Date()) {
const dayStart = utcDayStart(now);
const runs = await github.rest.actions.listWorkflowRuns({
owner,
repo,
@@ -101,15 +89,10 @@ async function hasSuccessfulReleaseWithinDays(
per_page: 30,
});
return runs.data.workflow_runs.some(
(r) => r.conclusion === 'success' && new Date(r.created_at) >= windowStart
(r) => r.conclusion === 'success' && new Date(r.created_at) >= dayStart
);
}
/** @deprecated Use hasSuccessfulReleaseWithinDays — kept for selftests. */
async function hasSuccessfulReleaseToday(github, owner, repo, now = new Date()) {
return hasSuccessfulReleaseWithinDays(github, owner, repo, now, 1);
}
async function lastGreenCoreTestsSha(github, owner, repo) {
const runs = await github.rest.actions.listWorkflowRuns({
owner,
@@ -152,11 +135,9 @@ async function evaluateReleasePreflight(github, owner, repo, options, core) {
}
const referenceTime = options.now instanceof Date ? options.now : new Date();
if (await hasSuccessfulReleaseWithinDays(github, owner, repo, referenceTime)) {
reasons.push(
`already released within last ${PATCH_RELEASE_INTERVAL_DAYS} days; `
+ `max one patch release every ${PATCH_RELEASE_INTERVAL_DAYS} days`
);
if (await hasSuccessfulReleaseToday(github, owner, repo, referenceTime)) {
const day = referenceTime.toISOString().slice(0, 10);
reasons.push(`already released today (UTC ${day}); max one patch release per day`);
return out;
}
@@ -241,9 +222,6 @@ module.exports = {
bumpPatch,
readVersionsFromTree,
pypiVersionExists,
PATCH_RELEASE_INTERVAL_DAYS,
releaseIntervalStart,
hasSuccessfulReleaseWithinDays,
hasSuccessfulReleaseToday,
utcDayStart,
evaluateReleasePreflight,
+5 -8
View File
@@ -49,13 +49,13 @@ jobs:
// --- Label triage ---
const labels = [];
// Kind labels (bug before "how to" — bug reports often include "## How to fix")
// Kind labels
if (content.includes('feature request') || content.includes('[feature')) {
labels.push('enhancement');
} else if (!title.includes('[question]') && (content.includes('bug') || content.includes('error') || content.includes('crash') || content.includes('traceback'))) {
labels.push('bug');
} else if (title.includes('[question]') || content.includes('how do i') || (content.includes('how to') && !content.includes('how to fix'))) {
} else if (title.includes('[question]') || content.includes('how do i') || content.includes('how to')) {
labels.push('question');
} else if (content.includes('bug') || content.includes('error') || content.includes('crash') || content.includes('traceback')) {
labels.push('bug');
} else if (content.includes('question')) {
labels.push('question');
}
@@ -108,10 +108,7 @@ jobs:
// --- Auto-trigger Claude for owner issues and actionable external bug/enhancement reports ---
const titleLower = (issue.title || '').toLowerCase();
const hasActionableTitle = /^(\[[^\]]+\]|bug:|fix[:(]|feat:|ux:|enhancement:)/i.test(titleLower);
const autoClaude = isOwner || (hasActionableTitle && (
labels.includes('bug') ||
(labels.includes('enhancement') && !labels.includes('question'))
));
const autoClaude = isOwner || (hasActionableTitle && (labels.includes('bug') || labels.includes('enhancement')) && !labels.includes('question'));
if (autoClaude) {
await github.rest.issues.addLabels({
issue_number: issue.number,
+3 -3
View File
@@ -1,12 +1,12 @@
name: Nightly Release Gate
# Preflight before PyPI Release (patch bump).
# Triggers: Core Tests success on main (workflow_run) or cron every 3 days at 00:00 UTC.
# Dedupe: max one successful patch release every 3 days (see release-gate.js).
# Triggers: Core Tests success on main (workflow_run) or nightly cron at 00:00 UTC.
# Dedupe: max one successful patch release per UTC day (see release-gate.js).
on:
schedule:
- cron: '0 0 */3 * *'
- cron: '0 0 * * *'
workflow_dispatch:
inputs:
dry_run:
+1 -3
View File
@@ -134,9 +134,7 @@ jobs:
'pypi-auto' || 'pypi'
}}
env:
# PyPI API token auth: username __token__, password = pypi-… token (see pypi.org/help/#invalid-auth)
UV_PUBLISH_USERNAME: __token__
UV_PUBLISH_PASSWORD: ${{ secrets.PYPI_TOKEN || secrets.PYPI_API_TOKEN }}
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN || secrets.PYPI_API_TOKEN }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
steps:
- name: Checkout main
-3
View File
@@ -782,9 +782,6 @@ jobs:
tests/unit/test_decorator_simple.py
tests/unit/test_db_adapter_tracing_init.py
../praisonai-bot/tests/unit/test_bot_wiring.py
../praisonai-bot/tests/unit/bots/test_enable_shell.py
../praisonai-bot/tests/unit/gateway/test_preflight.py
../praisonai-bot/tests/unit/gateway/test_gateway_doctor.py
../praisonai-bot/tests/unit/test_bot_history.py
../praisonai-bot/tests/unit/test_bot_fixes.py
tests/unit/test_auto_lazy_loading.py
-9
View File
@@ -29,15 +29,6 @@ output
threads.db
threads.db-journal
# Example run artifacts (generated at runtime, must not be committed)
examples/**/knowledge.db
examples/**/knowledge.db-journal
examples/python/managed-agents/managed_ids.json
examples/python/save_output/blog_post.md
examples/python/save_output/generated/
examples/python/token-metrics/token_metrics_export.json
examples/python/usecases/market_research_results.json
.chainlit
!praisonai/ui/config/.chainlit
+8 -7
View File
@@ -83,7 +83,6 @@ Methods:
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">run_autonomous_async</a>(prompt: str, max_iterations: Optional[int] = None, timeout_seconds: Optional[float] = None, completion_promise: Optional[str] = None, clear_context: bool = False)</code>
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">run_until</a>(prompt: str, criteria: str = '', threshold: float = 8.0, max_iterations: int = 5, mode: str = 'optimize', on_iteration: Optional[Callable[[Any], None]] = None, verbose: bool = False, goal: Optional[str] = None, goal_criteria: Optional[Any] = None, judge_model: Optional[str] = None) -> 'EvaluationLoopResult'</code>
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">run_until_async</a>(prompt: str, criteria: str, threshold: float = 8.0, max_iterations: int = 5, mode: str = 'optimize', on_iteration: Optional[Callable[[Any], None]] = None, verbose: bool = False) -> 'EvaluationLoopResult'</code>
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">set_snapshot_root</a>(project_path: str) -> bool</code>
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">skill_manager</a>() -> Optional[Any]</code>
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">store_memory</a>(content: str, memory_type: str = 'short_term', action: str = 'add', **kwargs: Any) -> None</code>
* <code title="class Agent">Agent.<a href="./src/praisonai-agents/praisonaiagents/agent/agent.py">stream_emitter</a>() -> Optional[Any]</code>
@@ -233,6 +232,13 @@ Methods:
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">repeat</a>(step: Any, until: Optional[Callable[[WorkflowContext], bool]] = None, max_iterations: int = 10) -> Repeat</code>
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/workflows/workflows.py">route</a>(routes: Dict[str, List], default: Optional[List] = None) -> Route</code>
# DB
Types:
```python
from praisonaiagents import db
```
# Memory
Types:
@@ -569,7 +575,6 @@ Methods:
* <code title="class MCP">MCP.<a href="./src/praisonai-agents/praisonaiagents/mcp/mcp.py">get_prompts</a>() -> List[dict]</code>
* <code title="class MCP">MCP.<a href="./src/praisonai-agents/praisonaiagents/mcp/mcp.py">get_resources</a>() -> List[dict]</code>
* <code title="class MCP">MCP.<a href="./src/praisonai-agents/praisonaiagents/mcp/mcp.py">get_tools</a>() -> List[Callable]</code>
* <code title="class MCP">MCP.<a href="./src/praisonai-agents/praisonaiagents/mcp/mcp.py">list_active_server_names</a>() -> set</code>
* <code title="class MCP">MCP.<a href="./src/praisonai-agents/praisonaiagents/mcp/mcp.py">shutdown</a>()</code>
* <code title="class MCP">MCP.<a href="./src/praisonai-agents/praisonaiagents/mcp/mcp.py">to_openai_tool</a>()</code>
* <code title="class MCP">MCP.<a href="./src/praisonai-agents/praisonaiagents/mcp/mcp.py">with_tool_prefix</a>(prefix: str) -> 'MCP'</code>
@@ -733,7 +738,7 @@ Methods:
Types:
```python
from praisonaiagents import AgentAppConfig, AgentAppProtocol, AgentFlow, AgentManager, AgentOSConfig, AgentOSProtocol, AgentTeam, AutoApproveBackend, EmbeddingResult, RetryBackoffConfig, RunOutcome, __version__, aembedding, aembeddings, embedding, embeddings, get_dimensions
from praisonaiagents import AgentAppConfig, AgentAppProtocol, AgentFlow, AgentManager, AgentOSConfig, AgentOSProtocol, AgentTeam, AutoApproveBackend, EmbeddingResult, RetryBackoffConfig, __version__, aembedding, aembeddings, embedding, embeddings, get_dimensions
```
Methods:
@@ -801,16 +806,12 @@ Methods:
* <code title="class AgentTeam">AgentTeam.<a href="./src/praisonai-agents/praisonaiagents/agents/agents.py">set_state</a>(key: str, value: Any) -> None</code>
* <code title="class AgentTeam">AgentTeam.<a href="./src/praisonai-agents/praisonaiagents/agents/agents.py">spawn_sub_agent</a>(agent: Agent, task: Any, completion_callback: Optional[Callable[[SubAgentCompletionEvent], Any]] = None, metadata: Optional[Dict[str, Any]] = None) -> SpawnedSubAgent</code>
* <code title="class AgentTeam">AgentTeam.<a href="./src/praisonai-agents/praisonaiagents/agents/agents.py">start</a>(content = None, return_dict = False, output = None, **kwargs)</code>
* <code title="class AgentTeam">AgentTeam.<a href="./src/praisonai-agents/praisonaiagents/agents/agents.py">stream_emitter</a>()</code>
* <code title="class AgentTeam">AgentTeam.<a href="./src/praisonai-agents/praisonaiagents/agents/agents.py">todo_list</a>()</code>
* <code title="class AgentTeam">AgentTeam.<a href="./src/praisonai-agents/praisonaiagents/agents/agents.py">update_plan_step_status</a>(step_id: str, status: str) -> bool</code>
* <code title="class AgentTeam">AgentTeam.<a href="./src/praisonai-agents/praisonaiagents/agents/agents.py">update_state</a>(updates: Dict) -> None</code>
* <code title="class AgentTeam">AgentTeam.<a href="./src/praisonai-agents/praisonaiagents/agents/agents.py">wait_for_completions</a>(timeout: Optional[float] = None, agent_ids: Optional[List[str]] = None) -> List[SubAgentCompletionEvent]</code>
* <code title="class AutoApproveBackend">AutoApproveBackend.<a href="./src/praisonai-agents/praisonaiagents/approval/backends.py">request_approval</a>(request: ApprovalRequest) -> ApprovalDecision</code>
* <code title="class AutoApproveBackend">AutoApproveBackend.<a href="./src/praisonai-agents/praisonaiagents/approval/backends.py">request_approval_sync</a>(request: ApprovalRequest) -> ApprovalDecision</code>
* <code title="class RunOutcome">RunOutcome.<a href="./src/praisonai-agents/praisonaiagents/agent/run_outcome.py">completed</a>(output: Optional[str] = None) -> 'RunOutcome'</code>
* <code title="class RunOutcome">RunOutcome.<a href="./src/praisonai-agents/praisonaiagents/agent/run_outcome.py">from_exception</a>(exc: BaseException, output: Optional[str] = None) -> 'RunOutcome'</code>
* <code title="class RunOutcome">RunOutcome.<a href="./src/praisonai-agents/praisonaiagents/agent/run_outcome.py">succeeded</a>() -> bool</code>
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/embedding/embed.py">aembedding</a>(input: Union[str, List[str]], model: str = 'text-embedding-3-small', dimensions: Optional[int] = None, encoding_format: str = 'float', timeout: float = 600.0, api_key: Optional[str] = None, api_base: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None, **kwargs) -> EmbeddingResult</code>
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/embedding/embed.py">aembeddings</a>(input: Union[str, List[str]], model: str = 'text-embedding-3-small', dimensions: Optional[int] = None, encoding_format: str = 'float', timeout: float = 600.0, api_key: Optional[str] = None, api_base: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None, **kwargs) -> EmbeddingResult</code>
* <code title="function">praisonaiagents.<a href="./src/praisonai-agents/praisonaiagents/embedding/dimensions.py">get_dimensions</a>(model_name: str) -> int</code>
+1 -1
View File
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
# Install Python packages (using latest versions)
RUN pip install --no-cache-dir \
praisonai_tools \
"praisonai>=4.6.157" \
"praisonai>=4.6.155" \
"praisonai[chat]" \
"embedchain[github,youtube]"
+1 -1
View File
@@ -20,7 +20,7 @@ RUN mkdir -p /root/.praison
# Install Python packages (using latest versions)
RUN pip install --no-cache-dir \
praisonai_tools \
"praisonai>=4.6.157" \
"praisonai>=4.6.155" \
"praisonai[ui]" \
"praisonai[chat]" \
"praisonai[realtime]" \
+1 -1
View File
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
# Install Python packages (using latest versions)
RUN pip install --no-cache-dir \
praisonai_tools \
"praisonai>=4.6.157" \
"praisonai>=4.6.155" \
"praisonai[ui]" \
"praisonai[crewai]"
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
HTTP Approval Example
=====================
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Slack Approval Example
======================
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Completions Capability Example
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Embeddings Capability Example
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Images Capability Example
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Moderations Capability Example
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Energy Industry Template
========================
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Transportation Industry Template
================================
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
#!/usr/bin/env python3
"""
CI Integration Example - Using Doctor in CI/CD pipelines
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Agent-centric Embedding Example
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
#!/usr/bin/env python3
"""
PraisonAI Endpoints Example
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
#!/usr/bin/env python3
"""
Fixed example demonstrating proper guardrail usage with PraisonAI Agents.
+5 -1
View File
@@ -150,10 +150,14 @@ def main():
print(f"\nOriginal document length: {len(content)} characters")
chunks = [{"text": content, "metadata": {"source": doc_path}}]
target_tokens = 2000
# Estimate original tokens (~4 chars/token) so each ratio maps to a
# distinct token budget — compress() truncates to target_tokens.
original_tokens = max(1, len(content) // 4)
# Compress with different ratios
for ratio in [0.3, 0.5, 0.7]:
target_tokens = max(1, int(original_tokens * ratio))
compressor = ContextCompressor(verbose=False)
result = compressor.compress(
chunks,
@@ -1,4 +1,3 @@
# praisonai: skip=true
#!/usr/bin/env python3
"""
ManagedAgent + ClickHouse Persistence — Real conversation with session resume.
@@ -1,4 +1,3 @@
# praisonai: skip=true
#!/usr/bin/env python3
"""
ManagedAgent + MongoDB Persistence — Real conversation with session resume.
@@ -1,4 +1,3 @@
# praisonai: skip=true
#!/usr/bin/env python3
"""
ManagedAgent + MySQL Persistence — Real conversation with session resume.
@@ -1,4 +1,3 @@
# praisonai: skip=true
#!/usr/bin/env python3
"""
ManagedAgent + PostgreSQL Persistence — Real conversation with session resume.
@@ -1,4 +1,3 @@
# praisonai: skip=true
#!/usr/bin/env python3
"""
ManagedAgent + Redis Persistence — Real conversation with session resume.
@@ -1,4 +1,3 @@
# praisonai: skip=true
#!/usr/bin/env python3
"""
ManagedAgent + SQLite Persistence — Real conversation with session resume.
@@ -1,4 +1,3 @@
# praisonai: skip=true
#!/usr/bin/env python3
"""
Custom Tools MCP Server Example
@@ -1,4 +1,3 @@
# praisonai: skip=true
#!/usr/bin/env python3
"""
HTTP Stream MCP Server Example
@@ -1,4 +1,3 @@
# praisonai: skip=true
#!/usr/bin/env python3
"""
MCP Client Example
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""Multi-Agent Shared Session Demo"""
from praisonaiagents import Agent
from praisonai.persistence import create_conversation_store
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Langfuse Integration Example (Updated for TraceSinkProtocol)
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""MLflow Local Observability Demo (no API key needed)"""
import mlflow
import time
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
ClickHouse — Persistence Example
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Minimal Agent with Database Persistence
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
MongoDB StateStore — Full Persistence Example
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
MySQL ConversationStore — Full Persistence Example
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
PostgreSQL ConversationStore — Full Persistence Example
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
PostgreSQL with Runs and Traces
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Redis StateStore — Full Persistence Example
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Session Resume Example
+1 -2
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Redis State Store - Agent-First Example
@@ -28,7 +27,7 @@ my_db = db(
agent = Agent(
name="Assistant",
instructions="You are a helpful assistant.",
memory=my_db,
db=my_db,
session_id="redis-state-example"
)
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
PraisonAI A2A Server Example
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Agent-Centric Autonomy Example.
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
AutoAgents Workflow Patterns Example
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
#!/usr/bin/env python3
"""
Context Agent Example - Basic Usage
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Math Agent Example
@@ -144,6 +144,7 @@ def example_auto_agents_multi_provider():
# After agents are created, upgrade them to multi-model agents
multi_model_agents = []
wrapper_by_original = {}
for agent in auto_agents.agents:
# Convert regular agents to multi-model agents
multi_agent = RouterAgent(
@@ -155,9 +156,18 @@ def example_auto_agents_multi_provider():
models=["gpt-4o-mini", "gemini/gemini-1.5-flash", "claude-3-haiku-20240307", "gpt-4o-mini"],
routing_strategy="auto")
multi_model_agents.append(multi_agent)
wrapper_by_original[id(agent)] = multi_agent
# Update the agents in the AutoAgents instance
auto_agents.agents = multi_model_agents
# Rebind each task's agent to its wrapper — AutoAgents stores a direct agent
# reference on every Task and execution reads task.agent, so replacing only
# auto_agents.agents would leave the workflow bound to the original agents.
for task in getattr(auto_agents, "tasks", []) or []:
wrapper = wrapper_by_original.get(id(task.agent))
if wrapper is not None:
task.agent = wrapper
# Run the auto-generated workflow
results = auto_agents.start()
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
from praisonaiagents import Agent, MCP
qa_agent = Agent(
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
from praisonaiagents import Agent, AgentTeam, Tools
research_agent = Agent(name="Research", instructions="You are a research agent to search internet about AI 2024", tools=[Tools.internet_search])
@@ -1,4 +1,3 @@
# praisonai: skip=true
from praisonaiagents import Agent, AgentTeam, Tools
research_agent = Agent(name="Research", instructions="You are a research agent to search internet about AI 2024", tools=[Tools.internet_search])
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Secondary Market Research FastAPI Application
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
from praisonaiagents import Agent, MCP
search_agent = Agent(
@@ -1,4 +1,3 @@
# praisonai: skip=true
from praisonaiagents import Agent, AgentTeam
from duckduckgo_search import DDGS
+1 -11
View File
@@ -1,15 +1,5 @@
import threading
import time
from praisonaiagents import Agent
if __name__ == "__main__":
agent = Agent(name="TweetAgent", instructions="Create a Tweet based on the topic provided")
server = threading.Thread(
target=lambda: agent.launch(port=8080, protocol="mcp", path="/mcp"),
daemon=True,
)
server.start()
time.sleep(2)
print("MCP server started on http://127.0.0.1:8080/mcp")
agent.launch(port=8080, protocol="mcp", path="/")
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
from praisonaiagents import AudioAgent
# Text to Speech
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
from praisonaiagents import AudioAgent
agent = AudioAgent(llm="openai/tts-1-hd")
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
# Text-to-Speech with OpenAI
# Requires: export OPENAI_API_KEY=your-key
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
from praisonaiagents import AudioAgent
agent = AudioAgent(llm="elevenlabs/eleven_multilingual_v2")
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
from praisonaiagents import AudioAgent
agent = AudioAgent(llm="gemini/gemini-2.5-flash-preview-tts")
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
from praisonaiagents import AudioAgent
agent = AudioAgent(llm="openai/tts-1")
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Bot Commands Example — Built-in /status, /new, /help commands.
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Bot Gateway Example — Run multiple bots from one gateway server.
+2 -2
View File
@@ -102,7 +102,7 @@ async def demo_with_run_control():
from praisonai.bots._run_control import SessionRunControl
from praisonai.bots._session import BotSessionManager
from praisonai.bots._commands import handle_stop_command_async
from praisonai.bots._commands import handle_stop_command
# Session manager with run control
run_control = SessionRunControl(
@@ -136,7 +136,7 @@ async def demo_with_run_control():
print("\n3. User decides to stop current task:")
print(" User: '/stop'")
stop_response = await handle_stop_command_async(user_id, run_control)
stop_response = await handle_stop_command(user_id, run_control)
print(f" Bot: {stop_response}")
# Wait for first task to complete (it should be cancelled)
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Standalone gateway example (praisonai-bot first).
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""HTTP Approval — serve a local web dashboard for tool approvals."""
from praisonaiagents import Agent
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Basic Camera Integration Example
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Continuous Camera Monitoring Example
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Multi-Agent Camera Analysis Example
@@ -46,6 +46,6 @@ custom_cmd = SlashCommand(
alt_names=["mc"]
)
handler.register_command(custom_cmd)
handler.register(custom_cmd)
result = handler.execute("/mycommand arg1 arg2")
print(f"\n=== Custom Command ===\n{result.get('message', '')}")
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Claude Code CLI Integration Example
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Codex CLI Integration Example
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Cursor CLI Integration Example
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
External Agents Integration Example
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Gemini CLI Integration Example
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
CSV Processing with PraisonAI Agents
@@ -10,18 +10,6 @@ import os
from praisonaiagents import Agent
from praisonaiagents.knowledge import Knowledge
def _result_items(results):
items = results.results if hasattr(results, "results") else results
return list(items)[:3]
def _result_text(result):
if isinstance(result, dict):
return result.get("memory", result.get("text", str(result)))
return getattr(result, "text", None) or getattr(result, "memory", None) or str(result)
def main():
"""
Demonstrates knowledge search with and without reranking.
@@ -94,9 +82,9 @@ def main():
basic_results = basic_knowledge.search(query, rerank=False)
print(f"Query: {query}")
print(f"Results (limit=3):")
for i, result in enumerate(_result_items(basic_results)):
text = _result_text(result)
score = result.get('score', 'N/A') if isinstance(result, dict) else getattr(result, 'score', 'N/A')
for i, result in enumerate(basic_results[:3]):
text = result.get('memory', result.get('text', str(result)))
score = result.get('score', 'N/A')
print(f" {i+1}. Score: {score}")
print(f" Text: {text[:100]}...")
print()
@@ -106,9 +94,9 @@ def main():
rerank_results = basic_knowledge.search(query, rerank=True)
print(f"Query: {query}")
print(f"Results (limit=3):")
for i, result in enumerate(_result_items(rerank_results)):
text = _result_text(result)
score = result.get('score', 'N/A') if isinstance(result, dict) else getattr(result, 'score', 'N/A')
for i, result in enumerate(rerank_results[:3]):
text = result.get('memory', result.get('text', str(result)))
score = result.get('score', 'N/A')
print(f" {i+1}. Score: {score}")
print(f" Text: {text[:100]}...")
print()
@@ -118,9 +106,9 @@ def main():
default_results = rerank_knowledge.search(query) # Will use default_rerank=True
print(f"Query: {query}")
print(f"Results (limit=3):")
for i, result in enumerate(_result_items(default_results)):
text = _result_text(result)
score = result.get('score', 'N/A') if isinstance(result, dict) else getattr(result, 'score', 'N/A')
for i, result in enumerate(default_results[:3]):
text = result.get('memory', result.get('text', str(result)))
score = result.get('score', 'N/A')
print(f" {i+1}. Score: {score}")
print(f" Text: {text[:100]}...")
print()
@@ -137,9 +125,9 @@ def main():
)
print(f"Query: {query}")
print(f"Advanced results with keyword_search=True, filter_memories=True:")
for i, result in enumerate(_result_items(advanced_results)):
text = _result_text(result)
score = result.get('score', 'N/A') if isinstance(result, dict) else getattr(result, 'score', 'N/A')
for i, result in enumerate(advanced_results[:3]):
text = result.get('memory', result.get('text', str(result)))
score = result.get('score', 'N/A')
print(f" {i+1}. Score: {score}")
print(f" Text: {text[:100]}...")
print()
@@ -150,7 +138,7 @@ def main():
agent = Agent(
name="AI Research Assistant",
instructions="You are an AI research assistant. Use your knowledge base to answer questions about artificial intelligence topics.",
knowledge={"sources": sample_documents, "rerank": True},
knowledge={**rerank_config, "sources": sample_documents},
llm="gpt-4o-mini"
)
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Reasoning Extraction Example
@@ -1,4 +1,3 @@
# praisonai: skip=true
from praisonaiagents import Agent, Task, AgentTeam
agent = Agent(
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Routing Patterns Example
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Self-Reflection Details Example
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Simple CSV URL Processor
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Example: Using Latency Tracking Tool with PraisonAI
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
MCP Server with Latency Tracking Example
@@ -1,4 +1,3 @@
# praisonai: skip=true
#!/usr/bin/env python3
"""
Minimal Example: Latency Tracking for MCP Server
+9 -9
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Model Failover Example - Automatic Provider Switching
@@ -44,8 +43,9 @@ failover_config = FailoverConfig(
retry_delay=1.0,
exponential_backoff=True,
max_retry_delay=60.0,
cooldown_on_rate_limit=60.0,
cooldown_on_error=30.0,
failover_on_rate_limit=True,
failover_on_timeout=True,
failover_on_error=True,
)
# Create failover manager
@@ -62,11 +62,11 @@ def demonstrate_failover():
# Get current status
status = manager.status()
for profile_info in status.get("profiles", []):
print(f" {profile_info.get('name', 'unknown')}:")
print(f" Status: {profile_info.get('status', 'unknown')}")
print(f" Priority: {profile_info.get('priority', 'N/A')}")
print(f" Failures: {profile_info.get('failure_count', 0)}")
for name, info in status.items():
print(f" {name}:")
print(f" Status: {info.get('status', 'unknown')}")
print(f" Priority: {info.get('priority', 'N/A')}")
print(f" Failures: {info.get('failure_count', 0)}")
print()
# Get next available profile
@@ -163,7 +163,7 @@ if __name__ == "__main__":
print(f" {profile.name}:")
print(f" Provider: {profile.provider}")
print(f" Priority: {profile.priority}")
print(f" Rate limit: {profile.rate_limit_rpm} req/min")
print(f" Rate limit: {profile.rate_limit} req/min")
print()
demonstrate_failover()
@@ -1,4 +1,3 @@
# praisonai: skip=true
"""
Advanced Callback Systems Example
-1
View File
@@ -1,4 +1,3 @@
# praisonai: skip=true
import asyncio
import time
from typing import List, Dict
@@ -1,4 +1,3 @@
# praisonai: skip=true
import asyncio
import time
from typing import List, Dict
@@ -1,4 +1,3 @@
# praisonai: skip=true
import asyncio
import time
from typing import List, Dict
@@ -1,4 +1,3 @@
# praisonai: skip=true
from praisonaiagents import Agent, Task, AgentTeam
import json
from e2b_code_interpreter import Sandbox
@@ -1,4 +1,3 @@
# praisonai: skip=true
from praisonaiagents import (
Agent,
Task,
@@ -1,4 +1,3 @@
# praisonai: skip=true
from praisonaiagents import Agent, Task, AgentTeam
from typing import List, Dict, Union
from duckduckgo_search import DDGS
@@ -1,4 +1,3 @@
# praisonai: skip=true
from praisonaiagents import Agent, Task, AgentTeam, error_logs
from duckduckgo_search import DDGS
@@ -1,4 +1,3 @@
# praisonai: skip=true
from praisonaiagents import Agent, Task, AgentTeam
from langchain_community.tools import YouTubeSearchTool
from langchain_community.utilities import WikipediaAPIWrapper
@@ -1,4 +1,3 @@
# praisonai: skip=true
from praisonaiagents import Agent, Task, AgentTeam
from datetime import datetime
import asyncio
@@ -1,4 +1,3 @@
# praisonai: skip=true
from praisonaiagents import Agent
from pydantic import BaseModel
from typing import List, Optional
Loaded 100 of 607 files, more files were not shown because too many files have changed in this diff. Show more