mirror of
https://github.com/MervinPraison/PraisonAI.git
synced 2026-11-09 17:31:52 -10:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25e7af3c8f |
No files matched your search
@@ -40,62 +40,6 @@ assert('claude final reply detected', mg.isClaudeFinalReplyComment(withClaudeRep
|
||||
|
||||
assert('cancelled detect-and-trigger does not block', mg.OPTIONAL_CANCELLED_CHECKS.has('detect-and-trigger'));
|
||||
|
||||
const coreGreenRuns = [
|
||||
{ name: 'test-core', status: 'completed', conclusion: 'success' },
|
||||
{ name: 'test-core (cli)', status: 'completed', conclusion: 'success' },
|
||||
{ name: 'smoke', status: 'completed', conclusion: 'cancelled' },
|
||||
{ name: 'test-windows', status: 'completed', conclusion: 'cancelled' },
|
||||
];
|
||||
assert('core green allows cancelled smoke', mg.isAcceptableCheckConclusion(
|
||||
{ name: 'smoke', status: 'completed', conclusion: 'cancelled' },
|
||||
coreGreenRuns
|
||||
));
|
||||
assert('core green allows cancelled test-windows', mg.isAcceptableCheckConclusion(
|
||||
{ name: 'test-windows', status: 'completed', conclusion: 'cancelled' },
|
||||
coreGreenRuns
|
||||
));
|
||||
assert('cancelled smoke blocks when core missing', !mg.isAcceptableCheckConclusion(
|
||||
{ name: 'smoke', status: 'completed', conclusion: 'cancelled' },
|
||||
[{ name: 'smoke', status: 'completed', conclusion: 'cancelled' }]
|
||||
));
|
||||
assert('cancelled smoke blocks when core failed', !mg.isAcceptableCheckConclusion(
|
||||
{ name: 'smoke', status: 'completed', conclusion: 'cancelled' },
|
||||
[
|
||||
{ name: 'test-core', status: 'completed', conclusion: 'failure' },
|
||||
{ name: 'smoke', status: 'completed', conclusion: 'cancelled' },
|
||||
]
|
||||
));
|
||||
assert('bestRunsByName prefers success over cancelled', (() => {
|
||||
const best = mg.bestRunsByName([
|
||||
{ name: 'smoke', conclusion: 'cancelled' },
|
||||
{ name: 'smoke', conclusion: 'success' },
|
||||
]);
|
||||
return best.length === 1 && best[0].conclusion === 'success';
|
||||
})());
|
||||
assert('bestRunsByName prefers pending over completed cancelled', (() => {
|
||||
const best = mg.bestRunsByName([
|
||||
{ name: 'smoke', status: 'completed', conclusion: 'cancelled' },
|
||||
{ name: 'smoke', status: 'in_progress', conclusion: null },
|
||||
]);
|
||||
return best.length === 1 && best[0].status === 'in_progress';
|
||||
})());
|
||||
assert('bestRunsByName keeps pending regardless of order', (() => {
|
||||
const best = mg.bestRunsByName([
|
||||
{ name: 'smoke', status: 'in_progress', conclusion: null },
|
||||
{ name: 'smoke', status: 'completed', conclusion: 'success' },
|
||||
]);
|
||||
return best.length === 1 && best[0].status === 'in_progress';
|
||||
})());
|
||||
assert('allChecksGreenOnSha style: pending re-run blocks despite core green', (() => {
|
||||
const runs = mg.bestRunsByName([
|
||||
{ name: 'test-core', status: 'completed', conclusion: 'success' },
|
||||
{ name: 'smoke', status: 'completed', conclusion: 'cancelled' },
|
||||
{ name: 'smoke', status: 'queued', conclusion: null },
|
||||
]);
|
||||
const smoke = runs.find((r) => r.name === 'smoke');
|
||||
return smoke.status !== 'completed';
|
||||
})());
|
||||
|
||||
// Stale-FINAL recovery guards (PR #2560 push loop)
|
||||
const nowMs = Date.now();
|
||||
const iso = (ms) => new Date(ms).toISOString();
|
||||
|
||||
@@ -44,8 +44,6 @@ const BLOCK_LABELS = new Set([
|
||||
const MERGE_READY_LABEL = 'pipeline/merge-ready';
|
||||
/** Superseded concurrency runs; must not block merge when real tests passed. */
|
||||
const OPTIONAL_CANCELLED_CHECKS = new Set(['detect-and-trigger']);
|
||||
/** Cancelled smoke/windows after timeout are non-blocking when core shards passed on HEAD. */
|
||||
const OPTIONAL_CANCELLED_WHEN_CORE_GREEN = new Set(['smoke', 'test-windows']);
|
||||
const BOT_REVIEWER_PATTERNS = [
|
||||
'coderabbit',
|
||||
'qodo',
|
||||
@@ -327,70 +325,8 @@ function listFailedChecksOnSha(runs) {
|
||||
});
|
||||
}
|
||||
|
||||
function isCoreTestRun(run) {
|
||||
const name = run?.name || '';
|
||||
return name === 'test-core' || name.startsWith('test-core ') || name === 'test-core-collect';
|
||||
}
|
||||
|
||||
function coreTestsGreenOnRuns(runs) {
|
||||
const coreRuns = (runs || []).filter(isCoreTestRun);
|
||||
if (coreRuns.length === 0) return false;
|
||||
return coreRuns.every(
|
||||
(run) =>
|
||||
run.status === 'completed' &&
|
||||
['success', 'neutral', 'skipped'].includes(run.conclusion)
|
||||
);
|
||||
}
|
||||
|
||||
function checkConclusionRank(conclusion) {
|
||||
if (conclusion === 'success') return 4;
|
||||
if (conclusion === 'neutral') return 3;
|
||||
if (conclusion === 'skipped') return 2;
|
||||
if (conclusion === 'cancelled') return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
function isPendingRun(run) {
|
||||
return !!(run && run.status && run.status !== 'completed');
|
||||
}
|
||||
|
||||
function bestRunsByName(runs) {
|
||||
const byName = new Map();
|
||||
for (const run of runs || []) {
|
||||
if (!run) continue;
|
||||
const existing = byName.get(run.name);
|
||||
if (!existing) {
|
||||
byName.set(run.name, run);
|
||||
continue;
|
||||
}
|
||||
const runPending = isPendingRun(run);
|
||||
const existingPending = isPendingRun(existing);
|
||||
if (existingPending) continue;
|
||||
if (
|
||||
runPending ||
|
||||
checkConclusionRank(run.conclusion) > checkConclusionRank(existing.conclusion)
|
||||
) {
|
||||
byName.set(run.name, run);
|
||||
}
|
||||
}
|
||||
return [...byName.values()];
|
||||
}
|
||||
|
||||
function isAcceptableCheckConclusion(run, runs) {
|
||||
if (['success', 'neutral', 'skipped'].includes(run.conclusion)) return true;
|
||||
if (run.conclusion === 'cancelled' && OPTIONAL_CANCELLED_CHECKS.has(run.name)) return true;
|
||||
if (
|
||||
run.conclusion === 'cancelled' &&
|
||||
OPTIONAL_CANCELLED_WHEN_CORE_GREEN.has(run.name) &&
|
||||
coreTestsGreenOnRuns(runs)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
async function allChecksGreenOnSha(github, owner, repo, sha, core) {
|
||||
const runs = bestRunsByName(await listChecksOnSha(github, owner, repo, sha));
|
||||
const runs = await listChecksOnSha(github, owner, repo, sha);
|
||||
if (runs.length === 0) {
|
||||
core?.info?.(`No check runs on ${sha.slice(0, 7)} — allowing (e.g. docs-only PR)`);
|
||||
return true;
|
||||
@@ -400,17 +336,13 @@ async function allChecksGreenOnSha(github, owner, repo, sha, core) {
|
||||
core?.info?.(`Check pending: ${run.name} (${run.status})`);
|
||||
return false;
|
||||
}
|
||||
if (!isAcceptableCheckConclusion(run, runs)) {
|
||||
const ok =
|
||||
['success', 'neutral', 'skipped'].includes(run.conclusion) ||
|
||||
(run.conclusion === 'cancelled' && OPTIONAL_CANCELLED_CHECKS.has(run.name));
|
||||
if (!ok) {
|
||||
core?.info?.(`Check failed: ${run.name} (${run.conclusion})`);
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
run.conclusion === 'cancelled' &&
|
||||
OPTIONAL_CANCELLED_WHEN_CORE_GREEN.has(run.name) &&
|
||||
coreTestsGreenOnRuns(runs)
|
||||
) {
|
||||
core?.info?.(`Ignoring cancelled ${run.name} — test-core green on HEAD`);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -923,12 +855,6 @@ module.exports = {
|
||||
finalClaudeCompletedOnSha,
|
||||
getMergeState,
|
||||
OPTIONAL_CANCELLED_CHECKS,
|
||||
OPTIONAL_CANCELLED_WHEN_CORE_GREEN,
|
||||
isCoreTestRun,
|
||||
coreTestsGreenOnRuns,
|
||||
isPendingRun,
|
||||
bestRunsByName,
|
||||
isAcceptableCheckConclusion,
|
||||
listChecksOnSha,
|
||||
listFailedChecksOnSha,
|
||||
allChecksGreenOnSha,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
name: Terminal-Bench Smoke
|
||||
|
||||
# Manual (and optional weekly) smoke run of the `praisonai code` assistant on a
|
||||
# small verified Terminal-Bench 2.1 subset via the Harbor harness.
|
||||
# Never runs on PRs — it costs money (LLM calls) and is inherently flaky.
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 6 * * 1" # Mondays 06:00 UTC
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
smoke:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
|
||||
- name: Install Harbor + PraisonAI
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install harbor
|
||||
pip install -e src/praisonai-agents -e src/praisonai
|
||||
|
||||
- name: Run Terminal-Bench 2.1 smoke subset
|
||||
env:
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
PYTHONPATH: .
|
||||
run: |
|
||||
harbor run -c examples/terminal_bench/job_code_smoke.yaml || true
|
||||
|
||||
- name: Upload Harbor results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: harbor-results
|
||||
path: |
|
||||
runs/
|
||||
**/results.json
|
||||
if-no-files-found: warn
|
||||
@@ -42,7 +42,7 @@ jobs:
|
||||
# ============================================
|
||||
smoke:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 12
|
||||
timeout-minutes: 8
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
|
||||
@@ -20,7 +20,7 @@ on:
|
||||
jobs:
|
||||
test-windows:
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 10
|
||||
timeout-minutes: 5
|
||||
env:
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
OPENAI_MODEL_NAME: gpt-4o-mini
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -232,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:
|
||||
|
||||
Whitespace-only changes.
@@ -1,4 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
"""
|
||||
HTTP Approval Example
|
||||
=====================
|
||||
|
||||
@@ -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,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,4 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
CI Integration Example - Using Doctor in CI/CD pipelines
|
||||
@@ -20,9 +19,7 @@ def run_doctor_ci():
|
||||
[sys.executable, "-m", "praisonai", "doctor", "ci"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
timeout=120,
|
||||
timeout=120
|
||||
)
|
||||
|
||||
# Parse JSON output
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
"""
|
||||
Agent-centric Embedding Example
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
PraisonAI Endpoints Example
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Fixed example demonstrating proper guardrail usage with PraisonAI Agents.
|
||||
|
||||
@@ -149,28 +149,21 @@ def main():
|
||||
|
||||
print(f"\nOriginal document length: {len(content)} characters")
|
||||
|
||||
chunks = [{"text": content, "metadata": {"source": doc_path}}]
|
||||
target_tokens = 2000
|
||||
|
||||
# Compress with different ratios
|
||||
for ratio in [0.3, 0.5, 0.7]:
|
||||
compressor = ContextCompressor(verbose=False)
|
||||
result = compressor.compress(
|
||||
chunks,
|
||||
query="security verification code",
|
||||
target_tokens=target_tokens,
|
||||
compression_ratio=ratio,
|
||||
compressor = ContextCompressor(
|
||||
max_tokens=2000,
|
||||
target_ratio=ratio,
|
||||
)
|
||||
result = compressor.compress([content], query="security verification code")
|
||||
|
||||
print(f"\nCompression ratio {ratio}:")
|
||||
print(f" Original tokens: {result.original_tokens}")
|
||||
print(f" Compressed tokens: {result.compressed_tokens}")
|
||||
print(f" Actual ratio: {result.compression_ratio:.2f}")
|
||||
print(f" Actual ratio: {result.compressed_tokens / max(result.original_tokens, 1):.2f}")
|
||||
|
||||
# Check if secret code is preserved
|
||||
compressed_text = " ".join(
|
||||
c.get("text", "") for c in result.chunks
|
||||
) if result.chunks else ""
|
||||
compressed_text = " ".join(result.chunks) if result.chunks else ""
|
||||
if SECRET_CODE in compressed_text:
|
||||
print(f" ✅ Secret code preserved in compressed output")
|
||||
else:
|
||||
|
||||
@@ -65,6 +65,7 @@ def main():
|
||||
name="Policy_Expert",
|
||||
instructions="You are a policy expert.",
|
||||
knowledge=[temp_dir],
|
||||
agent_id="policy_agent_v1", # Knowledge scoped to this agent
|
||||
)
|
||||
|
||||
response = shared_agent.chat("What are the expense report rules?")
|
||||
@@ -80,6 +81,7 @@ def main():
|
||||
instructions="You are a personal HR assistant.",
|
||||
knowledge=[temp_dir],
|
||||
memory={"user_id": "user_bob"},
|
||||
agent_id="hr_bot_v2",
|
||||
)
|
||||
|
||||
response = combined_agent.chat("What training is required?")
|
||||
|
||||
@@ -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,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,4 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
"""
|
||||
Session Resume Example
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
"""
|
||||
Redis State Store - Agent-First Example
|
||||
|
||||
@@ -14,8 +13,7 @@ Expected Output:
|
||||
Agent responds with state persisted to Redis
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.db import db
|
||||
from praisonaiagents import Agent, db
|
||||
|
||||
print("=== Redis State Store (Agent-First) ===")
|
||||
|
||||
@@ -28,7 +26,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"
|
||||
)
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ def demonstrate_collision_problem():
|
||||
_reset_default_registry()
|
||||
|
||||
# Agent 1 registers "custom" provider
|
||||
register_llm_provider("custom", Agent1Provider, override=True)
|
||||
register_llm_provider("custom", Agent1Provider)
|
||||
print("Agent 1 registered 'custom' provider")
|
||||
|
||||
# Agent 2 tries to register same name - ERROR!
|
||||
|
||||
@@ -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,4 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Context Agent Example - Basic Usage
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
# Uses removed praisonaiagents.tools exports; pending example refresh
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import read_csv, read_excel, write_csv, write_excel, filter_data, get_summary, group_by, pivot_table
|
||||
import os
|
||||
@@ -9,4 +7,4 @@ agent.start(f"""
|
||||
Read the data from the csv file {os.path.join(os.path.dirname(__file__), "tesla-stock-price.csv")}
|
||||
Analyse the data and give me the insights
|
||||
read_csv to read the file
|
||||
""")
|
||||
""")
|
||||
@@ -1,7 +1,5 @@
|
||||
# praisonai: skip=true
|
||||
# Uses removed praisonaiagents.tools exports; pending example refresh
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import get_stock_price, get_stock_info, get_historical_data
|
||||
|
||||
agent = Agent(instructions="You are a Research Agent", tools=[get_stock_price, get_stock_info, get_historical_data])
|
||||
agent.start("Understand current stock price and historical data of Apple and Google. Tell me if I can invest in them")
|
||||
agent.start("Understand current stock price and historical data of Apple and Google. Tell me if I can invest in them")
|
||||
@@ -1,4 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
"""
|
||||
Math Agent Example
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ def example_auto_agents_multi_provider():
|
||||
from praisonaiagents.agents import AutoAgents
|
||||
|
||||
# Create AutoAgents that will automatically assign appropriate models
|
||||
auto_agents = AutoAgents(
|
||||
auto_agents = AutoAgentTeam(
|
||||
instructions="Create a market research report on electric vehicles. Include data analysis, competitor analysis, and future projections.",
|
||||
max_agents=3,
|
||||
llm="gpt-4o-mini", # Default model for agent generation
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
# Uses removed praisonaiagents.tools exports; pending example refresh
|
||||
from praisonaiagents import Agent, Task, AgentTeam
|
||||
from praisonaiagents.tools import wiki_search, wiki_summary, wiki_page, wiki_random, wiki_language
|
||||
|
||||
@@ -15,4 +13,4 @@ agent.start(
|
||||
"First search the history of AI"
|
||||
"Read the page of the history of AI"
|
||||
"Get the summary of the page"
|
||||
)
|
||||
)
|
||||
@@ -1,4 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
from praisonaiagents import Agent, MCP
|
||||
|
||||
qa_agent = Agent(
|
||||
|
||||
@@ -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,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,34 +1,5 @@
|
||||
import socket
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
|
||||
from praisonaiagents import Agent
|
||||
|
||||
|
||||
def _wait_until_ready(host: str, port: int, timeout: float = 15.0) -> bool:
|
||||
"""Poll the MCP server port until it accepts connections or times out."""
|
||||
deadline = time.time() + timeout
|
||||
while time.time() < deadline:
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
|
||||
sock.settimeout(1.0)
|
||||
if sock.connect_ex((host, port)) == 0:
|
||||
return True
|
||||
time.sleep(0.25)
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
host, port = "127.0.0.1", 8080
|
||||
agent = Agent(name="TweetAgent", instructions="Create a Tweet based on the topic provided")
|
||||
server = threading.Thread(
|
||||
target=lambda: agent.launch(port=port, protocol="mcp", path="/mcp"),
|
||||
daemon=True,
|
||||
)
|
||||
server.start()
|
||||
|
||||
if _wait_until_ready(host, port):
|
||||
print(f"MCP server started on http://{host}:{port}/mcp")
|
||||
else:
|
||||
print(f"MCP server failed to start on http://{host}:{port}/mcp", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
agent.launch(port=8080, protocol="mcp", path="/")
|
||||
@@ -1,4 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
from praisonaiagents import AudioAgent
|
||||
|
||||
# Text to Speech
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
# Requires local audio.mp3 fixture
|
||||
from praisonaiagents import AudioAgent
|
||||
|
||||
agent = AudioAgent(llm="groq/whisper-large-v3") # 10x faster
|
||||
@@ -7,4 +5,3 @@ text = agent.transcribe("audio.mp3", language="en")
|
||||
print(text)
|
||||
|
||||
# Models: openai/whisper-1, groq/whisper-large-v3, deepgram/nova-2
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
# Requires local audio.mp3 fixture
|
||||
# Speech-to-Text with Groq (fastest)
|
||||
# Requires: export GROQ_API_KEY=your-key
|
||||
|
||||
@@ -8,4 +6,3 @@ from praisonaiagents import AudioAgent
|
||||
agent = AudioAgent(llm="groq/whisper-large-v3")
|
||||
text = agent.listen("audio.mp3") # Replace with your audio file
|
||||
print(text)
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
# praisonai: skip=true
|
||||
# Requires local audio.mp3 fixture
|
||||
from praisonaiagents import AudioAgent
|
||||
|
||||
agent = AudioAgent(llm="deepgram/nova-2")
|
||||
text = agent.listen("audio.mp3")
|
||||
print(text)
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
# praisonai: skip=true
|
||||
# Requires local audio.mp3 fixture
|
||||
from praisonaiagents import AudioAgent
|
||||
|
||||
agent = AudioAgent(llm="groq/whisper-large-v3")
|
||||
text = agent.listen("audio.mp3")
|
||||
print(text)
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
# praisonai: skip=true
|
||||
# Requires local audio.mp3 fixture
|
||||
from praisonaiagents import AudioAgent
|
||||
|
||||
agent = AudioAgent(llm="openai/whisper-1")
|
||||
text = agent.listen("audio.mp3")
|
||||
print(text)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
from praisonaiagents import AudioAgent
|
||||
|
||||
agent = AudioAgent(llm="openai/tts-1-hd")
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
# Text-to-Speech with OpenAI
|
||||
# Requires: export OPENAI_API_KEY=your-key
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
from praisonaiagents import AudioAgent
|
||||
|
||||
agent = AudioAgent(llm="elevenlabs/eleven_multilingual_v2")
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
from praisonaiagents import AudioAgent
|
||||
|
||||
agent = AudioAgent(llm="gemini/gemini-2.5-flash-preview-tts")
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
from praisonaiagents import AudioAgent
|
||||
|
||||
agent = AudioAgent(llm="openai/tts-1")
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
"""
|
||||
Bot Commands Example — Built-in /status, /new, /help commands.
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# praisonai: skip=true
|
||||
"""
|
||||
Bot Gateway Example — Run multiple bots from one gateway server.
|
||||
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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,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
|
||||
|
||||
Loaded 100 of 418 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user