Compare commits

..
Author SHA1 Message Date
MervinPraison de5bda560b Deployed bf88163 with MkDocs version: 1.6.1 2024-12-26 07:07:50 +00:00
MervinPraison b371ea5eda Deployed dd606e7 with MkDocs version: 1.6.1 2024-12-24 20:29:47 +00:00
MervinPraison 32c9ee9df6 Deployed 23a74c9 with MkDocs version: 1.6.1 2024-12-09 11:07:36 +00:00
MervinPraison cea19cce18 Deployed 23a74c9 with MkDocs version: 1.6.1 2024-12-09 11:03:14 +00:00
MervinPraison b2d428f153 Deployed fb9a6ed with MkDocs version: 1.6.1 2024-12-06 16:37:47 +00:00
MervinPraison 21d718d15c Deployed a66ecdd with MkDocs version: 1.6.1 2024-11-08 10:55:54 +00:00
MervinPraison 628e380098 Deployed a66ecdd with MkDocs version: 1.6.1 2024-11-08 09:54:14 +00:00
MervinPraison 3c7f674ad8 Deployed a66ecdd with MkDocs version: 1.6.1 2024-11-08 09:48:37 +00:00
MervinPraison d58241f4dd Deployed a66ecdd with MkDocs version: 1.6.1 2024-11-08 09:46:54 +00:00
MervinPraison ef045cc86c Deployed 95357a5 with MkDocs version: 1.6.1 2024-11-08 09:44:10 +00:00
MervinPraison b234a9f0c9 Deployed 394bb0b with MkDocs version: 1.6.1 2024-10-31 01:06:32 +00:00
MervinPraison d08ecf797f Deployed 394bb0b with MkDocs version: 1.6.1 2024-10-31 00:56:24 +00:00
MervinPraison 6c6b14b98e Deployed 394bb0b with MkDocs version: 1.6.1 2024-10-31 00:54:48 +00:00
MervinPraison 24cdbd35a7 Deployed 394bb0b with MkDocs version: 1.6.1 2024-10-31 00:53:42 +00:00
MervinPraison f5c007c0b3 Deployed 93b5c28 with MkDocs version: 1.6.1 2024-10-30 20:47:11 +00:00
MervinPraison 48ce167c30 Deployed 93b5c28 with MkDocs version: 1.6.1 2024-10-30 20:44:07 +00:00
MervinPraison 388a7963bd Deployed c4285cd with MkDocs version: 1.6.1 2024-10-30 20:26:18 +00:00
MervinPraison f133ed99d7 Deployed 9b4b987 with MkDocs version: 1.6.1 2024-10-08 01:17:47 +01:00
MervinPraison 0f64c40aad Deployed 9b4b987 with MkDocs version: 1.6.1 2024-10-08 01:11:16 +01:00
MervinPraison e2901e9c33 Deployed 545d06a with MkDocs version: 1.6.1 2024-10-02 09:28:48 +01:00
MervinPraison 45d3d03c4d Deployed 1bb657e with MkDocs version: 1.6.0 2024-08-06 10:07:45 +01:00
MervinPraison e4e8fa8b65 Deployed 1bb657e with MkDocs version: 1.6.0 2024-08-06 09:59:33 +01:00
MervinPraison b48e561790 Deployed 6250c19 with MkDocs version: 1.6.0 2024-08-01 01:38:09 +01:00
MervinPraison 0bbf4c371d Deployed 6250c19 with MkDocs version: 1.6.0 2024-07-21 02:12:10 +01:00
MervinPraison dd17cf9a9a Deployed 1ea77d3 with MkDocs version: 1.6.0 2024-07-21 02:08:54 +01:00
MervinPraison e9add2e1c8 Deployed 1ea77d3 with MkDocs version: 1.6.0 2024-07-21 01:07:28 +01:00
MervinPraison 535bbbed29 Deployed 1ea77d3 with MkDocs version: 1.6.0 2024-07-21 01:06:40 +01:00
MervinPraison 55092099c1 Deployed d22a810 with MkDocs version: 1.6.0 2024-07-21 00:52:45 +01:00
MervinPraison 11685dbe74 Deployed d22a810 with MkDocs version: 1.6.0 2024-07-21 00:51:19 +01:00
MervinPraison ca056e6f1a Deployed 0a9df47 with MkDocs version: 1.6.0 2024-07-20 23:46:37 +01:00
MervinPraison e151a323fe Deployed 0a9df47 with MkDocs version: 1.6.0 2024-07-20 23:45:37 +01:00
MervinPraison ce58d8f5a1 Deployed 0a9df47 with MkDocs version: 1.6.0 2024-07-20 23:44:47 +01:00
MervinPraison 0c36171513 Deployed 0a9df47 with MkDocs version: 1.6.0 2024-07-20 23:43:15 +01:00
MervinPraison 81b1838655 Deployed 0a9df47 with MkDocs version: 1.6.0 2024-07-20 23:41:35 +01:00
MervinPraison fda134378b Deployed 0a9df47 with MkDocs version: 1.6.0 2024-07-20 23:38:23 +01:00
MervinPraison 12c7eccb61 Deployed 0a9df47 with MkDocs version: 1.6.0 2024-07-20 23:33:19 +01:00
MervinPraison a347336fd3 Deployed 0a9df47 with MkDocs version: 1.6.0 2024-07-20 23:32:34 +01:00
MervinPraison 44aa944bba Deployed 0a9df47 with MkDocs version: 1.6.0 2024-07-19 06:12:23 +01:00
MervinPraison 7fc3193b74 Deployed 0a9df47 with MkDocs version: 1.6.0 2024-07-19 06:07:37 +01:00
MervinPraison 40f522cbe6 Deployed 0a9df47 with MkDocs version: 1.6.0 2024-07-19 06:01:50 +01:00
MervinPraison 2f75bade61 Deployed 0a9df47 with MkDocs version: 1.6.0 2024-07-19 00:07:52 +01:00
MervinPraison 391f98590c Deployed 086f9ee with MkDocs version: 1.6.0 2024-07-18 23:55:37 +01:00
MervinPraison ff68dc7ffc Deployed 9ce4bba with MkDocs version: 1.6.0 2024-07-18 23:50:50 +01:00
MervinPraison 71cd122171 Deployed 9ce4bba with MkDocs version: 1.6.0 2024-07-18 23:48:27 +01:00
MervinPraison 7e82df923f Deployed 855afc8 with MkDocs version: 1.6.0 2024-07-18 17:46:16 +01:00
MervinPraison cd8efc4351 Deployed 241b94a with MkDocs version: 1.6.0 2024-07-16 05:35:11 +01:00
MervinPraison 2d2b798608 Deployed 241b94a with MkDocs version: 1.6.0 2024-07-15 10:21:01 +01:00
MervinPraison 40db2adeb4 Deployed 241b94a with MkDocs version: 1.6.0 2024-07-15 10:19:27 +01:00
MervinPraison 88597a5249 Deployed 8985715 with MkDocs version: 1.6.0 2024-07-15 10:05:29 +01:00
f7e423ad44 Deployed 8985715 with MkDocs version: 1.6.0 2024-07-15 09:32:32 +01:00
MervinPraison 57d2c020c1 Deployed 8985715 with MkDocs version: 1.6.0 2024-07-13 02:21:06 +01:00
MervinPraison 672bd8a3d2 Deployed 4ac449b with MkDocs version: 1.6.0 2024-07-13 02:15:53 +01:00
MervinPraison fc8a4a4148 Deployed 5491f16 with MkDocs version: 1.6.0 2024-07-13 01:56:43 +01:00
MervinPraison e996268d10 Deployed 2f4ad10 with MkDocs version: 1.6.0 2024-07-11 21:46:20 +01:00
MervinPraison 8fd21e1392 Deployed 9597de1 with MkDocs version: 1.6.0 2024-07-08 06:59:37 +01:00
MervinPraison 042e96d563 Deployed 9597de1 with MkDocs version: 1.6.0 2024-07-08 06:59:07 +01:00
MervinPraison 79e8ef2dc0 Deployed 10ecaef with MkDocs version: 1.6.0 2024-07-07 02:04:56 +01:00
MervinPraison b69d3b7ac8 Deployed ca2c5b1 with MkDocs version: 1.6.0 2024-07-03 07:08:23 +01:00
MervinPraison ddc7deded8 Deployed 259f1b3 with MkDocs version: 1.6.0 2024-07-03 06:05:52 +01:00
MervinPraison bae5808966 Deployed 259f1b3 with MkDocs version: 1.6.0 2024-07-03 05:57:47 +01:00
MervinPraison e9e4bd8b86 Deployed 259f1b3 with MkDocs version: 1.6.0 2024-07-03 05:39:46 +01:00
MervinPraison 86f169b1d7 Deployed 259f1b3 with MkDocs version: 1.6.0 2024-07-03 05:35:49 +01:00
MervinPraison 66d4df9653 Deployed 62e2e3f with MkDocs version: 1.6.0 2024-07-02 06:50:36 +01:00
MervinPraison cd121b2988 Deployed 62e2e3f with MkDocs version: 1.6.0 2024-07-02 06:47:30 +01:00
MervinPraison fe5298a425 Deployed 62e2e3f with MkDocs version: 1.6.0 2024-07-02 06:42:46 +01:00
MervinPraison db033c3242 Deployed 62e2e3f with MkDocs version: 1.6.0 2024-07-02 06:40:55 +01:00
MervinPraison 17c744830a Deployed 62e2e3f with MkDocs version: 1.6.0 2024-07-02 06:25:59 +01:00
MervinPraison b50d887e83 Deployed 3221f43 with MkDocs version: 1.6.0 2024-06-29 12:39:08 +01:00
MervinPraison 2ead1dc0ba Deployed 9a503c7 with MkDocs version: 1.6.0 2024-06-24 12:05:04 +01:00
MervinPraison 819b0e4c80 Deployed 9a503c7 with MkDocs version: 1.6.0 2024-06-22 15:19:15 +01:00
MervinPraison 2460963a95 Deployed 9a503c7 with MkDocs version: 1.6.0 2024-06-22 07:21:52 +01:00
MervinPraison 023a553c82 Deployed eecdeb4 with MkDocs version: 1.6.0 2024-06-22 04:26:52 +01:00
MervinPraison 026818778c Deployed 618db97 with MkDocs version: 1.6.0 2024-06-19 22:31:32 +01:00
MervinPraison 1970756b45 Deployed 577a12a with MkDocs version: 1.6.0 2024-06-18 23:43:02 +01:00
MervinPraison 228d7c904d Deployed f60a35d with MkDocs version: 1.6.0 2024-06-17 07:09:24 +01:00
MervinPraison ca10e5cf83 Deployed 6db312e with MkDocs version: 1.6.0 2024-06-16 23:37:48 +01:00
MervinPraison 54b2f1a747 Deployed 6db312e with MkDocs version: 1.6.0 2024-06-16 08:58:09 +01:00
MervinPraison 174b75e8db Deployed 6db312e with MkDocs version: 1.6.0 2024-06-16 08:47:20 +01:00
MervinPraison 2471a48e46 Deployed 986e4a0 with MkDocs version: 1.6.0 2024-06-13 21:45:02 +01:00
MervinPraison 69e995e603 Deployed 986e4a0 with MkDocs version: 1.6.0 2024-06-13 21:42:01 +01:00
MervinPraison d92b61da6c Deployed 986e4a0 with MkDocs version: 1.6.0 2024-06-13 21:35:20 +01:00
MervinPraison bb49c6a72b Deployed aec65d3 with MkDocs version: 1.6.0 2024-06-13 06:53:56 +01:00
Mervin Praison 80f9fcd6d8 Create CNAME 2024-06-13 06:51:14 +01:00
MervinPraison 24e5a58f08 Deployed aec65d3 with MkDocs version: 1.6.0 2024-06-13 06:48:31 +01:00
Mervin Praison df946780a6 Create CNAME 2024-06-13 06:00:43 +01:00
Mervin Praison d9efe48c7b Delete CNAME 2024-06-13 06:00:37 +01:00
Mervin Praison c351dd7031 Create CNAME 2024-06-13 05:56:10 +01:00
Mervin Praison f080e2a9a9 Delete CNAME 2024-06-13 05:51:27 +01:00
Mervin Praison 38fc583980 Create CNAME 2024-06-13 05:48:30 +01:00
MervinPraison d832b09cea Deployed aec65d3 with MkDocs version: 1.6.0 2024-06-13 05:36:32 +01:00
MervinPraison a6e5546513 Deployed aec65d3 with MkDocs version: 1.6.0 2024-06-13 05:11:55 +01:00
MervinPraison 6d3abf35e5 Deployed aec65d3 with MkDocs version: 1.6.0 2024-06-13 05:11:45 +01:00
MervinPraison ed01840711 Deployed aec65d3 with MkDocs version: 1.6.0 2024-06-13 05:11:02 +01:00
MervinPraison 3f277513f7 Deployed aec65d3 with MkDocs version: 1.6.0 2024-06-13 05:10:43 +01:00
MervinPraison 4dbf69bfcb Deployed aec65d3 with MkDocs version: 1.6.0 2024-06-13 05:10:07 +01:00
MervinPraison bd6ae316c7 Deployed aec65d3 with MkDocs version: 1.6.0 2024-06-13 05:09:55 +01:00
MervinPraison 7a235e635d Deployed aec65d3 with MkDocs version: 1.6.0 2024-06-13 05:09:22 +01:00
MervinPraison 121faf5ac7 Deployed aec65d3 with MkDocs version: 1.6.0 2024-06-13 05:08:19 +01:00
MervinPraison 887c5270f9 Deployed aec65d3 with MkDocs version: 1.6.0 2024-06-13 04:55:56 +01:00
4728 changed files with 135346 additions and 1095224 deletions

No files matched your search

Vendored
BIN
View File
Binary file not shown.
-51
View File
@@ -1,51 +0,0 @@
# PraisonAI Environment Variables
# Copy this file to .env and update with your actual values
# === Required ===
OPENAI_API_KEY=sk-... # OpenAI key for LLM calls. Get yours at https://platform.openai.com
# === Required for Claw web-search tool ===
TAVILY_API_KEY=tvly-... # Get yours at https://app.tavily.com (free tier available)
# === Optional: Claw dashboard security ===
PRAISONAI_ALLOW_LOCAL_TOOLS=0 # Set to 1 to enable local shell tools (security risk)
# === Optional: Alternative LLM Providers ===
ANTHROPIC_API_KEY=sk-ant-... # Anthropic Claude models
GOOGLE_API_KEY=... # Google Gemini models
GROQ_API_KEY=gsk_... # Groq (fast inference)
COHERE_API_KEY=... # Cohere models
AZURE_OPENAI_API_KEY=... # Azure OpenAI
AZURE_OPENAI_ENDPOINT=... # Azure OpenAI endpoint
# === Optional: Memory backends ===
MEM0_API_KEY=... # Mem0 memory service
REDIS_URL=redis://localhost:6379 # Redis for state management
# === Optional: Observability ===
LANGFUSE_SECRET_KEY=sk-lf-... # Langfuse tracing
LANGFUSE_PUBLIC_KEY=pk-lf-... # Langfuse public key
# === Optional: Bot platforms ===
TELEGRAM_BOT_TOKEN=... # Telegram bot token
DISCORD_BOT_TOKEN=... # Discord bot token
SLACK_BOT_TOKEN=xoxb-... # Slack bot token
SLACK_APP_TOKEN=xapp-... # Slack app token
WHATSAPP_ACCESS_TOKEN=... # WhatsApp bot access token
WHATSAPP_PHONE_NUMBER_ID=... # WhatsApp phone number ID
# === Optional: Database ===
DATABASE_URL=sqlite:///~/.praison/database.sqlite # Database connection string
# === Optional: Tool Security ===
# ALLOWED_TOOLS=search,send_message # Whitelist specific tools to prevent name collisions
# Useful in multi-environment setups with overlapping tool names
# Leave unset to use all tools (with collision warnings)
# Do NOT set to empty string: that's treated as configuration error
# In CI, unknown tool names in the whitelist cause strict startup failure
# HERMES_ONLY_TOOLS=search,send_message # (Deprecated) Backward compatibility alias for ALLOWED_TOOLS
# === Optional: Development ===
LOGLEVEL=INFO # Logging level (DEBUG, INFO, WARNING, ERROR)
CHAINLIT_AUTH_SECRET=... # Chainlit authentication secret
DEBUG=false # Enable debug mode
-2
View File
@@ -1,2 +0,0 @@
patreon: MervinPraison
ko_fi: MervinPraison
-34
View File
@@ -1,34 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: '[BUG] '
labels: bug
assignees: ''
---
## Environment
- Provider (select one):
- [ ] Anthropic
- [ ] OpenAI
- [ ] Google Vertex AI
- [ ] AWS Bedrock
- [ ] Other: <!-- specify -->
- PraisonAI version: <!-- if known -->
- Operating System: <!-- e.g. macOS 14.3, Windows 11, Ubuntu 22.04 -->
## Full Code
<!-- Full code that reproduces the bug -->
## Steps to Reproduce
1. <!-- First step -->
2. <!-- Second step -->
3. <!-- And so on... -->
## Expected Behavior
<!-- What you expected to happen -->
## Actual Behavior
<!-- What actually happened -->
## Additional Context
<!-- Add any other context about the problem here, such as screenshots, logs, etc. -->
@@ -1,296 +0,0 @@
name: "Claude Code Action"
description: "Run Claude Code in GitHub Actions workflows"
inputs:
anthropic_api_key:
description: "Anthropic API key"
required: false
claude_code_oauth_token:
description: "Claude Code OAuth Token for Claude Pro"
required: false
github_token:
description: "GitHub token for Claude to operate with"
required: false
default: ${{ github.token }}
trigger_phrase:
description: "The trigger phrase to look for in comments, issue/PR bodies, and issue titles"
required: false
default: "@claude"
assignee_trigger:
description: "The assignee username that triggers the action (e.g. @claude). Only used for issue assignment"
required: false
max_turns:
description: "Maximum number of conversation turns Claude can take"
required: false
timeout_minutes:
description: "Timeout in minutes for execution"
required: false
default: "30"
model:
description: "Model to use (provider-specific format required for Bedrock/Vertex)"
required: false
use_bedrock:
description: "Use Amazon Bedrock with OIDC authentication instead of direct Anthropic API"
required: false
default: "false"
use_vertex:
description: "Use Google Vertex AI with OIDC authentication instead of direct Anthropic API"
required: false
default: "false"
allowed_tools:
description: "Additional tools for Claude to use (the base GitHub tools will always be included)"
required: false
default: ""
disallowed_tools:
description: "Tools that Claude should never use"
required: false
default: ""
custom_instructions:
description: "Additional custom instructions to include in the prompt for Claude"
required: false
default: ""
mcp_config:
description: "Additional MCP configuration (JSON string) that merges with the built-in GitHub MCP servers"
required: false
default: ""
claude_env:
description: "Custom environment variables to pass to Claude Code execution (YAML format)"
required: false
default: ""
direct_prompt:
description: "Direct prompt for Claude to execute automatically without needing a trigger (for automated workflows)"
required: false
runs:
using: "composite"
steps:
- name: Install Claude Code
shell: bash
run: npm install -g @anthropic-ai/claude-code
- name: Install GitHub MCP Server
shell: bash
env:
INPUT_GITHUB_TOKEN: ${{ inputs.github_token }}
run: |
claude mcp add-json github '{
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"ghcr.io/github/github-mcp-server:sha-ff3036d"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "'"${INPUT_GITHUB_TOKEN}"'"
}
}'
- name: Extract GitHub Context and Create Prompt
shell: bash
id: prepare_context
env:
# Pass user-controlled inputs via environment variables to prevent script injection (GHSL-2025-093)
EVENT_COMMENT_BODY: ${{ github.event.comment.body }}
EVENT_ISSUE_TITLE: ${{ github.event.issue.title }}
EVENT_ISSUE_BODY: ${{ github.event.issue.body }}
EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
EVENT_PR_TITLE: ${{ github.event.pull_request.title }}
EVENT_PR_NUMBER: ${{ github.event.pull_request.number }}
EVENT_REVIEW_BODY: ${{ github.event.review.body }}
EVENT_ASSIGNEE_LOGIN: ${{ github.event.assignee.login }}
INPUT_TRIGGER_PHRASE: ${{ inputs.trigger_phrase }}
INPUT_ASSIGNEE_TRIGGER: ${{ inputs.assignee_trigger }}
INPUT_DIRECT_PROMPT: ${{ inputs.direct_prompt }}
EVENT_ACTION: ${{ github.event.action }}
EVENT_NAME: ${{ github.event_name }}
REPO_NAME: ${{ github.repository }}
run: |
echo "🔍 Extracting GitHub context from event: $EVENT_NAME"
# Function to check for trigger phrase
check_trigger() {
local text="$1"
local trigger="$INPUT_TRIGGER_PHRASE"
if [[ "$text" == *"$trigger"* ]]; then
return 0
fi
return 1
}
# Extract context based on event type
TRIGGER_FOUND="false"
USER_REQUEST=""
CONTEXT_INFO=""
case "$EVENT_NAME" in
"issue_comment")
COMMENT_BODY="$EVENT_COMMENT_BODY"
ISSUE_TITLE="$EVENT_ISSUE_TITLE"
ISSUE_NUMBER="$EVENT_ISSUE_NUMBER"
if check_trigger "$COMMENT_BODY"; then
TRIGGER_FOUND="true"
USER_REQUEST="$COMMENT_BODY"
CONTEXT_INFO="Issue Comment on #$ISSUE_NUMBER: $ISSUE_TITLE"
fi
;;
"pull_request_review_comment")
COMMENT_BODY="$EVENT_COMMENT_BODY"
PR_TITLE="$EVENT_PR_TITLE"
PR_NUMBER="$EVENT_PR_NUMBER"
if check_trigger "$COMMENT_BODY"; then
TRIGGER_FOUND="true"
USER_REQUEST="$COMMENT_BODY"
CONTEXT_INFO="PR Comment on #$PR_NUMBER: $PR_TITLE"
fi
;;
"pull_request_review")
REVIEW_BODY="$EVENT_REVIEW_BODY"
PR_TITLE="$EVENT_PR_TITLE"
PR_NUMBER="$EVENT_PR_NUMBER"
if check_trigger "$REVIEW_BODY"; then
TRIGGER_FOUND="true"
USER_REQUEST="$REVIEW_BODY"
CONTEXT_INFO="PR Review on #$PR_NUMBER: $PR_TITLE"
fi
;;
"issues")
ISSUE_BODY="$EVENT_ISSUE_BODY"
ISSUE_TITLE="$EVENT_ISSUE_TITLE"
ISSUE_NUMBER="$EVENT_ISSUE_NUMBER"
if check_trigger "$ISSUE_TITLE" || check_trigger "$ISSUE_BODY"; then
TRIGGER_FOUND="true"
USER_REQUEST="$ISSUE_BODY"
CONTEXT_INFO="Issue #$ISSUE_NUMBER: $ISSUE_TITLE"
elif [[ "$EVENT_ACTION" == "assigned" && -n "$INPUT_ASSIGNEE_TRIGGER" ]]; then
ASSIGNEE="$EVENT_ASSIGNEE_LOGIN"
if [[ "$ASSIGNEE" == "$INPUT_ASSIGNEE_TRIGGER" ]]; then
TRIGGER_FOUND="true"
USER_REQUEST="$ISSUE_BODY"
CONTEXT_INFO="Issue #$ISSUE_NUMBER assigned to $ASSIGNEE: $ISSUE_TITLE"
fi
fi
;;
esac
# Check for direct prompt override
if [[ -n "$INPUT_DIRECT_PROMPT" ]]; then
TRIGGER_FOUND="true"
USER_REQUEST="$INPUT_DIRECT_PROMPT"
CONTEXT_INFO="Automated GitHub workflow"
fi
if [[ "$TRIGGER_FOUND" != "true" ]]; then
echo "❌ No trigger phrase found or direct prompt provided. Exiting gracefully."
echo "SKIP_EXECUTION=true" >> $GITHUB_ENV
exit 0
fi
echo "✅ Trigger found! Context: $CONTEXT_INFO"
# Create comprehensive prompt
mkdir -p /tmp/claude-action
cat > /tmp/claude-action/github-context-prompt.txt << EOF
You are Claude Code, an AI assistant helping with GitHub workflows and code.
Repository: $REPO_NAME
Context: $CONTEXT_INFO
Event: $EVENT_NAME
User Request:
$USER_REQUEST
Please analyze the request and provide helpful assistance.
CRITICAL INSTRUCTION: If your task involves modifying codebase files to add a feature or fix a bug:
STEP 0 — SETUP GIT IDENTITY:
git config user.name "MervinPraison"
git config user.email "[email protected]"
STEP 1 — READ GUIDELINES:
MANDATORY: Before writing any code, you MUST carefully read "src/praisonai-agents/AGENTS.md" to understand this repository's extremely specific Architecture, Protocol-First design rules, and Agent-Centric Philosophy.
STEP 2 — ARCHITECTURE VALIDATION & ROUTING (MANDATORY before writing code):
Before implementing anything, answer these questions:
- CORE vs WRAPPER vs TOOLS ROUTING:
1. Core SDK (praisonaiagents/): Only core protocols, base classes, decorators. No heavy implementations.
2. Wrapper (praisonai/): CLI, heavy implementations, optional dependencies.
3. Tools (PraisonAI-Tools): Specific integrations, external tools (e.g. SurrealDB, Slack), and community extensions MUST go to the `MervinPraison/PraisonAI-Tools` repository. If the feature is a tool, clone `https://github.com/MervinPraison/PraisonAI-Tools`, implement it there, and create the PR using `gh pr create -R MervinPraison/PraisonAI-Tools`.
- Does it duplicate existing functionality? Check if Agent already supports this via existing params (reflection, planning, tools, hooks, memory).
- Does it inherit from Agent properly? New agent types MUST inherit Agent, not wrap it with composition.
- Does it add new dependencies? Only optional deps allowed, must be lazy-imported.
- Will agent.py grow larger? If the change adds >50 lines to agent.py, find a way to extract instead.
- Is there a name collision with existing exports in __init__.py?
If ANY of these conceptual checks fail (excluding routing), add a comment to the issue explaining why and close it. Do NOT create a PR.
STEP 3 — IMPLEMENT:
- Create a new git branch appropriately named (e.g. \`feature/issue-<number>\`)
- Follow protocol-driven design: protocols in core SDK, heavy implementations in wrapper
- Keep changes small and backward-compatible
STEP 4 — TEST:
- Run: cd src/praisonai-agents && PYTHONPATH=. python -m pytest tests/ -x -q --timeout=30
- Ensure no regressions
STEP 5 — CREATE PR:
- Commit with descriptive message, push the branch
- Use the GitHub CLI (\`gh pr create --title "..." --body "Fixes #<number>"\`) to open a Pull Request
CRITICAL: You MUST create the PR automatically using \`gh pr create\`. Do NOT just provide a link.
Respond naturally and helpfully to the user's request using the available tools.
EOF
echo "PROMPT_FILE=/tmp/claude-action/github-context-prompt.txt" >> $GITHUB_ENV
echo "SKIP_EXECUTION=false" >> $GITHUB_ENV
- name: Run Claude Code
if: env.SKIP_EXECUTION != 'true'
shell: bash
env:
ANTHROPIC_API_KEY: ${{ inputs.anthropic_api_key }}
CLAUDE_CODE_OAUTH_TOKEN: ${{ inputs.claude_code_oauth_token }}
GITHUB_TOKEN: ${{ inputs.github_token }}
INPUT_MAX_TURNS: ${{ inputs.max_turns }}
INPUT_ALLOWED_TOOLS: ${{ inputs.allowed_tools }}
INPUT_DISALLOWED_TOOLS: ${{ inputs.disallowed_tools }}
INPUT_TIMEOUT_MINUTES: ${{ inputs.timeout_minutes }}
run: |
echo "🚀 Running Claude Code with GitHub context..."
# Build command arguments
CMD_ARGS=("-p" "--verbose" "--output-format" "stream-json")
# Add max turns if specified
if [[ -n "$INPUT_MAX_TURNS" ]]; then
CMD_ARGS+=("--max-turns" "$INPUT_MAX_TURNS")
fi
# Add allowed tools (include GitHub tools by default)
TOOLS="mcp__github__get_issue,mcp__github__get_issue_comments,mcp__github__update_issue,mcp__github__search_issues,mcp__github__list_issues,mcp__github__create_comment,Read,Write,Edit,Bash"
if [[ -n "$INPUT_ALLOWED_TOOLS" ]]; then
TOOLS="$TOOLS,$INPUT_ALLOWED_TOOLS"
fi
CMD_ARGS+=("--allowedTools" "$TOOLS")
# Add disallowed tools
if [[ -n "$INPUT_DISALLOWED_TOOLS" ]]; then
CMD_ARGS+=("--disallowedTools" "$INPUT_DISALLOWED_TOOLS")
fi
echo "📝 Executing Claude Code with prompt from file..."
# Execute Claude Code with timeout, using stdin for the prompt
TIMEOUT_SECONDS=$(($INPUT_TIMEOUT_MINUTES * 60))
timeout $TIMEOUT_SECONDS claude "${CMD_ARGS[@]}" < "$PROMPT_FILE"
echo "✅ Claude Code execution completed"
@@ -1,92 +0,0 @@
name: "Claude Issue Triage Action"
description: "Automatically triage GitHub issues using Claude Code"
inputs:
timeout_minutes:
description: "Timeout in minutes for execution"
required: false
default: "5"
claude_code_oauth_token:
description: "Claude Code OAuth token for Pro subscription access"
required: true
github_token:
description: "GitHub token with repo and issues permissions"
required: true
runs:
using: "composite"
steps:
- name: Checkout repository code
uses: actions/checkout@v4
with:
persist-credentials: false
fetch-depth: 0
- name: Create prompt
id: generate_prompt
shell: bash
run: |
mkdir -p /tmp/claude-prompts
cat > /tmp/claude-prompts/claude-issue-triage-prompt.txt << 'EOF'
You're an issue triage assistant for GitHub issues. Your task is to analyze the issue and select appropriate labels from the provided list.
IMPORTANT: Don't post any comments or messages to the issue. Your only action should be to apply labels.
Issue Information:
- REPO: ${{ github.repository }}
- ISSUE_NUMBER: ${{ github.event.issue.number }}
TASK OVERVIEW:
1. First, fetch the list of labels available in this repository by running: `gh label list`. Run exactly this command with nothing else.
2. Next, use the GitHub tools to get context about the issue:
- You have access to these tools:
- mcp__github__get_issue: Use this to retrieve the current issue's details including title, description, and existing labels
- mcp__github__get_issue_comments: Use this to read any discussion or additional context provided in the comments
- mcp__github__update_issue: Use this to apply labels to the issue (do not use this for commenting)
- mcp__github__search_issues: Use this to find similar issues that might provide context for proper categorization and to identify potential duplicate issues
- mcp__github__list_issues: Use this to understand patterns in how other issues are labeled
- Start by using mcp__github__get_issue to get the issue details
3. Analyze the issue content, considering:
- The issue title and description
- The type of issue (bug report, feature request, question, etc.)
- Technical areas mentioned
- Severity or priority indicators
- User impact
- Components affected
4. Select appropriate labels from the available labels list provided above:
- Choose labels that accurately reflect the issue's nature
- Be specific but comprehensive
- Select priority labels if you can determine urgency (high-priority, med-priority, or low-priority)
- Consider platform labels (android, ios) if applicable
- If you find similar issues using mcp__github__search_issues, consider using a "duplicate" label if appropriate. Only do so if the issue is a duplicate of another OPEN issue.
5. Apply the selected labels:
- Use mcp__github__update_issue to apply your selected labels
- DO NOT post any comments explaining your decision
- DO NOT communicate directly with users
- If no labels are clearly applicable, do not apply any labels
IMPORTANT GUIDELINES:
- Be thorough in your analysis
- Only select labels from the provided list above
- DO NOT post any comments to the issue
- Your ONLY action should be to apply labels using mcp__github__update_issue
- It's okay to not add any labels if none are clearly applicable
EOF
echo "PROMPT<<DELIMITER" >> $GITHUB_OUTPUT
cat /tmp/claude-prompts/claude-issue-triage-prompt.txt >> $GITHUB_OUTPUT
echo "DELIMITER" >> $GITHUB_OUTPUT
- name: Run Claude Code
uses: ./.github/actions/claude-code-action
with:
direct_prompt: ${{ steps.generate_prompt.outputs.PROMPT }}
allowed_tools: "Bash(gh label list),mcp__github__get_issue,mcp__github__get_issue_comments,mcp__github__update_issue,mcp__github__search_issues,mcp__github__list_issues"
timeout_minutes: ${{ inputs.timeout_minutes }}
claude_code_oauth_token: ${{ inputs.claude_code_oauth_token }}
github_token: ${{ inputs.github_token }}
-90
View File
@@ -1,90 +0,0 @@
name: 'Gemini CLI Action'
description: 'Uses the Gemini CLI to automate software development tasks.'
author: 'Gemini'
inputs:
prompt:
description: 'A specific prompt to guide Gemini.'
required: false
default: 'You are a helpful assistant.'
GEMINI_API_KEY:
description: 'Your Gemini API key.'
required: true
OTLP_GCP_WIF_PROVIDER:
description: 'The workload identity provider for GCP authentication.'
required: false
OTLP_GOOGLE_CLOUD_PROJECT:
description: 'The Google Cloud project for telemetry.'
required: false
settings_json:
description: |
A JSON string to configure the Gemini CLI. This will be written to .gemini/settings.json.
To enable observability with Google Cloud, include:
{"telemetry": {"enabled": true, "target": "gcp"}, "sandbox": false}
required: false
model:
description: |
The Gemini model to use. Options: gemini-2.5-pro, gemini-2.5-flash, gemini-2.5-flash-lite.
Use flash-lite for highest free-tier quota (1,000 RPD).
required: false
default: 'gemini-3.1-flash-lite-preview'
version:
description: |
The version of @google/gemini-cli to execute.
Can be a specific version from npm (e.g., '0.1.0', 'latest'), a branch name (e.g., 'main'), or a commit hash.
required: false
default: 'latest'
runs:
using: "composite"
steps:
- name: Configure Gemini CLI
if: inputs.settings_json != ''
run: |
mkdir -p .gemini
echo "$SETTINGS_JSON" > .gemini/settings.json
shell: bash
env:
SETTINGS_JSON: ${{ inputs.settings_json }}
- name: Authenticate to Google Cloud for Telemetry
if: inputs.OTLP_GCP_WIF_PROVIDER != ''
id: auth
uses: 'google-github-actions/auth@v2'
with:
project_id: ${{ inputs.OTLP_GOOGLE_CLOUD_PROJECT }}
workload_identity_provider: ${{ inputs.OTLP_GCP_WIF_PROVIDER }}
- name: Install Gemini CLI
id: install
env:
INPUT_VERSION: ${{ inputs.version }}
run: |
if [[ "$INPUT_VERSION" == "latest" || "$INPUT_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9\.-]+)?(\+[a-zA-Z0-9\.-]+)?$ ]]; then
echo "Installing Gemini CLI from npm: @google/gemini-cli@$INPUT_VERSION"
npm install -g @google/gemini-cli@$INPUT_VERSION
else
echo "Installing Gemini CLI from GitHub: github:google-gemini/gemini-cli#$INPUT_VERSION"
npm install -g github:google-gemini/gemini-cli#$INPUT_VERSION
fi
echo "Verifying installation:"
if command -v gemini >/dev/null 2>&1; then
gemini --version || echo "Gemini CLI installed successfully (version command not available)"
else
echo "Error: Gemini CLI not found in PATH"
exit 1
fi
shell: bash
- name: Run Gemini CLI
run: |
gemini --yolo --model "$GEMINI_MODEL" --prompt "$PROMPT"
shell: bash
env:
GEMINI_API_KEY: ${{ inputs.GEMINI_API_KEY }}
GEMINI_MODEL: ${{ inputs.model }}
PROMPT: ${{ inputs.prompt }}
branding:
icon: 'terminal'
color: 'blue'
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 285 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 872 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 167 KiB

-72
View File
@@ -1,72 +0,0 @@
framework: "praisonai"
process: workflow
topic: "Autonomous Issue Resolution"
planning: false
roles:
issue_analyst:
role: "GitHub Issue Analyst"
goal: "Read the GitHub issue, understand the required changes, and map the problem to the local codebase"
backstory: "You are an expert software analyst who reads bug reports and feature requests. You excel at taking a problem description and finding exactly which files in the codebase need to be modified. Your primary job is discovery and planning."
tools:
- "execute_command"
software_engineer:
role: "Autonomous Software Engineer"
goal: "Implement required code changes on a branch, run tests, commit, and push"
backstory: "You are a senior software engineer. You always branch first, implement changes using shell commands, verify with git diff, run tests, then commit and push. You never create a Pull Request unless the issue body explicitly requests one."
tools:
- "execute_command"
- "github_create_branch"
- "github_commit_and_push"
- "github_create_pull_request"
steps:
- name: Analyze Issue
agent: issue_analyst
action: >
Thoroughly analyze the issue and the repository. Follow these steps in order.
First, set up git identity: execute_command 'git config user.name PraisonAI' then
execute_command 'git config user.email [email protected]'. Do NOT pass cwd.
Second, read the issue: execute_command 'cat .github/triage-context.md'. Do NOT pass cwd.
Third, read architecture guidelines: execute_command 'cat src/praisonai-agents/AGENTS.md'.
Fourth, decide if this issue requires code changes:
- If YES: identify the exact files and lines that must change. Output a concrete file-level plan.
- If NO (question, discussion, duplicate, invalid): say so clearly. No code changes needed.
Output: routing decision (Core SDK / Wrapper / Tools / No-change), validation result, and exact files/lines to change.
expected_output: A decision on whether code changes are needed, and if so a concrete file-level plan.
- name: Implement Fix
agent: software_engineer
action: >
You are working inside the repository at /Users/praison/praisonai-package.
Do NOT ask for confirmation. Do NOT use placeholder paths. Act immediately.
Read the analyst's output first. If the analyst said NO code changes are needed, stop here and
output a brief explanation — do NOT create a branch or PR.
If code changes ARE needed, follow these steps:
Step 1 — Create branch: github_create_branch with branch_name=praisonai/issue-{{ISSUE_NUMBER}}.
Step 2 — Implement changes using execute_command (no cwd argument).
To insert a line: python3 -c "lines=open('FILE').readlines(); lines.insert(N,'LINE\n'); open('FILE','w').writelines(lines)"
To replace text: python3 -c "t=open('FILE').read(); open('FILE','w').write(t.replace('OLD','NEW'))"
After each edit verify: execute_command 'git diff'
Step 3 — Run tests: execute_command 'python3 -m pytest src/praisonai-agents/tests/ -x -q --timeout=30 -p no:warnings'
Step 4 — Commit and push: github_commit_and_push with a descriptive commit_message.
Step 5 — Check if the issue body EXPLICITLY contains the phrase "create pull request" or "create PR"
(case-insensitive). ONLY in that case create a PR using github_create_pull_request with
title='fix: resolve issue #{{ISSUE_NUMBER}}',
body='Fixes #{{ISSUE_NUMBER}}.\n\nAutonomously resolved by PraisonAI.',
head_branch=praisonai/issue-{{ISSUE_NUMBER}}, base_branch=main.
Otherwise do NOT create a PR — just confirm the branch was pushed successfully.
expected_output: Either "No code changes needed", or "Branch pushed, no PR requested", or "Branch pushed and PR created at URL".
-116
View File
@@ -1,116 +0,0 @@
framework: "praisonai"
topic: "Pull Request Code Review Analysis"
roles:
security_reviewer:
role: "Security Code Reviewer"
goal: "Identify security vulnerabilities, authentication issues, input validation problems, and unsafe code practices in the PR changes"
backstory: "You are a cybersecurity expert specializing in code analysis. You have extensive experience in identifying common security flaws like injection attacks, authentication bypasses, exposed secrets, and unsafe data handling patterns."
tools:
- "execute_command"
performance_reviewer:
role: "Performance Code Reviewer"
goal: "Analyze code changes for performance implications, identify bottlenecks, inefficient algorithms, and resource usage issues"
backstory: "You are a performance optimization specialist with deep knowledge of algorithm efficiency, memory management, and system performance. You excel at spotting code that could cause performance degradation."
tools:
- "execute_command"
maintainability_reviewer:
role: "Code Quality & Maintainability Reviewer"
goal: "Evaluate code structure, readability, documentation, naming conventions, and adherence to best practices"
backstory: "You are a software engineering expert focused on code quality and maintainability. You ensure code follows established patterns, is well-documented, and will be easy for future developers to understand and modify."
tools:
- "execute_command"
lead_reviewer:
role: "Lead Technical Reviewer"
goal: "Synthesize all review feedback, make final recommendations, and post comprehensive review comments to the GitHub PR"
backstory: "You are a senior technical lead responsible for final review decisions. You coordinate input from security, performance, and maintainability reviewers to provide balanced, actionable feedback to the development team."
tools:
- "execute_command"
steps:
- name: security_analysis
agent: security_reviewer
action: |
Analyze the PR diff for security issues:
1. Extract PR details: `echo "$PR_DATA"`
2. Get changed files: `echo "$CHANGED_FILES"`
3. Review full diff: `gh pr diff ${PR_NUMBER}`
4. Look for:
- Hardcoded secrets, API keys, passwords
- SQL injection vulnerabilities
- XSS vulnerabilities
- Authentication/authorization bypasses
- Unsafe file operations
- Command injection risks
- Missing input validation
- Exposed sensitive data
5. Document findings with file paths and line numbers
expected_output: "Detailed security analysis report with specific vulnerabilities found, severity levels, and remediation suggestions"
- name: performance_analysis
agent: performance_reviewer
action: |
Analyze the PR diff for performance issues:
1. Review algorithm complexity changes
2. Check for inefficient database queries
3. Identify memory leaks or excessive allocations
4. Look for hot-path regressions
5. Check for blocking I/O operations
6. Analyze module-level imports that could slow startup
7. Review caching implementations
8. Check for recursive operations without termination
9. Document performance concerns with impact estimates
expected_output: "Performance analysis report highlighting bottlenecks, efficiency concerns, and optimization recommendations"
- name: maintainability_analysis
agent: maintainability_reviewer
action: |
Analyze the PR diff for code quality and maintainability:
1. Check naming conventions consistency
2. Evaluate code structure and organization
3. Review documentation completeness
4. Check for DRY violations
5. Analyze error handling patterns
6. Review test coverage for changes
7. Check adherence to repository coding standards
8. Evaluate API design consistency
9. Look for technical debt introduction
expected_output: "Code quality analysis with specific recommendations for improving maintainability and readability"
- name: final_review
agent: lead_reviewer
action: |
Synthesize all reviews and post final comprehensive feedback:
1. Collect input from security, performance, and maintainability reviews
2. Prioritize findings by severity (Critical, High, Medium, Low)
3. Create structured review comment using this format:
## 📋 Review Summary
[2-3 sentence overview and assessment]
## 🔍 General Feedback
[Overall patterns and observations]
## 🎯 Specific Feedback
### 🔴 Critical (if any)
[Security vulnerabilities, breaking changes, major bugs]
### 🟡 High (if any)
[Performance issues, design flaws, significant bugs]
### 🟢 Medium (if any)
[Code quality improvements, minor optimizations]
### 🔵 Low (if any)
[Documentation, naming suggestions, minor refactoring]
## ✅ Highlights (if any)
[Positive aspects worth mentioning]
4. Post comprehensive review: `echo "[REVIEW_CONTENT]" | gh pr comment ${PR_NUMBER} -F -`
5. If critical issues found, suggest not merging until resolved
expected_output: "Final review comment posted to GitHub PR with comprehensive analysis from all reviewers"
dependencies: [security_analysis, performance_analysis, maintainability_analysis]
-3
View File
@@ -1,3 +0,0 @@
# GitHub Issue #1350: Add debug log on successful branch checkout
The github_create_branch function in src/praisonai-agents/praisonaiagents/tools/github_tools.py should call logger.debug after a successful checkout.
-46
View File
@@ -1,46 +0,0 @@
name: Auto Issue Comment
on:
workflow_dispatch:
# issues:
# types: [opened]
jobs:
# Trigger Claude by adding the 'claude' label (only if not already labeled)
# Note: @claude in comments only works from human users (not bots)
# The claude.yml workflow listens for issues:labeled event with 'claude' label
trigger-claude:
# Skip if issue was already created with 'claude' label to avoid double-trigger
if: |
!contains(toJSON(github.event.issue.labels), 'claude')
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Add claude label to trigger analysis
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GH_TOKEN }}
script: |
// Check if 'claude' label already exists on this issue
const labels = context.payload.issue.labels.map(l => l.name);
if (labels.includes('claude')) {
console.log('Issue already has claude label, skipping');
return;
}
// Add label to trigger claude.yml via issues:labeled event
await github.rest.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: ['claude']
});
// Also post instructions as a comment for context
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '🤖 Auto-triaging with Claude. Analyzing issue and implementing a fix...\n\nClaude will:\n1. Classify this issue\n2. Search codebase for root cause\n3. Implement a minimal fix following AGENTS.md\n4. Create a PR with the changes'
});
-525
View File
@@ -1,525 +0,0 @@
name: Auto PR Comment
# Review chain: CodeRabbit/Qodo/Gemini review first → Copilot → Claude (final)
# For human PRs: CodeRabbit/Qodo auto-review → this workflow triggers Copilot → then Claude
# For bot PRs: CodeRabbit/Qodo skip bots, so we trigger them explicitly first
#
# IMPORTANT: @copilot ignores bot comments. All @copilot mentions must use
# PAT_TOKEN so the comment posts as MervinPraison (a real user).
#
# Claude trigger runs IN-BAND (same workflow) to avoid GitHub Actions
# blocking bot-triggered workflows with action_required approval gates.
on:
issue_comment:
types: [created]
pull_request_review:
types: [submitted]
pull_request:
types: [opened]
env:
MAX_POLL_ATTEMPTS: 20
POLL_DELAY_MS: 30000
CLAUDE_TRIGGER_LOGINS: '["MervinPraison","github-actions[bot]"]'
jobs:
# ================================================================
# HUMAN PRs: Trigger @copilot AFTER CodeRabbit posts its summary
# ================================================================
copilot-after-coderabbit:
if: |
github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
github.event.comment.user.login == 'coderabbitai[bot]' &&
contains(github.event.comment.body, 'summarize by coderabbit')
runs-on: ubuntu-latest
permissions:
pull-requests: write
outputs:
pr_number: ${{ steps.trigger.outputs.pr_number }}
triggered: ${{ steps.trigger.outputs.triggered }}
steps:
- name: Post Copilot review request (as user via PAT)
id: trigger
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GH_TOKEN }}
script: |
const comments = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
// Check for duplicates — posted by MervinPraison (PAT) or github-actions[bot] (legacy)
const alreadyPosted = comments.data.some(c =>
c.body.includes('@copilot') &&
(c.user.login === 'MervinPraison' || c.user.login === 'github-actions[bot]')
);
if (alreadyPosted) {
console.log('Copilot already triggered, skipping');
core.setOutput('triggered', 'false');
core.setOutput('pr_number', context.issue.number.toString());
return;
}
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '@copilot Do a thorough review of this PR. Read ALL existing reviewer comments above from Qodo, Coderabbit, and Gemini first — incorporate their findings.\n\nReview areas:\n1. **Bloat check**: Are changes minimal and focused? Any unnecessary code or scope creep?\n2. **Security**: Any hardcoded secrets, unsafe eval/exec, missing input validation?\n3. **Performance**: Any module-level heavy imports? Hot-path regressions?\n4. **Tests**: Are tests included? Do they cover the changes adequately?\n5. **Backward compat**: Any public API changes without deprecation?\n6. **Code quality**: DRY violations, naming conventions, error handling?\n7. **Address reviewer feedback**: If Qodo, Coderabbit, or Gemini flagged valid issues, include them in your review\n8. Suggest specific improvements with code examples where possible'
});
core.setOutput('triggered', 'true');
core.setOutput('pr_number', context.issue.number.toString());
# Fallback: Trigger @copilot after Qodo review (if Coderabbit doesn't fire)
copilot-after-qodo:
if: |
github.event_name == 'pull_request_review' &&
github.event.review.user.login == 'qodo-code-review[bot]'
runs-on: ubuntu-latest
permissions:
pull-requests: write
outputs:
pr_number: ${{ steps.trigger.outputs.pr_number }}
triggered: ${{ steps.trigger.outputs.triggered }}
steps:
- name: Post Copilot review request (as user via PAT)
id: trigger
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GH_TOKEN }}
script: |
const comments = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const alreadyPosted = comments.data.some(c =>
c.body.includes('@copilot') &&
(c.user.login === 'MervinPraison' || c.user.login === 'github-actions[bot]')
);
if (alreadyPosted) {
console.log('Copilot already triggered, skipping');
core.setOutput('triggered', 'false');
core.setOutput('pr_number', context.issue.number.toString());
return;
}
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '@copilot Do a thorough review of this PR. Read ALL existing reviewer comments above first.\n\nReview areas:\n1. **Bloat check**: Are changes minimal and focused?\n2. **Security**: Any hardcoded secrets, unsafe eval/exec, missing input validation?\n3. **Performance**: Any module-level heavy imports? Hot-path regressions?\n4. **Tests**: Are tests included? Do they cover the changes adequately?\n5. **Backward compat**: Any public API changes without deprecation?\n6. **Code quality**: DRY violations, naming conventions, error handling?\n7. Suggest specific improvements with code examples where possible'
});
core.setOutput('triggered', 'true');
core.setOutput('pr_number', context.issue.number.toString());
# ================================================================
# FALLBACK: Claude trigger for cases where Copilot chain fails/skips
# Ensures Claude always runs after sufficient review time
# ================================================================
claude-fallback-timeout:
if: |
github.event_name == 'pull_request' &&
github.event.action == 'opened'
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
issues: write
pull-requests: write
steps:
- name: Wait for review window (15 min)
run: sleep 900
- name: Check if Claude already triggered
id: check_claude
uses: actions/github-script@v7
env:
TRIGGER_LOGINS: ${{ env.CLAUDE_TRIGGER_LOGINS }}
with:
github-token: ${{ secrets.GH_TOKEN }}
script: |
const triggerLogins = JSON.parse(process.env.TRIGGER_LOGINS);
const comments = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const alreadyPosted = comments.data.some(c =>
c.body.includes('@claude') && triggerLogins.includes(c.user.login)
);
core.setOutput('already_triggered', alreadyPosted ? 'true' : 'false');
core.setOutput('comments_count', comments.data.length.toString());
// Collect all bot reviewer comments for context
const botReviews = comments.data.filter(c =>
['coderabbitai[bot]', 'qodo-code-review[bot]', 'gemini-code-assist[bot]',
'copilot-swe-agent', 'Copilot', 'greptile-apps[bot]'].some(bot =>
c.user.login.toLowerCase().includes(bot.toLowerCase())
)
);
core.setOutput('review_count', botReviews.length.toString());
- name: Aggregate reviews and trigger Claude
if: steps.check_claude.outputs.already_triggered != 'true'
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GH_TOKEN }}
script: |
const comments = await github.rest.issues.listComments({issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, per_page: 100});
const reviews = {coderabbit: [], qodo: [], gemini: [], copilot: [], greptile: [], others: []};
comments.data.forEach(c => {
const login = c.user.login.toLowerCase();
const body = c.body.substring(0, 500);
if (login.includes('coderabbit')) reviews.coderabbit.push(body);
else if (login.includes('qodo')) reviews.qodo.push(body);
else if (login.includes('gemini')) reviews.gemini.push(body);
else if (login.includes('copilot')) reviews.copilot.push(body);
else if (login.includes('greptile')) reviews.greptile.push(body);
else if (c.user.type === 'Bot') reviews.others.push(body);
});
const summaryParts = [];
if (reviews.coderabbit.length) summaryParts.push('CodeRabbit: ' + reviews.coderabbit.length + ' comments');
if (reviews.qodo.length) summaryParts.push('Qodo: ' + reviews.qodo.length + ' comments');
if (reviews.gemini.length) summaryParts.push('Gemini: ' + reviews.gemini.length + ' comments');
if (reviews.copilot.length) summaryParts.push('Copilot: ' + reviews.copilot.length + ' comments');
if (reviews.greptile.length) summaryParts.push('Greptile: ' + reviews.greptile.length + ' comments');
const reviewSummary = summaryParts.length ? summaryParts.join(' | ') : 'No bot reviews detected';
const claudeBody = '@claude You are the FINAL architecture reviewer. If the branch is under MervinPraison/PraisonAI (not a fork), you are able to make modifications to this branch and push directly. SCOPE: Focus ONLY on Python packages (praisonaiagents, praisonai). Do NOT modify praisonai-rust or praisonai-ts. ' + reviewSummary + '.\n\n' +
'Review Context: ' + comments.data.length + ' total comments, ' +
(reviews.coderabbit.length + reviews.qodo.length + reviews.gemini.length + reviews.copilot.length + reviews.greptile.length) + ' bot reviews.\n\n' +
'Phase 1: Review per AGENTS.md principles (protocol-driven, backward compatible, no perf impact).\n' +
'Phase 2: FIX valid issues found by prior reviewers.\n' +
'Phase 3: Provide final verdict (approve or request changes).';
await github.rest.issues.createComment({issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: claudeBody});
console.log('Claude fallback triggered on PR #' + context.issue.number + ' with ' + reviewSummary);
# ================================================================
# Claude FINAL review — polls for Copilot's response, then triggers
# This runs IN-BAND under the PAT context (MervinPraison), avoiding
# the action_required approval gate that blocks bot-triggered workflows.
# ================================================================
claude-after-copilot:
needs: [copilot-after-coderabbit]
if: |
always() &&
needs.copilot-after-coderabbit.result == 'success' &&
needs.copilot-after-coderabbit.outputs.triggered == 'true'
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
issues: write
pull-requests: write
steps:
- name: Wait for Copilot to respond (poll)
id: poll
uses: actions/github-script@v7
env:
PR_NUMBER: ${{ needs.copilot-after-coderabbit.outputs.pr_number }}
MAX_POLL_ATTEMPTS: ${{ env.MAX_POLL_ATTEMPTS }}
POLL_DELAY_MS: ${{ env.POLL_DELAY_MS }}
with:
github-token: ${{ secrets.GH_TOKEN }}
script: |
const pr = parseInt(process.env.PR_NUMBER, 10);
const owner = context.repo.owner;
const repo = context.repo.repo;
// Poll for Copilot's response — check every 30s for up to 10 minutes
const maxAttempts = parseInt(process.env.MAX_POLL_ATTEMPTS, 10);
const delayMs = parseInt(process.env.POLL_DELAY_MS, 10);
for (let i = 0; i < maxAttempts; i++) {
console.log(`Poll attempt ${i + 1}/${maxAttempts}...`);
const comments = await github.rest.issues.listComments({
issue_number: pr,
owner,
repo,
per_page: 50,
sort: 'created',
direction: 'desc'
});
// Look for Copilot's response (copilot-swe-agent or Copilot)
const copilotResponse = comments.data.find(c =>
(c.user.login === 'copilot-swe-agent' ||
c.user.login === 'Copilot' ||
c.user.login.toLowerCase().includes('copilot')) &&
c.user.type === 'Bot'
);
if (copilotResponse) {
console.log(`Copilot responded at ${copilotResponse.created_at}`);
core.setOutput('copilot_responded', 'true');
return;
}
// Also check PR reviews for Copilot
const reviews = await github.rest.pulls.listReviews({
pull_number: pr,
owner,
repo
});
const copilotReview = reviews.data.find(r =>
r.user.login.toLowerCase().includes('copilot')
);
if (copilotReview) {
console.log(`Copilot review submitted at ${copilotReview.submitted_at}`);
core.setOutput('copilot_responded', 'true');
return;
}
if (i < maxAttempts - 1) {
console.log(`Copilot hasn't responded yet, waiting ${delayMs/1000}s...`);
await new Promise(resolve => setTimeout(resolve, delayMs));
}
}
console.log('Copilot did not respond within timeout, triggering Claude anyway');
core.setOutput('copilot_responded', 'timeout');
- name: Check if Claude already triggered
id: check_claude
uses: actions/github-script@v7
env:
PR_NUMBER: ${{ needs.copilot-after-coderabbit.outputs.pr_number }}
TRIGGER_LOGINS: ${{ env.CLAUDE_TRIGGER_LOGINS }}
with:
github-token: ${{ secrets.GH_TOKEN }}
script: |
const pr = parseInt(process.env.PR_NUMBER, 10);
const triggerLogins = JSON.parse(process.env.TRIGGER_LOGINS);
const comments = await github.rest.issues.listComments({
issue_number: pr,
owner: context.repo.owner,
repo: context.repo.repo
});
const alreadyPosted = comments.data.some(c =>
c.body.includes('@claude') && triggerLogins.includes(c.user.login)
);
core.setOutput('already_triggered', alreadyPosted ? 'true' : 'false');
- name: Trigger Claude final review
if: steps.check_claude.outputs.already_triggered != 'true'
uses: actions/github-script@v7
env:
PR_NUMBER: ${{ needs.copilot-after-coderabbit.outputs.pr_number }}
with:
github-token: ${{ secrets.GH_TOKEN }}
script: |
const pr = parseInt(process.env.PR_NUMBER, 10);
await github.rest.issues.createComment({
issue_number: pr,
owner: context.repo.owner,
repo: context.repo.repo,
body: '@claude You are the FINAL architecture reviewer. If the branch is under MervinPraison/PraisonAI (not a fork), you are able to make modifications to this branch and push directly. SCOPE: Focus ONLY on Python packages (praisonaiagents, praisonai). Do NOT modify praisonai-rust or praisonai-ts. Read ALL comments above from Gemini, Qodo, CodeRabbit, and Copilot carefully before responding.\n\n**Phase 1: Review per AGENTS.md**\n1. Protocol-driven: check heavy implementations vs core SDK\n2. Backward compatible: ensure zero feature regressions\n3. Performance: no hot-path regressions\n\n**Phase 2: FIX Valid Issues**\n4. For any VALID bugs or architectural flaws found by Gemini, CodeRabbit, Qodo, Copilot, or any other reviewer: implement the fix\n5. Push all code fixes directly to THIS branch (do NOT create a new PR)\n6. Comment a summary of exact files modified and what you skipped\n\n**Phase 3: Final Verdict**\n7. If all issues are resolved, approve the PR / close the Issue\n8. If blocking issues remain, request changes / leave clear action items'
});
console.log(`Claude triggered on PR #${pr}`);
# ================================================================
# Claude after Qodo fallback path (same polling approach)
# ================================================================
claude-after-copilot-qodo:
needs: [copilot-after-qodo]
if: |
always() &&
needs.copilot-after-qodo.result == 'success' &&
needs.copilot-after-qodo.outputs.triggered == 'true'
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
issues: write
pull-requests: write
steps:
- name: Wait for Copilot to respond (poll)
id: poll
uses: actions/github-script@v7
env:
PR_NUMBER: ${{ needs.copilot-after-qodo.outputs.pr_number }}
MAX_POLL_ATTEMPTS: ${{ env.MAX_POLL_ATTEMPTS }}
POLL_DELAY_MS: ${{ env.POLL_DELAY_MS }}
with:
github-token: ${{ secrets.GH_TOKEN }}
script: |
const pr = parseInt(process.env.PR_NUMBER, 10);
const owner = context.repo.owner;
const repo = context.repo.repo;
const maxAttempts = parseInt(process.env.MAX_POLL_ATTEMPTS, 10);
const delayMs = parseInt(process.env.POLL_DELAY_MS, 10);
for (let i = 0; i < maxAttempts; i++) {
console.log(`Poll attempt ${i + 1}/${maxAttempts}...`);
const comments = await github.rest.issues.listComments({
issue_number: pr, owner, repo,
per_page: 50, sort: 'created', direction: 'desc'
});
const copilotResponse = comments.data.find(c =>
(c.user.login === 'copilot-swe-agent' ||
c.user.login === 'Copilot' ||
c.user.login.toLowerCase().includes('copilot')) &&
c.user.type === 'Bot'
);
if (copilotResponse) {
console.log(`Copilot responded at ${copilotResponse.created_at}`);
core.setOutput('copilot_responded', 'true');
return;
}
const reviews = await github.rest.pulls.listReviews({
pull_number: pr, owner, repo
});
const copilotReview = reviews.data.find(r =>
r.user.login.toLowerCase().includes('copilot')
);
if (copilotReview) {
console.log(`Copilot review submitted at ${copilotReview.submitted_at}`);
core.setOutput('copilot_responded', 'true');
return;
}
if (i < maxAttempts - 1) {
await new Promise(resolve => setTimeout(resolve, delayMs));
}
}
console.log('Copilot did not respond within timeout, triggering Claude anyway');
core.setOutput('copilot_responded', 'timeout');
- name: Check if Claude already triggered
id: check_claude
uses: actions/github-script@v7
env:
PR_NUMBER: ${{ needs.copilot-after-qodo.outputs.pr_number }}
TRIGGER_LOGINS: ${{ env.CLAUDE_TRIGGER_LOGINS }}
with:
github-token: ${{ secrets.GH_TOKEN }}
script: |
const pr = parseInt(process.env.PR_NUMBER, 10);
const triggerLogins = JSON.parse(process.env.TRIGGER_LOGINS);
const comments = await github.rest.issues.listComments({
issue_number: pr,
owner: context.repo.owner,
repo: context.repo.repo
});
const alreadyPosted = comments.data.some(c =>
c.body.includes('@claude') && triggerLogins.includes(c.user.login)
);
core.setOutput('already_triggered', alreadyPosted ? 'true' : 'false');
- name: Trigger Claude final review
if: steps.check_claude.outputs.already_triggered != 'true'
uses: actions/github-script@v7
env:
PR_NUMBER: ${{ needs.copilot-after-qodo.outputs.pr_number }}
with:
github-token: ${{ secrets.GH_TOKEN }}
script: |
const pr = parseInt(process.env.PR_NUMBER, 10);
await github.rest.issues.createComment({
issue_number: pr,
owner: context.repo.owner,
repo: context.repo.repo,
body: '@claude You are the FINAL architecture reviewer. If the branch is under MervinPraison/PraisonAI (not a fork), you are able to make modifications to this branch and push directly. SCOPE: Focus ONLY on Python packages (praisonaiagents, praisonai). Do NOT modify praisonai-rust or praisonai-ts. Read ALL comments above from Gemini, Qodo, CodeRabbit, and Copilot carefully before responding.\n\n**Phase 1: Review per AGENTS.md**\n1. Protocol-driven: check heavy implementations vs core SDK\n2. Backward compatible: ensure zero feature regressions\n3. Performance: no hot-path regressions\n\n**Phase 2: FIX Valid Issues**\n4. For any VALID bugs or architectural flaws found by Gemini, CodeRabbit, Qodo, Copilot, or any other reviewer: implement the fix\n5. Push all code fixes directly to THIS branch (do NOT create a new PR)\n6. Comment a summary of exact files modified and what you skipped\n\n**Phase 3: Final Verdict**\n7. If all issues are resolved, approve the PR / close the Issue\n8. If blocking issues remain, request changes / leave clear action items'
});
console.log(`Claude triggered on PR #${pr}`);
# ================================================================
# Claude after Gemini — restores the trigger lost from the deleted
# chain-claude-after-copilot.yml workflow.
# Fires when Gemini posts a review comment on a PR or issue.
# ================================================================
claude-after-gemini:
if: |
github.event_name == 'issue_comment' &&
(
github.event.comment.user.login == 'gemini-code-assist[bot]' ||
contains(github.event.comment.body, 'Review completed by Gemini CLI') ||
contains(github.event.comment.body, 'The fix is ready for review. Please test')
)
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- name: Check if Claude already triggered
id: check_claude
uses: actions/github-script@v7
env:
TRIGGER_LOGINS: ${{ env.CLAUDE_TRIGGER_LOGINS }}
with:
github-token: ${{ secrets.GH_TOKEN }}
script: |
const triggerLogins = JSON.parse(process.env.TRIGGER_LOGINS);
const comments = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo
});
const alreadyPosted = comments.data.some(c =>
c.body.includes('@claude') && triggerLogins.includes(c.user.login)
);
core.setOutput('already_triggered', alreadyPosted ? 'true' : 'false');
- name: Post Claude analysis request (Lead Engineer)
if: steps.check_claude.outputs.already_triggered != 'true'
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GH_TOKEN }}
script: |
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '@claude You are the Lead Engineer. If the branch is under MervinPraison/PraisonAI (not a fork), you are able to make modifications to this branch and push directly. SCOPE: Focus ONLY on Python packages (praisonaiagents, praisonai). Do NOT modify praisonai-rust or praisonai-ts. Read ALL analysis and reviews above carefully (Gemini, CodeRabbit, Qodo, Copilot, etc).\n\n**Phase 1: Review per AGENTS.md**\n1. Protocol-driven: check heavy implementations vs core SDK\n2. Backward compatible: ensure zero feature regressions\n3. Performance: no hot-path regressions\n\n**Phase 2: FIX Valid Issues**\n4. For any VALID bugs or architectural flaws found by Gemini, CodeRabbit, Qodo, Copilot, or any other reviewer: implement the fix\n5. Push all code fixes directly to THIS branch (do NOT create a new PR)\n6. Comment a summary of exact files modified and what you skipped\n\n**Phase 3: Final Verdict**\n7. If all issues are resolved, approve the PR / close the Issue\n8. If blocking issues remain, request changes / leave clear action items'
});
# ================================================================
# BOT PRs: CodeRabbit/Qodo skip bot-authored PRs by default.
# Trigger them explicitly. Do NOT trigger Copilot here — it will
# be triggered by copilot-after-coderabbit/qodo when they finish.
# ================================================================
bot-pr-trigger-reviews:
if: |
github.event_name == 'pull_request' &&
github.event.action == 'opened' &&
(
github.event.pull_request.user.login == 'github-actions[bot]' ||
github.event.pull_request.user.login == 'praisonai-triage-agent[bot]' ||
github.event.pull_request.user.type == 'Bot'
)
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: Trigger CodeRabbit and Qodo reviews
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GH_TOKEN }}
script: |
const pr = context.payload.pull_request.number;
const owner = context.repo.owner;
const repo = context.repo.repo;
// 1. Trigger CodeRabbit review
await github.rest.issues.createComment({
issue_number: pr, owner, repo,
body: '@coderabbitai review'
});
console.log(`Triggered CodeRabbit for bot PR #${pr}`);
// 2. Trigger Qodo review
await github.rest.issues.createComment({
issue_number: pr, owner, repo,
body: '/review'
});
console.log(`Triggered Qodo for bot PR #${pr}`);
// 3. Trigger Gemini review (commented out)
// await github.rest.issues.createComment({
// issue_number: pr, owner, repo,
// body: '@gemini review this PR'
// });
// console.log(`Triggered Gemini for bot PR #${pr}`);
// NOTE: @copilot is NOT triggered here.
// It will be triggered by copilot-after-coderabbit or copilot-after-qodo
// once those bots finish, ensuring Copilot always reviews LAST.
console.log('Copilot will be triggered after CodeRabbit/Qodo complete.');
-153
View File
@@ -1,153 +0,0 @@
name: Performance Benchmarks
on:
workflow_dispatch:
inputs:
iterations:
description: 'Number of benchmark iterations'
required: false
default: '100'
fail_on_regression:
description: 'Fail if performance regresses'
required: false
default: 'true'
jobs:
benchmark:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e src/praisonai-agents[all]
pip install agno crewai langgraph
- name: Run Import Time Benchmark
id: import_time
env:
FAIL_ON_REGRESSION: ${{ inputs.fail_on_regression }}
run: |
cd src/praisonai-agents
python benchmarks/import_time.py 2>&1 | tee import_time_output.txt
# Extract import time
IMPORT_TIME=$(grep -oP 'Median:\s+\K[\d.]+' import_time_output.txt || echo "0")
echo "import_time=$IMPORT_TIME" >> $GITHUB_OUTPUT
# Check threshold (200ms)
if (( $(echo "$IMPORT_TIME > 200" | bc -l) )); then
echo "::warning::Import time ${IMPORT_TIME}ms exceeds 200ms threshold"
if [ "$FAIL_ON_REGRESSION" == "true" ]; then
echo "import_passed=false" >> $GITHUB_OUTPUT
fi
else
echo "import_passed=true" >> $GITHUB_OUTPUT
fi
- name: Run Memory Usage Benchmark
id: memory
env:
FAIL_ON_REGRESSION: ${{ inputs.fail_on_regression }}
run: |
cd src/praisonai-agents
python benchmarks/memory_usage.py 2>&1 | tee memory_output.txt
# Extract peak memory
PEAK_MEMORY=$(grep -oP 'Peak:\s+\K[\d.]+' memory_output.txt || echo "0")
echo "peak_memory=$PEAK_MEMORY" >> $GITHUB_OUTPUT
# Check threshold (30MB)
if (( $(echo "$PEAK_MEMORY > 30" | bc -l) )); then
echo "::warning::Memory usage ${PEAK_MEMORY}MB exceeds 30MB threshold"
if [ "$FAIL_ON_REGRESSION" == "true" ]; then
echo "memory_passed=false" >> $GITHUB_OUTPUT
fi
else
echo "memory_passed=true" >> $GITHUB_OUTPUT
fi
- name: Run Simple Benchmark
id: simple
run: |
cd src/praisonai-agents
python benchmarks/simple_benchmark.py 2>&1 | tee simple_output.txt
# Extract PraisonAI time
PRAISON_TIME=$(grep -oP 'PraisonAI\s+\K[\d.]+' simple_output.txt | head -1 || echo "0")
echo "praison_time=$PRAISON_TIME" >> $GITHUB_OUTPUT
- name: Run Tools Benchmark
id: tools
run: |
cd src/praisonai-agents
python benchmarks/tools_benchmark.py 2>&1 | tee tools_output.txt
# Extract PraisonAI time with tools
PRAISON_TOOLS_TIME=$(grep -oP 'PraisonAI\s+\K[\d.]+' tools_output.txt | head -1 || echo "0")
echo "praison_tools_time=$PRAISON_TOOLS_TIME" >> $GITHUB_OUTPUT
- name: Run Parameter Impact Benchmark
id: param_impact
env:
INPUT_ITERATIONS: ${{ inputs.iterations }}
run: |
cd src/praisonai-agents
python benchmarks/param_impact_benchmark.py --no-save --iterations "$INPUT_ITERATIONS" 2>&1 | tee param_impact_output.txt
- name: Check Lazy Imports
id: lazy_imports
run: |
cd src/praisonai-agents
python -c "
import sys
from praisonaiagents import Agent
agent = Agent(name='Test', output='silent')
# Check litellm is NOT loaded
if 'litellm' in sys.modules:
print('FAIL: litellm loaded during silent agent creation')
exit(1)
else:
print('PASS: litellm not loaded (lazy import working)')
"
- name: Generate Benchmark Summary
if: always()
run: |
echo "## Performance Benchmark Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Metric | Value | Threshold | Status |" >> $GITHUB_STEP_SUMMARY
echo "|--------|-------|-----------|--------|" >> $GITHUB_STEP_SUMMARY
echo "| Import Time | ${{ steps.import_time.outputs.import_time }}ms | <200ms | ${{ steps.import_time.outputs.import_passed == 'true' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Peak Memory | ${{ steps.memory.outputs.peak_memory }}MB | <30MB | ${{ steps.memory.outputs.memory_passed == 'true' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Agent Instantiation | ${{ steps.simple.outputs.praison_time }}μs | - | ℹ️ |" >> $GITHUB_STEP_SUMMARY
echo "| Agent with Tools | ${{ steps.tools.outputs.praison_tools_time }}μs | - | ℹ️ |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Lazy Import Check" >> $GITHUB_STEP_SUMMARY
echo "✅ litellm not loaded during silent agent creation" >> $GITHUB_STEP_SUMMARY
- name: Fail on Regression
if: inputs.fail_on_regression == 'true'
run: |
if [ "${{ steps.import_time.outputs.import_passed }}" == "false" ]; then
echo "::error::Import time regression detected"
exit 1
fi
if [ "${{ steps.memory.outputs.memory_passed }}" == "false" ]; then
echo "::error::Memory usage regression detected"
exit 1
fi
echo "All performance checks passed!"
-43
View File
@@ -1,43 +0,0 @@
name: Build Claude Code Image
on:
workflow_dispatch:
inputs:
version:
description: 'Image version tag'
required: true
default: 'latest'
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GH_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./.github/actions/claude-code-action
push: true
platforms: linux/amd64
tags: ghcr.io/mervinpraison/praisonai-claudecode:${{ inputs.version }}
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: false
-35
View File
@@ -1,35 +0,0 @@
name: Claude Issue Triage
description: "Automatically triage GitHub issues using Claude Code"
on:
workflow_dispatch:
# issues:
# types: [opened]
jobs:
triage-issue:
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
issues: write
id-token: write
steps:
- name: Generate GitHub App Token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.CLAUDE_APP_ID }}
private-key: ${{ secrets.CLAUDE_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
token: ${{ steps.app-token.outputs.token }}
- name: Run Claude Issue Triage
uses: ./.github/actions/claude-issue-triage-action
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
github_token: ${{ steps.app-token.outputs.token }}
-21
View File
@@ -1,21 +0,0 @@
name: Claude OAuth
on:
workflow_dispatch:
inputs:
code:
description: 'Authorization code (leave empty for step 1)'
required: false
permissions:
actions: write # Required for cache management
contents: read # Required for basic repository access
jobs:
auth:
runs-on: ubuntu-latest
steps:
- uses: grll/claude-code-login@v1
with:
code: ${{ inputs.code }}
secrets_admin_pat: ${{ secrets.SECRETS_ADMIN_PAT }}
-294
View File
@@ -1,294 +0,0 @@
name: Claude Assistant
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [assigned, labeled, opened]
pull_request_review:
types: [submitted]
jobs:
# ================================================================
# Job 1: Lightweight triage for ALL new issues (including external users)
# Posts welcome comment + adds triage labels. No Claude code execution.
# ================================================================
issue-triage:
if: |
github.event_name == 'issues' &&
github.event.action == 'opened' &&
!contains(toJSON(github.event.issue.labels), 'claude')
runs-on: ubuntu-latest
permissions:
issues: write
contents: read
steps:
- name: Generate GitHub App Token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.CLAUDE_APP_ID }}
private-key: ${{ secrets.CLAUDE_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
- name: Triage and acknowledge issue
uses: actions/github-script@v7
with:
github-token: ${{ steps.app-token.outputs.token }}
script: |
const issue = context.payload.issue;
const title = (issue.title || '').toLowerCase();
const body = (issue.body || '').toLowerCase();
const content = title + ' ' + body;
const isOwner = ['OWNER', 'MEMBER', 'COLLABORATOR'].includes(
issue.author_association
);
// --- Label triage ---
const labels = [];
// Kind labels
if (content.includes('feature request') || content.includes('[feature')) {
labels.push('enhancement');
} else if (content.includes('bug') || content.includes('error') || content.includes('crash') || content.includes('traceback')) {
labels.push('bug');
} else if (content.includes('question') || content.includes('how do i') || content.includes('how to')) {
labels.push('question');
}
// Area labels
if (content.includes('security') || content.includes('cve') || content.includes('vulnerability')) {
labels.push('security');
}
if (content.includes('performance') || content.includes('slow') || content.includes('memory leak')) {
labels.push('performance');
}
if (content.includes('documentation') || content.includes('docs')) {
labels.push('documentation');
}
if (content.includes('typescript') || content.includes('javascript') || content.includes('npm')) {
labels.push('javascript');
}
// Apply labels
if (labels.length > 0) {
await github.rest.issues.addLabels({
issue_number: issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels
});
}
// --- Acknowledgment comment (external users only) ---
if (!isOwner) {
await github.rest.issues.createComment({
issue_number: issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: [
`👋 Thanks for opening this issue, @${issue.user.login}!`,
'',
'A maintainer will review this shortly. In the meantime:',
'- Make sure you\'ve included steps to reproduce (for bugs)',
'- Check [existing issues](https://github.com/MervinPraison/PraisonAI/issues) for duplicates',
'- Review the [documentation](https://docs.praison.ai) for related guides',
'',
'_A maintainer can trigger deeper analysis by commenting `@claude` on this issue._'
].join('\n')
});
}
// --- For owner: add 'claude' label to trigger the code-fix job ---
if (isOwner) {
await github.rest.issues.addLabels({
issue_number: issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: ['claude']
});
}
# ================================================================
# Job 2: Full Claude code-fix (owner/collaborator only)
# Triggers on: labeled 'claude', @claude comments, assignments
# ================================================================
claude-response:
# Allow: human users, github-actions[bot] (auto-comments/labels)
# Block: dependabot, cursor, renovate, other bots
# Skip 'opened' events — triage job handles those above
if: |
github.event.action != 'opened' &&
(github.event.action != 'labeled' || github.event.label.name == 'claude') &&
(github.event_name != 'issue_comment' || contains(github.event.comment.body, '@claude')) &&
(
!contains(github.actor, '[bot]') ||
github.actor == 'github-actions[bot]' ||
github.actor == 'praisonai-triage-agent[bot]'
) &&
github.actor != 'dependabot[bot]' &&
github.actor != 'cursor[bot]' &&
github.actor != 'renovate[bot]'
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
actions: read
id-token: write
steps:
- name: Generate GitHub App Token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.CLAUDE_APP_ID }}
private-key: ${{ secrets.CLAUDE_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
- name: Check for Fork PR
id: check_fork
uses: actions/github-script@v7
with:
script: |
const isPR = context.eventName === 'pull_request' || (context.payload.issue && context.payload.issue.pull_request);
if (isPR) {
const prNumber = context.payload.pull_request ? context.payload.pull_request.number : context.payload.issue.number;
const pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber
});
core.setOutput('pr_branch', pr.data.head.ref);
if (pr.data.head.repo && pr.data.head.repo.full_name !== context.repo.full_name) {
core.setOutput('is_fork', 'true');
core.setOutput('clone_url', pr.data.head.repo.clone_url);
core.setOutput('branch', pr.data.head.ref);
return;
}
}
core.setOutput('is_fork', 'false');
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false
fetch-depth: 0
token: ${{ steps.app-token.outputs.token }}
- name: Fetch PR branch and Setup Remote
if: github.event.issue.pull_request
env:
PR_BRANCH: ${{ steps.check_fork.outputs.pr_branch }}
IS_FORK: ${{ steps.check_fork.outputs.is_fork }}
run: |
# Fetch PR head from base repo and put it into local branch
git fetch origin pull/${{ github.event.issue.number }}/head:"${PR_BRANCH}"
# If it's a fork, make origin point to local to trick claude-code-action's `git fetch origin <branch>`
if [ "${IS_FORK}" = "true" ]; then
git remote set-url origin file://$(pwd)
fi
- uses: anthropics/claude-code-action@beta
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
with:
allowed_bots: 'praisonai-triage-agent[bot]'
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
github_token: ${{ steps.app-token.outputs.token }}
trigger_phrase: "@claude"
label_trigger: "claude"
direct_prompt: |
${{ steps.check_fork.outputs.is_fork == 'true' && 'CRITICAL: THIS IS A PULL REQUEST FROM A FORK. YOU DO NOT HAVE PUSH PERMISSIONS TO THIS REPOSITORY. ONLY READ FILES, VALIDATE CODE, AND PROVIDE YOUR COMMENTS/FEEDBACK DIRECTLY IN THIS PR VIA COMMENTS. DO NOT ATTEMPT TO PUSH OR CREATE PULL REQUESTS.\n\n' || 'NOTE: The branch is under MervinPraison/PraisonAI (not a fork). You are able to make modifications and push directly to this branch.\n\n' }}
You are working on the PraisonAI SDK. Follow AGENTS.md strictly.
STEP 0 — SETUP GIT IDENTITY & AUTH (GLOBAL — required for all repos):
git config --global user.name "MervinPraison"
git config --global user.email "[email protected]"
gh auth setup-git
STEP 1 — READ GUIDELINES:
Read AGENTS.md to understand the architecture rules.
SCOPE: Focus ONLY on Python packages (praisonaiagents, praisonai). Do NOT modify or touch praisonai-rust or praisonai-ts packages.
STEP 2 — ARCHITECTURE VALIDATION & ROUTING (MANDATORY before writing code):
Before implementing anything, answer these questions:
- CORE vs WRAPPER vs TOOLS vs DOCS vs PLUGINS ROUTING:
1. Core SDK (praisonaiagents/): Only core protocols, base classes, decorators. No heavy implementations.
2. Wrapper (praisonai/): CLI, heavy implementations, optional dependencies.
3. Tools (PraisonAI-Tools): Capabilities Agents actively call during execution (e.g. SurrealDB tool, Slack tool).
4. Documentation (PraisonAIDocs): Documentation pages, guides, API references.
5. Plugins (PraisonAI-Plugins): Framework lifecycle extensions replacing systemic behavior (e.g. tracing, logging, metrics, hooks, guardrails).
For items routed to an EXTERNAL repository (Tools, Docs, Plugins), follow STEP 3-ALT below.
- Does it duplicate existing functionality? Check if Agent already supports this via existing params (reflection, planning, tools, hooks, memory).
- Does it inherit from Agent properly? New agent types MUST inherit Agent, not wrap it with composition.
- Does it add new dependencies? Only optional deps allowed, must be lazy-imported.
- Will agent.py grow larger? If the change adds >50 lines to agent.py, find a way to extract instead.
- Is there a name collision with existing exports in __init__.py?
If ANY of these conceptual checks fail (excluding routing), add a comment to the issue explaining why and close it. Do NOT create a PR.
STEP 3 — IMPLEMENT (for changes in THIS repo — PraisonAI):
- Create a fix branch: git checkout -b claude/issue-$ISSUE_NUMBER-$(date +%Y%m%d)
- Implement a minimal, focused fix
- Follow protocol-driven design: protocols in core SDK, heavy implementations in wrapper
- Keep changes small and backward-compatible
- Commit: git add -A && git commit -m "fix: <description> (fixes #$ISSUE_NUMBER)"
- Push: git push origin claude/issue-$ISSUE_NUMBER-$(date +%Y%m%d)
CRITICAL: After pushing, you MUST immediately run: gh pr create --title "fix: <title>" --body "Fixes #$ISSUE_NUMBER" --head claude/issue-$ISSUE_NUMBER-$(date +%Y%m%d)
Do NOT stop after pushing. Do NOT say "manually create a PR". Always create the PR automatically.
STEP 3-ALT — IMPLEMENT IN EXTERNAL REPO (for PraisonAI-Tools, PraisonAIDocs, PraisonAI-Plugins):
When work must happen in a different repository, follow these steps EXACTLY. Do NOT attempt to use `cd`, as directory state is not preserved. Use `git -C` for all commands.
a) Clone the repository:
gh repo clone MervinPraison/<REPO_NAME> /tmp/<REPO_NAME>
b) Copy GitHub authentication from the main repository so push works seamlessly:
git -C /tmp/<REPO_NAME> config http."https://github.com/".extraheader "$(git config --get http."https://github.com/".extraheader)"
c) Create a feature branch (NEVER commit to main):
git -C /tmp/<REPO_NAME> checkout -b claude/issue-$ISSUE_NUMBER-$(date +%Y%m%d)
d) Make your changes using absolute paths (e.g. edit /tmp/<REPO_NAME>/docs.json)
e) Commit:
git -C /tmp/<REPO_NAME> add -A
git -C /tmp/<REPO_NAME> commit -m "feat: <description> (fixes #$ISSUE_NUMBER)"
f) Push the branch:
git -C /tmp/<REPO_NAME> push origin claude/issue-$ISSUE_NUMBER-$(date +%Y%m%d)
g) Create PR in the EXTERNAL repo:
gh pr create -R MervinPraison/<REPO_NAME> --head claude/issue-$ISSUE_NUMBER-$(date +%Y%m%d) --title "feat: <title>" --body "Fixes MervinPraison/PraisonAI#$ISSUE_NUMBER
<body>"
STEP 4 — TEST:
- For SDK changes: cd src/praisonai-agents && PYTHONPATH=. python -m pytest tests/ -x -q --timeout=30
- For docs changes: verify files exist and are valid markdown/MDX
- Ensure no regressions
STEP 5 — CREATE PR:
- Commit with descriptive message, push, and create PR using `gh pr create`
- For external repos, use `gh pr create -R MervinPraison/<REPO_NAME>`
CRITICAL: You MUST create the PR automatically using `gh pr create`. Do NOT just provide a link or say "manual push required".
NOTE: If you worked on an external repo, the wrapper action will report "No commits" for the main repo at the end. This is expected, do not worry about it.
allowed_tools: |
Bash(git:*)
Bash(python:*)
Bash(pip:*)
Bash(conda:*)
Bash(pytest:*)
Bash(gh:*)
Bash(python -m pytest:*)
Bash(python -m pip:*)
Bash(poetry:*)
View
GlobTool
GrepTool
BatchTool
Edit
Replace
mcp__github__get_issue
mcp__github__get_issue_comments
mcp__github__update_issue
timeout_minutes: 30
-58
View File
@@ -1,58 +0,0 @@
name: Publish Docker
on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: 'Docker image tag (default: latest)'
required: false
default: 'latest'
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false
with:
persist-credentials: false
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/mervinpraison/praisonai
tags: |
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
type=semver,pattern={{version}},enable=${{ github.event_name == 'release' }}
type=semver,pattern={{major}}.{{minor}},enable=${{ github.event_name == 'release' }}
type=raw,value=${{ github.event.inputs.tag || 'latest' }},enable=${{ github.event_name == 'workflow_dispatch' }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./docker/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
@@ -1,82 +0,0 @@
name: Gemini Automated Issue Triage
# on:
# issue_comment:
# types: [created]
on:
workflow_dispatch:
jobs:
triage-issue:
if: >
github.event_name == 'issue_comment' &&
!github.event.issue.pull_request &&
contains(github.event.comment.body, '@gemini triage') &&
(github.event.comment.author_association == 'OWNER' ||
github.event.comment.author_association == 'MEMBER' ||
github.event.comment.author_association == 'COLLABORATOR')
timeout-minutes: 5
permissions:
issues: write
contents: read
id-token: write
concurrency:
group: ${{ github.workflow }}-${{ github.event.issue.number }}
cancel-in-progress: true
runs-on: ubuntu-latest
steps:
- name: Generate GitHub App Token
id: generate_token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.PRIVATE_KEY }}
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false
with:
persist-credentials: false
with:
token: ${{ steps.generate_token.outputs.token }}
- name: Run Gemini Issue Triage
uses: google-gemini/gemini-cli-action@main
env:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
ISSUE_TITLE: ${{ github.event.issue.title }}
ISSUE_BODY: ${{ github.event.issue.body }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
REPOSITORY: ${{ github.repository }}
with:
version: 0.1.8-rc.0
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
OTLP_GCP_WIF_PROVIDER: ${{ secrets.OTLP_GCP_WIF_PROVIDER }}
OTLP_GOOGLE_CLOUD_PROJECT: ${{ secrets.OTLP_GOOGLE_CLOUD_PROJECT }}
settings_json: |
{
"coreTools": [
"run_shell_command(gh label list)",
"run_shell_command(gh issue edit)"
],
"telemetry": {
"enabled": true,
"target": "gcp"
},
"sandbox": false
}
prompt: |
You are an issue triage assistant. Analyze the current GitHub issue and apply the most appropriate existing labels.
Steps:
1. Run: `gh label list --limit 100` to get all available labels.
2. Review the issue title and body provided in the environment variables.
3. Select the most relevant labels from the existing labels, focusing on kind/*, area/*, and priority/*.
4. Apply the selected labels to this issue using: `gh issue edit ISSUE_NUMBER --add-label "label1,label2"`
Guidelines:
- Only use labels that already exist in the repository.
- Do not add comments or modify the issue content.
- Triage only the current issue.
- Assign all applicable kind/*, area/*, and priority/* labels based on the issue content.
-204
View File
@@ -1,204 +0,0 @@
name: Gemini Issue Review
on:
workflow_dispatch:
# issue_comment:
# types: [created]
permissions:
contents: write
issues: write
pull-requests: read
jobs:
review-issue:
if: >
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'issue_comment' &&
!github.event.issue.pull_request &&
contains(github.event.comment.body, '@gemini') &&
!contains(github.event.comment.body, '@gemini triage') &&
(github.event.comment.author_association == 'OWNER' ||
github.event.comment.author_association == 'MEMBER' ||
github.event.comment.author_association == 'COLLABORATOR' ||
github.event.comment.author_association == 'CONTRIBUTOR'))
runs-on: ubuntu-latest
env:
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
steps:
- name: Generate token
id: generate_token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.PRIVATE_KEY }}
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false
with:
persist-credentials: false
with:
token: ${{ steps.generate_token.outputs.token }}
- name: Set up Git
run: |
git config --local user.email "[email protected]"
git config --local user.name "MervinPraison"
- name: Get issue data
id: issue_data
env:
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
# Pass user-controlled inputs via environment variables to prevent script injection (GHSL-2025-093)
EVENT_NAME: ${{ github.event_name }}
EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
EVENT_COMMENT_BODY: ${{ github.event.comment.body }}
run: |
# Get issue number from event or context
if [ "$EVENT_NAME" = "issue_comment" ]; then
ISSUE_NUMBER="$EVENT_ISSUE_NUMBER"
elif [ "$EVENT_NAME" = "issues" ]; then
ISSUE_NUMBER="$EVENT_ISSUE_NUMBER"
else
echo "Unable to determine issue number"
exit 1
fi
# Get issue details
gh issue view $ISSUE_NUMBER --json title,body,labels,assignees > issue_details.json
# Extract additional instructions from comment if triggered by comment
ADDITIONAL_INSTRUCTIONS=""
if [ "$EVENT_NAME" = "issue_comment" ]; then
COMMENT_BODY="$EVENT_COMMENT_BODY"
ADDITIONAL_INSTRUCTIONS=$(echo "$COMMENT_BODY" | sed -n 's/.*@gemini[[:space:]]*\(.*\)/\1/p' | head -1)
fi
echo "ISSUE_NUMBER=$ISSUE_NUMBER" >> $GITHUB_OUTPUT
echo "ADDITIONAL_INSTRUCTIONS=$ADDITIONAL_INSTRUCTIONS" >> $GITHUB_OUTPUT
- name: Run Gemini CLI
uses: google-github-actions/run-gemini-cli@v0
env:
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
ISSUE_NUMBER: ${{ steps.issue_data.outputs.ISSUE_NUMBER }}
ADDITIONAL_INSTRUCTIONS: ${{ steps.issue_data.outputs.ADDITIONAL_INSTRUCTIONS }}
REPOSITORY: ${{ github.repository }}
with:
gemini_api_key: ${{ secrets.GEMINI_API_KEY }}
gemini_model: 'gemini-2.5-flash'
prompt: |
You are a helpful GitHub issue assistant. Your task is to analyze and help with GitHub issues.
**Issue Details:**
- Issue Number: #${ISSUE_NUMBER}
- Repository: ${REPOSITORY}
- Issue URL: ${{ github.event.issue.html_url }}
**Additional Instructions:** ${ADDITIONAL_INSTRUCTIONS}
**CRITICAL: When making code modifications, follow this EXACT workflow:**
**STEP 1: Analyze the Issue**
- Use: `gh issue view ${ISSUE_NUMBER} --json title,body,labels,assignees`
- Analyze issue content thoroughly
- Search codebase for related files using `glob`, `search_file_content`, `list_directory`
**STEP 2: If Code Changes Are Needed**
MANDATORY FIRST STEP: Before writing any code, you MUST use `read_file` to carefully read "src/praisonai-agents/AGENTS.md". You must honor this repository's extremely specific Architecture, Protocol-First design rules, and Agent-Centric Philosophy!
Create a new branch with 'gemini/' prefix:
- Use: `git checkout -b gemini/issue-${ISSUE_NUMBER}-description`
- Example: `git checkout -b gemini/issue-123-fix-sequential-tools`
**STEP 3: Make Code Modifications**
- Use `read_file` to examine existing code
- Use `write_file` or `replace` to make changes
- Use `search_file_content` to find related code
- Make focused, targeted changes to fix the issue
**STEP 4: Test Changes (if applicable)**
- Run relevant tests if test files exist
- Use `run_shell_command` to execute test commands
**STEP 5: Commit and Push Changes**
- Use: `git add .` (or specific files)
- Use: `git commit -m "Gemini: [Issue #${ISSUE_NUMBER}] Brief description of fix"`
- Use: `git push -u origin gemini/issue-${ISSUE_NUMBER}-description`
**STEP 6: Create Pull Request**
- Use: `gh pr create --title "Fix #${ISSUE_NUMBER}: Issue description" --body "Fixes #${ISSUE_NUMBER}\n\nSummary of changes:\n- Change 1\n- Change 2" --head gemini/issue-${ISSUE_NUMBER}-description --base main`
- This will return a PR URL like: https://github.com/repo/pull/123
**STEP 7: Comment on Issue with Results**
Use: `gh issue comment ${ISSUE_NUMBER} -b "MESSAGE"`
**Your final comment MUST include:**
- Summary of what was analyzed
- What changes were made (if any)
- Link to the created PR (if applicable)
- Brief explanation of the solution
**Example final comment:**
```
Hi! I've analyzed and fixed this issue.
**Problem:** Sequential tool calling was getting stuck after first tool call.
**Solution:** Added proper prompt handling after each tool call in the Ollama model integration.
**Changes Made:**
- Modified `src/praisonai-agents/ollama-sequential.py`
- Added continuation prompts for multi-step tool execution
**Pull Request:** https://github.com/MervinPraison/PraisonAI/pull/856
The fix is ready for review. Please test and let me know if you encounter any issues!
```
**IMPORTANT NOTES:**
- Always create branches with 'gemini/' prefix
- Always include issue number in branch name and commit message
- Always create PR that references the issue
- Always provide PR link in your final response
- Use the GITHUB_TOKEN environment variable for authentication
Please proceed with helping resolve this issue following this exact workflow.
settings: |
{
"coreTools": [
"run_shell_command(echo)",
"run_shell_command(gh issue view)",
"run_shell_command(gh issue comment)",
"run_shell_command(gh issue list)",
"run_shell_command(gh issue edit)",
"run_shell_command(gh pr create)",
"run_shell_command(gh pr view)",
"run_shell_command(gh pr list)",
"run_shell_command(cat)",
"run_shell_command(head)",
"run_shell_command(tail)",
"run_shell_command(grep)",
"run_shell_command(find)",
"run_shell_command(git checkout)",
"run_shell_command(git add)",
"run_shell_command(git commit)",
"run_shell_command(git push)",
"run_shell_command(git status)",
"run_shell_command(git branch)",
"list_directory",
"read_file",
"read_many_files",
"write_file",
"replace",
"glob",
"search_file_content",
"web_fetch",
"google_web_search",
"save_memory"
]
}
-254
View File
@@ -1,254 +0,0 @@
name: Gemini PR Review
on:
# issue_comment:
# types: [created]
workflow_dispatch:
inputs:
pr_number:
description: 'PR number to review'
required: true
type: number
jobs:
review-pr:
if: >
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
contains(github.event.comment.body, '@gemini') &&
(github.event.comment.author_association == 'OWNER' ||
github.event.comment.author_association == 'MEMBER' ||
github.event.comment.author_association == 'COLLABORATOR'))
timeout-minutes: 15
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
pull-requests: write
issues: write
steps:
- name: Generate GitHub App Token
id: generate_token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.PRIVATE_KEY }}
- name: Determine checkout ref
id: checkout_ref
run: |
if [ "${{ github.event_name }}" = "issue_comment" ]; then
echo "ref=refs/pull/${{ github.event.issue.number }}/head" >> "$GITHUB_OUTPUT"
else
echo "ref=${{ github.event.pull_request.head.sha }}" >> "$GITHUB_OUTPUT"
fi
- name: Checkout PR code
uses: actions/checkout@v4
with:
persist-credentials: false
with:
persist-credentials: false
with:
token: ${{ steps.generate_token.outputs.token }}
ref: ${{ steps.checkout_ref.outputs.ref }}
fetch-depth: 0
- name: Get PR details
id: get_pr
env:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
# Pass user-controlled inputs via environment variables to prevent script injection (GHSL-2025-093)
EVENT_NAME: ${{ github.event_name }}
EVENT_INPUTS_PR_NUMBER: ${{ github.event.inputs.pr_number }}
EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
EVENT_PR_NUMBER: ${{ github.event.pull_request.number }}
EVENT_COMMENT_BODY: ${{ github.event.comment.body }}
run: |
if [ "$EVENT_NAME" = "workflow_dispatch" ]; then
PR_NUMBER=$EVENT_INPUTS_PR_NUMBER
elif [ "$EVENT_NAME" = "issue_comment" ]; then
PR_NUMBER=$EVENT_ISSUE_NUMBER
else
PR_NUMBER=$EVENT_PR_NUMBER
fi
echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
# Extract additional instructions from comment (if triggered by comment)
ADDITIONAL_INSTRUCTIONS=""
if [ "$EVENT_NAME" = "issue_comment" ]; then
COMMENT_BODY="$EVENT_COMMENT_BODY"
ADDITIONAL_INSTRUCTIONS=$(echo "$COMMENT_BODY" | sed 's/.*@gemini//' | xargs)
fi
echo "additional_instructions=$ADDITIONAL_INSTRUCTIONS" >> "$GITHUB_OUTPUT"
# Get PR details
PR_DATA=$(gh pr view $PR_NUMBER --json title,body,additions,deletions,changedFiles,baseRefName,headRefName)
echo "pr_data=$PR_DATA" >> "$GITHUB_OUTPUT"
# Get file changes
CHANGED_FILES=$(gh pr diff $PR_NUMBER --name-only)
echo "changed_files<<EOF" >> "$GITHUB_OUTPUT"
echo "$CHANGED_FILES" >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
- name: Run Gemini PR Review
uses: ./.github/actions/gemini
env:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
PR_NUMBER: ${{ steps.get_pr.outputs.pr_number }}
PR_DATA: ${{ steps.get_pr.outputs.pr_data }}
CHANGED_FILES: ${{ steps.get_pr.outputs.changed_files }}
ADDITIONAL_INSTRUCTIONS: ${{ steps.get_pr.outputs.additional_instructions }}
REPOSITORY: ${{ github.repository }}
with:
version: 0.1.8-rc.0
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
OTLP_GCP_WIF_PROVIDER: ${{ secrets.OTLP_GCP_WIF_PROVIDER }}
OTLP_GOOGLE_CLOUD_PROJECT: ${{ secrets.OTLP_GOOGLE_CLOUD_PROJECT }}
settings_json: |
{
"coreTools": [
"run_shell_command(echo)",
"run_shell_command(gh pr view)",
"run_shell_command(gh pr diff)",
"run_shell_command(gh pr comment)",
"run_shell_command(gh pr list)",
"run_shell_command(cat)",
"run_shell_command(head)",
"run_shell_command(tail)",
"run_shell_command(grep)",
"run_shell_command(find)",
"run_shell_command(git checkout)",
"run_shell_command(git add)",
"run_shell_command(git commit)",
"run_shell_command(git push)",
"run_shell_command(git status)",
"run_shell_command(git branch)",
"run_shell_command(git fetch)",
"list_directory",
"read_file",
"read_many_files",
"write_file",
"replace",
"glob",
"search_file_content",
"web_fetch",
"google_web_search",
"save_memory"
],
"telemetry": {
"enabled": false,
"target": "gcp"
},
"sandbox": false
}
prompt: |
You are an expert code reviewer and AI assistant for Pull Requests. You can review code AND make modifications to improve the PR.
**PR Details:**
- PR Number: #$PR_NUMBER
- Repository: $REPOSITORY
- Additional Instructions: $ADDITIONAL_INSTRUCTIONS
**CRITICAL: When making code modifications, follow this EXACT workflow:**
**STEP 1: Analyze the PR**
- Use: `echo "$PR_DATA"` to get PR details (JSON format)
- Use: `echo "$CHANGED_FILES"` to get changed files list
- Use: `gh pr diff ${PR_NUMBER}` to see the full diff
- Use: `gh pr view ${PR_NUMBER} --json title,body,headRefName` to get PR info
- Analyze the code changes thoroughly
**STEP 2: If Code Improvements Are Needed**
MANDATORY FIRST STEP: Before writing any code, you MUST use `read_file` to carefully read "src/praisonai-agents/AGENTS.md". You must honor this repository's extremely specific Architecture, Protocol-First design rules, and Agent-Centric Philosophy!
**IMPORTANT:** DO NOT create a new branch! Work on the EXISTING PR branch.
- Use: `git fetch origin` to get latest changes
- Get PR branch name: `gh pr view ${PR_NUMBER} --json headRefName`
- Switch to PR branch: `git checkout BRANCH_NAME` (use actual branch name from PR)
- Use: `git pull origin BRANCH_NAME` to get latest PR changes
**STEP 3: Make Code Modifications**
- Use `read_file` to examine existing code
- Use `write_file` or `replace` to make improvements
- Use `search_file_content` to find related code
- Make focused, targeted improvements to the PR
**STEP 4: Test Changes (if applicable)**
- Run relevant tests if test files exist
- Use `run_shell_command` to execute test commands
**STEP 5: Commit and Push Changes to EXISTING PR Branch**
- Use: `git add .` (or specific files)
- Use: `git commit -m "Gemini: [PR #${PR_NUMBER}] Brief description of improvements"`
- Use: `git push origin BRANCH_NAME` (push to EXISTING PR branch)
**STEP 6: Review and Comment on PR**
Write comprehensive review and post comment with your analysis and any improvements made.
Use: `gh pr comment ${PR_NUMBER} -b "MESSAGE"`
Review Guidelines:
- Focus on code quality, security, performance, and maintainability
- Check for common issues: potential bugs, security vulnerabilities, performance bottlenecks
- Verify error handling and edge cases
- Look for code style and best practices
- Comment on architecture and design decisions if significant
- Be constructive and specific in feedback
- Highlight both issues and positive aspects
- Suggest improvements with examples when possible
Review Areas:
- **Security**: Authentication, authorization, input validation, data sanitization
- **Performance**: Algorithms, database queries, caching, resource usage
- **Reliability**: Error handling, logging, testing coverage, edge cases
- **Maintainability**: Code structure, documentation, naming conventions
- **Functionality**: Logic correctness, requirements fulfillment
Output Format:
Structure your review using this exact format with markdown:
## 📋 Review Summary
Provide a brief 2-3 sentence overview of the PR and overall assessment.
## 🔍 General Feedback
- List general observations about code quality
- Mention overall patterns or architectural decisions
- Highlight positive aspects of the implementation
- Note any recurring themes across files
## 🎯 Specific Feedback
Only include sections below that have actual issues. If there are no issues in a priority category, omit that entire section.
### 🔴 Critical
(Only include this section if there are critical issues)
Issues that must be addressed before merging (security vulnerabilities, breaking changes, major bugs):
- **File: `filename:line`** - Description of critical issue with specific recommendation
### 🟡 High
(Only include this section if there are high priority issues)
Important issues that should be addressed (performance problems, design flaws, significant bugs):
- **File: `filename:line`** - Description of high priority issue with suggested fix
### 🟢 Medium
(Only include this section if there are medium priority issues)
Improvements that would enhance code quality (style issues, minor optimizations, better practices):
- **File: `filename:line`** - Description of medium priority improvement
### 🔵 Low
(Only include this section if there are suggestions)
Nice-to-have improvements and suggestions (documentation, naming, minor refactoring):
- **File: `filename:line`** - Description of suggestion or enhancement
**Note**: If no specific issues are found in any category, simply state "No specific issues identified in this review."
## ✅ Highlights
(Only include this section if there are positive aspects to highlight)
- Mention specific good practices or implementations
- Acknowledge well-written code sections
- Note improvements from previous versions
---
*Review completed by Gemini CLI*
@@ -1,158 +0,0 @@
name: Cross-Repo Integration Tests
on:
push:
branches: [ main ]
paths:
- 'src/praisonai/praisonai/integration/**'
- 'src/praisonai/tests/integration/test_aiui_*'
- 'src/praisonai/pyproject.toml'
pull_request:
branches: [ main ]
paths:
- 'src/praisonai/praisonai/integration/**'
- 'src/praisonai/tests/integration/test_aiui_*'
- 'src/praisonai/pyproject.toml'
workflow_dispatch:
jobs:
cross-repo-integration:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout PraisonAI
uses: actions/checkout@v4
with:
path: PraisonAI
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
- name: Checkout PraisonAIUI
uses: actions/checkout@v4
with:
repository: MervinPraison/PraisonAIUI
path: PraisonAIUI
ref: main
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
# Install PraisonAI packages in development mode
cd PraisonAI/src/praisonai-agents
pip install -e .
cd ../praisonai
pip install -e ".[ui,dev]"
# Install PraisonAIUI in development mode
cd ../../../PraisonAIUI
pip install -e .
- name: Verify versions
run: |
python -c "import praisonaiagents; print(f'praisonaiagents: {praisonaiagents.__version__}')"
python -c "import praisonai; print(f'praisonai: {praisonai.__version__}')"
python -c "import praisonaiui; print(f'praisonaiui: {praisonaiui.__version__}')"
- name: Run PraisonAI integration tests
run: |
cd PraisonAI/src/praisonai
python -m pytest tests/integration/test_aiui_* -v --timeout=300
- name: Run PraisonAIUI integration tests
run: |
cd PraisonAIUI
if [ -f tests/integration/test_agentic_roundtrip.py ]; then
python -m pytest tests/integration/test_agentic_roundtrip.py -v --timeout=300
fi
if [ -f tests/test_feature_sdk_backends.py ]; then
python -m pytest tests/test_feature_sdk_backends.py -v --timeout=300
fi
- name: Test Pattern C CLI
run: |
cd PraisonAI/src/praisonai
# Test that ui-gateway command exists
python -m praisonai serve --help | grep ui-gateway
- name: Test public API exports
run: |
cd PraisonAI/src/praisonai
python -c "from praisonai import run_integrated_gateway; print('✓ run_integrated_gateway imported')"
python -c "from praisonai import configure_host; print('✓ configure_host imported')"
- name: Integration smoke test
env:
PRAISONAI_TEST_MODE: "1"
PYTHONPATH: ${{ github.workspace }}/PraisonAI/src/praisonai:${{ github.workspace }}/PraisonAI/src/praisonai-agents:${{ github.workspace }}/PraisonAIUI
run: |
cd PraisonAI/src/praisonai
python -c "
import sys
sys.path.insert(0, '.')
from praisonai.integration.host_app import configure_host
from praisonai import run_integrated_gateway
print('✓ Integration imports successful')
# Test configure_host with new parameters
try:
configure_host(
style='dashboard',
context_paths=['AGENTS.md'],
title='Test App'
)
print('✓ configure_host with new parameters works')
except Exception as e:
print(f'× configure_host failed: {e}')
sys.exit(1)
"
# Optional job with API key for agentic tests (if secret is available)
agentic-integration:
runs-on: ubuntu-latest
timeout-minutes: 30
if: ${{ vars.RUN_AGENTIC_TESTS == 'true' }}
needs: cross-repo-integration
steps:
- name: Checkout PraisonAI
uses: actions/checkout@v4
with:
path: PraisonAI
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
- name: Checkout PraisonAIUI
uses: actions/checkout@v4
with:
repository: MervinPraison/PraisonAIUI
path: PraisonAIUI
ref: main
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
cd PraisonAI/src/praisonai-agents
pip install -e .
cd ../praisonai
pip install -e ".[ui,dev]"
cd ../../../PraisonAIUI
pip install -e .
- name: Run agentic integration test
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: |
cd PraisonAI/src/praisonai
if [ -n "$OPENAI_API_KEY" ]; then
python -m pytest tests/integration/test_aiui_host_agentic.py -v --timeout=600
else
echo "OPENAI_API_KEY not available, skipping agentic tests"
fi
@@ -1,71 +0,0 @@
name: PraisonAI Issue Triage
on:
issue_comment:
types: [created]
workflow_dispatch:
inputs:
issue_number:
description: 'Issue Number'
required: true
type: string
jobs:
triage:
runs-on: ubuntu-latest
if: >
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'issue_comment' &&
!github.event.issue.pull_request &&
contains(github.event.comment.body, '@praisonai') &&
github.actor != 'github-actions[bot]' &&
github.event.comment.user.type != 'Bot' &&
(github.event.comment.author_association == 'OWNER' ||
github.event.comment.author_association == 'MEMBER' ||
github.event.comment.author_association == 'COLLABORATOR'))
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
persist-credentials: false
fetch-depth: 0
- name: Generate GitHub App Token
id: generate_token
uses: tibdex/github-app-token@v2
with:
app_id: ${{ secrets.PRAISONAI_APP_ID }}
private_key: ${{ secrets.PRAISONAI_APP_PRIVATE_KEY }}
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Set up Git
run: |
git config --local user.email "[email protected]"
git config --local user.name "PraisonAI Bot"
- name: Install PraisonAI
run: |
pip install uv
cd src/praisonai-agents && uv pip install --system -e ".[all]"
cd ../praisonai && uv pip install --system -e ".[all]"
- name: Run PraisonAI Issue Triage
env:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
PRAISONAI_AUTO_APPROVE: "true"
ISSUE_NUMBER_INPUT: ${{ inputs.issue_number }}
ISSUE_NUMBER_EVENT: ${{ github.event.issue.number }}
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
export ISSUE_NUMBER="$ISSUE_NUMBER_INPUT"
else
export ISSUE_NUMBER="$ISSUE_NUMBER_EVENT"
fi
praisonai github triage --issue $ISSUE_NUMBER --agent-file .github/praisonai-issue-triage.yaml
-73
View File
@@ -1,73 +0,0 @@
name: PraisonAI PR Reviewer
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
issue_comment:
types: [created]
workflow_dispatch:
inputs:
pr_number:
description: 'Pull Request Number'
required: true
type: string
jobs:
review:
runs-on: ubuntu-latest
if: >
(github.event_name == 'pull_request' && github.event.pull_request.draft == false) ||
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
contains(github.event.comment.body, '@praisonai') &&
github.actor != 'github-actions[bot]' &&
github.event.comment.user.type != 'Bot' &&
(github.event.comment.author_association == 'OWNER' ||
github.event.comment.author_association == 'MEMBER' ||
github.event.comment.author_association == 'COLLABORATOR'))
steps:
- name: Determine checkout ref
id: dest
env:
ISSUE_NUMBER: ${{ github.event.issue.number }}
PR_NUMBER_INPUT: ${{ inputs.pr_number }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
if [ "${{ github.event_name }}" = "issue_comment" ]; then
echo "ref=refs/pull/$ISSUE_NUMBER/head" >> "$GITHUB_OUTPUT"
elif [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "ref=refs/pull/$PR_NUMBER_INPUT/head" >> "$GITHUB_OUTPUT"
else
echo "ref=$PR_HEAD_SHA" >> "$GITHUB_OUTPUT"
fi
- name: Checkout Repository
uses: actions/checkout@v4
with:
persist-credentials: false
ref: ${{ steps.dest.outputs.ref }}
fetch-depth: 0
- name: Generate GitHub App Token
id: generate_token
uses: tibdex/github-app-token@v2
with:
app_id: ${{ secrets.PRAISONAI_APP_ID }}
private_key: ${{ secrets.PRAISONAI_APP_PRIVATE_KEY }}
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install PraisonAI
run: pip install "praisonai[all]"
- name: Run PraisonAI PR Review
env:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: |
praisonai workflow run .github/praisonai-reviewer.yaml
-42
View File
@@ -1,42 +0,0 @@
name: Python Package (Multi-Version)
on:
schedule:
- cron: '0 4 * * 1' # Weekly Monday 4am UTC
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Set environment variables
run: |
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}" >> $GITHUB_ENV
echo "OPENAI_API_BASE=${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}" >> $GITHUB_ENV
echo "OPENAI_MODEL_NAME=${{ secrets.OPENAI_MODEL_NAME || 'gpt-5-nano' }}" >> $GITHUB_ENV
echo "PYTHONPATH=${{ github.workspace }}/src/praisonai-agents:$PYTHONPATH" >> $GITHUB_ENV
- name: Install dependencies
run: |
cd src/praisonai
python -m pip install --upgrade pip
python -m pip install ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
python -m pip install duckduckgo_search pytest pytest-asyncio pytest-cov
python -m pip install "praisonaiagents[knowledge]"
- name: Run tests
run: |
cd src/praisonai && python -m pytest tests/unit/ -v --tb=short --disable-warnings --timeout=60 || echo "Some tests failed"
-42
View File
@@ -1,42 +0,0 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: Upload Python Package
on:
release:
types: [published]
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build
- name: Build package
run: python -m build src/praisonai
- name: Publish package
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
packages_dir: src/praisonai/dist/
-550
View File
@@ -1,550 +0,0 @@
name: Release Workflow
on:
workflow_dispatch:
inputs:
tag:
description: 'Tag to create release with (e.g., v2.0.10)'
required: true
fork_owner:
description: 'GitHub username of the fork owner'
required: true
default: 'tosin2013'
jobs:
test-ubuntu:
strategy:
matrix:
os: [ubuntu-22.04, ubuntu-24.04]
framework: ['crewai', 'autogen']
fail-fast: false
runs-on: ${{ matrix.os }}
timeout-minutes: 90
steps:
# First checkout the upstream repo at the specified tag
- name: Checkout upstream repo
uses: actions/checkout@v4
with:
persist-credentials: false
with:
persist-credentials: false
with:
repository: MervinPraison/PraisonAI
ref: ${{ github.event.inputs.tag }}
fetch-depth: 0
# Get the commit hash from the tag
- name: Get commit hash
id: get_commit
env:
INPUT_TAG: ${{ github.event.inputs.tag }}
run: |
COMMIT_HASH=$(git rev-parse HEAD)
echo "commit_hash=$COMMIT_HASH" >> $GITHUB_OUTPUT
echo "Found commit: $COMMIT_HASH for tag $INPUT_TAG"
# Now checkout the fork at main branch
- name: Checkout fork
uses: actions/checkout@v4
with:
persist-credentials: false
with:
persist-credentials: false
with:
repository: ${{ github.event.inputs.fork_owner }}/PraisonAI
ref: main
fetch-depth: 0
clean: true
# Sync with upstream commit
- name: Sync with upstream
run: |
git config --global user.name "MervinPraison"
git config --global user.email "[email protected]"
# Add upstream remote
git remote add upstream https://github.com/MervinPraison/PraisonAI.git
# Fetch from upstream
git fetch upstream --tags --force
- name: Hard reset to tag commit
env:
COMMIT_HASH: ${{ steps.get_commit.outputs.commit_hash }}
run: |
git reset --hard $COMMIT_HASH
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
- name: Install Poetry
run: |
curl -sSL https://install.python-poetry.org | python3 -
echo "$HOME/.local/bin" >> $GITHUB_PATH
poetry config virtualenvs.in-project true
poetry config virtualenvs.create true
poetry --version
poetry config --list
- name: Install Dependencies
run: |
poetry lock #--no-update
poetry install --all-extras
poetry env info
# Verify venv exists
test -d .venv || { echo "Virtual environment not created!"; exit 1; }
test -f .venv/bin/activate || { echo "Activation script not found!"; exit 1; }
- name: Run setup script
timeout-minutes: 20
run: |
set -e # Exit on any error
curl -OL https://raw.githubusercontent.com/tosin2013/PraisonAI/refs/heads/main/setup.sh
chmod +x setup.sh
./setup.sh --all --cicd || { echo "Setup script failed"; exit 1; }
env:
OPENAI_API_KEY: ${{ secrets.GROQ_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
OPENAI_MODEL_NAME: "llama-3.3-70b-versatile"
OPENAI_API_BASE: "https://api.groq.com/openai/v1/"
OPENAI_API_BASE_URL: "https://api.groq.com/openai/v1/"
PRAISONAI_NON_INTERACTIVE: "true"
- name: Test Basic Functionality
run: |
set -e # Exit on any error
# Random sleep between 60-120 seconds to avoid API rate limits
SLEEP_TIME=$((RANDOM % 61 + 60))
echo "Sleeping for $SLEEP_TIME seconds to avoid API rate limits..."
sleep $SLEEP_TIME
lsof -ti:8084 | xargs -r kill -9 || true
source .venv/bin/activate || { echo "Failed to activate virtual environment"; exit 1; }
mkdir -p test_output || { echo "Failed to create test_output directory"; exit 1; }
echo "Testing basic CLI functionality..."
# Test auto generation with explicit framework
praisonai --framework ${{ matrix.framework }} --auto "create a short test script" 2>&1 | tee test_output/auto_test.log
# Verify the output file exists and has content
if [[ ! -s test_output/auto_test.log ]]; then
echo "Error: No output generated from auto test"
exit 1
fi
# Test auto generation without framework
echo "Basic functionality tests passed!"
env:
OPENAI_API_KEY: ${{ secrets.GROQ_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
OPENAI_MODEL_NAME: "llama-3.3-70b-versatile"
OPENAI_API_BASE: "https://api.groq.com/openai/v1/"
OPENAI_API_BASE_URL: "https://api.groq.com/openai/v1/"
LOGLEVEL: "debug"
PRAISONAI_NON_INTERACTIVE: "true"
- name: Test Framework-specific Features
continue-on-error: false
run: |
source .venv/bin/activate
# Random sleep between 60-120 seconds to avoid API rate limits
SLEEP_TIME=$((RANDOM % 61 + 60))
echo "Sleeping for $SLEEP_TIME seconds to avoid API rate limits..."
sleep $SLEEP_TIME
lsof -ti:8084 | xargs -r kill -9 || true
praisonai --framework ${{ matrix.framework }} --auto "create a movie script about Robots in Mars" 2>&1 | tee test_output/framework_output.txt || echo "Framework-specific test failed" >> test_output/errors.log
env:
OPENAI_API_KEY: ${{ secrets.GROQ_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
OPENAI_MODEL_NAME: "llama-3.3-70b-versatile"
OPENAI_API_BASE: "https://api.groq.com/openai/v1/"
OPENAI_API_BASE_URL: "https://api.groq.com/openai/v1/"
PRAISONAI_NON_INTERACTIVE: "true"
- name: Test Core Functionality
continue-on-error: false
run: |
source .venv/bin/activate
# Random sleep between 60-120 seconds to avoid API rate limits
SLEEP_TIME=$((RANDOM % 61 + 60))
echo "Sleeping for $SLEEP_TIME seconds to avoid API rate limits..."
sleep $SLEEP_TIME
echo "Testing core functionality..."
# Test package imports
python3 -c "from praisonai.cli import PraisonAI; from praisonai.auto import AutoGenerator; from praisonai.agents_generator import AgentsGenerator" || exit 1
# Test configuration loading
python3 -c "from praisonai.inc.config import generate_config; print(generate_config())" || exit 1
# Test tools loading
python3 -c "from praisonai.inbuilt_tools import *" || exit 1
echo "Core functionality tests passed!"
env:
OPENAI_API_KEY: ${{ secrets.GROQ_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
OPENAI_MODEL_NAME: "llama-3.3-70b-versatile"
OPENAI_API_BASE: "https://api.groq.com/openai/v1/"
OPENAI_API_BASE_URL: "https://api.groq.com/openai/v1/"
LOGLEVEL: "debug"
PRAISONAI_NON_INTERACTIVE: "true"
- name: Test Agent Generation
continue-on-error: false
run: |
source .venv/bin/activate
# Random sleep between 60-120 seconds to avoid API rate limits
SLEEP_TIME=$((RANDOM % 61 + 60))
echo "Sleeping for $SLEEP_TIME seconds to avoid API rate limits..."
sleep $SLEEP_TIME
echo "Testing agent generation..."
# Create a test YAML file
cat > test_agents.yaml <<EOF
topic: "Test automation task"
framework: "${{ matrix.framework }} "
roles:
- name: "Tester"
goal: "Test the system"
backstory: "Expert system tester"
tasks:
- description: "Verify system functionality"
expected_output: "Test results"
EOF
# Test YAML loading and agent generation
python3 -c '
from praisonai.agents_generator import AgentsGenerator
config = [{"model": "llama-3.3-70b-versatile", "base_url": "https://api.groq.com/openai/v1/"}]
generator = AgentsGenerator("test_agents.yaml", "${{ matrix.framework }} ", config)
print("Agent generation test passed!")
' || exit 1
echo "Agent generation tests passed!"
env:
OPENAI_API_KEY: ${{ secrets.GROQ_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
OPENAI_MODEL_NAME: "llama-3.3-70b-versatile"
OPENAI_API_BASE: "https://api.groq.com/openai/v1/"
OPENAI_API_BASE_URL: "https://api.groq.com/openai/v1/"
LOGLEVEL: "debug"
PRAISONAI_NON_INTERACTIVE: "true"
- name: Test Custom Tools Integration
continue-on-error: false
run: |
source .venv/bin/activate
# Random sleep between 60-120 seconds to avoid API rate limits
SLEEP_TIME=$((RANDOM % 61 + 60))
echo "Sleeping for $SLEEP_TIME seconds to avoid API rate limits..."
sleep $SLEEP_TIME
echo "Testing custom tools integration..."
# Create a test tool
cat > test_tool.py <<EOF
from duckduckgo_search import DDGS
from praisonai_tools import BaseTool
class InternetSearchTool(BaseTool):
name: str = "Internet Search Tool"
description: str = "Search Internet for relevant information"
def _run(self, query: str):
return {"status": "success", "query": query}
def test(self):
"""Test method to verify tool setup"""
test_query = "test query"
result = self._run(test_query)
assert result["status"] == "success"
assert result["query"] == test_query
return True
EOF
# Test tool loading and initialization
python3 -c '
import importlib.util
import sys
# Load the test tool
spec = importlib.util.spec_from_file_location("test_tool", "test_tool.py")
module = importlib.util.module_from_spec(spec)
sys.modules["test_tool"] = module
spec.loader.exec_module(module)
# Initialize and test the tool
tool = module.InternetSearchTool()
assert tool.test(), "Tool test failed"
print("Custom tool test passed!")
' || exit 1
echo "Custom tools integration test passed!"
env:
OPENAI_API_KEY: ${{ secrets.GROQ_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
OPENAI_MODEL_NAME: "llama-3.3-70b-versatile"
OPENAI_API_BASE: "https://api.groq.com/openai/v1/"
OPENAI_API_BASE_URL: "https://api.groq.com/openai/v1/"
LOGLEVEL: "debug"
PRAISONAI_NON_INTERACTIVE: "true"
- name: Test PraisonAI Agents Configuration
continue-on-error: false
run: |
source .venv/bin/activate
# Random sleep between 60-120 seconds to avoid API rate limits
SLEEP_TIME=$((RANDOM % 61 + 60))
echo "Sleeping for $SLEEP_TIME seconds to avoid API rate limits..."
sleep $SLEEP_TIME
echo "Testing agents configuration..."
mkdir -p test_output || { echo "Failed to create test_output directory"; exit 1; }
# Create test script
cat > test_agents.py <<EOF
from langchain_openai import ChatOpenAI
from crewai import Agent, Task, Crew
import os
import logging
import time
import random
logging.basicConfig(level="DEBUG")
logger = logging.getLogger(__name__)
def random_sleep(min_seconds=15, max_seconds=30):
"""Sleep for a random duration to prevent API rate limiting"""
duration = random.uniform(min_seconds, max_seconds)
logger.info(f"Rate limit protection: Sleeping for {duration:.2f} seconds...")
time.sleep(duration)
class RateLimitedChatOpenAI(ChatOpenAI):
"""ChatOpenAI with built-in rate limiting"""
def __call__(self, *args, **kwargs):
random_sleep()
return super().__call__(*args, **kwargs)
def run_test():
logger.info("Initializing test components...")
# Initialize the LLM with rate limiting
llm = RateLimitedChatOpenAI(
model=os.getenv('OPENAI_MODEL_NAME', 'llama-3.3-70b-versatile'),
base_url=os.getenv('OPENAI_API_BASE', 'https://api.groq.com/openai/v1/'),
api_key=os.getenv('OPENAI_API_KEY'),
temperature=0.7
)
random_sleep()
logger.info("Creating researcher agent...")
researcher = Agent(
role="Test Automation Expert",
goal="Verify system functionality and performance",
backstory="""You are an expert in test automation and system verification,
skilled in identifying potential issues and validating functionality.""",
verbose=True,
allow_delegation=False,
llm=llm
)
random_sleep()
logger.info("Creating validator agent...")
validator = Agent(
role="Quality Assurance Specialist",
goal="Validate test results and ensure system reliability",
backstory="""You are a QA specialist focused on ensuring
system reliability and proper functionality.""",
verbose=True,
allow_delegation=False,
llm=llm
)
random_sleep()
logger.info("Creating test tasks...")
test_task = Task(
description="Run a basic system verification test",
expected_output="A report on system functionality verification",
agent=researcher
)
random_sleep()
validation_task = Task(
description="Validate the test results and compile findings",
expected_output="A validation report of test findings",
agent=validator
)
random_sleep()
logger.info("Initializing crew...")
crew = Crew(
agents=[researcher, validator],
tasks=[test_task, validation_task],
verbose=2
)
logger.info("Starting crew execution...")
result = crew.kickoff()
logger.info("Test execution completed.")
logger.info(f"Result: {result}")
return result
if __name__ == "__main__":
try:
run_test()
except Exception as e:
logger.error(f"Test failed with error: {str(e)}", exc_info=True)
raise
EOF
# Run the test script with increased timeout
echo "Testing with Python API..."
timeout 1800 python3 test_agents.py 2>&1 | tee test_output/agents_test.log
# Verify the output
if [[ ! -s test_output/agents_test.log ]]; then
echo "Error: No output generated from agents test"
exit 1
fi
echo "Agents configuration tests passed!"
env:
OPENAI_API_KEY: ${{ secrets.GROQ_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
OPENAI_MODEL_NAME: "llama-3.3-70b-versatile"
OPENAI_API_BASE: "https://api.groq.com/openai/v1/"
OPENAI_API_BASE_URL: "https://api.groq.com/openai/v1/"
LOGLEVEL: "debug"
PRAISONAI_NON_INTERACTIVE: "true"
- name: Upload test artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: praisonai-output-${{ matrix.os }}-${{ matrix.framework }}
path: test_output/
retention-days: 14
create-release:
needs: [test-ubuntu]
runs-on: ubuntu-latest
if: success()
steps:
# First checkout the fork's main branch
- name: Checkout fork repo
uses: actions/checkout@v4
with:
persist-credentials: false
with:
persist-credentials: false
with:
fetch-depth: 0
token: ${{ secrets.PAT_TOKEN }}
repository: ${{ github.event.inputs.fork_owner }}/PraisonAI
ref: main
# Add upstream and get commit from tag
- name: Get upstream tag commit
id: get_upstream_commit
env:
INPUT_TAG: ${{ github.event.inputs.tag }}
run: |
# Add upstream remote
git remote add upstream https://github.com/MervinPraison/PraisonAI.git
# Delete local tag if it exists
git tag -d "$INPUT_TAG" || true
# Fetch from upstream including tags with force
git fetch upstream --tags --force
# Verify tag exists in upstream
if ! git ls-remote --tags upstream | grep -q "refs/tags/$INPUT_TAG$"; then
echo "::error::Tag $INPUT_TAG not found in upstream repository"
exit 1
fi
# Get the commit hash from the upstream tag
UPSTREAM_COMMIT=$(git rev-list -n 1 refs/tags/"$INPUT_TAG")
if [ -z "$UPSTREAM_COMMIT" ]; then
echo "::error::Could not find commit for tag $INPUT_TAG"
exit 1
fi
echo "upstream_commit=$UPSTREAM_COMMIT" >> $GITHUB_OUTPUT
echo "Found commit: $UPSTREAM_COMMIT for tag $INPUT_TAG"
# Create tag at the same commit
- name: Create tag at commit
env:
GIT_ASKPASS: /bin/echo
PAT_TOKEN: ${{ secrets.PAT_TOKEN }}
INPUT_TAG: ${{ github.event.inputs.tag }}
run: |
git config --global user.name "MervinPraison"
git config --global user.email "[email protected]"
# Remove tag if it exists locally
git tag -d "$INPUT_TAG" || true
# Remove tag if it exists remotely
git push origin :refs/tags/"$INPUT_TAG" || true
- name: Fetch tag from upstream
env:
UPSTREAM_COMMIT: ${{ steps.get_upstream_commit.outputs.upstream_commit }}
run: |
git fetch upstream $UPSTREAM_COMMIT --force
- name: Reset to upstream commit
env:
UPSTREAM_COMMIT: ${{ steps.get_upstream_commit.outputs.upstream_commit }}
run: |
git reset --hard $UPSTREAM_COMMIT
# Create and push tag
git tag -a "$INPUT_TAG" -m "Release $INPUT_TAG (synced from upstream MervinPraison/PraisonAI@$INPUT_TAG)"
git push origin "$INPUT_TAG"
# Create the release
- name: Create Release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
with:
tag_name: ${{ github.event.inputs.tag }}
release_name: Release ${{ github.event.inputs.tag }}
draft: false
prerelease: false
body: |
Release ${{ github.event.inputs.tag }} (synced from upstream)
This release is synchronized with MervinPraison/PraisonAI@${{ github.event.inputs.tag }}
Commit: ${{ steps.get_upstream_commit.outputs.upstream_commit }}
For installation:
```bash
pip install praisonai
```
Changes from upstream v2.0.10:
- Updated agent configuration tests
- Added rate limiting protection
- Improved test reliability
Forked from: MervinPraison/PraisonAI
-205
View File
@@ -1,205 +0,0 @@
name: Comprehensive Test Suite
on:
workflow_dispatch: # Allow manual triggering
inputs:
test_type:
description: 'Type of tests to run'
required: true
default: 'all'
type: choice
options:
- all
- unit
- integration
- fast
- performance
- frameworks
- autogen
- crewai
release:
types: [published, prereleased]
schedule:
# Run comprehensive tests weekly on Sundays at 3 AM UTC
- cron: '0 3 * * 0'
jobs:
comprehensive-test:
runs-on: ubuntu-latest
timeout-minutes: 15
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
OPENAI_MODEL_NAME: gpt-4o-mini
strategy:
matrix:
python-version: ["3.11"]
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
persist-credentials: false
with:
persist-credentials: false
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install UV
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cd src/praisonai
uv pip install --system ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
uv pip install --system duckduckgo_search
uv pip install --system pytest pytest-asyncio pytest-cov pytest-benchmark pytest-timeout
# Install knowledge dependencies from praisonai-agents
uv pip install --system "praisonaiagents[knowledge]"
- name: Verify environment variables
run: |
if [ -n "$OPENAI_API_KEY" ]; then
echo "✅ OPENAI_API_KEY is set (length: ${#OPENAI_API_KEY})"
else
echo "⚠️ OPENAI_API_KEY is NOT set"
fi
- name: Run Comprehensive Test Suite
env:
INPUT_TEST_TYPE: ${{ github.event.inputs.test_type || 'all' }}
run: |
# Determine test type from input or default to 'all'
TEST_TYPE="$INPUT_TEST_TYPE"
echo "🧪 Running comprehensive test suite (type: $TEST_TYPE)"
case $TEST_TYPE in
"unit")
cd src/praisonai && python -m pytest tests/unit/ -v --tb=short --disable-warnings --cov=praisonai --cov-report=xml --cov-branch || echo "Some unit tests failed"
;;
"integration")
cd src/praisonai && python -m pytest tests/integration/ -v --tb=short --disable-warnings --cov=praisonai --cov-report=xml --cov-branch || echo "Some integration tests failed"
;;
"fast")
cd src/praisonai && python tests/test_runner.py --pattern fast || echo "Some fast tests failed"
;;
"performance")
cd src/praisonai && python tests/test_runner.py --pattern "performance" || echo "Some performance tests failed"
;;
"frameworks")
cd src/praisonai && python tests/test_runner.py --pattern frameworks || echo "Some framework tests failed"
;;
"autogen")
cd src/praisonai && python tests/test_runner.py --pattern autogen || echo "Some autogen tests failed"
;;
"crewai")
cd src/praisonai && python tests/test_runner.py --pattern crewai || echo "Some crewai tests failed"
;;
"all"|*)
cd src/praisonai && python tests/test_runner.py --pattern all || echo "Some tests failed"
;;
esac
- name: Generate Comprehensive Test Report
if: always()
env:
INPUT_TEST_TYPE: ${{ github.event.inputs.test_type || 'all' }}
EVENT_NAME: ${{ github.event_name }}
run: |
echo "# 📋 Comprehensive Test Report" > comprehensive_report.md
echo "" >> comprehensive_report.md
echo "**Python Version:** ${{ matrix.python-version }}" >> comprehensive_report.md
echo "**Test Type:** $INPUT_TEST_TYPE" >> comprehensive_report.md
echo "**Trigger:** $EVENT_NAME" >> comprehensive_report.md
echo "**Status:** 🟢 All Tests Passed" >> comprehensive_report.md
echo "" >> comprehensive_report.md
echo "## 🧪 Test Categories Covered:" >> comprehensive_report.md
echo "" >> comprehensive_report.md
echo "### Unit Tests:" >> comprehensive_report.md
echo "- ✅ Core agent functionality" >> comprehensive_report.md
echo "- ✅ Async operations" >> comprehensive_report.md
echo "- ✅ Tool integrations" >> comprehensive_report.md
echo "- ✅ UI components" >> comprehensive_report.md
echo "" >> comprehensive_report.md
echo "### Integration Tests:" >> comprehensive_report.md
echo "- ✅ MCP (Model Context Protocol)" >> comprehensive_report.md
echo "- ✅ RAG (Retrieval Augmented Generation)" >> comprehensive_report.md
echo "- ✅ Base URL API mapping" >> comprehensive_report.md
echo "- ✅ Multi-agent workflows" >> comprehensive_report.md
echo "- ✅ AutoGen framework integration" >> comprehensive_report.md
echo "- ✅ CrewAI framework integration" >> comprehensive_report.md
echo "- 💬 LLM integrations (OpenAI, Anthropic, etc.)" >> comprehensive_report.md
echo "- 🖥️ UI frameworks (Gradio, Streamlit)" >> comprehensive_report.md
echo "- 📊 Memory and persistence" >> comprehensive_report.md
echo "- 🌐 Multi-modal capabilities" >> comprehensive_report.md
echo "- ✅ AutoGen framework integration" >> comprehensive_report.md
echo "- ✅ CrewAI framework integration" >> comprehensive_report.md
echo "" >> comprehensive_report.md
echo "### Key Features Tested:" >> comprehensive_report.md
echo "- 🤖 Agent creation and configuration" >> comprehensive_report.md
echo "- 📋 Task management and execution" >> comprehensive_report.md
echo "- 🔄 Sync/async workflows" >> comprehensive_report.md
echo "- 🛠️ Custom tools and error handling" >> comprehensive_report.md
echo "- 🧠 Knowledge bases and RAG" >> comprehensive_report.md
echo "- 🔌 MCP server connections" >> comprehensive_report.md
echo "- 💬 LLM integrations (OpenAI, Anthropic, etc.)" >> comprehensive_report.md
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: src/praisonai/coverage.xml
flags: comprehensive-tests
name: comprehensive-tests-coverage
fail_ci_if_error: false
verbose: true
- name: Upload Comprehensive Test Results
uses: actions/upload-artifact@v4
if: always()
with:
name: comprehensive-test-results-python-${{ matrix.python-version }}
path: |
comprehensive_report.md
src/praisonai/htmlcov/
src/praisonai/coverage.xml
src/praisonai/.coverage
retention-days: 30
test-matrix-summary:
runs-on: ubuntu-latest
needs: comprehensive-test
if: always()
steps:
- name: Generate Matrix Summary
run: |
echo "# 🎯 Test Matrix Summary" > matrix_summary.md
echo "" >> matrix_summary.md
echo "## Python Version Results:" >> matrix_summary.md
echo "- Python 3.10: ${{ needs.comprehensive-test.result }}" >> matrix_summary.md
echo "- Python 3.11: ${{ needs.comprehensive-test.result }}" >> matrix_summary.md
echo "" >> matrix_summary.md
echo "## Overall Status:" >> matrix_summary.md
if [ "${{ needs.comprehensive-test.result }}" == "success" ]; then
echo "✅ **All tests passed across all Python versions!**" >> matrix_summary.md
else
echo "❌ **Some tests failed. Check individual job logs for details.**" >> matrix_summary.md
fi
- name: Upload Matrix Summary
uses: actions/upload-artifact@v4
with:
name: test-matrix-summary
path: matrix_summary.md
retention-days: 30
-74
View File
@@ -1,74 +0,0 @@
name: Core Tests
on:
push:
branches: [ main, develop ]
paths:
- 'src/**'
- 'pyproject.toml'
- '.github/workflows/test-core.yml'
pull_request:
branches: [ main, develop ]
paths:
- 'src/**'
- 'pyproject.toml'
- '.github/workflows/test-core.yml'
workflow_dispatch:
jobs:
test-core:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install UV
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cd src/praisonai
uv pip install --system ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
uv pip install --system duckduckgo_search
uv pip install --system pytest pytest-asyncio pytest-cov pytest-timeout
uv pip install --system "praisonaiagents[knowledge]"
- name: Set environment variables
run: |
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}" >> $GITHUB_ENV
echo "OPENAI_API_BASE=${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}" >> $GITHUB_ENV
echo "OPENAI_MODEL_NAME=${{ secrets.OPENAI_MODEL_NAME || 'gpt-5-nano' }}" >> $GITHUB_ENV
echo "PYTHONPATH=${{ github.workspace }}/src/praisonai-agents:$PYTHONPATH" >> $GITHUB_ENV
- name: Run Unit Tests
run: |
cd src/praisonai && python -m pytest tests/unit/ -v --tb=short --disable-warnings \
--cov=praisonai --cov-report=xml --cov-branch \
--timeout=60 || echo "Some unit tests failed"
continue-on-error: true
- name: Run Integration Tests
run: |
cd src/praisonai && python -m pytest tests/integration/ -v --tb=short --disable-warnings \
--timeout=60 \
--ignore=tests/integration/test_tracker_complex_tasks.py \
--ignore=tests/integration/test_serve_integration.py \
|| echo "Some integration tests failed"
- name: Upload coverage to Codecov
if: always()
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN || '' }}
files: src/praisonai/coverage.xml
flags: core-tests
fail_ci_if_error: false
-178
View File
@@ -1,178 +0,0 @@
name: Extended Tests
on:
schedule:
- cron: '0 2 * * *'
workflow_dispatch:
jobs:
test-examples:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
persist-credentials: false
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Install UV
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cd src/praisonai
uv pip install --system ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
uv pip install --system duckduckgo_search
# Install knowledge dependencies from praisonai-agents
uv pip install --system "praisonaiagents[knowledge]"
- name: Set environment variables
run: |
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}" >> $GITHUB_ENV
echo "OPENAI_API_BASE=${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}" >> $GITHUB_ENV
echo "OPENAI_MODEL_NAME=${{ secrets.OPENAI_MODEL_NAME || 'gpt-5-nano' }}" >> $GITHUB_ENV
echo "PYTHONPATH=${{ github.workspace }}/src/praisonai-agents:$PYTHONPATH" >> $GITHUB_ENV
echo "PRAISONAI_TELEMETRY_DISABLED=true" >> $GITHUB_ENV
echo "PRAISONAI_DISABLE_TELEMETRY=true" >> $GITHUB_ENV
echo "DO_NOT_TRACK=true" >> $GITHUB_ENV
- name: Test Key Example Scripts
run: |
echo "🧪 Testing key example scripts from praisonai-agents..."
# Create a timeout function for consistent handling
timeout_run() {
timeout 30s "$@" || echo "⏱️ $1 test completed/timed out"
}
# Test basic agent functionality
timeout_run python ${{ github.workspace }}/src/praisonai-agents/basic-agents.py
# Test async functionality
timeout_run python ${{ github.workspace }}/src/praisonai-agents/async_example.py
# Test knowledge/RAG functionality
timeout_run python ${{ github.workspace }}/src/praisonai-agents/knowledge-agents.py
# Test MCP functionality
timeout_run python ${{ github.workspace }}/src/praisonai-agents/mcp-basic.py
# Test UI functionality
timeout_run python ${{ github.workspace }}/src/praisonai-agents/ui.py
echo "✅ Example script testing completed"
continue-on-error: true
performance-test:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
persist-credentials: false
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Install UV
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cd src/praisonai
uv pip install --system ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
uv pip install --system pytest pytest-benchmark
# Install knowledge dependencies from praisonai-agents
uv pip install --system "praisonaiagents[knowledge]"
- name: Set environment variables
run: |
echo "PRAISONAI_TELEMETRY_DISABLED=true" >> $GITHUB_ENV
echo "PRAISONAI_DISABLE_TELEMETRY=true" >> $GITHUB_ENV
echo "DO_NOT_TRACK=true" >> $GITHUB_ENV
- name: Run Performance Benchmarks
run: |
echo "🏃 Running performance benchmarks..."
python -c "
import time
import sys
import statistics
sys.path.insert(0, 'src/praisonai')
print('🏃 Testing agent creation performance...')
times = []
try:
from praisonaiagents import Agent
for i in range(5):
start_time = time.time()
agent = Agent(name=f'PerfAgent{i}')
times.append(time.time() - start_time)
avg_time = statistics.mean(times)
print(f'✅ Average agent creation time: {avg_time:.3f}s')
print(f'📊 Min: {min(times):.3f}s, Max: {max(times):.3f}s')
except Exception as e:
print(f'❌ Agent creation benchmark failed: {e}')
print('🏃 Testing import performance...')
start_time = time.time()
try:
import praisonaiagents
import_time = time.time() - start_time
print(f'✅ Import completed in {import_time:.3f}s')
except Exception as e:
print(f'❌ Import benchmark failed: {e}')
print('🏃 Testing memory usage...')
try:
import psutil
import os
process = psutil.Process(os.getpid())
memory_mb = process.memory_info().rss / 1024 / 1024
print(f'📊 Memory usage: {memory_mb:.1f} MB')
except ImportError:
print('⚠️ psutil not available for memory testing')
except Exception as e:
print(f'❌ Memory benchmark failed: {e}')
"
continue-on-error: true
- name: Generate Performance Report
run: |
echo "## 📊 Performance Test Results" > performance_report.md
echo "" >> performance_report.md
echo "### Benchmarks Run:" >> performance_report.md
echo "- ⚡ Agent creation speed" >> performance_report.md
echo "- 📦 Import performance" >> performance_report.md
echo "- 💾 Memory usage" >> performance_report.md
echo "- 🧪 Example script execution" >> performance_report.md
echo "" >> performance_report.md
echo "_Performance results are logged in the CI output above._" >> performance_report.md
- name: Upload Performance Report
uses: actions/upload-artifact@v4
with:
name: performance-report
path: performance_report.md
retention-days: 5
-158
View File
@@ -1,158 +0,0 @@
name: Framework Integration Tests
on:
workflow_dispatch: # Allow manual triggering
inputs:
framework:
description: 'Framework to test'
required: true
default: 'all'
type: choice
options:
- all
- autogen
- crewai
schedule:
# Run framework tests daily at 6 AM UTC
- cron: '0 6 * * *'
push:
paths:
- 'tests/integration/autogen/**'
- 'tests/integration/crewai/**'
- '.github/workflows/test-frameworks.yml'
jobs:
framework-tests:
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
matrix:
python-version: [3.11]
framework: [autogen, crewai]
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
persist-credentials: false
with:
persist-credentials: false
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install UV
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cd src/praisonai
uv pip install --system ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
uv pip install --system duckduckgo_search
uv pip install --system pytest pytest-asyncio pytest-cov pytest-timeout
- name: Set environment variables
run: |
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}" >> $GITHUB_ENV
echo "OPENAI_API_BASE=${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}" >> $GITHUB_ENV
echo "OPENAI_MODEL_NAME=${{ secrets.OPENAI_MODEL_NAME || 'gpt-5-nano' }}" >> $GITHUB_ENV
- name: Test ${{ matrix.framework }} Framework
run: |
echo "🧪 Testing ${{ matrix.framework }} framework integration with Python ${{ matrix.python-version }}"
cd src/praisonai && python tests/test_runner.py --pattern ${{ matrix.framework }} --verbose --coverage
continue-on-error: false
- name: Generate Framework Test Report
if: always()
run: |
echo "# 🤖 ${{ matrix.framework }} Framework Test Report" > ${{ matrix.framework }}_report.md
echo "" >> ${{ matrix.framework }}_report.md
echo "**Framework:** ${{ matrix.framework }}" >> ${{ matrix.framework }}_report.md
echo "**Python Version:** ${{ matrix.python-version }}" >> ${{ matrix.framework }}_report.md
echo "**Date:** $(date -u)" >> ${{ matrix.framework }}_report.md
echo "**Trigger:** ${{ github.event_name }}" >> ${{ matrix.framework }}_report.md
echo "" >> ${{ matrix.framework }}_report.md
if [ "${{ matrix.framework }}" == "autogen" ]; then
echo "## AutoGen Integration Tests" >> ${{ matrix.framework }}_report.md
echo "- ✅ AutoGen import verification" >> ${{ matrix.framework }}_report.md
echo "- ✅ Basic agent creation through PraisonAI" >> ${{ matrix.framework }}_report.md
echo "- ✅ Conversation flow testing" >> ${{ matrix.framework }}_report.md
echo "- ✅ Configuration validation" >> ${{ matrix.framework }}_report.md
elif [ "${{ matrix.framework }}" == "crewai" ]; then
echo "## CrewAI Integration Tests" >> ${{ matrix.framework }}_report.md
echo "- ✅ CrewAI import verification" >> ${{ matrix.framework }}_report.md
echo "- ✅ Basic crew creation through PraisonAI" >> ${{ matrix.framework }}_report.md
echo "- ✅ Multi-agent workflow testing" >> ${{ matrix.framework }}_report.md
echo "- ✅ Agent collaboration verification" >> ${{ matrix.framework }}_report.md
echo "- ✅ Configuration validation" >> ${{ matrix.framework }}_report.md
fi
echo "" >> ${{ matrix.framework }}_report.md
echo "## Test Commands" >> ${{ matrix.framework }}_report.md
echo '```bash' >> ${{ matrix.framework }}_report.md
echo "# Run ${{ matrix.framework }} tests locally:" >> ${{ matrix.framework }}_report.md
echo "python tests/test_runner.py --pattern ${{ matrix.framework }} --verbose" >> ${{ matrix.framework }}_report.md
echo '```' >> ${{ matrix.framework }}_report.md
- name: Upload Framework Test Results
uses: actions/upload-artifact@v4
if: always()
with:
name: ${{ matrix.framework }}-test-results-python-${{ matrix.python-version }}
path: |
${{ matrix.framework }}_report.md
htmlcov/
coverage.xml
.coverage
retention-days: 14
framework-summary:
runs-on: ubuntu-latest
needs: framework-tests
if: always()
steps:
- name: Generate Framework Summary
run: |
echo "# 🚀 Framework Integration Test Summary" > framework_summary.md
echo "" >> framework_summary.md
echo "## Test Results by Framework and Python Version:" >> framework_summary.md
echo "" >> framework_summary.md
echo "### AutoGen Framework:" >> framework_summary.md
echo "- Python 3.11: ${{ needs.framework-tests.result }}" >> framework_summary.md
echo "" >> framework_summary.md
echo "### CrewAI Framework:" >> framework_summary.md
echo "- Python 3.11: ${{ needs.framework-tests.result }}" >> framework_summary.md
echo "" >> framework_summary.md
echo "## Overall Status:" >> framework_summary.md
if [ "${{ needs.framework-tests.result }}" == "success" ]; then
echo "✅ **All framework integration tests passed!**" >> framework_summary.md
else
echo "❌ **Some framework tests failed. Check individual job logs for details.**" >> framework_summary.md
fi
echo "" >> framework_summary.md
echo "## Frameworks Tested:" >> framework_summary.md
echo "- **AutoGen**: Microsoft's conversational AI framework" >> framework_summary.md
echo "- **CrewAI**: Multi-agent collaboration framework" >> framework_summary.md
echo "" >> framework_summary.md
echo "## Test Coverage:" >> framework_summary.md
echo "- Import verification" >> framework_summary.md
echo "- Agent/crew creation" >> framework_summary.md
echo "- Workflow execution" >> framework_summary.md
echo "- Configuration validation" >> framework_summary.md
echo "- Integration with PraisonAI" >> framework_summary.md
- name: Upload Framework Summary
uses: actions/upload-artifact@v4
with:
name: framework-test-summary
path: framework_summary.md
retention-days: 30
-560
View File
@@ -1,560 +0,0 @@
name: Optimized Test Suite
on:
push:
branches: [ main, develop ]
paths:
- 'src/**'
- 'pyproject.toml'
- '.github/workflows/test-optimized.yml'
pull_request:
branches: [ main, develop ]
paths:
- 'src/**'
- 'pyproject.toml'
- '.github/workflows/test-optimized.yml'
schedule:
# Nightly extended tests at 3 AM UTC
- cron: '0 3 * * *'
workflow_dispatch:
inputs:
tier:
description: 'Test tier to run'
required: true
default: 'main'
type: choice
options:
- smoke
- main
- extended
- nightly
env:
PYTHONPATH: ${{ github.workspace }}/src/praisonai-agents
# Test gating environment variables
PRAISONAI_ALLOW_NETWORK: '0'
PRAISONAI_LIVE_TESTS: '0'
jobs:
# ============================================
# SMOKE TESTS - Fast unit tests, no network
# Target: <= 2 minutes
# ============================================
smoke:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Cache pip packages
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-smoke-${{ hashFiles('**/pyproject.toml') }}
restore-keys: |
${{ runner.os }}-pip-smoke-
${{ runner.os }}-pip-
- name: Install minimal dependencies
run: |
pip install --upgrade pip
# Install praisonai-agents with all deps (required for tests)
cd src/praisonai-agents
pip install -e ".[all]"
cd ../praisonai
pip install -e ".[chat,code]"
pip install pytest pytest-asyncio pytest-timeout prompt_toolkit
- name: Run Smoke Tests
env:
PRAISONAI_TEST_TIER: smoke
PRAISONAI_ALLOW_NETWORK: '0'
run: |
cd src/praisonai
# Run only CLI tests for smoke - fast and critical path
python -m pytest tests/unit/cli/ \
-m "not slow and not network" \
-q --tb=line \
--timeout=30 \
--ignore=tests/fixtures \
--ignore=tests/unit/cli/test_message_queue.py \
--maxfail=5 \
|| echo "Some smoke tests failed"
- name: Smoke Test Summary
if: always()
run: echo "✅ Smoke tests completed"
# ============================================
# MAIN TESTS - Unit + safe integration
# Target: <= 5 minutes
# ============================================
main:
needs: smoke
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
matrix:
python-version: ['3.11']
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Cache pip packages
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-main-${{ hashFiles('**/pyproject.toml') }}
restore-keys: |
${{ runner.os }}-pip-main-
${{ runner.os }}-pip-
- name: Install dependencies
run: |
pip install --upgrade pip
# Install praisonai-agents with all deps (required for tests)
cd src/praisonai-agents
pip install -e ".[all]"
cd ../praisonai
pip install -e ".[crewai,autogen]"
pip install pytest pytest-asyncio pytest-timeout pytest-cov pytest-xdist
- name: Run Main Tests
env:
PRAISONAI_TEST_TIER: main
PRAISONAI_ALLOW_NETWORK: '0'
OPENAI_API_KEY: 'test-key'
ANTHROPIC_API_KEY: 'test-key'
GOOGLE_API_KEY: 'test-key'
run: |
cd src/praisonai
python -m pytest tests/unit/ tests/integration/ \
-m "not provider_anthropic and not provider_google and not provider_ollama and not provider_grok_xai and not provider_groq and not provider_cohere" \
-q --tb=line \
--timeout=60 \
--ignore=tests/fixtures \
--ignore=tests/e2e \
--ignore=tests/live \
--ignore=tests/unit/jobs \
--ignore=tests/unit/api \
--cov=praisonai \
--cov-report=xml \
-n 4 \
--maxfail=10 \
|| echo "Some tests failed"
- name: Upload coverage
if: matrix.python-version == '3.11'
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN || '' }}
files: src/praisonai/coverage.xml
flags: main-tests
fail_ci_if_error: false
# ============================================
# OPENAI LIVE TESTS - Real OpenAI API calls
# Only runs if OPENAI_API_KEY secret is set
# Safe for forks (skips gracefully if no key)
# ============================================
openai-live:
needs: smoke
runs-on: ubuntu-latest
timeout-minutes: 8
# This job always runs but steps are conditional on secret availability
steps:
- name: Check if OpenAI key is available
id: check-key
run: |
if [ -n "${{ secrets.OPENAI_API_KEY }}" ]; then
echo "has_key=true" >> $GITHUB_OUTPUT
else
echo "has_key=false" >> $GITHUB_OUTPUT
echo "⚠️ OPENAI_API_KEY not set - skipping live tests"
fi
- uses: actions/checkout@v4
with:
persist-credentials: false
if: steps.check-key.outputs.has_key == 'true'
- name: Set up Python 3.11
if: steps.check-key.outputs.has_key == 'true'
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Cache pip packages
if: steps.check-key.outputs.has_key == 'true'
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-openai-${{ hashFiles('**/pyproject.toml') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install dependencies
if: steps.check-key.outputs.has_key == 'true'
run: |
pip install --upgrade pip
cd src/praisonai-agents
pip install -e ".[all]"
cd ../praisonai
pip install -e ".[openai]"
pip install pytest pytest-asyncio pytest-timeout
- name: Run OpenAI Live Tests
if: steps.check-key.outputs.has_key == 'true'
env:
PRAISONAI_TEST_TIER: extended
PRAISONAI_ALLOW_NETWORK: '1'
PRAISONAI_LIVE_TESTS: '1'
PRAISONAI_TEST_PROVIDERS: 'openai'
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
OPENAI_MODEL_NAME: ${{ secrets.OPENAI_MODEL_NAME || 'gpt-4o-mini' }}
run: |
cd src/praisonai
python -m pytest tests/ \
-m "provider_openai or real" \
-v --tb=short \
--timeout=120 \
--ignore=tests/fixtures \
|| echo "Some OpenAI tests failed"
- name: Skip notice
if: steps.check-key.outputs.has_key == 'false'
run: echo "✅ OpenAI live tests skipped (no API key available - this is expected for forks)"
# ============================================
# EXTENDED PROVIDER TESTS - Nightly only
# Runs all provider-specific tests
# ============================================
extended-anthropic:
if: github.event_name == 'schedule' || github.event.inputs.tier == 'extended' || github.event.inputs.tier == 'nightly'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Check if Anthropic key is available
id: check-key
run: |
if [ -n "${{ secrets.ANTHROPIC_API_KEY }}" ]; then
echo "has_key=true" >> $GITHUB_OUTPUT
else
echo "has_key=false" >> $GITHUB_OUTPUT
echo "⚠️ ANTHROPIC_API_KEY not set - skipping tests"
fi
- uses: actions/checkout@v4
with:
persist-credentials: false
if: steps.check-key.outputs.has_key == 'true'
- name: Set up Python 3.11
if: steps.check-key.outputs.has_key == 'true'
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
if: steps.check-key.outputs.has_key == 'true'
run: |
pip install --upgrade pip
cd src/praisonai-agents
pip install -e ".[all]"
cd ../praisonai
pip install -e ".[anthropic]"
pip install pytest pytest-asyncio pytest-timeout
- name: Run Anthropic Tests
if: steps.check-key.outputs.has_key == 'true'
env:
PRAISONAI_ALLOW_NETWORK: '1'
PRAISONAI_LIVE_TESTS: '1'
PRAISONAI_TEST_PROVIDERS: 'anthropic'
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
cd src/praisonai
python -m pytest tests/ \
-m "provider_anthropic" \
-v --tb=short \
--timeout=120 \
--ignore=tests/fixtures \
|| echo "Anthropic tests completed"
- name: Skip notice
if: steps.check-key.outputs.has_key == 'false'
run: echo "✅ Anthropic tests skipped (no API key available)"
extended-google:
if: github.event_name == 'schedule' || github.event.inputs.tier == 'extended' || github.event.inputs.tier == 'nightly'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Check if Google key is available
id: check-key
env:
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
run: |
if [ -n "$GOOGLE_API_KEY" ]; then
echo "has_key=true" >> $GITHUB_OUTPUT
else
echo "has_key=false" >> $GITHUB_OUTPUT
echo "⚠️ GOOGLE_API_KEY not set - skipping tests"
fi
- uses: actions/checkout@v4
with:
persist-credentials: false
if: steps.check-key.outputs.has_key == 'true'
- name: Set up Python 3.11
if: steps.check-key.outputs.has_key == 'true'
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
if: steps.check-key.outputs.has_key == 'true'
run: |
pip install --upgrade pip
cd src/praisonai-agents
pip install -e ".[all]"
cd ../praisonai
pip install -e ".[google]"
pip install pytest pytest-asyncio pytest-timeout
- name: Run Google/Gemini Tests
if: steps.check-key.outputs.has_key == 'true'
env:
PRAISONAI_ALLOW_NETWORK: '1'
PRAISONAI_LIVE_TESTS: '1'
PRAISONAI_TEST_PROVIDERS: 'google'
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
run: |
cd src/praisonai
python -m pytest tests/ \
-m "provider_google" \
-v --tb=short \
--timeout=120 \
--ignore=tests/fixtures \
|| echo "Google tests completed"
- name: Skip notice
if: steps.check-key.outputs.has_key == 'false'
run: echo "✅ Google tests skipped (no API key available)"
extended-groq:
if: github.event_name == 'schedule' || github.event.inputs.tier == 'extended' || github.event.inputs.tier == 'nightly'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Check if Groq key is available
id: check-key
env:
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
run: |
if [ -n "$GROQ_API_KEY" ]; then
echo "has_key=true" >> $GITHUB_OUTPUT
else
echo "has_key=false" >> $GITHUB_OUTPUT
echo "⚠️ GROQ_API_KEY not set - skipping tests"
fi
- uses: actions/checkout@v4
with:
persist-credentials: false
if: steps.check-key.outputs.has_key == 'true'
- name: Set up Python 3.11
if: steps.check-key.outputs.has_key == 'true'
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
if: steps.check-key.outputs.has_key == 'true'
run: |
pip install --upgrade pip
cd src/praisonai-agents
pip install -e ".[all]"
cd ../praisonai
pip install -e .
pip install pytest pytest-asyncio pytest-timeout
- name: Run Groq Tests
if: steps.check-key.outputs.has_key == 'true'
env:
PRAISONAI_ALLOW_NETWORK: '1'
PRAISONAI_LIVE_TESTS: '1'
PRAISONAI_TEST_PROVIDERS: 'groq'
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
run: |
cd src/praisonai
python -m pytest tests/ \
-m "provider_groq" \
-v --tb=short \
--timeout=120 \
--ignore=tests/fixtures \
|| echo "Groq tests completed"
- name: Skip notice
if: steps.check-key.outputs.has_key == 'false'
run: echo "✅ Groq tests skipped (no API key available)"
extended-xai:
if: github.event_name == 'schedule' || github.event.inputs.tier == 'extended' || github.event.inputs.tier == 'nightly'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Check if xAI key is available
id: check-key
env:
XAI_API_KEY: ${{ secrets.XAI_API_KEY }}
run: |
if [ -n "$XAI_API_KEY" ]; then
echo "has_key=true" >> $GITHUB_OUTPUT
else
echo "has_key=false" >> $GITHUB_OUTPUT
echo "⚠️ XAI_API_KEY not set - skipping tests"
fi
- uses: actions/checkout@v4
with:
persist-credentials: false
if: steps.check-key.outputs.has_key == 'true'
- name: Set up Python 3.11
if: steps.check-key.outputs.has_key == 'true'
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
if: steps.check-key.outputs.has_key == 'true'
run: |
pip install --upgrade pip
cd src/praisonai-agents
pip install -e ".[all]"
cd ../praisonai
pip install -e .
pip install pytest pytest-asyncio pytest-timeout
- name: Run xAI/Grok Tests
if: steps.check-key.outputs.has_key == 'true'
env:
PRAISONAI_ALLOW_NETWORK: '1'
PRAISONAI_LIVE_TESTS: '1'
PRAISONAI_TEST_PROVIDERS: 'grok_xai'
XAI_API_KEY: ${{ secrets.XAI_API_KEY }}
run: |
cd src/praisonai
python -m pytest tests/ \
-m "provider_grok_xai" \
-v --tb=short \
--timeout=120 \
--ignore=tests/fixtures \
|| echo "xAI tests completed"
- name: Skip notice
if: steps.check-key.outputs.has_key == 'false'
run: echo "✅ xAI tests skipped (no API key available)"
extended-cohere:
if: github.event_name == 'schedule' || github.event.inputs.tier == 'extended' || github.event.inputs.tier == 'nightly'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Check if Cohere key is available
id: check-key
env:
COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }}
run: |
if [ -n "$COHERE_API_KEY" ]; then
echo "has_key=true" >> $GITHUB_OUTPUT
else
echo "has_key=false" >> $GITHUB_OUTPUT
echo "⚠️ COHERE_API_KEY not set - skipping tests"
fi
- uses: actions/checkout@v4
with:
persist-credentials: false
if: steps.check-key.outputs.has_key == 'true'
- name: Set up Python 3.11
if: steps.check-key.outputs.has_key == 'true'
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
if: steps.check-key.outputs.has_key == 'true'
run: |
pip install --upgrade pip
cd src/praisonai-agents
pip install -e ".[all]"
cd ../praisonai
pip install -e ".[cohere]"
pip install pytest pytest-asyncio pytest-timeout
- name: Run Cohere Tests
if: steps.check-key.outputs.has_key == 'true'
env:
PRAISONAI_ALLOW_NETWORK: '1'
PRAISONAI_LIVE_TESTS: '1'
PRAISONAI_TEST_PROVIDERS: 'cohere'
COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }}
run: |
cd src/praisonai
python -m pytest tests/ \
-m "provider_cohere" \
-v --tb=short \
--timeout=120 \
--ignore=tests/fixtures \
|| echo "Cohere tests completed"
- name: Skip notice
if: steps.check-key.outputs.has_key == 'false'
run: echo "✅ Cohere tests skipped (no API key available)"
# ============================================
# TEST SUMMARY
# ============================================
test-summary:
needs: [smoke, main]
if: always()
runs-on: ubuntu-latest
steps:
- name: Test Summary
run: |
echo "# 📊 Test Suite Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Job | Status |" >> $GITHUB_STEP_SUMMARY
echo "|-----|--------|" >> $GITHUB_STEP_SUMMARY
echo "| Smoke | ${{ needs.smoke.result }} |" >> $GITHUB_STEP_SUMMARY
echo "| Main | ${{ needs.main.result }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "## Test Tiers" >> $GITHUB_STEP_SUMMARY
echo "- **smoke**: Fast unit tests, no network (≤2 min)" >> $GITHUB_STEP_SUMMARY
echo "- **main**: Unit + integration, no network (≤5 min)" >> $GITHUB_STEP_SUMMARY
echo "- **openai-live**: OpenAI API tests (when key available)" >> $GITHUB_STEP_SUMMARY
echo "- **extended-***: Provider-specific tests (nightly)" >> $GITHUB_STEP_SUMMARY
-180
View File
@@ -1,180 +0,0 @@
name: Real End-to-End Tests
# ⚠️ WARNING: This workflow makes real API calls and incurs costs!
# Only runs when manually triggered to prevent accidental charges
on:
workflow_dispatch: # Manual trigger only
inputs:
framework:
description: 'Framework to test (⚠️ Will incur API costs!)'
required: true
default: 'none'
type: choice
options:
- none
- autogen
- crewai
- all
confirm_costs:
description: 'I understand this will make real API calls and may incur costs'
required: true
type: boolean
default: false
jobs:
real-tests:
runs-on: ubuntu-latest
if: ${{ github.event.inputs.confirm_costs == 'true' && github.event.inputs.framework != 'none' }}
timeout-minutes: 15
strategy:
matrix:
python-version: [3.11] # Single version to minimize costs
steps:
- name: 🚨 Cost Warning
env:
INPUT_FRAMEWORK: ${{ github.event.inputs.framework }}
INPUT_CONFIRM_COSTS: ${{ github.event.inputs.confirm_costs }}
run: |
echo "⚠️ WARNING: This workflow will make real API calls!"
echo "💰 This may incur charges on your API accounts"
echo "🎯 Framework: $INPUT_FRAMEWORK"
echo "✅ Cost confirmation: $INPUT_CONFIRM_COSTS"
- name: Checkout code
uses: actions/checkout@v4
with:
persist-credentials: false
with:
persist-credentials: false
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install UV
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cd src/praisonai
uv pip install --system ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
uv pip install --system pytest pytest-asyncio pytest-cov
# Install knowledge dependencies from praisonai-agents
uv pip install --system "praisonaiagents[knowledge]"
- name: Set environment variables
run: |
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }}" >> $GITHUB_ENV
echo "ANTHROPIC_API_KEY=${{ secrets.ANTHROPIC_API_KEY }}" >> $GITHUB_ENV
echo "GOOGLE_API_KEY=${{ secrets.GOOGLE_API_KEY }}" >> $GITHUB_ENV
- name: Verify API Keys
run: |
if [ -z "${{ secrets.OPENAI_API_KEY }}" ]; then
echo "❌ OPENAI_API_KEY not set in secrets"
echo "🔧 Add your API key to repository secrets"
exit 1
fi
echo "✅ API keys configured"
- name: Run Real AutoGen Tests
if: ${{ github.event.inputs.framework == 'autogen' || github.event.inputs.framework == 'all' }}
run: |
echo "🤖 Running REAL AutoGen tests (⚠️ API costs may apply)"
cd src/praisonai && python -m pytest tests/e2e/autogen/ -v -m real --tb=short
continue-on-error: false
- name: Run Real CrewAI Tests
if: ${{ github.event.inputs.framework == 'crewai' || github.event.inputs.framework == 'all' }}
run: |
echo "⛵ Running REAL CrewAI tests (⚠️ API costs may apply)"
cd src/praisonai && python -m pytest tests/e2e/crewai/ -v -m real --tb=short
continue-on-error: false
- name: Generate Real Test Report
if: always()
env:
INPUT_FRAMEWORK: ${{ github.event.inputs.framework }}
run: |
echo "# 🔥 Real End-to-End Test Report" > real_test_report.md
echo "" >> real_test_report.md
echo "⚠️ **WARNING: This report represents tests that made real API calls**" >> real_test_report.md
echo "" >> real_test_report.md
echo "**Framework Tested:** $INPUT_FRAMEWORK" >> real_test_report.md
echo "**Python Version:** ${{ matrix.python-version }}" >> real_test_report.md
echo "**Date:** $(date -u)" >> real_test_report.md
echo "**Triggered by:** $GITHUB_ACTOR" >> real_test_report.md
echo "" >> real_test_report.md
echo "## 🧪 Test Results" >> real_test_report.md
echo "" >> real_test_report.md
if [ "$INPUT_FRAMEWORK" == "autogen" ] || [ "$INPUT_FRAMEWORK" == "all" ]; then
echo "### AutoGen Real Tests:" >> real_test_report.md
echo "- Environment verification" >> real_test_report.md
echo "- Agent creation with real API calls" >> real_test_report.md
echo "- Configuration validation" >> real_test_report.md
echo "" >> real_test_report.md
fi
if [ "$INPUT_FRAMEWORK" == "crewai" ] || [ "$INPUT_FRAMEWORK" == "all" ]; then
echo "### CrewAI Real Tests:" >> real_test_report.md
echo "- Environment verification" >> real_test_report.md
echo "- Crew creation with real API calls" >> real_test_report.md
echo "- Multi-agent setup validation" >> real_test_report.md
echo "" >> real_test_report.md
fi
echo "## 💰 Cost Considerations" >> real_test_report.md
echo "- These tests made actual API calls to LLM providers" >> real_test_report.md
echo "- Costs depend on your API pricing tier" >> real_test_report.md
echo "- Tests are designed to be minimal to reduce costs" >> real_test_report.md
echo "- Check your API provider dashboard for actual usage" >> real_test_report.md
echo "## 📋 Next Steps" >> real_test_report.md
echo "- Review test results for any failures" >> real_test_report.md
echo "- Check API usage in your provider dashboard" >> real_test_report.md
echo "- Use mock tests (tests/integration/) for routine testing" >> real_test_report.md
- name: Upload Real Test Results
uses: actions/upload-artifact@v4
if: always()
with:
name: real-test-results-${{ github.event.inputs.framework }}-python-${{ matrix.python-version }}
path: |
real_test_report.md
retention-days: 30
# Safety job that runs when costs not confirmed
safety-check:
runs-on: ubuntu-latest
if: ${{ github.event.inputs.confirm_costs != 'true' || github.event.inputs.framework == 'none' }}
steps:
- name: 🛡️ Safety Check Failed
env:
INPUT_FRAMEWORK: ${{ github.event.inputs.framework }}
INPUT_CONFIRM_COSTS: ${{ github.event.inputs.confirm_costs }}
run: |
echo "🚨 Real tests not executed due to safety checks:"
echo ""
echo "✅ Costs confirmed: $INPUT_CONFIRM_COSTS"
echo "✅ Framework selected: $INPUT_FRAMEWORK"
echo ""
echo "To run real tests:"
echo "1. Select a framework (autogen, crewai, or all)"
echo "2. Check 'I understand this will make real API calls and may incur costs'"
echo "3. Ensure API keys are set in repository secrets"
echo ""
echo "💡 For cost-free testing, use mock tests instead:"
echo " - Run 'python -m pytest tests/integration/' locally"
echo " - Or trigger other workflows that use mock tests"
exit 1
-218
View File
@@ -1,218 +0,0 @@
name: Windows Tests
on:
push:
branches: [main, develop]
paths:
- 'src/**'
- 'pyproject.toml'
- '.github/workflows/test-windows.yml'
pull_request:
branches: [main, develop]
paths:
- 'src/**'
- 'pyproject.toml'
- '.github/workflows/test-windows.yml'
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
PYTHONUTF8: 1
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- 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 -e .
shell: bash
- name: Install praisonai wrapper
run: |
cd src/praisonai
pip install -e .
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; print('Task 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
run: |
python -c "
from praisonaiagents import Workflow
w = Workflow(name='test')
print('Workflow:', w.name)
"
# ==================== 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
# ==================== PACKAGING TESTS ====================
- name: Test packaging/daemon entry points
run: |
echo "Testing both entry point methods..."
python -m praisonai --version
praisonai --version
- name: Test doctor packaging command
run: |
echo "Testing doctor packaging diagnostics..."
praisonai doctor packaging --json
# ==================== 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')
"
-57
View File
@@ -1,57 +0,0 @@
name: Update API Reference
on:
push:
branches: [ "main" ]
paths:
- 'src/praisonai-agents/praisonaiagents/**/*.py'
- 'src/praisonai/praisonai/**/*.py'
- 'src/praisonai-ts/src/**/*.ts'
- '.github/workflows/update-api-md.yml'
permissions:
contents: write
jobs:
update-api-md:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: main
persist-credentials: true
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Generate api.md
run: |
cd $GITHUB_WORKSPACE
python3 src/praisonai/scripts/generate_api_md.py
- name: Check for changes
id: check_changes
run: |
if git diff --quiet api.md; then
echo "changes=false" >> $GITHUB_OUTPUT
echo "No changes to api.md"
else
echo "changes=true" >> $GITHUB_OUTPUT
echo "api.md has been updated"
git diff api.md | head -50
fi
- name: Commit and push changes
if: steps.check_changes.outputs.changes == 'true'
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "docs: auto-update api.md [skip ci]"
file_pattern: 'api.md'
commit_user_name: "MervinPraison"
commit_user_email: "[email protected]"
commit_author: "MervinPraison <[email protected]>"
-83
View File
@@ -1,83 +0,0 @@
name: Update Documentation Parity Tracker
on:
push:
branches: [ "main" ]
paths:
- 'src/praisonai-agents/praisonaiagents/**/*.py'
- 'src/praisonai-ts/src/**/*.ts'
- 'src/praisonai-rust/src/**/*.rs'
- 'src/praisonai/praisonai/_dev/parity/**/*.py'
- '.github/workflows/update-docs-parity.yml'
workflow_dispatch: # Allow manual trigger
permissions:
contents: write
jobs:
update-docs-parity:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: main
persist-credentials: true
fetch-depth: 0
- name: Checkout PraisonAIDocs
id: checkout_docs
continue-on-error: true
uses: actions/checkout@v4
with:
repository: MervinPraison/PraisonAIDocs
path: PraisonAIDocs
token: ${{ secrets.SECRETS_ADMIN_PAT }}
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install pyyaml
- name: Generate docs parity trackers
if: steps.checkout_docs.outcome == 'success'
run: |
cd $GITHUB_WORKSPACE
python3 src/praisonai/scripts/generate_docs_parity.py --docs-root PraisonAIDocs/docs --copy-docs
- name: Check for changes
id: check_changes
run: |
if git diff --quiet src/praisonai-agents/DOCS_PARITY.md src/praisonai-ts/DOCS_PARITY.md src/praisonai-rust/DOCS_PARITY.md 2>/dev/null; then
echo "changes=false" >> $GITHUB_OUTPUT
echo "No changes to docs parity trackers"
else
echo "changes=true" >> $GITHUB_OUTPUT
echo "Docs parity trackers have been updated"
git diff --stat src/praisonai-agents/DOCS_PARITY.md src/praisonai-ts/DOCS_PARITY.md src/praisonai-rust/DOCS_PARITY.md
fi
- name: Commit and push changes to praisonai-package
if: steps.check_changes.outputs.changes == 'true'
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "docs: auto-update documentation parity trackers [skip ci]"
file_pattern: 'src/praisonai-agents/DOCS_PARITY.md src/praisonai-ts/DOCS_PARITY.md src/praisonai-rust/DOCS_PARITY.md'
commit_user_name: "MervinPraison"
commit_user_email: "[email protected]"
commit_author: "MervinPraison <[email protected]>"
- name: Commit and push changes to PraisonAIDocs
if: steps.check_changes.outputs.changes == 'true' && steps.checkout_docs.outcome == 'success'
run: |
cd PraisonAIDocs
git config user.name "MervinPraison"
git config user.email "[email protected]"
git add docs/features/DOCS_PARITY.md docs/js/DOCS_PARITY.md docs/rust/DOCS_PARITY.md
git diff --staged --quiet || git commit -m "docs: auto-update documentation parity trackers [skip ci]"
git push
@@ -1,61 +0,0 @@
name: Update Feature Parity Tracker
on:
push:
branches: [ "main" ]
paths:
- 'src/praisonai-agents/praisonaiagents/**/*.py'
- 'src/praisonai-ts/src/**/*.ts'
- 'src/praisonai-rust/src/**/*.rs'
- '.github/workflows/update-parity-tracker.yml'
permissions:
contents: write
jobs:
update-parity-tracker:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: main
persist-credentials: true
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: pip install pyyaml
- name: Generate parity trackers
run: |
cd $GITHUB_WORKSPACE
python3 src/praisonai/scripts/generate_parity_tracker.py
- name: Check for changes
id: check_changes
run: |
if git diff --quiet src/praisonai-ts/FEATURE_PARITY_TRACKER.json src/praisonai-ts/PARITY.md src/praisonai-rust/FEATURE_PARITY_TRACKER.json src/praisonai-rust/PARITY.md 2>/dev/null; then
echo "changes=false" >> $GITHUB_OUTPUT
echo "No changes to parity trackers"
else
echo "changes=true" >> $GITHUB_OUTPUT
echo "Parity trackers have been updated"
git diff src/praisonai-ts/FEATURE_PARITY_TRACKER.json | head -50
fi
- name: Commit and push changes
if: steps.check_changes.outputs.changes == 'true'
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "docs: auto-update feature parity trackers [skip ci]"
file_pattern: 'src/praisonai-ts/FEATURE_PARITY_TRACKER.json src/praisonai-ts/PARITY.md src/praisonai-rust/FEATURE_PARITY_TRACKER.json src/praisonai-rust/PARITY.md'
commit_user_name: "MervinPraison"
commit_user_email: "[email protected]"
commit_author: "MervinPraison <[email protected]>"
-101
View File
@@ -1,101 +0,0 @@
workspace.code-workspace
.vscode
crewai
.cache
__pycache__
chroma.sqlite3
test
dist
.env
assets
.idea
.DS_Store
.pytest_cache
praisonAI.egg-info
flagged
test.yaml
db
praisonai_prompt.txt
watch.sh
docs.sh
other
output
!src/praisonai/praisonai/cli/output/
!src/praisonai-agents/praisonaiagents/output/
.files
threads.db
threads.db-journal
.chainlit
!praisonai/ui/config/.chainlit
site
# Ignore Sphinx build directory
docs/_build/
docs/source/
docs/build/
# Ignore Sphinx cache
docs/_build/doctrees/
docs/_build/doctrees/*
docs/_build/doctrees/.doctrees
# Ignore Sphinx logs and local build files
docs/_build/.buildinfo
docs/_build/.buildinfo/*
docs/_build/.buildinfo/.buildinfo
praisonai/doc
# agentops
trained_agents_data.pkl
agentops.log
# crewAI
crewAI
!tests/integration/crewai
!tests/e2e/crewai
!src/praisonai/tests/integration/crewai
!src/praisonai/tests/e2e/crewai
# virtualenv
.venv
# Credentials
credentials.json
# node_modules
node_modules
outputs
agents/praisonaiagents/build
agents/praisonaiagents/dist
agents/praisonaiagents/praisonaiagents.egg-info
.codegpt
.praison
# Local Netlify folder
.netlify
.qodo
CopilotKit*
.gemini
issue_details.json
# MCP Registry tokens
.mcpregistry_*
*.log
.internal
.praisonai
# Rust / Cargo
target/
Cargo.lock
**/*.rs.bk
*.pdb
.windsurf
src/praisonai/build*.egg-info/
src/praisonai/PraisonAI.egg-info/
jobs/*
*.egg-info
File renamed without changes.
+2033
View File
File diff suppressed because it is too large. Load diff
+1
View File
@@ -0,0 +1 @@
docs.praison.ai
-14
View File
@@ -1,14 +0,0 @@
# Contributing to PraisonAI
Thank you for your interest! Here's how to get started:
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Submit a pull request
## Guidelines
- Follow existing code style
- Add tests for new features
- Update documentation as needed
-20
View File
@@ -1,20 +0,0 @@
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+20
View File
@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
-968
View File
@@ -1,968 +0,0 @@
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset=".github/images/logo_dark.png" />
<source media="(prefers-color-scheme: light)" srcset=".github/images/logo_light.png" />
<img alt="PraisonAI Logo" src=".github/images/logo_light.png" width="250" />
</picture>
</p>
<!-- mcp-name: io.github.MervinPraison/praisonai -->
<p align="center">
<a href="https://github.com/MervinPraison/PraisonAI"><img src="https://static.pepy.tech/badge/PraisonAI" alt="Total Downloads" /></a>
<a href="https://github.com/MervinPraison/PraisonAI"><img src="https://img.shields.io/github/v/release/MervinPraison/PraisonAI" alt="Latest Stable Version" /></a>
<a href="https://github.com/MervinPraison/PraisonAI"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License" /></a>
<a href="https://registry.modelcontextprotocol.io/servers/io.github.MervinPraison/praisonai"><img src="https://img.shields.io/badge/MCP-Registry-blue" alt="MCP Registry" /></a>
</p>
<div align="center">
# PraisonAI 🦞
<a href="https://trendshift.io/repositories/9130" target="_blank"><img src="https://trendshift.io/api/badge/repositories/9130" alt="MervinPraison%2FPraisonAI | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
</div>
PraisonAI 🦞 — **Hire a 24/7 AI Workforce.** Stop writing boilerplate and start shipping autonomous, self-improving agents that research, plan, and execute tasks across your apps. From one agent to an entire organization, deployed in 5 lines of code.
```bash
curl -fsSL https://praison.ai/install.sh | bash
```
<div align="center">
<br>
<a href="https://x.com/elonmusk/status/1893870468249141688" target="_blank">
<img src="https://img.shields.io/badge/Highlighted_by_Elon_Musk-000000?style=for-the-badge&logo=x&logoColor=white" alt="Highlighted by Elon Musk" />
</a>
<br>
</div>
<p align="center">
<img src=".github/images/dashboard.png" alt="PraisonAI Dashboard" width="800" />
</p>
<p align="center">
<img src=".github/images/agentflow.gif" alt="PraisonAI AgentFlow" width="800" />
</p>
```
██████╗ ██████╗ █████╗ ██╗███████╗ ██████╗ ███╗ ██╗ █████╗ ██╗
██╔══██╗██╔══██╗██╔══██╗██║██╔════╝██╔═══██╗████╗ ██║ ██╔══██╗██║
██████╔╝██████╔╝███████║██║███████╗██║ ██║██╔██╗ ██║ ███████║██║
██╔═══╝ ██╔══██╗██╔══██║██║╚════██║██║ ██║██║╚██╗██║ ██╔══██║██║
██║ ██║ ██║██║ ██║██║███████║╚██████╔╝██║ ╚████║ ██║ ██║██║
╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚══════╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝
pip install praisonai
```
<p align="center">
<img src=".github/images/latest_ai_news_and_crawl_each_url_to_find_info.gif" alt="PraisonAI command execution" width="800" />
</p>
\* `export TAVILY_API_KEY=xxxxx`
<div align="center">
<a href="https://docs.praison.ai">
<p align="center">
<img src="https://img.shields.io/badge/📚_Documentation-Visit_docs.praison.ai-blue?style=for-the-badge&logo=bookstack&logoColor=white" alt="Documentation" />
</p>
</a>
</div>
---
## 🎯 Use Cases
AI agents solving real-world problems across industries:
| Use Case | Description |
|----------|-------------|
| 🔍 **Research & Analysis** | Conduct deep research, gather information, and generate insights from multiple sources automatically |
| 💻 **Code Generation** | Write, debug, and refactor code with AI agents that understand your codebase and requirements |
| ✍️ **Content Creation** | Generate blog posts, documentation, marketing copy, and technical writing with multi-agent teams |
| 📊 **Data Pipelines** | Extract, transform, and analyze data from APIs, databases, and web sources automatically |
| 🤖 **Customer Support** | Deploy 24/7 support bots on Telegram, Discord, Slack with memory and knowledge-backed responses |
| ⚙️ **Workflow Automation** | Automate multi-step business processes with agents that hand off tasks, verify results, and self-correct |
---
## 🚀 Meet your first Agent (Under 1 Minute)
1. Install the lightweight core SDK:
```bash
pip install praisonaiagents
export OPENAI_API_KEY="your-api-key"
```
2. Run your first autonomous agent:
```python
from praisonaiagents import Agent
# Give your agent a goal, and watch it work.
agent = Agent(instructions="You are a senior data analyst.")
agent.start("Analyze the top 3 tech trends of 2026 and format as a markdown table.")
```
---
## 🌌 The PraisonAI Ecosystem
Start simple with the core SDK, or expand to full visual builders and dashboards when you're ready.
* **Core SDK (`praisonaiagents`)**: For pure Python development. `pip install praisonaiagents`
* 💻 **PraisonAI CLI (`praisonai`)**: For terminal-based developers. `pip install praisonai`
* 🦞 **Claw Dashboard**: Connect agents directly to Telegram, Slack, or Discord. `pip install "praisonai[claw]"`
* 🔗 **Flow Visual Builder**: Drag-and-drop workflow creation. `pip install "praisonai[flow]"`
* 🤖 **PraisonAI UI**: Clean chat interface. `pip install "praisonai[ui]"`
### JavaScript SDK
```bash
npm install praisonai
```
## 🧠 Supported Providers & Features
Powered by 100+ LLMs (OpenAI, Anthropic, Gemini & local models).
<p align="center">
<img src="https://img.shields.io/badge/OpenAI-412991?style=flat&logo=openai&logoColor=white" alt="OpenAI" />
<img src="https://img.shields.io/badge/Anthropic-191919?style=flat&logo=anthropic&logoColor=white" alt="Anthropic" />
<img src="https://img.shields.io/badge/Google_Gemini-4285F4?style=flat&logo=google&logoColor=white" alt="Google Gemini" />
<img src="https://img.shields.io/badge/DeepSeek-566AB2?style=flat" alt="DeepSeek" />
<img src="https://img.shields.io/badge/Azure-0078D4?style=flat&logo=microsoftazure&logoColor=white" alt="Azure" />
<img src="https://img.shields.io/badge/Ollama-000000?style=flat" alt="Ollama" />
<img src="https://img.shields.io/badge/Groq-F05237?style=flat" alt="Groq" />
<img src="https://img.shields.io/badge/Mistral-FF7000?style=flat" alt="Mistral" />
<img src="https://img.shields.io/badge/Cerebras-F05A28?style=flat" alt="Cerebras" />
<img src="https://img.shields.io/badge/Cohere-39594D?style=flat" alt="Cohere" />
<img src="https://img.shields.io/badge/OpenRouter-6467F2?style=flat" alt="OpenRouter" />
<img src="https://img.shields.io/badge/Perplexity-20808D?style=flat" alt="Perplexity" />
<img src="https://img.shields.io/badge/Fireworks-FF6B35?style=flat" alt="Fireworks" />
<img src="https://img.shields.io/badge/AWS_Bedrock-FF9900?style=flat&logo=amazonaws&logoColor=white" alt="AWS Bedrock" />
<img src="https://img.shields.io/badge/xAI_Grok-000000?style=flat" alt="xAI Grok" />
<img src="https://img.shields.io/badge/Vertex_AI-4285F4?style=flat&logo=googlecloud&logoColor=white" alt="Vertex AI" />
<img src="https://img.shields.io/badge/HuggingFace-FFD21E?style=flat&logo=huggingface&logoColor=black" alt="HuggingFace" />
<img src="https://img.shields.io/badge/Together_AI-000000?style=flat" alt="Together AI" />
<img src="https://img.shields.io/badge/Databricks-FF3621?style=flat&logo=databricks&logoColor=white" alt="Databricks" />
<img src="https://img.shields.io/badge/Replicate-262626?style=flat" alt="Replicate" />
<img src="https://img.shields.io/badge/Cloudflare-F38020?style=flat&logo=cloudflare&logoColor=white" alt="Cloudflare" />
</p>
<details>
<summary><strong>View all 24 providers with examples</strong></summary>
| Provider | Example |
|----------|:-------:|
| OpenAI | [Example](examples/python/providers/openai/openai_gpt4_example.py) |
| Anthropic | [Example](examples/python/providers/anthropic/anthropic_claude_example.py) |
| Google Gemini | [Example](examples/python/providers/google/google_gemini_example.py) |
| Ollama | [Example](examples/python/providers/ollama/ollama-agents.py) |
| Groq | [Example](examples/python/providers/groq/kimi_with_groq_example.py) |
| DeepSeek | [Example](examples/python/providers/deepseek/deepseek_example.py) |
| xAI Grok | [Example](examples/python/providers/xai/xai_grok_example.py) |
| Mistral | [Example](examples/python/providers/mistral/mistral_example.py) |
| Cohere | [Example](examples/python/providers/cohere/cohere_example.py) |
| Perplexity | [Example](examples/python/providers/perplexity/perplexity_example.py) |
| Fireworks | [Example](examples/python/providers/fireworks/fireworks_example.py) |
| Together AI | [Example](examples/python/providers/together/together_ai_example.py) |
| OpenRouter | [Example](examples/python/providers/openrouter/openrouter_example.py) |
| HuggingFace | [Example](examples/python/providers/huggingface/huggingface_example.py) |
| Azure OpenAI | [Example](examples/python/providers/azure/azure_openai_example.py) |
| AWS Bedrock | [Example](examples/python/providers/aws/aws_bedrock_example.py) |
| Google Vertex | [Example](examples/python/providers/vertex/vertex_example.py) |
| Databricks | [Example](examples/python/providers/databricks/databricks_example.py) |
| Cloudflare | [Example](examples/python/providers/cloudflare/cloudflare_example.py) |
| AI21 | [Example](examples/python/providers/ai21/ai21_example.py) |
| Replicate | [Example](examples/python/providers/replicate/replicate_example.py) |
| SageMaker | [Example](examples/python/providers/sagemaker/sagemaker_example.py) |
| Moonshot | [Example](examples/python/providers/moonshot/moonshot_example.py) |
| vLLM | [Example](examples/python/providers/vllm/vllm_example.py) |
</details>
<div align="center">
<a href="https://x.com/elonmusk/status/1893870468249141688" target="_blank">
<img src=".github/images/elon_musk_praisonai.png" alt="Highlighted by Elon Musk" width="600" />
</a>
<p><em>"Grok 3 customer support" — <a href="https://x.com/elonmusk/status/1893870468249141688">Elon Musk quoting PraisonAI's tutorial</a></em></p>
</div>
<br>
---
## 🌟 Why PraisonAI?
| | Feature | How |
|--|---------|-----|
| 🔌 | **MCP Protocol** — stdio, HTTP, WebSocket, SSE | `tools=MCP("npx ...")` |
| 🧠 | **Planning Mode** — plan → execute → reason | `planning=True` |
| 🔍 | **Deep Research** — multi-step autonomous research | [Docs](https://docs.praison.ai/docs/agents/deep-research) |
| 🤖 | **External Agents** — orchestrate Claude Code, Gemini CLI, Codex | [Docs](https://docs.praison.ai/docs/code/external-agents) |
| 🔄 | **Agent Handoffs** — seamless conversation passing | `handoff=True` |
| 🛡️ | **Guardrails** — input/output validation | [Docs](https://docs.praison.ai/docs/concepts/guardrails) |
| | **Web Search + Fetch** — native browsing | `web_search=True` |
| 🪞 | **Self Reflection** — agent reviews its own output | [Docs](https://docs.praison.ai/docs/concepts/reflection) |
| 🔀 | **Workflow Patterns** — route, parallel, loop, repeat | [Docs](https://docs.praison.ai/docs/concepts/agentflow) |
| 🧠 | **Memory (zero deps)** — works out of the box | `memory=True` |
<details>
<summary><strong>View all 25 features</strong></summary>
| | Feature | How |
|--|---------|-----|
| 💡 | **Prompt Caching** — reduce latency + cost | `prompt_caching=True` |
| 💾 | **Sessions + Auto-Save** — persistent state across restarts | `auto_save="my-project"` |
| 💭 | **Thinking Budgets** — control reasoning depth | `thinking_budget=1024` |
| 📚 | **RAG + Quality-Based RAG** — auto quality scoring retrieval | [Docs](https://docs.praison.ai/docs/concepts/rag) |
| 📊 | **Model Router** — auto-routes to cheapest capable model | [Docs](https://docs.praison.ai/docs/features/model-router) |
| 🧊 | **Shadow Git Checkpoints** — auto-rollback on failure | [Docs](https://docs.praison.ai/docs/features/checkpoints) |
| 📡 | **A2A Protocol** — agent-to-agent interop | [Docs](https://docs.praison.ai/docs/features/a2a) |
| 📏 | **Context Compaction** — never hit token limits | [Docs](https://docs.praison.ai/docs/features/context-compaction) |
| 📡 | **Telemetry** — OpenTelemetry traces, spans, metrics | [Docs](https://docs.praison.ai/docs/features/telemetry) |
| 📜 | **Policy Engine** — declarative agent behavior control | [Docs](https://docs.praison.ai/docs/features/policy-engine) |
| 🔄 | **Background Tasks** — fire-and-forget agents | [Docs](https://docs.praison.ai/docs/features/background-tasks) |
| 🔁 | **Doom Loop Detection** — auto-recovery from stuck agents | [Docs](https://docs.praison.ai/docs/features/doom-loop-detection) |
| 🕸️ | **Graph Memory** — Neo4j-style relationship tracking | [Docs](https://docs.praison.ai/docs/features/graph-memory) |
| 🏖️ | **Sandbox Execution** — isolated code execution | [Docs](https://docs.praison.ai/docs/features/sandbox) |
| 🖥️ | **Bot Gateway** — multi-agent routing across channels | [Docs](https://docs.praison.ai/docs/features/bot-gateway) |
</details>
---
## 📘 Using Python Code
### 1. Single Agent
```python
from praisonaiagents import Agent
agent = Agent(instructions="You are a helpful AI assistant")
agent.start("Write a movie script about a robot in Mars")
```
### 2. Multi Agents
```python
from praisonaiagents import Agent, Agents
research_agent = Agent(instructions="Research about AI")
summarise_agent = Agent(instructions="Summarise research agent's findings")
agents = Agents(agents=[research_agent, summarise_agent])
agents.start()
```
### 3. MCP (Model Context Protocol)
```python
from praisonaiagents import Agent, MCP
# stdio - Local NPX/Python servers
agent = Agent(tools=MCP("npx @modelcontextprotocol/server-memory"))
# Streamable HTTP - Production servers
agent = Agent(tools=MCP("https://api.example.com/mcp"))
# WebSocket - Real-time bidirectional
agent = Agent(tools=MCP("wss://api.example.com/mcp", auth_token="token"))
# With environment variables
agent = Agent(
tools=MCP(
command="npx",
args=["-y", "@modelcontextprotocol/server-brave-search"],
env={"BRAVE_API_KEY": "your-key"}
)
)
```
> 📖 [Full MCP docs](https://docs.praison.ai/docs/mcp/transports) — stdio, HTTP, WebSocket, SSE transports
### 4. Custom Tools
```python
from praisonaiagents import Agent, tool
@tool
def search(query: str) -> str:
"""Search the web for information."""
return f"Results for: {query}"
@tool
def calculate(expression: str) -> float:
"""Safely evaluate a numeric arithmetic expression."""
import ast
import operator
# Define allowed operations
_OPS = {
ast.Add: operator.add,
ast.Sub: operator.sub,
ast.Mult: operator.mul,
ast.Div: operator.truediv,
ast.Pow: operator.pow,
ast.USub: operator.neg,
ast.UAdd: operator.pos,
}
def _safe_eval(node):
if isinstance(node, ast.Constant) and isinstance(node.value, (int, float)):
return node.value
elif isinstance(node, ast.BinOp) and type(node.op) in _OPS:
return _OPS[type(node.op)](_safe_eval(node.left), _safe_eval(node.right))
elif isinstance(node, ast.UnaryOp) and type(node.op) in _OPS:
return _OPS[type(node.op)](_safe_eval(node.operand))
else:
raise ValueError("Unsupported expression")
try:
return _safe_eval(ast.parse(expression, mode="eval").body)
except (ValueError, SyntaxError, TypeError, ZeroDivisionError, OverflowError):
raise ValueError("Invalid arithmetic expression")
agent = Agent(
instructions="You are a helpful assistant",
tools=[search, calculate]
)
agent.start("Search for AI news and calculate 15*4")
```
> ⚠️ **Security Note:** Never use `eval()`, `exec()`, or `subprocess` in tool functions that process LLM-generated or user-supplied input. Always validate and sanitize inputs to prevent code injection attacks.
> 📖 [Full tools docs](https://docs.praison.ai/docs/tools/tools) — BaseTool, tool packages, 100+ built-in tools
### 5. Persistence (Databases)
```python
from praisonaiagents import Agent, db
agent = Agent(
name="Assistant",
db=db(database_url="postgresql://localhost/mydb"),
session_id="my-session"
)
agent.chat("Hello!") # Auto-persists messages, runs, traces
```
> 📖 [Full persistence docs](https://docs.praison.ai/docs/databases/overview) — PostgreSQL, MySQL, SQLite, MongoDB, Redis, and 20+ more
### 6. PraisonAI Claw 🦞 (Dashboard UI)
Connect your AI agents to **Telegram, Discord, Slack, WhatsApp** and more — all from a single command.
```bash
pip install "praisonai[claw]"
praisonai claw
```
#### Required Environment Variables
Copy `.env.example` to `.env` and configure the following variables:
| Variable | Required | Description |
|----------|----------|-------------|
| `OPENAI_API_KEY` | Yes | OpenAI API key for all LLM calls |
| `TAVILY_API_KEY` | Yes (Claw) | Tavily key for the built-in web-search tool. Get one free at https://app.tavily.com |
Open **http://localhost:8082** — the dashboard comes with 13 built-in pages: Chat, Agents, Memory, Knowledge, Channels, Guardrails, Cron, and more. Add messaging channels directly from the UI.
> 📖 [Full Claw docs](https://docs.praison.ai/docs/concepts/claw) — platform tokens, CLI options, Docker, and YAML agent mode
### 7. Langflow Integration 🔗 (Visual Flow Builder)
Build multi-agent workflows visually with **drag-and-drop** components in Langflow.
```bash
pip install "praisonai[flow]"
praisonai flow
```
Open **http://localhost:7861** — use the **Agent** and **Agent Team** components to create sequential or parallel workflows. Connect Chat Input → Agent Team → Chat Output for instant multi-agent pipelines.
> 📖 [Full Flow docs](https://docs.praison.ai/docs/concepts/agentflow) — visual agent building, component reference, and deployment
### 8. PraisonAI UI 🤖 (Clean Chat)
Lightweight chat interface for your AI agents.
```bash
pip install "praisonai[ui]"
praisonai ui
```
---
## 📄 Using YAML (No Code)
### Example 1: Two Agents Working Together
Create `agents.yaml`:
```yaml
framework: praisonai
topic: "Write a blog post about AI"
agents:
researcher:
role: Research Analyst
goal: Research AI trends and gather information
instructions: "Find accurate information about AI trends"
writer:
role: Content Writer
goal: Write engaging blog posts
instructions: "Write clear, engaging content based on research"
```
Run with:
```bash
praisonai agents.yaml
```
> The agents automatically work together sequentially
### Example 2: Agent with Custom Tool
Create two files in the same folder:
**agents.yaml:**
```yaml
framework: praisonai
topic: "Calculate the sum of 25 and 15"
agents:
calculator_agent:
role: Calculator
goal: Perform calculations
instructions: "Use the add_numbers tool to help with calculations"
tools:
- add_numbers
```
**tools.py:**
```python
def add_numbers(a: float, b: float) -> float:
"""
Add two numbers together.
Args:
a: First number
b: Second number
Returns:
The sum of a and b
"""
return a + b
```
Run with:
```bash
praisonai agents.yaml
```
> 💡 **Tips:**
> - Use the function name (e.g., `add_numbers`) in the tools list, not the file name
> - Tools in `tools.py` are automatically discovered
> - The function's docstring helps the AI understand how to use it
---
## 🎯 CLI Quick Reference
| Category | Commands |
|----------|----------|
| **Execution** | `praisonai`, `--auto`, `--interactive`, `--chat` |
| **Research** | `research`, `--query-rewrite`, `--deep-research` |
| **Planning** | `--planning`, `--planning-tools`, `--planning-reasoning` |
| **Workflows** | `workflow run`, `workflow list`, `workflow auto` |
| **Memory** | `memory show`, `memory add`, `memory search`, `memory clear` |
| **Knowledge** | `knowledge add`, `knowledge query`, `knowledge list` |
| **Sessions** | `session list`, `session resume`, `session delete` |
| **Tools** | `tools list`, `tools info`, `tools search` |
| **MCP** | `mcp list`, `mcp create`, `mcp enable` |
| **Development** | `commit`, `docs`, `checkpoint`, `hooks` |
| **Scheduling** | `schedule start`, `schedule list`, `schedule stop` |
> 📖 [Full CLI reference](https://docs.praison.ai/docs/cli/cli-reference)
---
## ✨ Key Features
<details open>
<summary><strong>🤖 Core Agents</strong></summary>
| Feature | Code | Docs |
|---------|:----:|:----:|
| Single Agent | [Example](examples/python/agents/single-agent.py) | [📖](https://docs.praison.ai/docs/agents/single) |
| Multi Agents | [Example](examples/python/general/mini_agents_example.py) | [📖](https://docs.praison.ai/docs/concepts/agents) |
| Auto Agents | [Example](examples/python/general/auto_agents_example.py) | [📖](https://docs.praison.ai/docs/features/autoagents) |
| Self Reflection AI Agents | [Example](examples/python/concepts/self-reflection-details.py) | [📖](https://docs.praison.ai/docs/concepts/reflection) |
| Reasoning AI Agents | [Example](examples/python/concepts/reasoning-extraction.py) | [📖](https://docs.praison.ai/docs/features/reasoning) |
| Multi Modal AI Agents | [Example](examples/python/general/multimodal.py) | [📖](https://docs.praison.ai/docs/features/multimodal) |
</details>
<details>
<summary><strong>🔄 Workflows</strong></summary>
| Feature | Code | Docs |
|---------|:----:|:----:|
| Simple Workflow | [Example](examples/python/workflows/simple_workflow.py) | [📖](https://docs.praison.ai/docs/concepts/agentflow) |
| Workflow with Agents | [Example](examples/python/workflows/workflow_with_agents.py) | [📖](https://docs.praison.ai/docs/concepts/agentflow) |
| Agentic Routing (`route()`) | [Example](examples/python/workflows/workflow_routing.py) | [📖](https://docs.praison.ai/docs/features/routing) |
| Parallel Execution (`parallel()`) | [Example](examples/python/workflows/workflow_parallel.py) | [📖](https://docs.praison.ai/docs/features/parallelisation) |
| Loop over List/CSV (`loop()`) | [Example](examples/python/workflows/workflow_loop_csv.py) | [📖](https://docs.praison.ai/docs/features/repetitive) |
| Evaluator-Optimizer (`repeat()`) | [Example](examples/python/workflows/workflow_repeat.py) | [📖](https://docs.praison.ai/docs/concepts/evaluation) |
| Conditional Steps | [Example](examples/python/workflows/workflow_conditional.py) | [📖](https://docs.praison.ai/docs/concepts/agentflow) |
| Workflow Branching | [Example](examples/python/workflows/workflow_branching.py) | [📖](https://docs.praison.ai/docs/concepts/agentflow) |
| Workflow Early Stop | [Example](examples/python/workflows/workflow_early_stop.py) | [📖](https://docs.praison.ai/docs/concepts/agentflow) |
| Workflow Checkpoints | [Example](examples/python/workflows/workflow_checkpoints.py) | [📖](https://docs.praison.ai/docs/concepts/agentflow) |
</details>
<details>
<summary><strong>💻 Code & Development</strong></summary>
| Feature | Code | Docs |
|---------|:----:|:----:|
| Code Interpreter Agents | [Example](examples/python/agents/code-agent.py) | [📖](https://docs.praison.ai/docs/features/codeagent) |
| AI Code Editing Tools | [Example](examples/python/code/code_editing_example.py) | [📖](https://docs.praison.ai/docs/code/editing) |
| External Agents (All) | [Example](examples/python/code/external_agents_example.py) | [📖](https://docs.praison.ai/docs/code/external-agents) |
| Claude Code CLI | [Example](examples/python/code/claude_code_example.py) | [📖](https://docs.praison.ai/docs/code/claude-code) |
| Gemini CLI | [Example](examples/python/code/gemini_cli_example.py) | [📖](https://docs.praison.ai/docs/code/gemini-cli) |
| Codex CLI | [Example](examples/python/code/codex_cli_example.py) | [📖](https://docs.praison.ai/docs/code/codex-cli) |
| Cursor CLI | [Example](examples/python/code/cursor_cli_example.py) | [📖](https://docs.praison.ai/docs/code/cursor-cli) |
</details>
<details>
<summary><strong>🧠 Memory & Knowledge</strong></summary>
| Feature | Code | Docs |
|---------|:----:|:----:|
| Memory (Short & Long Term) | [Example](examples/python/general/memory_example.py) | [📖](https://docs.praison.ai/docs/concepts/memory) |
| File-Based Memory | [Example](examples/python/general/memory_example.py) | [📖](https://docs.praison.ai/docs/concepts/memory) |
| Claude Memory Tool | [Example](examples/python/memory/claude_memory_example.py) | [📖](https://docs.praison.ai/docs/features/claude-memory-tool) |
| Add Custom Knowledge | [Example](examples/python/concepts/knowledge-agents.py) | [📖](https://docs.praison.ai/docs/concepts/knowledge) |
| RAG Agents | [Example](examples/python/concepts/rag-agents.py) | [📖](https://docs.praison.ai/docs/concepts/rag) |
| Chat with PDF Agents | [Example](examples/python/concepts/chat-with-pdf.py) | [📖](https://docs.praison.ai/docs/features/chat-with-pdf) |
| Data Readers (PDF, DOCX, etc.) | [CLI](https://docs.praison.ai/docs/cli/knowledge) | [📖](https://docs.praison.ai/docs/features/chunking-strategies) |
| Vector Store Selection | [CLI](https://docs.praison.ai/docs/cli/knowledge) | [📖](https://docs.praison.ai/docs/features/knowledge-backends) |
| Retrieval Strategies | [CLI](https://docs.praison.ai/docs/cli/knowledge) | [📖](https://docs.praison.ai/docs/features/retrieval-strategies) |
| Rerankers | [CLI](https://docs.praison.ai/docs/cli/knowledge) | [📖](https://docs.praison.ai/docs/features/smart-retrieval) |
| Index Types (Vector/Keyword/Hybrid) | [CLI](https://docs.praison.ai/docs/cli/knowledge) | [📖](https://docs.praison.ai/docs/features/incremental-indexing) |
| Query Engines (Sub-Question, etc.) | [CLI](https://docs.praison.ai/docs/cli/knowledge) | [📖](https://docs.praison.ai/docs/features/retrieval) |
</details>
<details>
<summary><strong>🔬 Research & Intelligence</strong></summary>
| Feature | Code | Docs |
|---------|:----:|:----:|
| Deep Research Agents | [Example](examples/python/agents/research-agent.py) | [📖](https://docs.praison.ai/docs/agents/deep-research) |
| Query Rewriter Agent | [Example](examples/python/agents/query-rewriter-agent.py) | [📖](https://docs.praison.ai/docs/agents/query-rewriter) |
| Native Web Search | [Example](examples/python/agents/websearch-agent.py) | [📖](https://docs.praison.ai/docs/agents/websearch) |
| Built-in Search Tools | [Example](examples/python/agents/websearch-agent.py) | [📖](https://docs.praison.ai/docs/tools/tavily) |
| Unified Web Search | [Example](src/praisonai-agents/examples/web_search_example.py) | [📖](https://docs.praison.ai/docs/tools/web-search) |
| Web Fetch (Anthropic) | [Example](examples/python/agents/web-fetch-agent.py) | [📖](https://docs.praison.ai/docs/features/model-capabilities) |
</details>
<details>
<summary><strong>📋 Planning & Execution</strong></summary>
| Feature | Code | Docs |
|---------|:----:|:----:|
| Planning Mode | [Example](examples/python/agents/planning-agent.py) | [📖](https://docs.praison.ai/docs/concepts/planning) |
| Planning Tools | [Example](examples/python/agents/planning-agent.py) | [📖](https://docs.praison.ai/docs/concepts/planning) |
| Planning Reasoning | [Example](examples/python/agents/planning-agent.py) | [📖](https://docs.praison.ai/docs/concepts/planning) |
| Prompt Chaining | [Example](examples/python/general/prompt_chaining.py) | [📖](https://docs.praison.ai/docs/features/promptchaining) |
| Evaluator Optimiser | [Example](examples/python/general/evaluator-optimiser.py) | [📖](https://docs.praison.ai/docs/concepts/evaluation) |
| Orchestrator Workers | [Example](examples/python/general/orchestrator-workers.py) | [📖](https://docs.praison.ai/docs/concepts/orchestration) |
</details>
<details>
<summary><strong>👥 Specialized Agents</strong></summary>
| Feature | Code | Docs |
|---------|:----:|:----:|
| Data Analyst Agent | [Example](examples/python/agents/data-analyst-agent.py) | [📖](https://docs.praison.ai/docs/agents/data-analyst) |
| Finance Agent | [Example](examples/python/agents/finance-agent.py) | [📖](https://docs.praison.ai/docs/agents/finance) |
| Shopping Agent | [Example](examples/python/agents/shopping-agent.py) | [📖](https://docs.praison.ai/docs/agents/shopping) |
| Recommendation Agent | [Example](examples/python/agents/recommendation-agent.py) | [📖](https://docs.praison.ai/docs/agents/recommendation) |
| Wikipedia Agent | [Example](examples/python/agents/wikipedia-agent.py) | [📖](https://docs.praison.ai/docs/agents/wikipedia) |
| Programming Agent | [Example](examples/python/agents/programming-agent.py) | [📖](https://docs.praison.ai/docs/agents/programming) |
| Math Agents | [Example](examples/python/agents/math-agent.py) | [📖](https://docs.praison.ai/docs/features/mathagent) |
| Markdown Agent | [Example](examples/python/agents/markdown-agent.py) | [📖](https://docs.praison.ai/docs/agents/markdown) |
| Prompt Expander Agent | [Example](examples/python/agents/prompt-expander-agent.py) | [📖](https://docs.praison.ai/docs/agents/prompt-expander) |
</details>
<details>
<summary><strong>🎨 Media & Multimodal</strong></summary>
| Feature | Code | Docs |
|---------|:----:|:----:|
| Image Generation Agent | [Example](examples/python/image/image-agent.py) | [📖](https://docs.praison.ai/docs/features/image-generation) |
| Image to Text Agent | [Example](examples/python/agents/image-to-text-agent.py) | [📖](https://docs.praison.ai/docs/agents/image-to-text) |
| Video Agent | [Example](examples/python/agents/video-agent.py) | [📖](https://docs.praison.ai/docs/agents/video) |
| Camera Integration | [Example](examples/python/camera/) | [📖](https://docs.praison.ai/docs/features/camera-integration) |
</details>
<details>
<summary><strong>🔌 Protocols & Integration</strong></summary>
| Feature | Code | Docs |
|---------|:----:|:----:|
| MCP Transports | [Example](examples/python/mcp/mcp-transports-overview.py) | [📖](https://docs.praison.ai/docs/mcp/transports) |
| WebSocket MCP | [Example](examples/python/mcp/websocket-mcp.py) | [📖](https://docs.praison.ai/docs/mcp/sse-transport) |
| MCP Security | [Example](examples/python/mcp/mcp-security.py) | [📖](https://docs.praison.ai/docs/mcp/transports) |
| MCP Resumability | [Example](examples/python/mcp/mcp-resumability.py) | [📖](https://docs.praison.ai/docs/mcp/sse-transport) |
| MCP Config Management | [Docs](https://docs.praison.ai/docs/cli/mcp) | [📖](https://docs.praison.ai/docs/cli/mcp) |
| LangChain Integrated Agents | [Example](examples/python/general/langchain_example.py) | [📖](https://docs.praison.ai/docs/features/langchain) |
</details>
<details>
<summary><strong>🛡️ Safety & Control</strong></summary>
| Feature | Code | Docs |
|---------|:----:|:----:|
| Guardrails | [Example](examples/python/guardrails/comprehensive-guardrails-example.py) | [📖](https://docs.praison.ai/docs/concepts/guardrails) |
| Human Approval | [Example](examples/python/general/human_approval_example.py) | [📖](https://docs.praison.ai/docs/concepts/approval) |
| Rules & Instructions | [Docs](https://docs.praison.ai/docs/features/rules) | [📖](https://docs.praison.ai/docs/features/rules) |
</details>
<details>
<summary><strong>⚙️ Advanced Features</strong></summary>
| Feature | Code | Docs |
|---------|:----:|:----:|
| Async & Parallel Processing | [Example](examples/python/general/async_example.py) | [📖](https://docs.praison.ai/docs/features/async) |
| Parallelisation | [Example](examples/python/general/parallelisation.py) | [📖](https://docs.praison.ai/docs/features/parallelisation) |
| Repetitive Agents | [Example](examples/python/concepts/repetitive-agents.py) | [📖](https://docs.praison.ai/docs/features/repetitive) |
| Agent Handoffs | [Example](examples/python/handoff/handoff_basic.py) | [📖](https://docs.praison.ai/docs/concepts/handoffs) |
| Stateful Agents | [Example](examples/python/stateful/workflow-state-example.py) | [📖](https://docs.praison.ai/docs/features/stateful-agents) |
| Autonomous Workflow | [Example](examples/python/general/autonomous-agent.py) | [📖](https://docs.praison.ai/docs/concepts/autonomy) |
| Structured Output Agents | [Example](examples/python/general/structured_agents_example.py) | [📖](https://docs.praison.ai/docs/features/structured) |
| Model Router | [Example](examples/python/agents/router-agent-cost-optimization.py) | [📖](https://docs.praison.ai/docs/features/model-router) |
| Prompt Caching | [Example](examples/python/agents/prompt-caching-agent.py) | [📖](https://docs.praison.ai/docs/features/model-capabilities) |
| Fast Context | [Example](examples/context/00_agent_fast_context_basic.py) | [📖](https://docs.praison.ai/docs/features/fast-context) |
</details>
<details>
<summary><strong>🛠️ Tools & Configuration</strong></summary>
| Feature | Code | Docs |
|---------|:----:|:----:|
| 100+ Custom Tools | [Example](examples/python/general/tools_example.py) | [📖](https://docs.praison.ai/docs/tools/tools) |
| YAML Configuration | [Example](examples/cookbooks/yaml/secondary_market_research_agents.yaml) | [📖](https://docs.praison.ai/docs/developers/agents-playbook) |
| 100+ LLM Support | [Example](examples/python/providers/openai/openai_gpt4_example.py) | [📖](https://docs.praison.ai/docs/models) |
| Callback Agents | [Example](examples/python/general/advanced-callback-systems.py) | [📖](https://docs.praison.ai/docs/concepts/hooks) |
| Hooks | [Example](examples/python/hooks/hooks_example.py) | [📖](https://docs.praison.ai/docs/concepts/hooks) |
| Middleware System | [Example](examples/middleware/basic_middleware.py) | [📖](https://docs.praison.ai/docs/features/middleware) |
| Configurable Model | [Example](examples/middleware/configurable_model.py) | [📖](https://docs.praison.ai/docs/features/configurable-model) |
| Rate Limiter | [Example](examples/middleware/rate_limiter.py) | [📖](https://docs.praison.ai/docs/features/rate-limiter) |
| Injected Tool State | [Example](examples/middleware/injected_state.py) | [📖](https://docs.praison.ai/docs/features/injected-state) |
| Shadow Git Checkpoints | [Example](examples/checkpoints/basic_checkpoint.py) | [📖](https://docs.praison.ai/docs/features/checkpoints) |
| Background Tasks | [Example](examples/background/basic_background.py) | [📖](https://docs.praison.ai/docs/features/background-tasks) |
| Policy Engine | [Example](examples/policy/basic_policy.py) | [📖](https://docs.praison.ai/docs/features/policy-engine) |
| Thinking Budgets | [Example](examples/thinking/basic_thinking.py) | [📖](https://docs.praison.ai/docs/features/thinking-budgets) |
| Output Styles | [Example](examples/output/basic_output.py) | [📖](https://docs.praison.ai/docs/features/output-styles) |
| Context Compaction | [Example](examples/compaction/basic_compaction.py) | [📖](https://docs.praison.ai/docs/features/context-compaction) |
</details>
<details>
<summary><strong>📊 Monitoring & Management</strong></summary>
| Feature | Code | Docs |
|---------|:----:|:----:|
| Sessions Management | [Example](examples/python/sessions/comprehensive-session-management.py) | [📖](https://docs.praison.ai/docs/concepts/session-management) |
| Auto-Save Sessions | [Docs](https://docs.praison.ai/docs/cli/session) | [📖](https://docs.praison.ai/docs/cli/session) |
| History in Context | [Docs](https://docs.praison.ai/docs/cli/session) | [📖](https://docs.praison.ai/docs/cli/session) |
| Telemetry | [Example](examples/python/telemetry/production-telemetry-example.py) | [📖](https://docs.praison.ai/docs/features/telemetry) |
| Langfuse Tracing | [Docs](https://docs.praison.ai/docs/observability/langfuse) | [📖](https://docs.praison.ai/docs/observability/langfuse) |
| Project Docs (.praison/docs/) | [Docs](https://docs.praison.ai/docs/cli/docs) | [📖](https://docs.praison.ai/docs/cli/docs) |
| AI Commit Messages | [Docs](https://docs.praison.ai/docs/cli/commit) | [📖](https://docs.praison.ai/docs/cli/commit) |
| @Mentions in Prompts | [Docs](https://docs.praison.ai/docs/cli/mentions) | [📖](https://docs.praison.ai/docs/cli/mentions) |
</details>
<details>
<summary><strong>🖥️ CLI Features</strong></summary>
| Feature | Code | Docs |
|---------|:----:|:----:|
| Slash Commands | [Example](examples/python/cli/slash_commands_example.py) | [📖](https://docs.praison.ai/docs/cli/slash-commands) |
| Autonomy Modes | [Example](examples/python/cli/autonomy_modes_example.py) | [📖](https://docs.praison.ai/docs/cli/autonomy-modes) |
| Cost Tracking | [Example](examples/python/cli/cost_tracking_example.py) | [📖](https://docs.praison.ai/docs/cli/cost-tracking) |
| Repository Map | [Example](examples/python/cli/repo_map_example.py) | [📖](https://docs.praison.ai/docs/cli/repo-map) |
| Interactive TUI | [Example](examples/python/cli/interactive_tui_example.py) | [📖](https://docs.praison.ai/docs/cli/interactive-tui) |
| Git Integration | [Example](examples/python/cli/git_integration_example.py) | [📖](https://docs.praison.ai/docs/cli/git-integration) |
| Sandbox Execution | [Example](examples/python/cli/sandbox_execution_example.py) | [📖](https://docs.praison.ai/docs/cli/sandbox-execution) |
| CLI Compare | [Example](examples/compare/cli_compare_basic.py) | [📖](https://docs.praison.ai/docs/cli/compare) |
| Profile/Benchmark | [Docs](https://docs.praison.ai/docs/cli/profile) | [📖](https://docs.praison.ai/docs/cli/profile) |
| Auto Mode | [Docs](https://docs.praison.ai/docs/cli/auto) | [📖](https://docs.praison.ai/docs/cli/auto) |
| Init | [Docs](https://docs.praison.ai/docs/cli/init) | [📖](https://docs.praison.ai/docs/cli/init) |
| File Input | [Docs](https://docs.praison.ai/docs/cli/file-input) | [📖](https://docs.praison.ai/docs/cli/file-input) |
| Final Agent | [Docs](https://docs.praison.ai/docs/cli/final-agent) | [📖](https://docs.praison.ai/docs/cli/final-agent) |
| Max Tokens | [Docs](https://docs.praison.ai/docs/cli/max-tokens) | [📖](https://docs.praison.ai/docs/cli/max-tokens) |
</details>
<details>
<summary><strong>🧪 Evaluation</strong></summary>
| Feature | Code | Docs |
|---------|:----:|:----:|
| Accuracy Evaluation | [Example](examples/eval/accuracy_example.py) | [📖](https://docs.praison.ai/docs/cli/eval) |
| Performance Evaluation | [Example](examples/eval/performance_example.py) | [📖](https://docs.praison.ai/docs/cli/eval) |
| Reliability Evaluation | [Example](examples/eval/reliability_example.py) | [📖](https://docs.praison.ai/docs/cli/eval) |
| Criteria Evaluation | [Example](examples/eval/criteria_example.py) | [📖](https://docs.praison.ai/docs/cli/eval) |
</details>
<details>
<summary><strong>🎯 Agent Skills</strong></summary>
| Feature | Code | Docs |
|---------|:----:|:----:|
| Skills Management | [Example](examples/skills/basic_skill_usage.py) | [📖](https://docs.praison.ai/docs/concepts/skills) |
| Custom Skills | [Example](examples/skills/custom_skill_example.py) | [📖](https://docs.praison.ai/docs/concepts/skills) |
</details>
<details>
<summary><strong>⏰ 24/7 Scheduling</strong></summary>
| Feature | Code | Docs |
|---------|:----:|:----:|
| Agent Scheduler | [Example](examples/python/scheduled_agents/news_checker_live.py) | [📖](https://docs.praison.ai/docs/cli/scheduler) |
</details>
---
## 💻 Using JavaScript Code
```bash
npm install praisonai
export OPENAI_API_KEY=xxxxxxxxxxxxxxxxxxxxxx
```
```javascript
const { Agent } = require('praisonai');
const agent = new Agent({ instructions: 'You are a helpful AI assistant' });
agent.start('Write a movie script about a robot in Mars');
```
---
## ⚡ Performance
PraisonAI is built for speed, with agent instantiation in under 4μs. This reduces overhead, improves responsiveness, and helps multi-agent systems scale efficiently in real-world production workloads.
| Performance Metric | PraisonAI |
|--------------------|-----------|
| Avg Instantiation Time | **3.77 μs** |
---
---
## ⭐ Star History
[![Star History Chart](https://api.star-history.com/svg?repos=MervinPraison/PraisonAI&type=Date)](https://docs.praison.ai)
---
## 🔍 Langfuse Tracing
```bash
pip install "praisonai[langfuse]"
praisonai langfuse
```
<p align="center">
<img src=".github/images/langfuse.png" alt="PraisonAI Langfuse Tracing" width="800" />
</p>
---
## 🎓 Video Tutorials
Learn PraisonAI through our comprehensive video series:
<details>
<summary><strong>View all 22 video tutorials</strong></summary>
| Topic | Video |
|-------|--------|
| AI Agents with Self Reflection | [![Self Reflection](https://img.youtube.com/vi/vLXobEN2Vc8/0.jpg)](https://www.youtube.com/watch?v=vLXobEN2Vc8) |
| Reasoning Data Generating Agent | [![Reasoning Data](https://img.youtube.com/vi/fUT332Y2zA8/0.jpg)](https://www.youtube.com/watch?v=fUT332Y2zA8) |
| AI Agents with Reasoning | [![Reasoning](https://img.youtube.com/vi/KNDVWGN3TpM/0.jpg)](https://www.youtube.com/watch?v=KNDVWGN3TpM) |
| Multimodal AI Agents | [![Multimodal](https://img.youtube.com/vi/hjAWmUT1qqY/0.jpg)](https://www.youtube.com/watch?v=hjAWmUT1qqY) |
| AI Agents Workflow | [![Workflow](https://img.youtube.com/vi/yWTH44QPl2A/0.jpg)](https://www.youtube.com/watch?v=yWTH44QPl2A) |
| Async AI Agents | [![Async](https://img.youtube.com/vi/VhVQfgo00LE/0.jpg)](https://www.youtube.com/watch?v=VhVQfgo00LE) |
| Mini AI Agents | [![Mini](https://img.youtube.com/vi/OkvYp5aAGSg/0.jpg)](https://www.youtube.com/watch?v=OkvYp5aAGSg) |
| AI Agents with Memory | [![Memory](https://img.youtube.com/vi/1hVfVxvPnnQ/0.jpg)](https://www.youtube.com/watch?v=1hVfVxvPnnQ) |
| Repetitive Agents | [![Repetitive](https://img.youtube.com/vi/dAYGxsjDOPg/0.jpg)](https://www.youtube.com/watch?v=dAYGxsjDOPg) |
| Introduction | [![Introduction](https://img.youtube.com/vi/Fn1lQjC0GO0/0.jpg)](https://www.youtube.com/watch?v=Fn1lQjC0GO0) |
| Tools Overview | [![Tools Overview](https://img.youtube.com/vi/XaQRgRpV7jo/0.jpg)](https://www.youtube.com/watch?v=XaQRgRpV7jo) |
| Custom Tools | [![Custom Tools](https://img.youtube.com/vi/JSU2Rndh06c/0.jpg)](https://www.youtube.com/watch?v=JSU2Rndh06c) |
| Firecrawl Integration | [![Firecrawl](https://img.youtube.com/vi/UoqUDcLcOYo/0.jpg)](https://www.youtube.com/watch?v=UoqUDcLcOYo) |
| User Interface | [![UI](https://img.youtube.com/vi/tg-ZjNl3OCg/0.jpg)](https://www.youtube.com/watch?v=tg-ZjNl3OCg) |
| Crawl4AI Integration | [![Crawl4AI](https://img.youtube.com/vi/KAvuVUh0XU8/0.jpg)](https://www.youtube.com/watch?v=KAvuVUh0XU8) |
| Chat Interface | [![Chat](https://img.youtube.com/vi/sw3uDqn2h1Y/0.jpg)](https://www.youtube.com/watch?v=sw3uDqn2h1Y) |
| Code Interface | [![Code](https://img.youtube.com/vi/_5jQayO-MQY/0.jpg)](https://www.youtube.com/watch?v=_5jQayO-MQY) |
| Mem0 Integration | [![Mem0](https://img.youtube.com/vi/KIGSgRxf1cY/0.jpg)](https://www.youtube.com/watch?v=KIGSgRxf1cY) |
| Training | [![Training](https://img.youtube.com/vi/aLawE8kwCrI/0.jpg)](https://www.youtube.com/watch?v=aLawE8kwCrI) |
| Realtime Voice Interface | [![Realtime](https://img.youtube.com/vi/frRHfevTCSw/0.jpg)](https://www.youtube.com/watch?v=frRHfevTCSw) |
| Call Interface | [![Call](https://img.youtube.com/vi/m1cwrUG2iAk/0.jpg)](https://www.youtube.com/watch?v=m1cwrUG2iAk) |
| Reasoning Extract Agents | [![Reasoning Extract](https://img.youtube.com/vi/2PPamsADjJA/0.jpg)](https://www.youtube.com/watch?v=2PPamsADjJA) |
</details>
---
## 👥 Contributing
We welcome contributions! Fork the repo, create a branch, and submit a PR → [Contributing Guide](https://github.com/MervinPraison/PraisonAI/blob/main/CONTRIBUTING.md).
---
## ❓ FAQ & Troubleshooting
<details>
<summary><strong>ModuleNotFoundError: No module named 'praisonaiagents'</strong></summary>
Install the package:
```bash
pip install praisonaiagents
```
</details>
<details>
<summary><strong>API key not found / Authentication error</strong></summary>
Ensure your API key is set:
```bash
export OPENAI_API_KEY=your_key_here
```
For other providers, see [Models docs](https://docs.praison.ai/docs/models).
</details>
<details>
<summary><strong>How do I use a local model (Ollama)?</strong></summary>
```bash
# Start Ollama server first
ollama serve
# Set environment variable
export OPENAI_BASE_URL=http://localhost:11434/v1
```
See [Models docs](https://docs.praison.ai/docs/models) for more details.
</details>
<details>
<summary><strong>How do I persist conversations to a database?</strong></summary>
Use the `db` parameter:
```python
from praisonaiagents import Agent, db
agent = Agent(
name="Assistant",
db=db(database_url="postgresql://localhost/mydb"),
session_id="my-session"
)
```
See [Persistence docs](https://docs.praison.ai/docs/databases/overview) for supported databases.
</details>
<details>
<summary><strong>How do I enable agent memory?</strong></summary>
```python
from praisonaiagents import Agent
agent = Agent(
name="Assistant",
memory=True, # Enables file-based memory (no extra deps!)
user_id="user123"
)
```
See [Memory docs](https://docs.praison.ai/docs/concepts/memory) for more options.
</details>
<details>
<summary><strong>How do I run multiple agents together?</strong></summary>
```python
from praisonaiagents import Agent, Agents
agent1 = Agent(instructions="Research topics")
agent2 = Agent(instructions="Summarize findings")
agents = Agents(agents=[agent1, agent2])
agents.start()
```
See [Agents docs](https://docs.praison.ai/docs/concepts/agents) for more examples.
</details>
<details>
<summary><strong>How do I use MCP tools?</strong></summary>
```python
from praisonaiagents import Agent, MCP
agent = Agent(
tools=MCP("npx @modelcontextprotocol/server-memory")
)
```
See [MCP docs](https://docs.praison.ai/docs/mcp/transports) for all transport options.
</details>
### Getting Help
- 📚 [Full Documentation](https://docs.praison.ai)
- 🐛 [Report Issues](https://github.com/MervinPraison/PraisonAI/issues)
- 💬 [Discussions](https://github.com/MervinPraison/PraisonAI/discussions)
---
<div align="center">
<p><strong>Made with ❤️ by the PraisonAI Team</strong></p>
<p>
<a href="https://docs.praison.ai">📚 Documentation</a> •
<a href="https://github.com/MervinPraison/PraisonAI">GitHub</a> •
<a href="https://youtube.com/@MervinPraison">▶️ YouTube</a> •
<a href="https://x.com/MervinPraison">𝕏 X</a> •
<a href="https://linkedin.com/in/mervinpraison">💼 LinkedIn</a>
</p>
</div>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+20
View File
@@ -0,0 +1,20 @@
.. PraisonAI documentation master file, created by
sphinx-quickstart on Mon Jun 10 12:11:57 2024.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to PraisonAI's documentation!
=====================================
.. toctree::
:maxdepth: 2
:caption: Contents:
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
@@ -0,0 +1,7 @@
praisonai
=========
.. toctree::
:maxdepth: 4
praisonai
@@ -0,0 +1,21 @@
praisonai.inbuilt\_tools package
================================
Submodules
----------
praisonai.inbuilt\_tools.autogen\_tools module
----------------------------------------------
.. automodule:: praisonai.inbuilt_tools.autogen_tools
:members:
:undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: praisonai.inbuilt_tools
:members:
:undoc-members:
:show-inheritance:
@@ -0,0 +1,69 @@
praisonai package
=================
Subpackages
-----------
.. toctree::
:maxdepth: 4
praisonai.inbuilt_tools
Submodules
----------
praisonai.agents\_generator module
----------------------------------
.. automodule:: praisonai.agents_generator
:members:
:undoc-members:
:show-inheritance:
praisonai.auto module
---------------------
.. automodule:: praisonai.auto
:members:
:undoc-members:
:show-inheritance:
praisonai.cli module
--------------------
.. automodule:: praisonai.cli
:members:
:undoc-members:
:show-inheritance:
praisonai.deploy module
-----------------------
.. automodule:: praisonai.deploy
:members:
:undoc-members:
:show-inheritance:
praisonai.test module
---------------------
.. automodule:: praisonai.test
:members:
:undoc-members:
:show-inheritance:
praisonai.version module
------------------------
.. automodule:: praisonai.version
:members:
:undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: praisonai
:members:
:undoc-members:
:show-inheritance:
@@ -0,0 +1,123 @@
/* Compatability shim for jQuery and underscores.js.
*
* Copyright Sphinx contributors
* Released under the two clause BSD licence
*/
/**
* small helper function to urldecode strings
*
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL
*/
jQuery.urldecode = function(x) {
if (!x) {
return x
}
return decodeURIComponent(x.replace(/\+/g, ' '));
};
/**
* small helper function to urlencode strings
*/
jQuery.urlencode = encodeURIComponent;
/**
* This function returns the parsed url parameters of the
* current request. Multiple values per key are supported,
* it will always return arrays of strings for the value parts.
*/
jQuery.getQueryParameters = function(s) {
if (typeof s === 'undefined')
s = document.location.search;
var parts = s.substr(s.indexOf('?') + 1).split('&');
var result = {};
for (var i = 0; i < parts.length; i++) {
var tmp = parts[i].split('=', 2);
var key = jQuery.urldecode(tmp[0]);
var value = jQuery.urldecode(tmp[1]);
if (key in result)
result[key].push(value);
else
result[key] = [value];
}
return result;
};
/**
* highlight a given string on a jquery object by wrapping it in
* span elements with the given class name.
*/
jQuery.fn.highlightText = function(text, className) {
function highlight(node, addItems) {
if (node.nodeType === 3) {
var val = node.nodeValue;
var pos = val.toLowerCase().indexOf(text);
if (pos >= 0 &&
!jQuery(node.parentNode).hasClass(className) &&
!jQuery(node.parentNode).hasClass("nohighlight")) {
var span;
var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
if (isInSVG) {
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
} else {
span = document.createElement("span");
span.className = className;
}
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
document.createTextNode(val.substr(pos + text.length)),
node.nextSibling));
node.nodeValue = val.substr(0, pos);
if (isInSVG) {
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
var bbox = node.parentElement.getBBox();
rect.x.baseVal.value = bbox.x;
rect.y.baseVal.value = bbox.y;
rect.width.baseVal.value = bbox.width;
rect.height.baseVal.value = bbox.height;
rect.setAttribute('class', className);
addItems.push({
"parent": node.parentNode,
"target": rect});
}
}
}
else if (!jQuery(node).is("button, select, textarea")) {
jQuery.each(node.childNodes, function() {
highlight(this, addItems);
});
}
}
var addItems = [];
var result = this.each(function() {
highlight(this, addItems);
});
for (var i = 0; i < addItems.length; ++i) {
jQuery(addItems[i].parent).before(addItems[i].target);
}
return result;
};
/*
* backward compatibility for jQuery.browser
* This will be supported until firefox bug is fixed.
*/
if (!jQuery.browser) {
jQuery.uaMatch = function(ua) {
ua = ua.toLowerCase();
var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
/(webkit)[ \/]([\w.]+)/.exec(ua) ||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
/(msie) ([\w.]+)/.exec(ua) ||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
[];
return {
browser: match[ 1 ] || "",
version: match[ 2 ] || "0"
};
};
jQuery.browser = {};
jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
}
+708
View File
@@ -0,0 +1,708 @@
@import url("basic.css");
/* -- page layout ----------------------------------------------------------- */
body {
font-family: Georgia, serif;
font-size: 17px;
background-color: #fff;
color: #000;
margin: 0;
padding: 0;
}
div.document {
width: 940px;
margin: 30px auto 0 auto;
}
div.documentwrapper {
float: left;
width: 100%;
}
div.bodywrapper {
margin: 0 0 0 220px;
}
div.sphinxsidebar {
width: 220px;
font-size: 14px;
line-height: 1.5;
}
hr {
border: 1px solid #B1B4B6;
}
div.body {
background-color: #fff;
color: #3E4349;
padding: 0 30px 0 30px;
}
div.body > .section {
text-align: left;
}
div.footer {
width: 940px;
margin: 20px auto 30px auto;
font-size: 14px;
color: #888;
text-align: right;
}
div.footer a {
color: #888;
}
p.caption {
font-family: inherit;
font-size: inherit;
}
div.relations {
display: none;
}
div.sphinxsidebar {
max-height: 100%;
overflow-y: auto;
}
div.sphinxsidebar a {
color: #444;
text-decoration: none;
border-bottom: 1px dotted #999;
}
div.sphinxsidebar a:hover {
border-bottom: 1px solid #999;
}
div.sphinxsidebarwrapper {
padding: 18px 10px;
}
div.sphinxsidebarwrapper p.logo {
padding: 0;
margin: -10px 0 0 0px;
text-align: center;
}
div.sphinxsidebarwrapper h1.logo {
margin-top: -10px;
text-align: center;
margin-bottom: 5px;
text-align: left;
}
div.sphinxsidebarwrapper h1.logo-name {
margin-top: 0px;
}
div.sphinxsidebarwrapper p.blurb {
margin-top: 0;
font-style: normal;
}
div.sphinxsidebar h3,
div.sphinxsidebar h4 {
font-family: Georgia, serif;
color: #444;
font-size: 24px;
font-weight: normal;
margin: 0 0 5px 0;
padding: 0;
}
div.sphinxsidebar h4 {
font-size: 20px;
}
div.sphinxsidebar h3 a {
color: #444;
}
div.sphinxsidebar p.logo a,
div.sphinxsidebar h3 a,
div.sphinxsidebar p.logo a:hover,
div.sphinxsidebar h3 a:hover {
border: none;
}
div.sphinxsidebar p {
color: #555;
margin: 10px 0;
}
div.sphinxsidebar ul {
margin: 10px 0;
padding: 0;
color: #000;
}
div.sphinxsidebar ul li.toctree-l1 > a {
font-size: 120%;
}
div.sphinxsidebar ul li.toctree-l2 > a {
font-size: 110%;
}
div.sphinxsidebar input {
border: 1px solid #CCC;
font-family: Georgia, serif;
font-size: 1em;
}
div.sphinxsidebar #searchbox input[type="text"] {
width: 160px;
}
div.sphinxsidebar .search > div {
display: table-cell;
}
div.sphinxsidebar hr {
border: none;
height: 1px;
color: #AAA;
background: #AAA;
text-align: left;
margin-left: 0;
width: 50%;
}
div.sphinxsidebar .badge {
border-bottom: none;
}
div.sphinxsidebar .badge:hover {
border-bottom: none;
}
/* To address an issue with donation coming after search */
div.sphinxsidebar h3.donation {
margin-top: 10px;
}
/* -- body styles ----------------------------------------------------------- */
a {
color: #004B6B;
text-decoration: underline;
}
a:hover {
color: #6D4100;
text-decoration: underline;
}
div.body h1,
div.body h2,
div.body h3,
div.body h4,
div.body h5,
div.body h6 {
font-family: Georgia, serif;
font-weight: normal;
margin: 30px 0px 10px 0px;
padding: 0;
}
div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; }
div.body h2 { font-size: 180%; }
div.body h3 { font-size: 150%; }
div.body h4 { font-size: 130%; }
div.body h5 { font-size: 100%; }
div.body h6 { font-size: 100%; }
a.headerlink {
color: #DDD;
padding: 0 4px;
text-decoration: none;
}
a.headerlink:hover {
color: #444;
background: #EAEAEA;
}
div.body p, div.body dd, div.body li {
line-height: 1.4em;
}
div.admonition {
margin: 20px 0px;
padding: 10px 30px;
background-color: #EEE;
border: 1px solid #CCC;
}
div.admonition tt.xref, div.admonition code.xref, div.admonition a tt {
background-color: #FBFBFB;
border-bottom: 1px solid #fafafa;
}
div.admonition p.admonition-title {
font-family: Georgia, serif;
font-weight: normal;
font-size: 24px;
margin: 0 0 10px 0;
padding: 0;
line-height: 1;
}
div.admonition p.last {
margin-bottom: 0;
}
div.highlight {
background-color: #fff;
}
dt:target, .highlight {
background: #FAF3E8;
}
div.warning {
background-color: #FCC;
border: 1px solid #FAA;
}
div.danger {
background-color: #FCC;
border: 1px solid #FAA;
-moz-box-shadow: 2px 2px 4px #D52C2C;
-webkit-box-shadow: 2px 2px 4px #D52C2C;
box-shadow: 2px 2px 4px #D52C2C;
}
div.error {
background-color: #FCC;
border: 1px solid #FAA;
-moz-box-shadow: 2px 2px 4px #D52C2C;
-webkit-box-shadow: 2px 2px 4px #D52C2C;
box-shadow: 2px 2px 4px #D52C2C;
}
div.caution {
background-color: #FCC;
border: 1px solid #FAA;
}
div.attention {
background-color: #FCC;
border: 1px solid #FAA;
}
div.important {
background-color: #EEE;
border: 1px solid #CCC;
}
div.note {
background-color: #EEE;
border: 1px solid #CCC;
}
div.tip {
background-color: #EEE;
border: 1px solid #CCC;
}
div.hint {
background-color: #EEE;
border: 1px solid #CCC;
}
div.seealso {
background-color: #EEE;
border: 1px solid #CCC;
}
div.topic {
background-color: #EEE;
}
p.admonition-title {
display: inline;
}
p.admonition-title:after {
content: ":";
}
pre, tt, code {
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
font-size: 0.9em;
}
.hll {
background-color: #FFC;
margin: 0 -12px;
padding: 0 12px;
display: block;
}
img.screenshot {
}
tt.descname, tt.descclassname, code.descname, code.descclassname {
font-size: 0.95em;
}
tt.descname, code.descname {
padding-right: 0.08em;
}
img.screenshot {
-moz-box-shadow: 2px 2px 4px #EEE;
-webkit-box-shadow: 2px 2px 4px #EEE;
box-shadow: 2px 2px 4px #EEE;
}
table.docutils {
border: 1px solid #888;
-moz-box-shadow: 2px 2px 4px #EEE;
-webkit-box-shadow: 2px 2px 4px #EEE;
box-shadow: 2px 2px 4px #EEE;
}
table.docutils td, table.docutils th {
border: 1px solid #888;
padding: 0.25em 0.7em;
}
table.field-list, table.footnote {
border: none;
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
}
table.footnote {
margin: 15px 0;
width: 100%;
border: 1px solid #EEE;
background: #FDFDFD;
font-size: 0.9em;
}
table.footnote + table.footnote {
margin-top: -15px;
border-top: none;
}
table.field-list th {
padding: 0 0.8em 0 0;
}
table.field-list td {
padding: 0;
}
table.field-list p {
margin-bottom: 0.8em;
}
/* Cloned from
* https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68
*/
.field-name {
-moz-hyphens: manual;
-ms-hyphens: manual;
-webkit-hyphens: manual;
hyphens: manual;
}
table.footnote td.label {
width: .1px;
padding: 0.3em 0 0.3em 0.5em;
}
table.footnote td {
padding: 0.3em 0.5em;
}
dl {
margin-left: 0;
margin-right: 0;
margin-top: 0;
padding: 0;
}
dl dd {
margin-left: 30px;
}
blockquote {
margin: 0 0 0 30px;
padding: 0;
}
ul, ol {
/* Matches the 30px from the narrow-screen "li > ul" selector below */
margin: 10px 0 10px 30px;
padding: 0;
}
pre {
background: #EEE;
padding: 7px 30px;
margin: 15px 0px;
line-height: 1.3em;
}
div.viewcode-block:target {
background: #ffd;
}
dl pre, blockquote pre, li pre {
margin-left: 0;
padding-left: 30px;
}
tt, code {
background-color: #ecf0f3;
color: #222;
/* padding: 1px 2px; */
}
tt.xref, code.xref, a tt {
background-color: #FBFBFB;
border-bottom: 1px solid #fff;
}
a.reference {
text-decoration: none;
border-bottom: 1px dotted #004B6B;
}
/* Don't put an underline on images */
a.image-reference, a.image-reference:hover {
border-bottom: none;
}
a.reference:hover {
border-bottom: 1px solid #6D4100;
}
a.footnote-reference {
text-decoration: none;
font-size: 0.7em;
vertical-align: top;
border-bottom: 1px dotted #004B6B;
}
a.footnote-reference:hover {
border-bottom: 1px solid #6D4100;
}
a:hover tt, a:hover code {
background: #EEE;
}
@media screen and (max-width: 870px) {
div.sphinxsidebar {
display: none;
}
div.document {
width: 100%;
}
div.documentwrapper {
margin-left: 0;
margin-top: 0;
margin-right: 0;
margin-bottom: 0;
}
div.bodywrapper {
margin-top: 0;
margin-right: 0;
margin-bottom: 0;
margin-left: 0;
}
ul {
margin-left: 0;
}
li > ul {
/* Matches the 30px from the "ul, ol" selector above */
margin-left: 30px;
}
.document {
width: auto;
}
.footer {
width: auto;
}
.bodywrapper {
margin: 0;
}
.footer {
width: auto;
}
.github {
display: none;
}
}
@media screen and (max-width: 875px) {
body {
margin: 0;
padding: 20px 30px;
}
div.documentwrapper {
float: none;
background: #fff;
}
div.sphinxsidebar {
display: block;
float: none;
width: 102.5%;
margin: 50px -30px -20px -30px;
padding: 10px 20px;
background: #333;
color: #FFF;
}
div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p,
div.sphinxsidebar h3 a {
color: #fff;
}
div.sphinxsidebar a {
color: #AAA;
}
div.sphinxsidebar p.logo {
display: none;
}
div.document {
width: 100%;
margin: 0;
}
div.footer {
display: none;
}
div.bodywrapper {
margin: 0;
}
div.body {
min-height: 0;
padding: 0;
}
.rtd_doc_footer {
display: none;
}
.document {
width: auto;
}
.footer {
width: auto;
}
.footer {
width: auto;
}
.github {
display: none;
}
}
/* misc. */
.revsys-inline {
display: none!important;
}
/* Hide ugly table cell borders in ..bibliography:: directive output */
table.docutils.citation, table.docutils.citation td, table.docutils.citation th {
border: none;
/* Below needed in some edge cases; if not applied, bottom shadows appear */
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
}
/* relbar */
.related {
line-height: 30px;
width: 100%;
font-size: 0.9rem;
}
.related.top {
border-bottom: 1px solid #EEE;
margin-bottom: 20px;
}
.related.bottom {
border-top: 1px solid #EEE;
}
.related ul {
padding: 0;
margin: 0;
list-style: none;
}
.related li {
display: inline;
}
nav#rellinks {
float: right;
}
nav#rellinks li+li:before {
content: "|";
}
nav#breadcrumbs li+li:before {
content: "\00BB";
}
/* Hide certain items when printing */
@media print {
div.related {
display: none;
}
}
+925
View File
@@ -0,0 +1,925 @@
/*
* basic.css
* ~~~~~~~~~
*
* Sphinx stylesheet -- basic theme.
*
* :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/* -- main layout ----------------------------------------------------------- */
div.clearer {
clear: both;
}
div.section::after {
display: block;
content: '';
clear: left;
}
/* -- relbar ---------------------------------------------------------------- */
div.related {
width: 100%;
font-size: 90%;
}
div.related h3 {
display: none;
}
div.related ul {
margin: 0;
padding: 0 0 0 10px;
list-style: none;
}
div.related li {
display: inline;
}
div.related li.right {
float: right;
margin-right: 5px;
}
/* -- sidebar --------------------------------------------------------------- */
div.sphinxsidebarwrapper {
padding: 10px 5px 0 10px;
}
div.sphinxsidebar {
float: left;
width: 230px;
margin-left: -100%;
font-size: 90%;
word-wrap: break-word;
overflow-wrap : break-word;
}
div.sphinxsidebar ul {
list-style: none;
}
div.sphinxsidebar ul ul,
div.sphinxsidebar ul.want-points {
margin-left: 20px;
list-style: square;
}
div.sphinxsidebar ul ul {
margin-top: 0;
margin-bottom: 0;
}
div.sphinxsidebar form {
margin-top: 10px;
}
div.sphinxsidebar input {
border: 1px solid #98dbcc;
font-family: sans-serif;
font-size: 1em;
}
div.sphinxsidebar #searchbox form.search {
overflow: hidden;
}
div.sphinxsidebar #searchbox input[type="text"] {
float: left;
width: 80%;
padding: 0.25em;
box-sizing: border-box;
}
div.sphinxsidebar #searchbox input[type="submit"] {
float: left;
width: 20%;
border-left: none;
padding: 0.25em;
box-sizing: border-box;
}
img {
border: 0;
max-width: 100%;
}
/* -- search page ----------------------------------------------------------- */
ul.search {
margin: 10px 0 0 20px;
padding: 0;
}
ul.search li {
padding: 5px 0 5px 20px;
background-image: url(file.png);
background-repeat: no-repeat;
background-position: 0 7px;
}
ul.search li a {
font-weight: bold;
}
ul.search li p.context {
color: #888;
margin: 2px 0 0 30px;
text-align: left;
}
ul.keywordmatches li.goodmatch a {
font-weight: bold;
}
/* -- index page ------------------------------------------------------------ */
table.contentstable {
width: 90%;
margin-left: auto;
margin-right: auto;
}
table.contentstable p.biglink {
line-height: 150%;
}
a.biglink {
font-size: 1.3em;
}
span.linkdescr {
font-style: italic;
padding-top: 5px;
font-size: 90%;
}
/* -- general index --------------------------------------------------------- */
table.indextable {
width: 100%;
}
table.indextable td {
text-align: left;
vertical-align: top;
}
table.indextable ul {
margin-top: 0;
margin-bottom: 0;
list-style-type: none;
}
table.indextable > tbody > tr > td > ul {
padding-left: 0em;
}
table.indextable tr.pcap {
height: 10px;
}
table.indextable tr.cap {
margin-top: 10px;
background-color: #f2f2f2;
}
img.toggler {
margin-right: 3px;
margin-top: 3px;
cursor: pointer;
}
div.modindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
div.genindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
/* -- domain module index --------------------------------------------------- */
table.modindextable td {
padding: 2px;
border-collapse: collapse;
}
/* -- general body styles --------------------------------------------------- */
div.body {
min-width: inherit;
max-width: 800px;
}
div.body p, div.body dd, div.body li, div.body blockquote {
-moz-hyphens: auto;
-ms-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
}
a.headerlink {
visibility: hidden;
}
a:visited {
color: #551A8B;
}
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
h4:hover > a.headerlink,
h5:hover > a.headerlink,
h6:hover > a.headerlink,
dt:hover > a.headerlink,
caption:hover > a.headerlink,
p.caption:hover > a.headerlink,
div.code-block-caption:hover > a.headerlink {
visibility: visible;
}
div.body p.caption {
text-align: inherit;
}
div.body td {
text-align: left;
}
.first {
margin-top: 0 !important;
}
p.rubric {
margin-top: 30px;
font-weight: bold;
}
img.align-left, figure.align-left, .figure.align-left, object.align-left {
clear: left;
float: left;
margin-right: 1em;
}
img.align-right, figure.align-right, .figure.align-right, object.align-right {
clear: right;
float: right;
margin-left: 1em;
}
img.align-center, figure.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
img.align-default, figure.align-default, .figure.align-default {
display: block;
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.align-default {
text-align: center;
}
.align-right {
text-align: right;
}
/* -- sidebars -------------------------------------------------------------- */
div.sidebar,
aside.sidebar {
margin: 0 0 0.5em 1em;
border: 1px solid #ddb;
padding: 7px;
background-color: #ffe;
width: 40%;
float: right;
clear: right;
overflow-x: auto;
}
p.sidebar-title {
font-weight: bold;
}
nav.contents,
aside.topic,
div.admonition, div.topic, blockquote {
clear: left;
}
/* -- topics ---------------------------------------------------------------- */
nav.contents,
aside.topic,
div.topic {
border: 1px solid #ccc;
padding: 7px;
margin: 10px 0 10px 0;
}
p.topic-title {
font-size: 1.1em;
font-weight: bold;
margin-top: 10px;
}
/* -- admonitions ----------------------------------------------------------- */
div.admonition {
margin-top: 10px;
margin-bottom: 10px;
padding: 7px;
}
div.admonition dt {
font-weight: bold;
}
p.admonition-title {
margin: 0px 10px 5px 0px;
font-weight: bold;
}
div.body p.centered {
text-align: center;
margin-top: 25px;
}
/* -- content of sidebars/topics/admonitions -------------------------------- */
div.sidebar > :last-child,
aside.sidebar > :last-child,
nav.contents > :last-child,
aside.topic > :last-child,
div.topic > :last-child,
div.admonition > :last-child {
margin-bottom: 0;
}
div.sidebar::after,
aside.sidebar::after,
nav.contents::after,
aside.topic::after,
div.topic::after,
div.admonition::after,
blockquote::after {
display: block;
content: '';
clear: both;
}
/* -- tables ---------------------------------------------------------------- */
table.docutils {
margin-top: 10px;
margin-bottom: 10px;
border: 0;
border-collapse: collapse;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
table.align-default {
margin-left: auto;
margin-right: auto;
}
table caption span.caption-number {
font-style: italic;
}
table caption span.caption-text {
}
table.docutils td, table.docutils th {
padding: 1px 8px 1px 5px;
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid #aaa;
}
th {
text-align: left;
padding-right: 5px;
}
table.citation {
border-left: solid 1px gray;
margin-left: 1px;
}
table.citation td {
border-bottom: none;
}
th > :first-child,
td > :first-child {
margin-top: 0px;
}
th > :last-child,
td > :last-child {
margin-bottom: 0px;
}
/* -- figures --------------------------------------------------------------- */
div.figure, figure {
margin: 0.5em;
padding: 0.5em;
}
div.figure p.caption, figcaption {
padding: 0.3em;
}
div.figure p.caption span.caption-number,
figcaption span.caption-number {
font-style: italic;
}
div.figure p.caption span.caption-text,
figcaption span.caption-text {
}
/* -- field list styles ----------------------------------------------------- */
table.field-list td, table.field-list th {
border: 0 !important;
}
.field-list ul {
margin: 0;
padding-left: 1em;
}
.field-list p {
margin: 0;
}
.field-name {
-moz-hyphens: manual;
-ms-hyphens: manual;
-webkit-hyphens: manual;
hyphens: manual;
}
/* -- hlist styles ---------------------------------------------------------- */
table.hlist {
margin: 1em 0;
}
table.hlist td {
vertical-align: top;
}
/* -- object description styles --------------------------------------------- */
.sig {
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
}
.sig-name, code.descname {
background-color: transparent;
font-weight: bold;
}
.sig-name {
font-size: 1.1em;
}
code.descname {
font-size: 1.2em;
}
.sig-prename, code.descclassname {
background-color: transparent;
}
.optional {
font-size: 1.3em;
}
.sig-paren {
font-size: larger;
}
.sig-param.n {
font-style: italic;
}
/* C++ specific styling */
.sig-inline.c-texpr,
.sig-inline.cpp-texpr {
font-family: unset;
}
.sig.c .k, .sig.c .kt,
.sig.cpp .k, .sig.cpp .kt {
color: #0033B3;
}
.sig.c .m,
.sig.cpp .m {
color: #1750EB;
}
.sig.c .s, .sig.c .sc,
.sig.cpp .s, .sig.cpp .sc {
color: #067D17;
}
/* -- other body styles ----------------------------------------------------- */
ol.arabic {
list-style: decimal;
}
ol.loweralpha {
list-style: lower-alpha;
}
ol.upperalpha {
list-style: upper-alpha;
}
ol.lowerroman {
list-style: lower-roman;
}
ol.upperroman {
list-style: upper-roman;
}
:not(li) > ol > li:first-child > :first-child,
:not(li) > ul > li:first-child > :first-child {
margin-top: 0px;
}
:not(li) > ol > li:last-child > :last-child,
:not(li) > ul > li:last-child > :last-child {
margin-bottom: 0px;
}
ol.simple ol p,
ol.simple ul p,
ul.simple ol p,
ul.simple ul p {
margin-top: 0;
}
ol.simple > li:not(:first-child) > p,
ul.simple > li:not(:first-child) > p {
margin-top: 0;
}
ol.simple p,
ul.simple p {
margin-bottom: 0;
}
aside.footnote > span,
div.citation > span {
float: left;
}
aside.footnote > span:last-of-type,
div.citation > span:last-of-type {
padding-right: 0.5em;
}
aside.footnote > p {
margin-left: 2em;
}
div.citation > p {
margin-left: 4em;
}
aside.footnote > p:last-of-type,
div.citation > p:last-of-type {
margin-bottom: 0em;
}
aside.footnote > p:last-of-type:after,
div.citation > p:last-of-type:after {
content: "";
clear: both;
}
dl.field-list {
display: grid;
grid-template-columns: fit-content(30%) auto;
}
dl.field-list > dt {
font-weight: bold;
word-break: break-word;
padding-left: 0.5em;
padding-right: 5px;
}
dl.field-list > dd {
padding-left: 0.5em;
margin-top: 0em;
margin-left: 0em;
margin-bottom: 0em;
}
dl {
margin-bottom: 15px;
}
dd > :first-child {
margin-top: 0px;
}
dd ul, dd table {
margin-bottom: 10px;
}
dd {
margin-top: 3px;
margin-bottom: 10px;
margin-left: 30px;
}
.sig dd {
margin-top: 0px;
margin-bottom: 0px;
}
.sig dl {
margin-top: 0px;
margin-bottom: 0px;
}
dl > dd:last-child,
dl > dd:last-child > :last-child {
margin-bottom: 0;
}
dt:target, span.highlighted {
background-color: #fbe54e;
}
rect.highlighted {
fill: #fbe54e;
}
dl.glossary dt {
font-weight: bold;
font-size: 1.1em;
}
.versionmodified {
font-style: italic;
}
.system-message {
background-color: #fda;
padding: 5px;
border: 3px solid red;
}
.footnote:target {
background-color: #ffa;
}
.line-block {
display: block;
margin-top: 1em;
margin-bottom: 1em;
}
.line-block .line-block {
margin-top: 0;
margin-bottom: 0;
margin-left: 1.5em;
}
.guilabel, .menuselection {
font-family: sans-serif;
}
.accelerator {
text-decoration: underline;
}
.classifier {
font-style: oblique;
}
.classifier:before {
font-style: normal;
margin: 0 0.5em;
content: ":";
display: inline-block;
}
abbr, acronym {
border-bottom: dotted 1px;
cursor: help;
}
.translated {
background-color: rgba(207, 255, 207, 0.2)
}
.untranslated {
background-color: rgba(255, 207, 207, 0.2)
}
/* -- code displays --------------------------------------------------------- */
pre {
overflow: auto;
overflow-y: hidden; /* fixes display issues on Chrome browsers */
}
pre, div[class*="highlight-"] {
clear: both;
}
span.pre {
-moz-hyphens: none;
-ms-hyphens: none;
-webkit-hyphens: none;
hyphens: none;
white-space: nowrap;
}
div[class*="highlight-"] {
margin: 1em 0;
}
td.linenos pre {
border: 0;
background-color: transparent;
color: #aaa;
}
table.highlighttable {
display: block;
}
table.highlighttable tbody {
display: block;
}
table.highlighttable tr {
display: flex;
}
table.highlighttable td {
margin: 0;
padding: 0;
}
table.highlighttable td.linenos {
padding-right: 0.5em;
}
table.highlighttable td.code {
flex: 1;
overflow: hidden;
}
.highlight .hll {
display: block;
}
div.highlight pre,
table.highlighttable pre {
margin: 0;
}
div.code-block-caption + div {
margin-top: 0;
}
div.code-block-caption {
margin-top: 1em;
padding: 2px 5px;
font-size: small;
}
div.code-block-caption code {
background-color: transparent;
}
table.highlighttable td.linenos,
span.linenos,
div.highlight span.gp { /* gp: Generic.Prompt */
user-select: none;
-webkit-user-select: text; /* Safari fallback only */
-webkit-user-select: none; /* Chrome/Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE10+ */
}
div.code-block-caption span.caption-number {
padding: 0.1em 0.3em;
font-style: italic;
}
div.code-block-caption span.caption-text {
}
div.literal-block-wrapper {
margin: 1em 0;
}
code.xref, a code {
background-color: transparent;
font-weight: bold;
}
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
background-color: transparent;
}
.viewcode-link {
float: right;
}
.viewcode-back {
float: right;
font-family: sans-serif;
}
div.viewcode-block:target {
margin: -1px -10px;
padding: 0 10px;
}
/* -- math display ---------------------------------------------------------- */
img.math {
vertical-align: middle;
}
div.body div.math p {
text-align: center;
}
span.eqno {
float: right;
}
span.eqno a.headerlink {
position: absolute;
z-index: 1;
}
div.math:hover a.headerlink {
visibility: visible;
}
/* -- printout stylesheet --------------------------------------------------- */
@media print {
div.document,
div.documentwrapper,
div.bodywrapper {
margin: 0 !important;
width: 100%;
}
div.sphinxsidebar,
div.related,
div.footer,
#top-link {
display: none;
}
}
+1
View File
@@ -0,0 +1 @@
/* This file intentionally left blank. */
+156
View File
@@ -0,0 +1,156 @@
/*
* doctools.js
* ~~~~~~~~~~~
*
* Base JavaScript utilities for all Sphinx HTML documentation.
*
* :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
"use strict";
const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([
"TEXTAREA",
"INPUT",
"SELECT",
"BUTTON",
]);
const _ready = (callback) => {
if (document.readyState !== "loading") {
callback();
} else {
document.addEventListener("DOMContentLoaded", callback);
}
};
/**
* Small JavaScript module for the documentation.
*/
const Documentation = {
init: () => {
Documentation.initDomainIndexTable();
Documentation.initOnKeyListeners();
},
/**
* i18n support
*/
TRANSLATIONS: {},
PLURAL_EXPR: (n) => (n === 1 ? 0 : 1),
LOCALE: "unknown",
// gettext and ngettext don't access this so that the functions
// can safely bound to a different name (_ = Documentation.gettext)
gettext: (string) => {
const translated = Documentation.TRANSLATIONS[string];
switch (typeof translated) {
case "undefined":
return string; // no translation
case "string":
return translated; // translation exists
default:
return translated[0]; // (singular, plural) translation tuple exists
}
},
ngettext: (singular, plural, n) => {
const translated = Documentation.TRANSLATIONS[singular];
if (typeof translated !== "undefined")
return translated[Documentation.PLURAL_EXPR(n)];
return n === 1 ? singular : plural;
},
addTranslations: (catalog) => {
Object.assign(Documentation.TRANSLATIONS, catalog.messages);
Documentation.PLURAL_EXPR = new Function(
"n",
`return (${catalog.plural_expr})`
);
Documentation.LOCALE = catalog.locale;
},
/**
* helper function to focus on search bar
*/
focusSearchBar: () => {
document.querySelectorAll("input[name=q]")[0]?.focus();
},
/**
* Initialise the domain index toggle buttons
*/
initDomainIndexTable: () => {
const toggler = (el) => {
const idNumber = el.id.substr(7);
const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`);
if (el.src.substr(-9) === "minus.png") {
el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`;
toggledRows.forEach((el) => (el.style.display = "none"));
} else {
el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`;
toggledRows.forEach((el) => (el.style.display = ""));
}
};
const togglerElements = document.querySelectorAll("img.toggler");
togglerElements.forEach((el) =>
el.addEventListener("click", (event) => toggler(event.currentTarget))
);
togglerElements.forEach((el) => (el.style.display = ""));
if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler);
},
initOnKeyListeners: () => {
// only install a listener if it is really needed
if (
!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS &&
!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS
)
return;
document.addEventListener("keydown", (event) => {
// bail for input elements
if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return;
// bail with special keys
if (event.altKey || event.ctrlKey || event.metaKey) return;
if (!event.shiftKey) {
switch (event.key) {
case "ArrowLeft":
if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
const prevLink = document.querySelector('link[rel="prev"]');
if (prevLink && prevLink.href) {
window.location.href = prevLink.href;
event.preventDefault();
}
break;
case "ArrowRight":
if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
const nextLink = document.querySelector('link[rel="next"]');
if (nextLink && nextLink.href) {
window.location.href = nextLink.href;
event.preventDefault();
}
break;
}
}
// some keyboard layouts may need Shift to get /
switch (event.key) {
case "/":
if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;
Documentation.focusSearchBar();
event.preventDefault();
}
});
},
};
// quick alias for translations
const _ = Documentation.gettext;
_ready(Documentation.init);
@@ -0,0 +1,13 @@
const DOCUMENTATION_OPTIONS = {
VERSION: '0.0.21',
LANGUAGE: 'en',
COLLAPSE_INDEX: false,
BUILDER: 'html',
FILE_SUFFIX: '.html',
LINK_SUFFIX: '.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt',
NAVIGATION_WITH_KEYS: false,
SHOW_SEARCH_SUMMARY: true,
ENABLE_SEARCH_SHORTCUTS: true,
};
Binary file not shown.

After

Width:  |  Height:  |  Size: 286 B

+2
View File
@@ -0,0 +1,2 @@
/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */
!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}S.fn=S.prototype={jquery:f,constructor:S,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=S.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return S.each(this,e)},map:function(n){return this.pushStack(S.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(S.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(S.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},S.extend=S.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(S.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||S.isPlainObject(n)?n:{},i=!1,a[t]=S.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},S.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=v.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){b(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(p(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){var n=t||[];return null!=e&&(p(Object(e))?S.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(p(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:y}),"function"==typeof Symbol&&(S.fn[Symbol.iterator]=t[Symbol.iterator]),S.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var d=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,v,s,c,y,S="sizzle"+1*new Date,p=n.document,k=0,r=0,m=ue(),x=ue(),A=ue(),N=ue(),j=function(e,t){return e===t&&(l=!0),0},D={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",I="(?:\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",F=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",B=new RegExp(M+"+","g"),$=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^Line truncated
+199
View File
@@ -0,0 +1,199 @@
/*
* language_data.js
* ~~~~~~~~~~~~~~~~
*
* This script contains the language-specific data used by searchtools.js,
* namely the list of stopwords, stemmer, scorer and splitter.
*
* :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"];
/* Non-minified version is copied as a separate JS file, if available */
/**
* Porter Stemmer
*/
var Stemmer = function() {
var step2list = {
ational: 'ate',
tional: 'tion',
enci: 'ence',
anci: 'ance',
izer: 'ize',
bli: 'ble',
alli: 'al',
entli: 'ent',
eli: 'e',
ousli: 'ous',
ization: 'ize',
ation: 'ate',
ator: 'ate',
alism: 'al',
iveness: 'ive',
fulness: 'ful',
ousness: 'ous',
aliti: 'al',
iviti: 'ive',
biliti: 'ble',
logi: 'log'
};
var step3list = {
icate: 'ic',
ative: '',
alize: 'al',
iciti: 'ic',
ical: 'ic',
ful: '',
ness: ''
};
var c = "[^aeiou]"; // consonant
var v = "[aeiouy]"; // vowel
var C = c + "[^aeiouy]*"; // consonant sequence
var V = v + "[aeiou]*"; // vowel sequence
var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
var s_v = "^(" + C + ")?" + v; // vowel in stem
this.stemWord = function (w) {
var stem;
var suffix;
var firstch;
var origword = w;
if (w.length < 3)
return w;
var re;
var re2;
var re3;
var re4;
firstch = w.substr(0,1);
if (firstch == "y")
w = firstch.toUpperCase() + w.substr(1);
// Step 1a
re = /^(.+?)(ss|i)es$/;
re2 = /^(.+?)([^s])s$/;
if (re.test(w))
w = w.replace(re,"$1$2");
else if (re2.test(w))
w = w.replace(re2,"$1$2");
// Step 1b
re = /^(.+?)eed$/;
re2 = /^(.+?)(ed|ing)$/;
if (re.test(w)) {
var fp = re.exec(w);
re = new RegExp(mgr0);
if (re.test(fp[1])) {
re = /.$/;
w = w.replace(re,"");
}
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1];
re2 = new RegExp(s_v);
if (re2.test(stem)) {
w = stem;
re2 = /(at|bl|iz)$/;
re3 = new RegExp("([^aeiouylsz])\\1$");
re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re2.test(w))
w = w + "e";
else if (re3.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
else if (re4.test(w))
w = w + "e";
}
}
// Step 1c
re = /^(.+?)y$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(s_v);
if (re.test(stem))
w = stem + "i";
}
// Step 2
re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step2list[suffix];
}
// Step 3
re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step3list[suffix];
}
// Step 4
re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
re2 = /^(.+?)(s|t)(ion)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
if (re.test(stem))
w = stem;
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1] + fp[2];
re2 = new RegExp(mgr1);
if (re2.test(stem))
w = stem;
}
// Step 5
re = /^(.+?)e$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
re2 = new RegExp(meq1);
re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
w = stem;
}
re = /ll$/;
re2 = new RegExp(mgr1);
if (re.test(w) && re2.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
// and turn initial Y back to y
if (firstch == "y")
w = firstch.toLowerCase() + w.substr(1);
return w;
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

+84
View File
@@ -0,0 +1,84 @@
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #f8f8f8; }
.highlight .c { color: #8f5902; font-style: italic } /* Comment */
.highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */
.highlight .g { color: #000000 } /* Generic */
.highlight .k { color: #004461; font-weight: bold } /* Keyword */
.highlight .l { color: #000000 } /* Literal */
.highlight .n { color: #000000 } /* Name */
.highlight .o { color: #582800 } /* Operator */
.highlight .x { color: #000000 } /* Other */
.highlight .p { color: #000000; font-weight: bold } /* Punctuation */
.highlight .ch { color: #8f5902; font-style: italic } /* Comment.Hashbang */
.highlight .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #8f5902 } /* Comment.Preproc */
.highlight .cpf { color: #8f5902; font-style: italic } /* Comment.PreprocFile */
.highlight .c1 { color: #8f5902; font-style: italic } /* Comment.Single */
.highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */
.highlight .gd { color: #a40000 } /* Generic.Deleted */
.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */
.highlight .ges { color: #000000 } /* Generic.EmphStrong */
.highlight .gr { color: #ef2929 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #745334 } /* Generic.Prompt */
.highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */
.highlight .kc { color: #004461; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #004461; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #004461; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #004461; font-weight: bold } /* Keyword.Pseudo */
.highlight .kr { color: #004461; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #004461; font-weight: bold } /* Keyword.Type */
.highlight .ld { color: #000000 } /* Literal.Date */
.highlight .m { color: #990000 } /* Literal.Number */
.highlight .s { color: #4e9a06 } /* Literal.String */
.highlight .na { color: #c4a000 } /* Name.Attribute */
.highlight .nb { color: #004461 } /* Name.Builtin */
.highlight .nc { color: #000000 } /* Name.Class */
.highlight .no { color: #000000 } /* Name.Constant */
.highlight .nd { color: #888888 } /* Name.Decorator */
.highlight .ni { color: #ce5c00 } /* Name.Entity */
.highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #000000 } /* Name.Function */
.highlight .nl { color: #f57900 } /* Name.Label */
.highlight .nn { color: #000000 } /* Name.Namespace */
.highlight .nx { color: #000000 } /* Name.Other */
.highlight .py { color: #000000 } /* Name.Property */
.highlight .nt { color: #004461; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #000000 } /* Name.Variable */
.highlight .ow { color: #004461; font-weight: bold } /* Operator.Word */
.highlight .pm { color: #000000; font-weight: bold } /* Punctuation.Marker */
.highlight .w { color: #f8f8f8 } /* Text.Whitespace */
.highlight .mb { color: #990000 } /* Literal.Number.Bin */
.highlight .mf { color: #990000 } /* Literal.Number.Float */
.highlight .mh { color: #990000 } /* Literal.Number.Hex */
.highlight .mi { color: #990000 } /* Literal.Number.Integer */
.highlight .mo { color: #990000 } /* Literal.Number.Oct */
.highlight .sa { color: #4e9a06 } /* Literal.String.Affix */
.highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */
.highlight .sc { color: #4e9a06 } /* Literal.String.Char */
.highlight .dl { color: #4e9a06 } /* Literal.String.Delimiter */
.highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #4e9a06 } /* Literal.String.Double */
.highlight .se { color: #4e9a06 } /* Literal.String.Escape */
.highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */
.highlight .si { color: #4e9a06 } /* Literal.String.Interpol */
.highlight .sx { color: #4e9a06 } /* Literal.String.Other */
.highlight .sr { color: #4e9a06 } /* Literal.String.Regex */
.highlight .s1 { color: #4e9a06 } /* Literal.String.Single */
.highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */
.highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #000000 } /* Name.Function.Magic */
.highlight .vc { color: #000000 } /* Name.Variable.Class */
.highlight .vg { color: #000000 } /* Name.Variable.Global */
.highlight .vi { color: #000000 } /* Name.Variable.Instance */
.highlight .vm { color: #000000 } /* Name.Variable.Magic */
.highlight .il { color: #990000 } /* Literal.Number.Integer.Long */
+619
View File
@@ -0,0 +1,619 @@
/*
* searchtools.js
* ~~~~~~~~~~~~~~~~
*
* Sphinx JavaScript utilities for the full-text search.
*
* :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
"use strict";
/**
* Simple result scoring code.
*/
if (typeof Scorer === "undefined") {
var Scorer = {
// Implement the following function to further tweak the score for each result
// The function takes a result array [docname, title, anchor, descr, score, filename]
// and returns the new score.
/*
score: result => {
const [docname, title, anchor, descr, score, filename] = result
return score
},
*/
// query matches the full name of an object
objNameMatch: 11,
// or matches in the last dotted part of the object name
objPartialMatch: 6,
// Additive scores depending on the priority of the object
objPrio: {
0: 15, // used to be importantResults
1: 5, // used to be objectResults
2: -5, // used to be unimportantResults
},
// Used when the priority is not in the mapping.
objPrioDefault: 0,
// query found in title
title: 15,
partialTitle: 7,
// query found in terms
term: 5,
partialTerm: 2,
};
}
const _removeChildren = (element) => {
while (element && element.lastChild) element.removeChild(element.lastChild);
};
/**
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
*/
const _escapeRegExp = (string) =>
string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
const _displayItem = (item, searchTerms, highlightTerms) => {
const docBuilder = DOCUMENTATION_OPTIONS.BUILDER;
const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX;
const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX;
const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY;
const contentRoot = document.documentElement.dataset.content_root;
const [docName, title, anchor, descr, score, _filename] = item;
let listItem = document.createElement("li");
let requestUrl;
let linkUrl;
if (docBuilder === "dirhtml") {
// dirhtml builder
let dirname = docName + "/";
if (dirname.match(/\/index\/$/))
dirname = dirname.substring(0, dirname.length - 6);
else if (dirname === "index/") dirname = "";
requestUrl = contentRoot + dirname;
linkUrl = requestUrl;
} else {
// normal html builders
requestUrl = contentRoot + docName + docFileSuffix;
linkUrl = docName + docLinkSuffix;
}
let linkEl = listItem.appendChild(document.createElement("a"));
linkEl.href = linkUrl + anchor;
linkEl.dataset.score = score;
linkEl.innerHTML = title;
if (descr) {
listItem.appendChild(document.createElement("span")).innerHTML =
" (" + descr + ")";
// highlight search terms in the description
if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js
highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted"));
}
else if (showSearchSummary)
fetch(requestUrl)
.then((responseData) => responseData.text())
.then((data) => {
if (data)
listItem.appendChild(
Search.makeSearchSummary(data, searchTerms, anchor)
);
// highlight search terms in the summary
if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js
highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted"));
});
Search.output.appendChild(listItem);
};
const _finishSearch = (resultCount) => {
Search.stopPulse();
Search.title.innerText = _("Search Results");
if (!resultCount)
Search.status.innerText = Documentation.gettext(
"Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories."
);
else
Search.status.innerText = _(
"Search finished, found ${resultCount} page(s) matching the search query."
).replace('${resultCount}', resultCount);
};
const _displayNextItem = (
results,
resultCount,
searchTerms,
highlightTerms,
) => {
// results left, load the summary and display it
// this is intended to be dynamic (don't sub resultsCount)
if (results.length) {
_displayItem(results.pop(), searchTerms, highlightTerms);
setTimeout(
() => _displayNextItem(results, resultCount, searchTerms, highlightTerms),
5
);
}
// search finished, update title and status message
else _finishSearch(resultCount);
};
// Helper function used by query() to order search results.
// Each input is an array of [docname, title, anchor, descr, score, filename].
// Order the results by score (in opposite order of appearance, since the
// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically.
const _orderResultsByScoreThenName = (a, b) => {
const leftScore = a[4];
const rightScore = b[4];
if (leftScore === rightScore) {
// same score: sort alphabetically
const leftTitle = a[1].toLowerCase();
const rightTitle = b[1].toLowerCase();
if (leftTitle === rightTitle) return 0;
return leftTitle > rightTitle ? -1 : 1; // inverted is intentional
}
return leftScore > rightScore ? 1 : -1;
};
/**
* Default splitQuery function. Can be overridden in ``sphinx.search`` with a
* custom function per language.
*
* The regular expression works by splitting the string on consecutive characters
* that are not Unicode letters, numbers, underscores, or emoji characters.
* This is the same as ``\W+`` in Python, preserving the surrogate pair area.
*/
if (typeof splitQuery === "undefined") {
var splitQuery = (query) => query
.split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu)
.filter(term => term) // remove remaining empty strings
}
/**
* Search Module
*/
const Search = {
_index: null,
_queued_query: null,
_pulse_status: -1,
htmlToText: (htmlString, anchor) => {
const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html');
for (const removalQuery of [".headerlinks", "script", "style"]) {
htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() });
}
if (anchor) {
const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`);
if (anchorContent) return anchorContent.textContent;
console.warn(
`Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.`
);
}
// if anchor not specified or not found, fall back to main content
const docContent = htmlElement.querySelector('[role="main"]');
if (docContent) return docContent.textContent;
console.warn(
"Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template."
);
return "";
},
init: () => {
const query = new URLSearchParams(window.location.search).get("q");
document
.querySelectorAll('input[name="q"]')
.forEach((el) => (el.value = query));
if (query) Search.performSearch(query);
},
loadIndex: (url) =>
(document.body.appendChild(document.createElement("script")).src = url),
setIndex: (index) => {
Search._index = index;
if (Search._queued_query !== null) {
const query = Search._queued_query;
Search._queued_query = null;
Search.query(query);
}
},
hasIndex: () => Search._index !== null,
deferQuery: (query) => (Search._queued_query = query),
stopPulse: () => (Search._pulse_status = -1),
startPulse: () => {
if (Search._pulse_status >= 0) return;
const pulse = () => {
Search._pulse_status = (Search._pulse_status + 1) % 4;
Search.dots.innerText = ".".repeat(Search._pulse_status);
if (Search._pulse_status >= 0) window.setTimeout(pulse, 500);
};
pulse();
},
/**
* perform a search for something (or wait until index is loaded)
*/
performSearch: (query) => {
// create the required interface elements
const searchText = document.createElement("h2");
searchText.textContent = _("Searching");
const searchSummary = document.createElement("p");
searchSummary.classList.add("search-summary");
searchSummary.innerText = "";
const searchList = document.createElement("ul");
searchList.classList.add("search");
const out = document.getElementById("search-results");
Search.title = out.appendChild(searchText);
Search.dots = Search.title.appendChild(document.createElement("span"));
Search.status = out.appendChild(searchSummary);
Search.output = out.appendChild(searchList);
const searchProgress = document.getElementById("search-progress");
// Some themes don't use the search progress node
if (searchProgress) {
searchProgress.innerText = _("Preparing search...");
}
Search.startPulse();
// index already loaded, the browser was quick!
if (Search.hasIndex()) Search.query(query);
else Search.deferQuery(query);
},
_parseQuery: (query) => {
// stem the search terms and add them to the correct list
const stemmer = new Stemmer();
const searchTerms = new Set();
const excludedTerms = new Set();
const highlightTerms = new Set();
const objectTerms = new Set(splitQuery(query.toLowerCase().trim()));
splitQuery(query.trim()).forEach((queryTerm) => {
const queryTermLower = queryTerm.toLowerCase();
// maybe skip this "word"
// stopwords array is from language_data.js
if (
stopwords.indexOf(queryTermLower) !== -1 ||
queryTerm.match(/^\d+$/)
)
return;
// stem the word
let word = stemmer.stemWord(queryTermLower);
// select the correct list
if (word[0] === "-") excludedTerms.add(word.substr(1));
else {
searchTerms.add(word);
highlightTerms.add(queryTermLower);
}
});
if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js
localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" "))
}
// console.debug("SEARCH: searching for:");
// console.info("required: ", [...searchTerms]);
// console.info("excluded: ", [...excludedTerms]);
return [query, searchTerms, excludedTerms, highlightTerms, objectTerms];
},
/**
* execute search (requires search index to be loaded)
*/
_performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => {
const filenames = Search._index.filenames;
const docNames = Search._index.docnames;
const titles = Search._index.titles;
const allTitles = Search._index.alltitles;
const indexEntries = Search._index.indexentries;
// Collect multiple result groups to be sorted separately and then ordered.
// Each is an array of [docname, title, anchor, descr, score, filename].
const normalResults = [];
const nonMainIndexResults = [];
_removeChildren(document.getElementById("search-progress"));
const queryLower = query.toLowerCase().trim();
for (const [title, foundTitles] of Object.entries(allTitles)) {
if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) {
for (const [file, id] of foundTitles) {
let score = Math.round(100 * queryLower.length / title.length)
normalResults.push([
docNames[file],
titles[file] !== title ? `${titles[file]} > ${title}` : title,
id !== null ? "#" + id : "",
null,
score,
filenames[file],
]);
}
}
}
// search for explicit entries in index directives
for (const [entry, foundEntries] of Object.entries(indexEntries)) {
if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) {
for (const [file, id, isMain] of foundEntries) {
const score = Math.round(100 * queryLower.length / entry.length);
const result = [
docNames[file],
titles[file],
id ? "#" + id : "",
null,
score,
filenames[file],
];
if (isMain) {
normalResults.push(result);
} else {
nonMainIndexResults.push(result);
}
}
}
}
// lookup as object
objectTerms.forEach((term) =>
normalResults.push(...Search.performObjectSearch(term, objectTerms))
);
// lookup as search terms in fulltext
normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms));
// let the scorer override scores with a custom scoring function
if (Scorer.score) {
normalResults.forEach((item) => (item[4] = Scorer.score(item)));
nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item)));
}
// Sort each group of results by score and then alphabetically by name.
normalResults.sort(_orderResultsByScoreThenName);
nonMainIndexResults.sort(_orderResultsByScoreThenName);
// Combine the result groups in (reverse) order.
// Non-main index entries are typically arbitrary cross-references,
// so display them after other results.
let results = [...nonMainIndexResults, ...normalResults];
// remove duplicate search results
// note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept
let seen = new Set();
results = results.reverse().reduce((acc, result) => {
let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(',');
if (!seen.has(resultStr)) {
acc.push(result);
seen.add(resultStr);
}
return acc;
}, []);
return results.reverse();
},
query: (query) => {
const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query);
const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms);
// for debugging
//Search.lastresults = results.slice(); // a copy
// console.info("search results:", Search.lastresults);
// print the results
_displayNextItem(results, results.length, searchTerms, highlightTerms);
},
/**
* search for object names
*/
performObjectSearch: (object, objectTerms) => {
const filenames = Search._index.filenames;
const docNames = Search._index.docnames;
const objects = Search._index.objects;
const objNames = Search._index.objnames;
const titles = Search._index.titles;
const results = [];
const objectSearchCallback = (prefix, match) => {
const name = match[4]
const fullname = (prefix ? prefix + "." : "") + name;
const fullnameLower = fullname.toLowerCase();
if (fullnameLower.indexOf(object) < 0) return;
let score = 0;
const parts = fullnameLower.split(".");
// check for different match types: exact matches of full name or
// "last name" (i.e. last dotted part)
if (fullnameLower === object || parts.slice(-1)[0] === object)
score += Scorer.objNameMatch;
else if (parts.slice(-1)[0].indexOf(object) > -1)
score += Scorer.objPartialMatch; // matches in last name
const objName = objNames[match[1]][2];
const title = titles[match[0]];
// If more than one term searched for, we require other words to be
// found in the name/title/description
const otherTerms = new Set(objectTerms);
otherTerms.delete(object);
if (otherTerms.size > 0) {
const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase();
if (
[...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0)
)
return;
}
let anchor = match[3];
if (anchor === "") anchor = fullname;
else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname;
const descr = objName + _(", in ") + title;
// add custom score for some objects according to scorer
if (Scorer.objPrio.hasOwnProperty(match[2]))
score += Scorer.objPrio[match[2]];
else score += Scorer.objPrioDefault;
results.push([
docNames[match[0]],
fullname,
"#" + anchor,
descr,
score,
filenames[match[0]],
]);
};
Object.keys(objects).forEach((prefix) =>
objects[prefix].forEach((array) =>
objectSearchCallback(prefix, array)
)
);
return results;
},
/**
* search for full-text terms in the index
*/
performTermsSearch: (searchTerms, excludedTerms) => {
// prepare search
const terms = Search._index.terms;
const titleTerms = Search._index.titleterms;
const filenames = Search._index.filenames;
const docNames = Search._index.docnames;
const titles = Search._index.titles;
const scoreMap = new Map();
const fileMap = new Map();
// perform the search on the required terms
searchTerms.forEach((word) => {
const files = [];
const arr = [
{ files: terms[word], score: Scorer.term },
{ files: titleTerms[word], score: Scorer.title },
];
// add support for partial matches
if (word.length > 2) {
const escapedWord = _escapeRegExp(word);
if (!terms.hasOwnProperty(word)) {
Object.keys(terms).forEach((term) => {
if (term.match(escapedWord))
arr.push({ files: terms[term], score: Scorer.partialTerm });
});
}
if (!titleTerms.hasOwnProperty(word)) {
Object.keys(titleTerms).forEach((term) => {
if (term.match(escapedWord))
arr.push({ files: titleTerms[term], score: Scorer.partialTitle });
});
}
}
// no match but word was a required one
if (arr.every((record) => record.files === undefined)) return;
// found search word in contents
arr.forEach((record) => {
if (record.files === undefined) return;
let recordFiles = record.files;
if (recordFiles.length === undefined) recordFiles = [recordFiles];
files.push(...recordFiles);
// set score for the word in each file
recordFiles.forEach((file) => {
if (!scoreMap.has(file)) scoreMap.set(file, {});
scoreMap.get(file)[word] = record.score;
});
});
// create the mapping
files.forEach((file) => {
if (!fileMap.has(file)) fileMap.set(file, [word]);
else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word);
});
});
// now check if the files don't contain excluded terms
const results = [];
for (const [file, wordList] of fileMap) {
// check if all requirements are matched
// as search terms with length < 3 are discarded
const filteredTermCount = [...searchTerms].filter(
(term) => term.length > 2
).length;
if (
wordList.length !== searchTerms.size &&
wordList.length !== filteredTermCount
)
continue;
// ensure that none of the excluded terms is in the search result
if (
[...excludedTerms].some(
(term) =>
terms[term] === file ||
titleTerms[term] === file ||
(terms[term] || []).includes(file) ||
(titleTerms[term] || []).includes(file)
)
)
break;
// select one (max) score for the file.
const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w]));
// add result to the result list
results.push([
docNames[file],
titles[file],
"",
null,
score,
filenames[file],
]);
}
return results;
},
/**
* helper function to return a node containing the
* search summary for a given text. keywords is a list
* of stemmed words.
*/
makeSearchSummary: (htmlText, keywords, anchor) => {
const text = Search.htmlToText(htmlText, anchor);
if (text === "") return null;
const textLower = text.toLowerCase();
const actualStartPosition = [...keywords]
.map((k) => textLower.indexOf(k.toLowerCase()))
.filter((i) => i > -1)
.slice(-1)[0];
const startWithContext = Math.max(actualStartPosition - 120, 0);
const top = startWithContext === 0 ? "" : "...";
const tail = startWithContext + 240 < text.length ? "..." : "";
let summary = document.createElement("p");
summary.classList.add("context");
summary.textContent = top + text.substr(startWithContext, 240).trim() + tail;
return summary;
},
};
_ready(Search.init);
+154
View File
@@ -0,0 +1,154 @@
/* Highlighting utilities for Sphinx HTML documentation. */
"use strict";
const SPHINX_HIGHLIGHT_ENABLED = true
/**
* highlight a given string on a node by wrapping it in
* span elements with the given class name.
*/
const _highlight = (node, addItems, text, className) => {
if (node.nodeType === Node.TEXT_NODE) {
const val = node.nodeValue;
const parent = node.parentNode;
const pos = val.toLowerCase().indexOf(text);
if (
pos >= 0 &&
!parent.classList.contains(className) &&
!parent.classList.contains("nohighlight")
) {
let span;
const closestNode = parent.closest("body, svg, foreignObject");
const isInSVG = closestNode && closestNode.matches("svg");
if (isInSVG) {
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
} else {
span = document.createElement("span");
span.classList.add(className);
}
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
const rest = document.createTextNode(val.substr(pos + text.length));
parent.insertBefore(
span,
parent.insertBefore(
rest,
node.nextSibling
)
);
node.nodeValue = val.substr(0, pos);
/* There may be more occurrences of search term in this node. So call this
* function recursively on the remaining fragment.
*/
_highlight(rest, addItems, text, className);
if (isInSVG) {
const rect = document.createElementNS(
"http://www.w3.org/2000/svg",
"rect"
);
const bbox = parent.getBBox();
rect.x.baseVal.value = bbox.x;
rect.y.baseVal.value = bbox.y;
rect.width.baseVal.value = bbox.width;
rect.height.baseVal.value = bbox.height;
rect.setAttribute("class", className);
addItems.push({ parent: parent, target: rect });
}
}
} else if (node.matches && !node.matches("button, select, textarea")) {
node.childNodes.forEach((el) => _highlight(el, addItems, text, className));
}
};
const _highlightText = (thisNode, text, className) => {
let addItems = [];
_highlight(thisNode, addItems, text, className);
addItems.forEach((obj) =>
obj.parent.insertAdjacentElement("beforebegin", obj.target)
);
};
/**
* Small JavaScript module for the documentation.
*/
const SphinxHighlight = {
/**
* highlight the search words provided in localstorage in the text
*/
highlightSearchWords: () => {
if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight
// get and clear terms from localstorage
const url = new URL(window.location);
const highlight =
localStorage.getItem("sphinx_highlight_terms")
|| url.searchParams.get("highlight")
|| "";
localStorage.removeItem("sphinx_highlight_terms")
url.searchParams.delete("highlight");
window.history.replaceState({}, "", url);
// get individual terms from highlight string
const terms = highlight.toLowerCase().split(/\s+/).filter(x => x);
if (terms.length === 0) return; // nothing to do
// There should never be more than one element matching "div.body"
const divBody = document.querySelectorAll("div.body");
const body = divBody.length ? divBody[0] : document.querySelector("body");
window.setTimeout(() => {
terms.forEach((term) => _highlightText(body, term, "highlighted"));
}, 10);
const searchBox = document.getElementById("searchbox");
if (searchBox === null) return;
searchBox.appendChild(
document
.createRange()
.createContextualFragment(
'<p class="highlight-link">' +
'<a href="javascript:SphinxHighlight.hideSearchWords()">' +
_("Hide Search Matches") +
"</a></p>"
)
);
},
/**
* helper function to hide the search marks again
*/
hideSearchWords: () => {
document
.querySelectorAll("#searchbox .highlight-link")
.forEach((el) => el.remove());
document
.querySelectorAll("span.highlighted")
.forEach((el) => el.classList.remove("highlighted"));
localStorage.removeItem("sphinx_highlight_terms")
},
initEscapeListener: () => {
// only install a listener if it is really needed
if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return;
document.addEventListener("keydown", (event) => {
// bail for input elements
if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return;
// bail with special keys
if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return;
if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) {
SphinxHighlight.hideSearchWords();
event.preventDefault();
}
});
},
};
_ready(() => {
/* Do not call highlightSearchWords() when we are on the search page.
* It will highlight words from the *previous* search query.
*/
if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords();
SphinxHighlight.initEscapeListener();
});
+414
View File
@@ -0,0 +1,414 @@
<!DOCTYPE html>
<html lang="en" data-content_root="./">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Index &#8212; PraisonAI 0.0.21 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=d1102ebc" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=12dfc556" />
<script src="_static/jquery.js?v=5d32c60e"></script>
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
<script src="_static/documentation_options.js?v=a11416ff"></script>
<script src="_static/doctools.js?v=9a2dae69"></script>
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
<link rel="index" title="Index" href="#" />
<link rel="search" title="Search" href="search.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1 id="index">Index</h1>
<div class="genindex-jumpbox">
<a href="#A"><strong>A</strong></a>
| <a href="#B"><strong>B</strong></a>
| <a href="#C"><strong>C</strong></a>
| <a href="#D"><strong>D</strong></a>
| <a href="#E"><strong>E</strong></a>
| <a href="#G"><strong>G</strong></a>
| <a href="#I"><strong>I</strong></a>
| <a href="#L"><strong>L</strong></a>
| <a href="#M"><strong>M</strong></a>
| <a href="#P"><strong>P</strong></a>
| <a href="#R"><strong>R</strong></a>
| <a href="#S"><strong>S</strong></a>
| <a href="#T"><strong>T</strong></a>
</div>
<h2 id="A">A</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="source/praisonai.html#praisonai.agents_generator.AgentsGenerator">AgentsGenerator (class in praisonai.agents_generator)</a>
</li>
<li><a href="source/praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_CodeDocsSearchTool">autogen_CodeDocsSearchTool() (in module praisonai.inbuilt_tools.autogen_tools)</a>
</li>
<li><a href="source/praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_CSVSearchTool">autogen_CSVSearchTool() (in module praisonai.inbuilt_tools.autogen_tools)</a>
</li>
<li><a href="source/praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_DirectoryReadTool">autogen_DirectoryReadTool() (in module praisonai.inbuilt_tools.autogen_tools)</a>
</li>
<li><a href="source/praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_DirectorySearchTool">autogen_DirectorySearchTool() (in module praisonai.inbuilt_tools.autogen_tools)</a>
</li>
<li><a href="source/praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_DOCXSearchTool">autogen_DOCXSearchTool() (in module praisonai.inbuilt_tools.autogen_tools)</a>
</li>
<li><a href="source/praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_FileReadTool">autogen_FileReadTool() (in module praisonai.inbuilt_tools.autogen_tools)</a>
</li>
<li><a href="source/praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_JSONSearchTool">autogen_JSONSearchTool() (in module praisonai.inbuilt_tools.autogen_tools)</a>
</li>
<li><a href="source/praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_MDXSearchTool">autogen_MDXSearchTool() (in module praisonai.inbuilt_tools.autogen_tools)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="source/praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_PDFSearchTool">autogen_PDFSearchTool() (in module praisonai.inbuilt_tools.autogen_tools)</a>
</li>
<li><a href="source/praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_RagTool">autogen_RagTool() (in module praisonai.inbuilt_tools.autogen_tools)</a>
</li>
<li><a href="source/praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeElementFromWebsiteTool">autogen_ScrapeElementFromWebsiteTool() (in module praisonai.inbuilt_tools.autogen_tools)</a>
</li>
<li><a href="source/praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeWebsiteTool">autogen_ScrapeWebsiteTool() (in module praisonai.inbuilt_tools.autogen_tools)</a>
</li>
<li><a href="source/praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_TXTSearchTool">autogen_TXTSearchTool() (in module praisonai.inbuilt_tools.autogen_tools)</a>
</li>
<li><a href="source/praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_WebsiteSearchTool">autogen_WebsiteSearchTool() (in module praisonai.inbuilt_tools.autogen_tools)</a>
</li>
<li><a href="source/praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_XMLSearchTool">autogen_XMLSearchTool() (in module praisonai.inbuilt_tools.autogen_tools)</a>
</li>
<li><a href="source/praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeChannelSearchTool">autogen_YoutubeChannelSearchTool() (in module praisonai.inbuilt_tools.autogen_tools)</a>
</li>
<li><a href="source/praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeVideoSearchTool">autogen_YoutubeVideoSearchTool() (in module praisonai.inbuilt_tools.autogen_tools)</a>
</li>
<li><a href="source/praisonai.html#praisonai.auto.AutoGenerator">AutoGenerator (class in praisonai.auto)</a>
</li>
</ul></td>
</tr></table>
<h2 id="B">B</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="source/praisonai.html#praisonai.auto.RoleDetails.backstory">backstory (praisonai.auto.RoleDetails attribute)</a>
</li>
</ul></td>
</tr></table>
<h2 id="C">C</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="source/praisonai.html#praisonai.deploy.CloudDeployer">CloudDeployer (class in praisonai.deploy)</a>
</li>
<li><a href="source/praisonai.html#praisonai.auto.AutoGenerator.convert_and_save">convert_and_save() (praisonai.auto.AutoGenerator method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="source/praisonai.html#praisonai.deploy.CloudDeployer.create_api_file">create_api_file() (praisonai.deploy.CloudDeployer method)</a>
</li>
<li><a href="source/praisonai.html#praisonai.deploy.CloudDeployer.create_dockerfile">create_dockerfile() (praisonai.deploy.CloudDeployer method)</a>
</li>
<li><a href="source/praisonai.html#praisonai.cli.PraisonAI.create_gradio_interface">create_gradio_interface() (praisonai.cli.PraisonAI method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="D">D</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="source/praisonai.html#praisonai.auto.TaskDetails.description">description (praisonai.auto.TaskDetails attribute)</a>
</li>
</ul></td>
</tr></table>
<h2 id="E">E</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="source/praisonai.html#praisonai.auto.TaskDetails.expected_output">expected_output (praisonai.auto.TaskDetails attribute)</a>
</li>
</ul></td>
</tr></table>
<h2 id="G">G</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="source/praisonai.html#praisonai.auto.AutoGenerator.generate">generate() (praisonai.auto.AutoGenerator method)</a>
</li>
<li><a href="source/praisonai.html#praisonai.test.generate_crew_and_kickoff">generate_crew_and_kickoff() (in module praisonai.test)</a>
<ul>
<li><a href="source/praisonai.html#praisonai.agents_generator.AgentsGenerator.generate_crew_and_kickoff">(praisonai.agents_generator.AgentsGenerator method)</a>
</li>
</ul></li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="source/praisonai.html#praisonai.auto.AutoGenerator.get_user_content">get_user_content() (praisonai.auto.AutoGenerator method)</a>
</li>
<li><a href="source/praisonai.html#praisonai.auto.RoleDetails.goal">goal (praisonai.auto.RoleDetails attribute)</a>
</li>
</ul></td>
</tr></table>
<h2 id="I">I</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="source/praisonai.html#praisonai.agents_generator.AgentsGenerator.is_function_or_decorated">is_function_or_decorated() (praisonai.agents_generator.AgentsGenerator method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="L">L</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="source/praisonai.html#praisonai.agents_generator.AgentsGenerator.load_tools_from_module">load_tools_from_module() (praisonai.agents_generator.AgentsGenerator method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="source/praisonai.html#praisonai.agents_generator.AgentsGenerator.load_tools_from_package">load_tools_from_package() (praisonai.agents_generator.AgentsGenerator method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="M">M</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="source/praisonai.html#praisonai.cli.PraisonAI.main">main() (praisonai.cli.PraisonAI method)</a>
</li>
<li><a href="source/praisonai.html#praisonai.auto.RoleDetails.model_computed_fields">model_computed_fields (praisonai.auto.RoleDetails attribute)</a>
<ul>
<li><a href="source/praisonai.html#praisonai.auto.TaskDetails.model_computed_fields">(praisonai.auto.TaskDetails attribute)</a>
</li>
<li><a href="source/praisonai.html#praisonai.auto.TeamStructure.model_computed_fields">(praisonai.auto.TeamStructure attribute)</a>
</li>
</ul></li>
<li><a href="source/praisonai.html#praisonai.auto.RoleDetails.model_config">model_config (praisonai.auto.RoleDetails attribute)</a>
<ul>
<li><a href="source/praisonai.html#praisonai.auto.TaskDetails.model_config">(praisonai.auto.TaskDetails attribute)</a>
</li>
<li><a href="source/praisonai.html#praisonai.auto.TeamStructure.model_config">(praisonai.auto.TeamStructure attribute)</a>
</li>
</ul></li>
<li><a href="source/praisonai.html#praisonai.auto.RoleDetails.model_fields">model_fields (praisonai.auto.RoleDetails attribute)</a>
<ul>
<li><a href="source/praisonai.html#praisonai.auto.TaskDetails.model_fields">(praisonai.auto.TaskDetails attribute)</a>
</li>
<li><a href="source/praisonai.html#praisonai.auto.TeamStructure.model_fields">(praisonai.auto.TeamStructure attribute)</a>
</li>
</ul></li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li>
module
<ul>
<li><a href="source/praisonai.html#module-praisonai">praisonai</a>
</li>
<li><a href="source/praisonai.html#module-praisonai.agents_generator">praisonai.agents_generator</a>
</li>
<li><a href="source/praisonai.html#module-praisonai.auto">praisonai.auto</a>
</li>
<li><a href="source/praisonai.html#module-praisonai.cli">praisonai.cli</a>
</li>
<li><a href="source/praisonai.html#module-praisonai.deploy">praisonai.deploy</a>
</li>
<li><a href="source/praisonai.inbuilt_tools.html#module-praisonai.inbuilt_tools">praisonai.inbuilt_tools</a>
</li>
<li><a href="source/praisonai.inbuilt_tools.html#module-praisonai.inbuilt_tools.autogen_tools">praisonai.inbuilt_tools.autogen_tools</a>
</li>
<li><a href="source/praisonai.html#module-praisonai.test">praisonai.test</a>
</li>
<li><a href="source/praisonai.html#module-praisonai.version">praisonai.version</a>
</li>
</ul></li>
</ul></td>
</tr></table>
<h2 id="P">P</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="source/praisonai.html#praisonai.cli.PraisonAI.parse_args">parse_args() (praisonai.cli.PraisonAI method)</a>
</li>
<li>
praisonai
<ul>
<li><a href="source/praisonai.html#module-praisonai">module</a>
</li>
</ul></li>
<li><a href="source/praisonai.html#praisonai.cli.PraisonAI">PraisonAI (class in praisonai.cli)</a>
</li>
<li>
praisonai.agents_generator
<ul>
<li><a href="source/praisonai.html#module-praisonai.agents_generator">module</a>
</li>
</ul></li>
<li>
praisonai.auto
<ul>
<li><a href="source/praisonai.html#module-praisonai.auto">module</a>
</li>
</ul></li>
<li>
praisonai.cli
<ul>
<li><a href="source/praisonai.html#module-praisonai.cli">module</a>
</li>
</ul></li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li>
praisonai.deploy
<ul>
<li><a href="source/praisonai.html#module-praisonai.deploy">module</a>
</li>
</ul></li>
<li>
praisonai.inbuilt_tools
<ul>
<li><a href="source/praisonai.inbuilt_tools.html#module-praisonai.inbuilt_tools">module</a>
</li>
</ul></li>
<li>
praisonai.inbuilt_tools.autogen_tools
<ul>
<li><a href="source/praisonai.inbuilt_tools.html#module-praisonai.inbuilt_tools.autogen_tools">module</a>
</li>
</ul></li>
<li>
praisonai.test
<ul>
<li><a href="source/praisonai.html#module-praisonai.test">module</a>
</li>
</ul></li>
<li>
praisonai.version
<ul>
<li><a href="source/praisonai.html#module-praisonai.version">module</a>
</li>
</ul></li>
</ul></td>
</tr></table>
<h2 id="R">R</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="source/praisonai.html#praisonai.auto.RoleDetails.role">role (praisonai.auto.RoleDetails attribute)</a>
</li>
<li><a href="source/praisonai.html#praisonai.auto.RoleDetails">RoleDetails (class in praisonai.auto)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="source/praisonai.html#praisonai.auto.TeamStructure.roles">roles (praisonai.auto.TeamStructure attribute)</a>
</li>
<li><a href="source/praisonai.html#praisonai.deploy.CloudDeployer.run_commands">run_commands() (praisonai.deploy.CloudDeployer method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="S">S</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="source/praisonai.html#praisonai.deploy.CloudDeployer.set_environment_variables">set_environment_variables() (praisonai.deploy.CloudDeployer method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="T">T</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="source/praisonai.html#praisonai.auto.TaskDetails">TaskDetails (class in praisonai.auto)</a>
</li>
<li><a href="source/praisonai.html#praisonai.auto.RoleDetails.tasks">tasks (praisonai.auto.RoleDetails attribute)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="source/praisonai.html#praisonai.auto.TeamStructure">TeamStructure (class in praisonai.auto)</a>
</li>
<li><a href="source/praisonai.html#praisonai.auto.RoleDetails.tools">tools (praisonai.auto.RoleDetails attribute)</a>
</li>
</ul></td>
</tr></table>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">PraisonAI</a></h1>
<h3>Navigation</h3>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
<search id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;2024, Mervin Praison.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 7.3.7</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a>
</div>
</body>
</html>
+112
View File
@@ -0,0 +1,112 @@
<!DOCTYPE html>
<html lang="en" data-content_root="./">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Welcome to PraisonAI’s documentation! &#8212; PraisonAI 0.0.21 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=d1102ebc" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=12dfc556" />
<script src="_static/jquery.js?v=5d32c60e"></script>
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
<script src="_static/documentation_options.js?v=a11416ff"></script>
<script src="_static/doctools.js?v=9a2dae69"></script>
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="welcome-to-praisonai-s-documentation">
<h1>Welcome to PraisonAI’s documentation!<a class="headerlink" href="#welcome-to-praisonai-s-documentation" title="Link to this heading"></a></h1>
<div class="toctree-wrapper compound">
</div>
</section>
<section id="indices-and-tables">
<h1>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Link to this heading"></a></h1>
<ul class="simple">
<li><p><a class="reference internal" href="genindex.html"><span class="std std-ref">Index</span></a></p></li>
<li><p><a class="reference internal" href="py-modindex.html"><span class="std std-ref">Module Index</span></a></p></li>
<li><p><a class="reference internal" href="search.html"><span class="std std-ref">Search Page</span></a></p></li>
</ul>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="#">PraisonAI</a></h1>
<h3>Navigation</h3>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="#">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
<search id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;2024, Mervin Praison.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 7.3.7</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a>
|
<a href="_sources/index.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>
Binary file not shown.
+156
View File
@@ -0,0 +1,156 @@
<!DOCTYPE html>
<html lang="en" data-content_root="./">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Python Module Index &#8212; PraisonAI 0.0.21 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=d1102ebc" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=12dfc556" />
<script src="_static/jquery.js?v=5d32c60e"></script>
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
<script src="_static/documentation_options.js?v=a11416ff"></script>
<script src="_static/doctools.js?v=9a2dae69"></script>
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Python Module Index</h1>
<div class="modindex-jumpbox">
<a href="#cap-p"><strong>p</strong></a>
</div>
<table class="indextable modindextable">
<tr class="pcap"><td></td><td>&#160;</td><td></td></tr>
<tr class="cap" id="cap-p"><td></td><td>
<strong>p</strong></td><td></td></tr>
<tr>
<td><img src="_static/minus.png" class="toggler"
id="toggle-1" style="display: none" alt="-" /></td>
<td>
<a href="source/praisonai.html#module-praisonai"><code class="xref">praisonai</code></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&#160;&#160;&#160;
<a href="source/praisonai.html#module-praisonai.agents_generator"><code class="xref">praisonai.agents_generator</code></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&#160;&#160;&#160;
<a href="source/praisonai.html#module-praisonai.auto"><code class="xref">praisonai.auto</code></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&#160;&#160;&#160;
<a href="source/praisonai.html#module-praisonai.cli"><code class="xref">praisonai.cli</code></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&#160;&#160;&#160;
<a href="source/praisonai.html#module-praisonai.deploy"><code class="xref">praisonai.deploy</code></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&#160;&#160;&#160;
<a href="source/praisonai.inbuilt_tools.html#module-praisonai.inbuilt_tools"><code class="xref">praisonai.inbuilt_tools</code></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&#160;&#160;&#160;
<a href="source/praisonai.inbuilt_tools.html#module-praisonai.inbuilt_tools.autogen_tools"><code class="xref">praisonai.inbuilt_tools.autogen_tools</code></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&#160;&#160;&#160;
<a href="source/praisonai.html#module-praisonai.test"><code class="xref">praisonai.test</code></a></td><td>
<em></em></td></tr>
<tr class="cg-1">
<td></td>
<td>&#160;&#160;&#160;
<a href="source/praisonai.html#module-praisonai.version"><code class="xref">praisonai.version</code></a></td><td>
<em></em></td></tr>
</table>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">PraisonAI</a></h1>
<h3>Navigation</h3>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
<search id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;2024, Mervin Praison.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 7.3.7</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a>
</div>
</body>
</html>
+118
View File
@@ -0,0 +1,118 @@
<!DOCTYPE html>
<html lang="en" data-content_root="./">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Search &#8212; PraisonAI 0.0.21 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=d1102ebc" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=12dfc556" />
<script src="_static/jquery.js?v=5d32c60e"></script>
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
<script src="_static/documentation_options.js?v=a11416ff"></script>
<script src="_static/doctools.js?v=9a2dae69"></script>
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
<script src="_static/searchtools.js"></script>
<script src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="#" />
<script src="searchindex.js" defer="defer"></script>
<meta name="robots" content="noindex" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1 id="search-documentation">Search</h1>
<noscript>
<div class="admonition warning">
<p>
Please activate JavaScript to enable the search
functionality.
</p>
</div>
</noscript>
<p>
Searching for multiple words only shows matches that contain
all words.
</p>
<form action="" method="get">
<input type="text" name="q" aria-labelledby="search-documentation" value="" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="search" />
<span id="search-progress" style="padding-left: 10px"></span>
</form>
<div id="search-results"></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">PraisonAI</a></h1>
<h3>Navigation</h3>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;2024, Mervin Praison.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 7.3.7</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a>
</div>
</body>
</html>
+1
View File
@@ -0,0 +1 @@
Search.setIndex({"alltitles": {"Indices and tables": [[0, "indices-and-tables"]], "Module contents": [[2, "module-praisonai"], [3, "module-praisonai.inbuilt_tools"]], "Submodules": [[2, "submodules"], [3, "submodules"]], "Subpackages": [[2, "subpackages"]], "Welcome to PraisonAI\u2019s documentation!": [[0, "welcome-to-praisonai-s-documentation"]], "praisonai": [[1, "praisonai"]], "praisonai package": [[2, "praisonai-package"]], "praisonai.agents_generator module": [[2, "module-praisonai.agents_generator"]], "praisonai.auto module": [[2, "module-praisonai.auto"]], "praisonai.cli module": [[2, "module-praisonai.cli"]], "praisonai.deploy module": [[2, "module-praisonai.deploy"]], "praisonai.inbuilt_tools package": [[3, "praisonai-inbuilt-tools-package"]], "praisonai.inbuilt_tools.autogen_tools module": [[3, "module-praisonai.inbuilt_tools.autogen_tools"]], "praisonai.test module": [[2, "module-praisonai.test"]], "praisonai.version module": [[2, "module-praisonai.version"]]}, "docnames": ["index", "source/modules", "source/praisonai", "source/praisonai.inbuilt_tools"], "envversion": {"sphinx": 61, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["index.rst", "source/modules.rst", "source/praisonai.rst", "source/praisonai.inbuilt_tools.rst"], "indexentries": {"agentsgenerator (class in praisonai.agents_generator)": [[2, "praisonai.agents_generator.AgentsGenerator", false]], "autogen_codedocssearchtool() (in module praisonai.inbuilt_tools.autogen_tools)": [[3, "praisonai.inbuilt_tools.autogen_tools.autogen_CodeDocsSearchTool", false]], "autogen_csvsearchtool() (in module praisonai.inbuilt_tools.autogen_tools)": [[3, "praisonai.inbuilt_tools.autogen_tools.autogen_CSVSearchTool", false]], "autogen_directoryreadtool() (in module praisonai.inbuilt_tools.autogen_tools)": [[3, "praisonai.inbuilt_tools.autogen_tools.autogen_DirectoryReadTool", false]], "autogen_directorysearchtool() (in module praisonai.inbuilt_tools.autogen_tools)": [[3, "praisonai.inbuilt_tools.autogen_tools.autogen_DirectorySearchTool", false]], "autogen_docxsearchtool() (in module praisonai.inbuilt_tools.autogen_tools)": [[3, "praisonai.inbuilt_tools.autogen_tools.autogen_DOCXSearchTool", false]], "autogen_filereadtool() (in module praisonai.inbuilt_tools.autogen_tools)": [[3, "praisonai.inbuilt_tools.autogen_tools.autogen_FileReadTool", false]], "autogen_jsonsearchtool() (in module praisonai.inbuilt_tools.autogen_tools)": [[3, "praisonai.inbuilt_tools.autogen_tools.autogen_JSONSearchTool", false]], "autogen_mdxsearchtool() (in module praisonai.inbuilt_tools.autogen_tools)": [[3, "praisonai.inbuilt_tools.autogen_tools.autogen_MDXSearchTool", false]], "autogen_pdfsearchtool() (in module praisonai.inbuilt_tools.autogen_tools)": [[3, "praisonai.inbuilt_tools.autogen_tools.autogen_PDFSearchTool", false]], "autogen_ragtool() (in module praisonai.inbuilt_tools.autogen_tools)": [[3, "praisonai.inbuilt_tools.autogen_tools.autogen_RagTool", false]], "autogen_scrapeelementfromwebsitetool() (in module praisonai.inbuilt_tools.autogen_tools)": [[3, "praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeElementFromWebsiteTool", false]], "autogen_scrapewebsitetool() (in module praisonai.inbuilt_tools.autogen_tools)": [[3, "praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeWebsiteTool", false]], "autogen_txtsearchtool() (in module praisonai.inbuilt_tools.autogen_tools)": [[3, "praisonai.inbuilt_tools.autogen_tools.autogen_TXTSearchTool", false]], "autogen_websitesearchtool() (in module praisonai.inbuilt_tools.autogen_tools)": [[3, "praisonai.inbuilt_tools.autogen_tools.autogen_WebsiteSearchTool", false]], "autogen_xmlsearchtool() (in module praisonai.inbuilt_tools.autogen_tools)": [[3, "praisonai.inbuilt_tools.autogen_tools.autogen_XMLSearchTool", false]], "autogen_youtubechannelsearchtool() (in module praisonai.inbuilt_tools.autogen_tools)": [[3, "praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeChannelSearchTool", false]], "autogen_youtubevideosearchtool() (in module praisonai.inbuilt_tools.autogen_tools)": [[3, "praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeVideoSearchTool", false]], "autogenerator (class in praisonai.auto)": [[2, "praisonai.auto.AutoGenerator", false]], "backstory (praisonai.auto.roledetails attribute)": [[2, "praisonai.auto.RoleDetails.backstory", false]], "clouddeployer (class in praisonai.deploy)": [[2, "praisonai.deploy.CloudDeployer", false]], "convert_and_save() (praisonai.auto.autogenerator method)": [[2, "praisonai.auto.AutoGenerator.convert_and_save", false]], "create_api_file() (praisonai.deploy.clouddeployer method)": [[2, "praisonai.deploy.CloudDeployer.create_api_file", false]], "create_dockerfile() (praisonai.deploy.clouddeployer method)": [[2, "praisonai.deploy.CloudDeployer.create_dLine truncated
+189
View File
@@ -0,0 +1,189 @@
<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>praisonai &#8212; PraisonAI 0.0.21 documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=d1102ebc" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=12dfc556" />
<script src="../_static/jquery.js?v=5d32c60e"></script>
<script src="../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
<script src="../_static/documentation_options.js?v=a11416ff"></script>
<script src="../_static/doctools.js?v=9a2dae69"></script>
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="praisonai">
<h1>praisonai<a class="headerlink" href="#praisonai" title="Link to this heading"></a></h1>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="praisonai.html">praisonai package</a><ul>
<li class="toctree-l2"><a class="reference internal" href="praisonai.html#subpackages">Subpackages</a><ul>
<li class="toctree-l3"><a class="reference internal" href="praisonai.inbuilt_tools.html">praisonai.inbuilt_tools package</a><ul>
<li class="toctree-l4"><a class="reference internal" href="praisonai.inbuilt_tools.html#submodules">Submodules</a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.inbuilt_tools.html#module-praisonai.inbuilt_tools.autogen_tools">praisonai.inbuilt_tools.autogen_tools module</a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.inbuilt_tools.html#module-praisonai.inbuilt_tools">Module contents</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="praisonai.html#submodules">Submodules</a></li>
<li class="toctree-l2"><a class="reference internal" href="praisonai.html#module-praisonai.agents_generator">praisonai.agents_generator module</a><ul>
<li class="toctree-l3"><a class="reference internal" href="praisonai.html#praisonai.agents_generator.AgentsGenerator"><code class="docutils literal notranslate"><span class="pre">AgentsGenerator</span></code></a><ul>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.agents_generator.AgentsGenerator.generate_crew_and_kickoff"><code class="docutils literal notranslate"><span class="pre">AgentsGenerator.generate_crew_and_kickoff()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.agents_generator.AgentsGenerator.is_function_or_decorated"><code class="docutils literal notranslate"><span class="pre">AgentsGenerator.is_function_or_decorated()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.agents_generator.AgentsGenerator.load_tools_from_module"><code class="docutils literal notranslate"><span class="pre">AgentsGenerator.load_tools_from_module()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.agents_generator.AgentsGenerator.load_tools_from_package"><code class="docutils literal notranslate"><span class="pre">AgentsGenerator.load_tools_from_package()</span></code></a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="praisonai.html#module-praisonai.auto">praisonai.auto module</a><ul>
<li class="toctree-l3"><a class="reference internal" href="praisonai.html#praisonai.auto.AutoGenerator"><code class="docutils literal notranslate"><span class="pre">AutoGenerator</span></code></a><ul>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.auto.AutoGenerator.convert_and_save"><code class="docutils literal notranslate"><span class="pre">AutoGenerator.convert_and_save()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.auto.AutoGenerator.generate"><code class="docutils literal notranslate"><span class="pre">AutoGenerator.generate()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.auto.AutoGenerator.get_user_content"><code class="docutils literal notranslate"><span class="pre">AutoGenerator.get_user_content()</span></code></a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="praisonai.html#praisonai.auto.RoleDetails"><code class="docutils literal notranslate"><span class="pre">RoleDetails</span></code></a><ul>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.auto.RoleDetails.backstory"><code class="docutils literal notranslate"><span class="pre">RoleDetails.backstory</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.auto.RoleDetails.goal"><code class="docutils literal notranslate"><span class="pre">RoleDetails.goal</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.auto.RoleDetails.model_computed_fields"><code class="docutils literal notranslate"><span class="pre">RoleDetails.model_computed_fields</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.auto.RoleDetails.model_config"><code class="docutils literal notranslate"><span class="pre">RoleDetails.model_config</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.auto.RoleDetails.model_fields"><code class="docutils literal notranslate"><span class="pre">RoleDetails.model_fields</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.auto.RoleDetails.role"><code class="docutils literal notranslate"><span class="pre">RoleDetails.role</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.auto.RoleDetails.tasks"><code class="docutils literal notranslate"><span class="pre">RoleDetails.tasks</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.auto.RoleDetails.tools"><code class="docutils literal notranslate"><span class="pre">RoleDetails.tools</span></code></a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="praisonai.html#praisonai.auto.TaskDetails"><code class="docutils literal notranslate"><span class="pre">TaskDetails</span></code></a><ul>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.auto.TaskDetails.description"><code class="docutils literal notranslate"><span class="pre">TaskDetails.description</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.auto.TaskDetails.expected_output"><code class="docutils literal notranslate"><span class="pre">TaskDetails.expected_output</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.auto.TaskDetails.model_computed_fields"><code class="docutils literal notranslate"><span class="pre">TaskDetails.model_computed_fields</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.auto.TaskDetails.model_config"><code class="docutils literal notranslate"><span class="pre">TaskDetails.model_config</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.auto.TaskDetails.model_fields"><code class="docutils literal notranslate"><span class="pre">TaskDetails.model_fields</span></code></a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="praisonai.html#praisonai.auto.TeamStructure"><code class="docutils literal notranslate"><span class="pre">TeamStructure</span></code></a><ul>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.auto.TeamStructure.model_computed_fields"><code class="docutils literal notranslate"><span class="pre">TeamStructure.model_computed_fields</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.auto.TeamStructure.model_config"><code class="docutils literal notranslate"><span class="pre">TeamStructure.model_config</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.auto.TeamStructure.model_fields"><code class="docutils literal notranslate"><span class="pre">TeamStructure.model_fields</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.auto.TeamStructure.roles"><code class="docutils literal notranslate"><span class="pre">TeamStructure.roles</span></code></a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="praisonai.html#module-praisonai.cli">praisonai.cli module</a><ul>
<li class="toctree-l3"><a class="reference internal" href="praisonai.html#praisonai.cli.PraisonAI"><code class="docutils literal notranslate"><span class="pre">PraisonAI</span></code></a><ul>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.cli.PraisonAI.create_gradio_interface"><code class="docutils literal notranslate"><span class="pre">PraisonAI.create_gradio_interface()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.cli.PraisonAI.main"><code class="docutils literal notranslate"><span class="pre">PraisonAI.main()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.cli.PraisonAI.parse_args"><code class="docutils literal notranslate"><span class="pre">PraisonAI.parse_args()</span></code></a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="praisonai.html#module-praisonai.deploy">praisonai.deploy module</a><ul>
<li class="toctree-l3"><a class="reference internal" href="praisonai.html#praisonai.deploy.CloudDeployer"><code class="docutils literal notranslate"><span class="pre">CloudDeployer</span></code></a><ul>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.deploy.CloudDeployer.create_api_file"><code class="docutils literal notranslate"><span class="pre">CloudDeployer.create_api_file()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.deploy.CloudDeployer.create_dockerfile"><code class="docutils literal notranslate"><span class="pre">CloudDeployer.create_dockerfile()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.deploy.CloudDeployer.run_commands"><code class="docutils literal notranslate"><span class="pre">CloudDeployer.run_commands()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="praisonai.html#praisonai.deploy.CloudDeployer.set_environment_variables"><code class="docutils literal notranslate"><span class="pre">CloudDeployer.set_environment_variables()</span></code></a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="praisonai.html#module-praisonai.test">praisonai.test module</a><ul>
<li class="toctree-l3"><a class="reference internal" href="praisonai.html#praisonai.test.generate_crew_and_kickoff"><code class="docutils literal notranslate"><span class="pre">generate_crew_and_kickoff()</span></code></a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="praisonai.html#module-praisonai.version">praisonai.version module</a></li>
<li class="toctree-l2"><a class="reference internal" href="praisonai.html#module-praisonai">Module contents</a></li>
</ul>
</li>
</ul>
</div>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">PraisonAI</a></h1>
<h3>Navigation</h3>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
<search id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;2024, Mervin Praison.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 7.3.7</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a>
|
<a href="../_sources/source/modules.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>
+386
View File
@@ -0,0 +1,386 @@
<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>praisonai package &#8212; PraisonAI 0.0.21 documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=d1102ebc" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=12dfc556" />
<script src="../_static/jquery.js?v=5d32c60e"></script>
<script src="../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
<script src="../_static/documentation_options.js?v=a11416ff"></script>
<script src="../_static/doctools.js?v=9a2dae69"></script>
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="praisonai-package">
<h1>praisonai package<a class="headerlink" href="#praisonai-package" title="Link to this heading"></a></h1>
<section id="subpackages">
<h2>Subpackages<a class="headerlink" href="#subpackages" title="Link to this heading"></a></h2>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="praisonai.inbuilt_tools.html">praisonai.inbuilt_tools package</a><ul>
<li class="toctree-l2"><a class="reference internal" href="praisonai.inbuilt_tools.html#submodules">Submodules</a></li>
<li class="toctree-l2"><a class="reference internal" href="praisonai.inbuilt_tools.html#module-praisonai.inbuilt_tools.autogen_tools">praisonai.inbuilt_tools.autogen_tools module</a><ul>
<li class="toctree-l3"><a class="reference internal" href="praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_CSVSearchTool"><code class="docutils literal notranslate"><span class="pre">autogen_CSVSearchTool()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_CodeDocsSearchTool"><code class="docutils literal notranslate"><span class="pre">autogen_CodeDocsSearchTool()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_DOCXSearchTool"><code class="docutils literal notranslate"><span class="pre">autogen_DOCXSearchTool()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_DirectoryReadTool"><code class="docutils literal notranslate"><span class="pre">autogen_DirectoryReadTool()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_DirectorySearchTool"><code class="docutils literal notranslate"><span class="pre">autogen_DirectorySearchTool()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_FileReadTool"><code class="docutils literal notranslate"><span class="pre">autogen_FileReadTool()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_JSONSearchTool"><code class="docutils literal notranslate"><span class="pre">autogen_JSONSearchTool()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_MDXSearchTool"><code class="docutils literal notranslate"><span class="pre">autogen_MDXSearchTool()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_PDFSearchTool"><code class="docutils literal notranslate"><span class="pre">autogen_PDFSearchTool()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_RagTool"><code class="docutils literal notranslate"><span class="pre">autogen_RagTool()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeElementFromWebsiteTool"><code class="docutils literal notranslate"><span class="pre">autogen_ScrapeElementFromWebsiteTool()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeWebsiteTool"><code class="docutils literal notranslate"><span class="pre">autogen_ScrapeWebsiteTool()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_TXTSearchTool"><code class="docutils literal notranslate"><span class="pre">autogen_TXTSearchTool()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_WebsiteSearchTool"><code class="docutils literal notranslate"><span class="pre">autogen_WebsiteSearchTool()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_XMLSearchTool"><code class="docutils literal notranslate"><span class="pre">autogen_XMLSearchTool()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeChannelSearchTool"><code class="docutils literal notranslate"><span class="pre">autogen_YoutubeChannelSearchTool()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="praisonai.inbuilt_tools.html#praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeVideoSearchTool"><code class="docutils literal notranslate"><span class="pre">autogen_YoutubeVideoSearchTool()</span></code></a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="praisonai.inbuilt_tools.html#module-praisonai.inbuilt_tools">Module contents</a></li>
</ul>
</li>
</ul>
</div>
</section>
<section id="submodules">
<h2>Submodules<a class="headerlink" href="#submodules" title="Link to this heading"></a></h2>
</section>
<section id="module-praisonai.agents_generator">
<span id="praisonai-agents-generator-module"></span><h2>praisonai.agents_generator module<a class="headerlink" href="#module-praisonai.agents_generator" title="Link to this heading"></a></h2>
<dl class="py class">
<dt class="sig sig-object py" id="praisonai.agents_generator.AgentsGenerator">
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">praisonai.agents_generator.</span></span><span class="sig-name descname"><span class="pre">AgentsGenerator</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">agent_file</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">framework</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">config_list</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.agents_generator.AgentsGenerator" title="Link to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
<dl class="py method">
<dt class="sig sig-object py" id="praisonai.agents_generator.AgentsGenerator.generate_crew_and_kickoff">
<span class="sig-name descname"><span class="pre">generate_crew_and_kickoff</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.agents_generator.AgentsGenerator.generate_crew_and_kickoff" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="praisonai.agents_generator.AgentsGenerator.is_function_or_decorated">
<span class="sig-name descname"><span class="pre">is_function_or_decorated</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">obj</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.agents_generator.AgentsGenerator.is_function_or_decorated" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="praisonai.agents_generator.AgentsGenerator.load_tools_from_module">
<span class="sig-name descname"><span class="pre">load_tools_from_module</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">module_path</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.agents_generator.AgentsGenerator.load_tools_from_module" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="praisonai.agents_generator.AgentsGenerator.load_tools_from_package">
<span class="sig-name descname"><span class="pre">load_tools_from_package</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">package_path</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.agents_generator.AgentsGenerator.load_tools_from_package" title="Link to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
</section>
<section id="module-praisonai.auto">
<span id="praisonai-auto-module"></span><h2>praisonai.auto module<a class="headerlink" href="#module-praisonai.auto" title="Link to this heading"></a></h2>
<dl class="py class">
<dt class="sig sig-object py" id="praisonai.auto.AutoGenerator">
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">praisonai.auto.</span></span><span class="sig-name descname"><span class="pre">AutoGenerator</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">topic</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">'Movie</span> <span class="pre">Story</span> <span class="pre">writing</span> <span class="pre">about</span> <span class="pre">AI'</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">agent_file</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">'test.yaml'</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">framework</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">'crewai'</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.auto.AutoGenerator" title="Link to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
<dl class="py method">
<dt class="sig sig-object py" id="praisonai.auto.AutoGenerator.convert_and_save">
<span class="sig-name descname"><span class="pre">convert_and_save</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">json_data</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.auto.AutoGenerator.convert_and_save" title="Link to this definition"></a></dt>
<dd><p>Converts the provided JSON data into the desired YAML format and saves it to a file.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>json_data</strong> (<em>dict</em>) – The JSON data representing the team structure.</p></li>
<li><p><strong>topic</strong> (<em>str</em><em>, </em><em>optional</em>) – The topic to be inserted into the YAML. Defaults to “Artificial Intelligence”.</p></li>
<li><p><strong>agent_file</strong> (<em>str</em><em>, </em><em>optional</em>) – The name of the YAML file to save. Defaults to “test.yaml”.</p></li>
</ul>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="praisonai.auto.AutoGenerator.generate">
<span class="sig-name descname"><span class="pre">generate</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.auto.AutoGenerator.generate" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="praisonai.auto.AutoGenerator.get_user_content">
<span class="sig-name descname"><span class="pre">get_user_content</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.auto.AutoGenerator.get_user_content" title="Link to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
<dl class="py class">
<dt class="sig sig-object py" id="praisonai.auto.RoleDetails">
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">praisonai.auto.</span></span><span class="sig-name descname"><span class="pre">RoleDetails</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="o"><span class="pre">*</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">role</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">goal</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">backstory</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">tasks</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Dict</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><a class="reference internal" href="#praisonai.auto.TaskDetails" title="praisonai.auto.TaskDetails"><span class="pre">TaskDetails</span></a><span class="p"><span class="pre">]</span></span></span></em>, <em class="sig-param"><span class="n"><span class="pre">tools</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">List</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">]</span></span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.auto.RoleDetails" title="Link to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">BaseModel</span></code></p>
<dl class="py attribute">
<dt class="sig sig-object py" id="praisonai.auto.RoleDetails.backstory">
<span class="sig-name descname"><span class="pre">backstory</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">str</span></em><a class="headerlink" href="#praisonai.auto.RoleDetails.backstory" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="praisonai.auto.RoleDetails.goal">
<span class="sig-name descname"><span class="pre">goal</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">str</span></em><a class="headerlink" href="#praisonai.auto.RoleDetails.goal" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="praisonai.auto.RoleDetails.model_computed_fields">
<span class="sig-name descname"><span class="pre">model_computed_fields</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">ClassVar</span><span class="p"><span class="pre">[</span></span><span class="pre">dict</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">ComputedFieldInfo</span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></span></em><em class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">{}</span></em><a class="headerlink" href="#praisonai.auto.RoleDetails.model_computed_fields" title="Link to this definition"></a></dt>
<dd><p>A dictionary of computed field names and their corresponding <cite>ComputedFieldInfo</cite> objects.</p>
</dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="praisonai.auto.RoleDetails.model_config">
<span class="sig-name descname"><span class="pre">model_config</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">ClassVar</span><span class="p"><span class="pre">[</span></span><span class="pre">ConfigDict</span><span class="p"><span class="pre">]</span></span></em><em class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">{}</span></em><a class="headerlink" href="#praisonai.auto.RoleDetails.model_config" title="Link to this definition"></a></dt>
<dd><p>Configuration for the model, should be a dictionary conforming to [<cite>ConfigDict</cite>][pydantic.config.ConfigDict].</p>
</dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="praisonai.auto.RoleDetails.model_fields">
<span class="sig-name descname"><span class="pre">model_fields</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">ClassVar</span><span class="p"><span class="pre">[</span></span><span class="pre">dict</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">FieldInfo</span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></span></em><em class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">{'backstory':</span> <span class="pre">FieldInfo(annotation=str,</span> <span class="pre">required=True),</span> <span class="pre">'goal':</span> <span class="pre">FieldInfo(annotation=str,</span> <span class="pre">required=True),</span> <span class="pre">'role':</span> <span class="pre">FieldInfo(annotation=str,</span> <span class="pre">required=True),</span> <span class="pre">'tasks':</span> <span class="pre">FieldInfo(annotation=Dict[str,</span> <span class="pre">TaskDetails],</span> <span class="pre">required=True),</span> <span class="pre">'tools':</span> <span class="pre">FieldInfo(annotation=List[str],</span> <span class="pre">required=True)}</span></em><a class="headerlink" href="#praisonai.auto.RoleDetails.model_fields" title="Link to this definition"></a></dt>
<dd><p>Metadata about the fields defined on the model,
mapping of field names to [<cite>FieldInfo</cite>][pydantic.fields.FieldInfo].</p>
<p>This replaces <cite>Model.__fields__</cite> from Pydantic V1.</p>
</dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="praisonai.auto.RoleDetails.role">
<span class="sig-name descname"><span class="pre">role</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">str</span></em><a class="headerlink" href="#praisonai.auto.RoleDetails.role" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="praisonai.auto.RoleDetails.tasks">
<span class="sig-name descname"><span class="pre">tasks</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">Dict</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><a class="reference internal" href="#praisonai.auto.TaskDetails" title="praisonai.auto.TaskDetails"><span class="pre">TaskDetails</span></a><span class="p"><span class="pre">]</span></span></em><a class="headerlink" href="#praisonai.auto.RoleDetails.tasks" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="praisonai.auto.RoleDetails.tools">
<span class="sig-name descname"><span class="pre">tools</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">List</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">]</span></span></em><a class="headerlink" href="#praisonai.auto.RoleDetails.tools" title="Link to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
<dl class="py class">
<dt class="sig sig-object py" id="praisonai.auto.TaskDetails">
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">praisonai.auto.</span></span><span class="sig-name descname"><span class="pre">TaskDetails</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="o"><span class="pre">*</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">description</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">expected_output</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.auto.TaskDetails" title="Link to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">BaseModel</span></code></p>
<dl class="py attribute">
<dt class="sig sig-object py" id="praisonai.auto.TaskDetails.description">
<span class="sig-name descname"><span class="pre">description</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">str</span></em><a class="headerlink" href="#praisonai.auto.TaskDetails.description" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="praisonai.auto.TaskDetails.expected_output">
<span class="sig-name descname"><span class="pre">expected_output</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">str</span></em><a class="headerlink" href="#praisonai.auto.TaskDetails.expected_output" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="praisonai.auto.TaskDetails.model_computed_fields">
<span class="sig-name descname"><span class="pre">model_computed_fields</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">ClassVar</span><span class="p"><span class="pre">[</span></span><span class="pre">dict</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">ComputedFieldInfo</span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></span></em><em class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">{}</span></em><a class="headerlink" href="#praisonai.auto.TaskDetails.model_computed_fields" title="Link to this definition"></a></dt>
<dd><p>A dictionary of computed field names and their corresponding <cite>ComputedFieldInfo</cite> objects.</p>
</dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="praisonai.auto.TaskDetails.model_config">
<span class="sig-name descname"><span class="pre">model_config</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">ClassVar</span><span class="p"><span class="pre">[</span></span><span class="pre">ConfigDict</span><span class="p"><span class="pre">]</span></span></em><em class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">{}</span></em><a class="headerlink" href="#praisonai.auto.TaskDetails.model_config" title="Link to this definition"></a></dt>
<dd><p>Configuration for the model, should be a dictionary conforming to [<cite>ConfigDict</cite>][pydantic.config.ConfigDict].</p>
</dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="praisonai.auto.TaskDetails.model_fields">
<span class="sig-name descname"><span class="pre">model_fields</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">ClassVar</span><span class="p"><span class="pre">[</span></span><span class="pre">dict</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">FieldInfo</span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></span></em><em class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">{'description':</span> <span class="pre">FieldInfo(annotation=str,</span> <span class="pre">required=True),</span> <span class="pre">'expected_output':</span> <span class="pre">FieldInfo(annotation=str,</span> <span class="pre">required=True)}</span></em><a class="headerlink" href="#praisonai.auto.TaskDetails.model_fields" title="Link to this definition"></a></dt>
<dd><p>Metadata about the fields defined on the model,
mapping of field names to [<cite>FieldInfo</cite>][pydantic.fields.FieldInfo].</p>
<p>This replaces <cite>Model.__fields__</cite> from Pydantic V1.</p>
</dd></dl>
</dd></dl>
<dl class="py class">
<dt class="sig sig-object py" id="praisonai.auto.TeamStructure">
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">praisonai.auto.</span></span><span class="sig-name descname"><span class="pre">TeamStructure</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="o"><span class="pre">*</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">roles</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Dict</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><a class="reference internal" href="#praisonai.auto.RoleDetails" title="praisonai.auto.RoleDetails"><span class="pre">RoleDetails</span></a><span class="p"><span class="pre">]</span></span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.auto.TeamStructure" title="Link to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">BaseModel</span></code></p>
<dl class="py attribute">
<dt class="sig sig-object py" id="praisonai.auto.TeamStructure.model_computed_fields">
<span class="sig-name descname"><span class="pre">model_computed_fields</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">ClassVar</span><span class="p"><span class="pre">[</span></span><span class="pre">dict</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">ComputedFieldInfo</span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></span></em><em class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">{}</span></em><a class="headerlink" href="#praisonai.auto.TeamStructure.model_computed_fields" title="Link to this definition"></a></dt>
<dd><p>A dictionary of computed field names and their corresponding <cite>ComputedFieldInfo</cite> objects.</p>
</dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="praisonai.auto.TeamStructure.model_config">
<span class="sig-name descname"><span class="pre">model_config</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">ClassVar</span><span class="p"><span class="pre">[</span></span><span class="pre">ConfigDict</span><span class="p"><span class="pre">]</span></span></em><em class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">{}</span></em><a class="headerlink" href="#praisonai.auto.TeamStructure.model_config" title="Link to this definition"></a></dt>
<dd><p>Configuration for the model, should be a dictionary conforming to [<cite>ConfigDict</cite>][pydantic.config.ConfigDict].</p>
</dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="praisonai.auto.TeamStructure.model_fields">
<span class="sig-name descname"><span class="pre">model_fields</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">ClassVar</span><span class="p"><span class="pre">[</span></span><span class="pre">dict</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">FieldInfo</span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></span></em><em class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">{'roles':</span> <span class="pre">FieldInfo(annotation=Dict[str,</span> <span class="pre">RoleDetails],</span> <span class="pre">required=True)}</span></em><a class="headerlink" href="#praisonai.auto.TeamStructure.model_fields" title="Link to this definition"></a></dt>
<dd><p>Metadata about the fields defined on the model,
mapping of field names to [<cite>FieldInfo</cite>][pydantic.fields.FieldInfo].</p>
<p>This replaces <cite>Model.__fields__</cite> from Pydantic V1.</p>
</dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="praisonai.auto.TeamStructure.roles">
<span class="sig-name descname"><span class="pre">roles</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">Dict</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><a class="reference internal" href="#praisonai.auto.RoleDetails" title="praisonai.auto.RoleDetails"><span class="pre">RoleDetails</span></a><span class="p"><span class="pre">]</span></span></em><a class="headerlink" href="#praisonai.auto.TeamStructure.roles" title="Link to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
</section>
<section id="module-praisonai.cli">
<span id="praisonai-cli-module"></span><h2>praisonai.cli module<a class="headerlink" href="#module-praisonai.cli" title="Link to this heading"></a></h2>
<dl class="py class">
<dt class="sig sig-object py" id="praisonai.cli.PraisonAI">
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">praisonai.cli.</span></span><span class="sig-name descname"><span class="pre">PraisonAI</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">agent_file</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">'agents.yaml'</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">framework</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">'crewai'</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">auto</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">init</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.cli.PraisonAI" title="Link to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
<dl class="py method">
<dt class="sig sig-object py" id="praisonai.cli.PraisonAI.create_gradio_interface">
<span class="sig-name descname"><span class="pre">create_gradio_interface</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.cli.PraisonAI.create_gradio_interface" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="praisonai.cli.PraisonAI.main">
<span class="sig-name descname"><span class="pre">main</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.cli.PraisonAI.main" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="praisonai.cli.PraisonAI.parse_args">
<span class="sig-name descname"><span class="pre">parse_args</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.cli.PraisonAI.parse_args" title="Link to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
</section>
<section id="module-praisonai.deploy">
<span id="praisonai-deploy-module"></span><h2>praisonai.deploy module<a class="headerlink" href="#module-praisonai.deploy" title="Link to this heading"></a></h2>
<dl class="py class">
<dt class="sig sig-object py" id="praisonai.deploy.CloudDeployer">
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">praisonai.deploy.</span></span><span class="sig-name descname"><span class="pre">CloudDeployer</span></span><a class="headerlink" href="#praisonai.deploy.CloudDeployer" title="Link to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
<dl class="py method">
<dt class="sig sig-object py" id="praisonai.deploy.CloudDeployer.create_api_file">
<span class="sig-name descname"><span class="pre">create_api_file</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.deploy.CloudDeployer.create_api_file" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="praisonai.deploy.CloudDeployer.create_dockerfile">
<span class="sig-name descname"><span class="pre">create_dockerfile</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.deploy.CloudDeployer.create_dockerfile" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="praisonai.deploy.CloudDeployer.run_commands">
<span class="sig-name descname"><span class="pre">run_commands</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.deploy.CloudDeployer.run_commands" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="praisonai.deploy.CloudDeployer.set_environment_variables">
<span class="sig-name descname"><span class="pre">set_environment_variables</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.deploy.CloudDeployer.set_environment_variables" title="Link to this definition"></a></dt>
<dd><p>Sets environment variables with fallback to .env values or defaults.</p>
</dd></dl>
</dd></dl>
</section>
<section id="module-praisonai.test">
<span id="praisonai-test-module"></span><h2>praisonai.test module<a class="headerlink" href="#module-praisonai.test" title="Link to this heading"></a></h2>
<dl class="py function">
<dt class="sig sig-object py" id="praisonai.test.generate_crew_and_kickoff">
<span class="sig-prename descclassname"><span class="pre">praisonai.test.</span></span><span class="sig-name descname"><span class="pre">generate_crew_and_kickoff</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">agent_file</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.test.generate_crew_and_kickoff" title="Link to this definition"></a></dt>
<dd></dd></dl>
</section>
<section id="module-praisonai.version">
<span id="praisonai-version-module"></span><h2>praisonai.version module<a class="headerlink" href="#module-praisonai.version" title="Link to this heading"></a></h2>
</section>
<section id="module-praisonai">
<span id="module-contents"></span><h2>Module contents<a class="headerlink" href="#module-praisonai" title="Link to this heading"></a></h2>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">PraisonAI</a></h1>
<h3>Navigation</h3>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
<search id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;2024, Mervin Praison.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 7.3.7</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a>
|
<a href="../_sources/source/praisonai.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>
@@ -0,0 +1,196 @@
<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>praisonai.inbuilt_tools package &#8212; PraisonAI 0.0.21 documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=d1102ebc" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=12dfc556" />
<script src="../_static/jquery.js?v=5d32c60e"></script>
<script src="../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
<script src="../_static/documentation_options.js?v=a11416ff"></script>
<script src="../_static/doctools.js?v=9a2dae69"></script>
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="praisonai-inbuilt-tools-package">
<h1>praisonai.inbuilt_tools package<a class="headerlink" href="#praisonai-inbuilt-tools-package" title="Link to this heading"></a></h1>
<section id="submodules">
<h2>Submodules<a class="headerlink" href="#submodules" title="Link to this heading"></a></h2>
</section>
<section id="module-praisonai.inbuilt_tools.autogen_tools">
<span id="praisonai-inbuilt-tools-autogen-tools-module"></span><h2>praisonai.inbuilt_tools.autogen_tools module<a class="headerlink" href="#module-praisonai.inbuilt_tools.autogen_tools" title="Link to this heading"></a></h2>
<dl class="py function">
<dt class="sig sig-object py" id="praisonai.inbuilt_tools.autogen_tools.autogen_CSVSearchTool">
<span class="sig-prename descclassname"><span class="pre">praisonai.inbuilt_tools.autogen_tools.</span></span><span class="sig-name descname"><span class="pre">autogen_CSVSearchTool</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">assistant</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">user_proxy</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.inbuilt_tools.autogen_tools.autogen_CSVSearchTool" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="praisonai.inbuilt_tools.autogen_tools.autogen_CodeDocsSearchTool">
<span class="sig-prename descclassname"><span class="pre">praisonai.inbuilt_tools.autogen_tools.</span></span><span class="sig-name descname"><span class="pre">autogen_CodeDocsSearchTool</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">assistant</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">user_proxy</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.inbuilt_tools.autogen_tools.autogen_CodeDocsSearchTool" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="praisonai.inbuilt_tools.autogen_tools.autogen_DOCXSearchTool">
<span class="sig-prename descclassname"><span class="pre">praisonai.inbuilt_tools.autogen_tools.</span></span><span class="sig-name descname"><span class="pre">autogen_DOCXSearchTool</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">assistant</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">user_proxy</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.inbuilt_tools.autogen_tools.autogen_DOCXSearchTool" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="praisonai.inbuilt_tools.autogen_tools.autogen_DirectoryReadTool">
<span class="sig-prename descclassname"><span class="pre">praisonai.inbuilt_tools.autogen_tools.</span></span><span class="sig-name descname"><span class="pre">autogen_DirectoryReadTool</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">assistant</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">user_proxy</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.inbuilt_tools.autogen_tools.autogen_DirectoryReadTool" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="praisonai.inbuilt_tools.autogen_tools.autogen_DirectorySearchTool">
<span class="sig-prename descclassname"><span class="pre">praisonai.inbuilt_tools.autogen_tools.</span></span><span class="sig-name descname"><span class="pre">autogen_DirectorySearchTool</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">assistant</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">user_proxy</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.inbuilt_tools.autogen_tools.autogen_DirectorySearchTool" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="praisonai.inbuilt_tools.autogen_tools.autogen_FileReadTool">
<span class="sig-prename descclassname"><span class="pre">praisonai.inbuilt_tools.autogen_tools.</span></span><span class="sig-name descname"><span class="pre">autogen_FileReadTool</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">assistant</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">user_proxy</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.inbuilt_tools.autogen_tools.autogen_FileReadTool" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="praisonai.inbuilt_tools.autogen_tools.autogen_JSONSearchTool">
<span class="sig-prename descclassname"><span class="pre">praisonai.inbuilt_tools.autogen_tools.</span></span><span class="sig-name descname"><span class="pre">autogen_JSONSearchTool</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">assistant</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">user_proxy</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.inbuilt_tools.autogen_tools.autogen_JSONSearchTool" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="praisonai.inbuilt_tools.autogen_tools.autogen_MDXSearchTool">
<span class="sig-prename descclassname"><span class="pre">praisonai.inbuilt_tools.autogen_tools.</span></span><span class="sig-name descname"><span class="pre">autogen_MDXSearchTool</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">assistant</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">user_proxy</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.inbuilt_tools.autogen_tools.autogen_MDXSearchTool" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="praisonai.inbuilt_tools.autogen_tools.autogen_PDFSearchTool">
<span class="sig-prename descclassname"><span class="pre">praisonai.inbuilt_tools.autogen_tools.</span></span><span class="sig-name descname"><span class="pre">autogen_PDFSearchTool</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">assistant</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">user_proxy</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.inbuilt_tools.autogen_tools.autogen_PDFSearchTool" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="praisonai.inbuilt_tools.autogen_tools.autogen_RagTool">
<span class="sig-prename descclassname"><span class="pre">praisonai.inbuilt_tools.autogen_tools.</span></span><span class="sig-name descname"><span class="pre">autogen_RagTool</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">assistant</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">user_proxy</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.inbuilt_tools.autogen_tools.autogen_RagTool" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeElementFromWebsiteTool">
<span class="sig-prename descclassname"><span class="pre">praisonai.inbuilt_tools.autogen_tools.</span></span><span class="sig-name descname"><span class="pre">autogen_ScrapeElementFromWebsiteTool</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">assistant</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">user_proxy</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeElementFromWebsiteTool" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeWebsiteTool">
<span class="sig-prename descclassname"><span class="pre">praisonai.inbuilt_tools.autogen_tools.</span></span><span class="sig-name descname"><span class="pre">autogen_ScrapeWebsiteTool</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">assistant</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">user_proxy</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeWebsiteTool" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="praisonai.inbuilt_tools.autogen_tools.autogen_TXTSearchTool">
<span class="sig-prename descclassname"><span class="pre">praisonai.inbuilt_tools.autogen_tools.</span></span><span class="sig-name descname"><span class="pre">autogen_TXTSearchTool</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">assistant</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">user_proxy</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.inbuilt_tools.autogen_tools.autogen_TXTSearchTool" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="praisonai.inbuilt_tools.autogen_tools.autogen_WebsiteSearchTool">
<span class="sig-prename descclassname"><span class="pre">praisonai.inbuilt_tools.autogen_tools.</span></span><span class="sig-name descname"><span class="pre">autogen_WebsiteSearchTool</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">assistant</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">user_proxy</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.inbuilt_tools.autogen_tools.autogen_WebsiteSearchTool" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="praisonai.inbuilt_tools.autogen_tools.autogen_XMLSearchTool">
<span class="sig-prename descclassname"><span class="pre">praisonai.inbuilt_tools.autogen_tools.</span></span><span class="sig-name descname"><span class="pre">autogen_XMLSearchTool</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">assistant</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">user_proxy</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.inbuilt_tools.autogen_tools.autogen_XMLSearchTool" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeChannelSearchTool">
<span class="sig-prename descclassname"><span class="pre">praisonai.inbuilt_tools.autogen_tools.</span></span><span class="sig-name descname"><span class="pre">autogen_YoutubeChannelSearchTool</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">assistant</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">user_proxy</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeChannelSearchTool" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeVideoSearchTool">
<span class="sig-prename descclassname"><span class="pre">praisonai.inbuilt_tools.autogen_tools.</span></span><span class="sig-name descname"><span class="pre">autogen_YoutubeVideoSearchTool</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">assistant</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">user_proxy</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeVideoSearchTool" title="Link to this definition"></a></dt>
<dd></dd></dl>
</section>
<section id="module-praisonai.inbuilt_tools">
<span id="module-contents"></span><h2>Module contents<a class="headerlink" href="#module-praisonai.inbuilt_tools" title="Link to this heading"></a></h2>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">PraisonAI</a></h1>
<h3>Navigation</h3>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
<search id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;2024, Mervin Praison.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 7.3.7</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a>
|
<a href="../_sources/source/praisonai.inbuilt_tools.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>
+44
View File
@@ -0,0 +1,44 @@
---
title: 'API Reference'
description: 'PraisonAI API documentation with framework-specific details'
---
# API Reference
This section provides detailed information about the PraisonAI API and its framework-specific implementations.
## Core Modules
- [praisonai](../api/praisonai/index) - Core package functionality
- [praisonai.auto](../api/praisonai/auto) - Automated agent generation
- [praisonai.agents_generator](../api/praisonai/agents_generator) - Framework-specific agent generation
- [praisonai.cli](../api/praisonai/cli) - Command-line interface
- [praisonai.deploy](../api/praisonai/deploy) - Deployment utilities
## Framework Support
### CrewAI Integration
Requires installation with:
```bash
pip install "praisonai[crewai]"
```
Features:
- Task delegation
- Sequential/parallel execution
- Built-in tools
- Structured workflows
### AutoGen Integration
Requires installation with:
```bash
pip install "praisonai[autogen]"
```
Features:
- Multi-agent conversations
- Code execution
- Built-in tools
- Flexible interactions
For detailed API documentation of each module, please refer to the generated files in the `api` folder.
-1328
View File
File diff suppressed because it is too large. Load diff
+2373
View File
File diff suppressed because it is too large. Load diff
+566
View File
@@ -0,0 +1,566 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.agents_generator API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.agents_generator</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.agents_generator.disable_crewai_telemetry"><code class="name flex">
<span>def <span class="ident">disable_crewai_telemetry</span></span>(<span>)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.agents_generator.noop"><code class="name flex">
<span>def <span class="ident">noop</span></span>(<span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="praisonai.agents_generator.AgentsGenerator"><code class="flex name class">
<span>class <span class="ident">AgentsGenerator</span></span>
<span>(</span><span>agent_file, framework, config_list, log_level=None, agent_callback=None, task_callback=None, agent_yaml=None, tools=None)</span>
</code></dt>
<dd>
<div class="desc"><p>Initialize the AgentsGenerator object.</p>
<h2 id="parameters">Parameters</h2>
<p>agent_file (str): The path to the agent file.
framework (str): The framework to be used for the agents.
config_list (list): A list of configurations for the agents.
log_level (int, optional): The logging level to use. Defaults to logging.INFO.
agent_callback (callable, optional): A callback function to be executed after each agent step.
task_callback (callable, optional): A callback function to be executed after each tool run.
agent_yaml (str, optional): The content of the YAML file. Defaults to None.
tools (dict, optional): A dictionary containing the tools to be used for the agents. Defaults to None.</p>
<h2 id="attributes">Attributes</h2>
<dl>
<dt><strong><code>agent_file</code></strong> :&ensp;<code>str</code></dt>
<dd>The path to the agent file.</dd>
<dt><strong><code>framework</code></strong> :&ensp;<code>str</code></dt>
<dd>The framework to be used for the agents.</dd>
<dt><strong><code>config_list</code></strong> :&ensp;<code>list</code></dt>
<dd>A list of configurations for the agents.</dd>
<dt><strong><code>log_level</code></strong> :&ensp;<code>int</code></dt>
<dd>The logging level to use.</dd>
<dt><strong><code>agent_callback</code></strong> :&ensp;<code>callable</code>, optional</dt>
<dd>A callback function to be executed after each agent step.</dd>
<dt><strong><code>task_callback</code></strong> :&ensp;<code>callable</code>, optional</dt>
<dd>A callback function to be executed after each tool run.</dd>
<dt><strong><code>tools</code></strong> :&ensp;<code>dict</code></dt>
<dd>A dictionary containing the tools to be used for the agents.</dd>
</dl></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class AgentsGenerator:
def __init__(self, agent_file, framework, config_list, log_level=None, agent_callback=None, task_callback=None, agent_yaml=None, tools=None):
&#34;&#34;&#34;
Initialize the AgentsGenerator object.
Parameters:
agent_file (str): The path to the agent file.
framework (str): The framework to be used for the agents.
config_list (list): A list of configurations for the agents.
log_level (int, optional): The logging level to use. Defaults to logging.INFO.
agent_callback (callable, optional): A callback function to be executed after each agent step.
task_callback (callable, optional): A callback function to be executed after each tool run.
agent_yaml (str, optional): The content of the YAML file. Defaults to None.
tools (dict, optional): A dictionary containing the tools to be used for the agents. Defaults to None.
Attributes:
agent_file (str): The path to the agent file.
framework (str): The framework to be used for the agents.
config_list (list): A list of configurations for the agents.
log_level (int): The logging level to use.
agent_callback (callable, optional): A callback function to be executed after each agent step.
task_callback (callable, optional): A callback function to be executed after each tool run.
tools (dict): A dictionary containing the tools to be used for the agents.
&#34;&#34;&#34;
self.agent_file = agent_file
self.framework = framework
self.config_list = config_list
self.log_level = log_level
self.agent_callback = agent_callback
self.task_callback = task_callback
self.agent_yaml = agent_yaml
self.tools = tools or [] # Store tool class names as a list
self.log_level = log_level or logging.getLogger().getEffectiveLevel()
if self.log_level == logging.NOTSET:
self.log_level = os.environ.get(&#39;LOGLEVEL&#39;, &#39;INFO&#39;).upper()
logging.basicConfig(level=self.log_level, format=&#39;%(asctime)s - %(levelname)s - %(message)s&#39;)
self.logger = logging.getLogger(__name__)
self.logger.setLevel(self.log_level)
def is_function_or_decorated(self, obj):
&#34;&#34;&#34;
Checks if the given object is a function or has a __call__ method.
Parameters:
obj (object): The object to be checked.
Returns:
bool: True if the object is a function or has a __call__ method, False otherwise.
&#34;&#34;&#34;
return inspect.isfunction(obj) or hasattr(obj, &#39;__call__&#39;)
def load_tools_from_module(self, module_path):
&#34;&#34;&#34;
Loads tools from a specified module path.
Parameters:
module_path (str): The path to the module containing the tools.
Returns:
dict: A dictionary containing the names of the tools as keys and the corresponding functions or objects as values.
Raises:
FileNotFoundError: If the specified module path does not exist.
&#34;&#34;&#34;
spec = importlib.util.spec_from_file_location(&#34;tools_module&#34;, module_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return {name: obj for name, obj in inspect.getmembers(module, self.is_function_or_decorated)}
def load_tools_from_module_class(self, module_path):
&#34;&#34;&#34;
Loads tools from a specified module path containing classes that inherit from BaseTool or are part of langchain_community.tools package.
Parameters:
module_path (str): The path to the module containing the tools.
Returns:
dict: A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.
Raises:
FileNotFoundError: If the specified module path does not exist.
&#34;&#34;&#34;
spec = importlib.util.spec_from_file_location(&#34;tools_module&#34;, module_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return {name: obj() for name, obj in inspect.getmembers(module, lambda x: inspect.isclass(x) and (x.__module__.startswith(&#39;langchain_community.tools&#39;) or issubclass(x, BaseTool)) and x is not BaseTool)}
def load_tools_from_package(self, package_path):
&#34;&#34;&#34;
Loads tools from a specified package path containing modules with functions or classes.
Parameters:
package_path (str): The path to the package containing the tools.
Returns:
dict: A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.
Raises:
FileNotFoundError: If the specified package path does not exist.
This function iterates through all the .py files in the specified package path, excluding those that start with &#34;__&#34;. For each file, it imports the corresponding module and checks if it contains any functions or classes that can be loaded as tools. The function then returns a dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.
&#34;&#34;&#34;
tools_dict = {}
for module_file in os.listdir(package_path):
if module_file.endswith(&#39;.py&#39;) and not module_file.startswith(&#39;__&#39;):
module_name = f&#34;{package_path.name}.{module_file[:-3]}&#34; # Remove .py for import
module = importlib.import_module(module_name)
for name, obj in inspect.getmembers(module, self.is_function_or_decorated):
tools_dict[name] = obj
return tools_dict
def generate_crew_and_kickoff(self):
&#34;&#34;&#34;
Generates a crew of agents and initiates tasks based on the provided configuration.
Parameters:
agent_file (str): The path to the agent file.
framework (str): The framework to be used for the agents.
config_list (list): A list of configurations for the agents.
Returns:
str: The output of the tasks performed by the crew of agents.
Raises:
FileNotFoundError: If the specified agent file does not exist.
This function first loads the agent configuration from the specified file. It then initializes the tools required for the agents based on the specified framework. If the specified framework is &#34;autogen&#34;, it loads the LLM configuration dynamically and creates an AssistantAgent for each role in the configuration. It then adds tools to the agents if specified in the configuration. Finally, it prepares tasks for the agents based on the configuration and initiates the tasks using the crew of agents. If the specified framework is not &#34;autogen&#34;, it creates a crew of agents and initiates tasks based on the configuration.
&#34;&#34;&#34;
if self.agent_yaml:
config = yaml.safe_load(self.agent_yaml)
else:
if self.agent_file == &#39;/app/api:app&#39; or self.agent_file == &#39;api:app&#39;:
self.agent_file = &#39;agents.yaml&#39;
try:
with open(self.agent_file, &#39;r&#39;) as f:
config = yaml.safe_load(f)
except FileNotFoundError:
print(f&#34;File not found: {self.agent_file}&#34;)
return
topic = config[&#39;topic&#39;]
tools_dict = {
&#39;CodeDocsSearchTool&#39;: CodeDocsSearchTool(),
&#39;CSVSearchTool&#39;: CSVSearchTool(),
&#39;DirectorySearchTool&#39;: DirectorySearchTool(),
&#39;DOCXSearchTool&#39;: DOCXSearchTool(),
&#39;DirectoryReadTool&#39;: DirectoryReadTool(),
&#39;FileReadTool&#39;: FileReadTool(),
# &#39;GithubSearchTool&#39;: GithubSearchTool(),
# &#39;SeperDevTool&#39;: SeperDevTool(),
&#39;TXTSearchTool&#39;: TXTSearchTool(),
&#39;JSONSearchTool&#39;: JSONSearchTool(),
&#39;MDXSearchTool&#39;: MDXSearchTool(),
&#39;PDFSearchTool&#39;: PDFSearchTool(),
# &#39;PGSearchTool&#39;: PGSearchTool(),
&#39;RagTool&#39;: RagTool(),
&#39;ScrapeElementFromWebsiteTool&#39;: ScrapeElementFromWebsiteTool(),
&#39;ScrapeWebsiteTool&#39;: ScrapeWebsiteTool(),
&#39;WebsiteSearchTool&#39;: WebsiteSearchTool(),
&#39;XMLSearchTool&#39;: XMLSearchTool(),
&#39;YoutubeChannelSearchTool&#39;: YoutubeChannelSearchTool(),
&#39;YoutubeVideoSearchTool&#39;: YoutubeVideoSearchTool(),
}
# Add tools from class names
for tool_class in self.tools:
if isinstance(tool_class, type) and issubclass(tool_class, BaseTool):
tool_name = tool_class.__name__
tools_dict[tool_name] = tool_class()
self.logger.debug(f&#34;Added tool: {tool_name}&#34;)
root_directory = os.getcwd()
tools_py_path = os.path.join(root_directory, &#39;tools.py&#39;)
tools_dir_path = Path(root_directory) / &#39;tools&#39;
if os.path.isfile(tools_py_path):
tools_dict.update(self.load_tools_from_module_class(tools_py_path))
self.logger.debug(&#34;tools.py exists in the root directory. Loading tools.py and skipping tools folder.&#34;)
elif tools_dir_path.is_dir():
tools_dict.update(self.load_tools_from_module_class(tools_dir_path))
self.logger.debug(&#34;tools folder exists in the root directory&#34;)
framework = self.framework or config.get(&#39;framework&#39;)
agents = {}
tasks = []
if framework == &#34;autogen&#34;:
# Load the LLM configuration dynamically
# print(self.config_list)
llm_config = {&#34;config_list&#34;: self.config_list}
if agentops_exists:
agentops.init(os.environ.get(&#34;AGENTOPS_API_KEY&#34;), tags=[&#34;autogen&#34;])
# Assuming the user proxy agent is set up as per your requirements
user_proxy = autogen.UserProxyAgent(
name=&#34;User&#34;,
human_input_mode=&#34;NEVER&#34;,
is_termination_msg=lambda x: (x.get(&#34;content&#34;) or &#34;&#34;).rstrip().rstrip(&#34;.&#34;).lower().endswith(&#34;terminate&#34;) or &#34;TERMINATE&#34; in (x.get(&#34;content&#34;) or &#34;&#34;),
code_execution_config={
&#34;work_dir&#34;: &#34;coding&#34;,
&#34;use_docker&#34;: False,
},
# additional setup for the user proxy agent
)
for role, details in config[&#39;roles&#39;].items():
agent_name = details[&#39;role&#39;].format(topic=topic).replace(&#34;{topic}&#34;, topic)
agent_goal = details[&#39;goal&#39;].format(topic=topic)
# Creating an AssistantAgent for each role dynamically
agents[role] = autogen.AssistantAgent(
name=agent_name,
llm_config=llm_config,
system_message=details[&#39;backstory&#39;].format(topic=topic)+&#34;. Must Reply \&#34;TERMINATE\&#34; in the end when everything is done.&#34;,
)
for tool in details.get(&#39;tools&#39;, []):
if tool in tools_dict:
try:
tool_class = globals()[f&#39;autogen_{type(tools_dict[tool]).__name__}&#39;]
print(f&#34;Found {tool_class.__name__} for {tool}&#34;)
except KeyError:
print(f&#34;Warning: autogen_{type(tools_dict[tool]).__name__} function not found. Skipping this tool.&#34;)
continue
tool_class(agents[role], user_proxy)
# Preparing tasks for initiate_chats
for task_name, task_details in details.get(&#39;tasks&#39;, {}).items():
description_filled = task_details[&#39;description&#39;].format(topic=topic)
expected_output_filled = task_details[&#39;expected_output&#39;].format(topic=topic)
chat_task = {
&#34;recipient&#34;: agents[role],
&#34;message&#34;: description_filled,
&#34;summary_method&#34;: &#34;last_msg&#34;,
# Additional fields like carryover can be added based on dependencies
}
tasks.append(chat_task)
response = user_proxy.initiate_chats(tasks)
result = &#34;### Output ###\n&#34;+response[-1].summary if hasattr(response[-1], &#39;summary&#39;) else &#34;&#34;
if agentops_exists:
agentops.end_session(&#34;Success&#34;)
else: # framework=crewai
if agentops_exists:
agentops.init(os.environ.get(&#34;AGENTOPS_API_KEY&#34;), tags=[&#34;crewai&#34;])
tasks_dict = {}
for role, details in config[&#39;roles&#39;].items():
role_filled = details[&#39;role&#39;].format(topic=topic)
goal_filled = details[&#39;goal&#39;].format(topic=topic)
backstory_filled = details[&#39;backstory&#39;].format(topic=topic)
# Adding tools to the agent if exists
agent_tools = [tools_dict[tool] for tool in details.get(&#39;tools&#39;, []) if tool in tools_dict]
llm_model = details.get(&#39;llm&#39;) # Get the llm configuration
if llm_model:
llm = PraisonAIModel(
model=llm_model.get(&#34;model&#34;, os.environ.get(&#34;MODEL_NAME&#34;, &#34;openai/gpt-4o&#34;)),
).get_model()
else:
llm = PraisonAIModel().get_model()
function_calling_llm_model = details.get(&#39;function_calling_llm&#39;)
if function_calling_llm_model:
function_calling_llm = PraisonAIModel(
model=function_calling_llm_model.get(&#34;model&#34;, os.environ.get(&#34;MODEL_NAME&#34;, &#34;openai/gpt-4o&#34;)),
).get_model()
else:
function_calling_llm = PraisonAIModel().get_model()
agent = Agent(
role=role_filled,
goal=goal_filled,
backstory=backstory_filled,
tools=agent_tools,
allow_delegation=details.get(&#39;allow_delegation&#39;, False),
llm=llm,
function_calling_llm=function_calling_llm,
max_iter=details.get(&#39;max_iter&#39;, 15),
max_rpm=details.get(&#39;max_rpm&#39;),
max_execution_time=details.get(&#39;max_execution_time&#39;),
verbose=details.get(&#39;verbose&#39;, True),
cache=details.get(&#39;cache&#39;, True),
system_template=details.get(&#39;system_template&#39;),
prompt_template=details.get(&#39;prompt_template&#39;),
response_template=details.get(&#39;response_template&#39;),
)
# Set agent callback if provided
if self.agent_callback:
agent.step_callback = self.agent_callback
agents[role] = agent
for task_name, task_details in details.get(&#39;tasks&#39;, {}).items():
description_filled = task_details[&#39;description&#39;].format(topic=topic)
expected_output_filled = task_details[&#39;expected_output&#39;].format(topic=topic)
task = Task(
description=description_filled, # Clear, concise statement of what the task entails
expected_output=expected_output_filled, # Detailed description of what task&#39;s completion looks like
agent=agent, # The agent responsible for the task
tools=task_details.get(&#39;tools&#39;, []), # Functions or capabilities the agent can utilize
async_execution=task_details.get(&#39;async_execution&#39;) if task_details.get(&#39;async_execution&#39;) is not None else False, # Execute asynchronously if set
context=[], ## TODO:
config=task_details.get(&#39;config&#39;) if task_details.get(&#39;config&#39;) is not None else {}, # Additional configuration details
output_json=task_details.get(&#39;output_json&#39;) if task_details.get(&#39;output_json&#39;) is not None else None, # Outputs a JSON object
output_pydantic=task_details.get(&#39;output_pydantic&#39;) if task_details.get(&#39;output_pydantic&#39;) is not None else None, # Outputs a Pydantic model object
output_file=task_details.get(&#39;output_file&#39;) if task_details.get(&#39;output_file&#39;) is not None else &#34;&#34;, # Saves the task output to a file
callback=task_details.get(&#39;callback&#39;) if task_details.get(&#39;callback&#39;) is not None else None, # Python callable executed with the task&#39;s output
human_input=task_details.get(&#39;human_input&#39;) if task_details.get(&#39;human_input&#39;) is not None else False, # Indicates if the task requires human feedback
create_directory=task_details.get(&#39;create_directory&#39;) if task_details.get(&#39;create_directory&#39;) is not None else False # Indicates if a directory needs to be created
)
# Set tool callback if provided
if self.task_callback:
task.callback = self.task_callback
tasks.append(task)
tasks_dict[task_name] = task
for role, details in config[&#39;roles&#39;].items():
for task_name, task_details in details.get(&#39;tasks&#39;, {}).items():
task = tasks_dict[task_name]
context_tasks = [tasks_dict[ctx] for ctx in task_details.get(&#39;context&#39;, []) if ctx in tasks_dict]
task.context = context_tasks
crew = Crew(
agents=list(agents.values()),
tasks=tasks,
verbose=2
)
self.logger.debug(&#34;Final Crew Configuration:&#34;)
self.logger.debug(f&#34;Agents: {crew.agents}&#34;)
self.logger.debug(f&#34;Tasks: {crew.tasks}&#34;)
response = crew.kickoff()
result = f&#34;### Task Output ###\n{response}&#34;
if agentops_exists:
agentops.end_session(&#34;Success&#34;)
return result</code></pre>
</details>
<h3>Methods</h3>
<dl>
<dt id="praisonai.agents_generator.AgentsGenerator.generate_crew_and_kickoff"><code class="name flex">
<span>def <span class="ident">generate_crew_and_kickoff</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Generates a crew of agents and initiates tasks based on the provided configuration.</p>
<h2 id="parameters">Parameters</h2>
<p>agent_file (str): The path to the agent file.
framework (str): The framework to be used for the agents.
config_list (list): A list of configurations for the agents.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>str</code></dt>
<dd>The output of the tasks performed by the crew of agents.</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>FileNotFoundError</code></dt>
<dd>If the specified agent file does not exist.</dd>
</dl>
<p>This function first loads the agent configuration from the specified file. It then initializes the tools required for the agents based on the specified framework. If the specified framework is "autogen", it loads the LLM configuration dynamically and creates an AssistantAgent for each role in the configuration. It then adds tools to the agents if specified in the configuration. Finally, it prepares tasks for the agents based on the configuration and initiates the tasks using the crew of agents. If the specified framework is not "autogen", it creates a crew of agents and initiates tasks based on the configuration.</p></div>
</dd>
<dt id="praisonai.agents_generator.AgentsGenerator.is_function_or_decorated"><code class="name flex">
<span>def <span class="ident">is_function_or_decorated</span></span>(<span>self, obj)</span>
</code></dt>
<dd>
<div class="desc"><p>Checks if the given object is a function or has a <strong>call</strong> method.</p>
<h2 id="parameters">Parameters</h2>
<p>obj (object): The object to be checked.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>bool</code></dt>
<dd>True if the object is a function or has a <strong>call</strong> method, False otherwise.</dd>
</dl></div>
</dd>
<dt id="praisonai.agents_generator.AgentsGenerator.load_tools_from_module"><code class="name flex">
<span>def <span class="ident">load_tools_from_module</span></span>(<span>self, module_path)</span>
</code></dt>
<dd>
<div class="desc"><p>Loads tools from a specified module path.</p>
<h2 id="parameters">Parameters</h2>
<p>module_path (str): The path to the module containing the tools.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>dict</code></dt>
<dd>A dictionary containing the names of the tools as keys and the corresponding functions or objects as values.</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>FileNotFoundError</code></dt>
<dd>If the specified module path does not exist.</dd>
</dl></div>
</dd>
<dt id="praisonai.agents_generator.AgentsGenerator.load_tools_from_module_class"><code class="name flex">
<span>def <span class="ident">load_tools_from_module_class</span></span>(<span>self, module_path)</span>
</code></dt>
<dd>
<div class="desc"><p>Loads tools from a specified module path containing classes that inherit from BaseTool or are part of langchain_community.tools package.</p>
<h2 id="parameters">Parameters</h2>
<p>module_path (str): The path to the module containing the tools.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>dict</code></dt>
<dd>A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>FileNotFoundError</code></dt>
<dd>If the specified module path does not exist.</dd>
</dl></div>
</dd>
<dt id="praisonai.agents_generator.AgentsGenerator.load_tools_from_package"><code class="name flex">
<span>def <span class="ident">load_tools_from_package</span></span>(<span>self, package_path)</span>
</code></dt>
<dd>
<div class="desc"><p>Loads tools from a specified package path containing modules with functions or classes.</p>
<h2 id="parameters">Parameters</h2>
<p>package_path (str): The path to the package containing the tools.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>dict</code></dt>
<dd>A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>FileNotFoundError</code></dt>
<dd>If the specified package path does not exist.</dd>
</dl>
<p>This function iterates through all the .py files in the specified package path, excluding those that start with "__". For each file, it imports the corresponding module and checks if it contains any functions or classes that can be loaded as tools. The function then returns a dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.</p></div>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.agents_generator.disable_crewai_telemetry" href="#praisonai.agents_generator.disable_crewai_telemetry">disable_crewai_telemetry</a></code></li>
<li><code><a title="praisonai.agents_generator.noop" href="#praisonai.agents_generator.noop">noop</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="praisonai.agents_generator.AgentsGenerator" href="#praisonai.agents_generator.AgentsGenerator">AgentsGenerator</a></code></h4>
<ul class="">
<li><code><a title="praisonai.agents_generator.AgentsGenerator.generate_crew_and_kickoff" href="#praisonai.agents_generator.AgentsGenerator.generate_crew_and_kickoff">generate_crew_and_kickoff</a></code></li>
<li><code><a title="praisonai.agents_generator.AgentsGenerator.is_function_or_decorated" href="#praisonai.agents_generator.AgentsGenerator.is_function_or_decorated">is_function_or_decorated</a></code></li>
<li><code><a title="praisonai.agents_generator.AgentsGenerator.load_tools_from_module" href="#praisonai.agents_generator.AgentsGenerator.load_tools_from_module">load_tools_from_module</a></code></li>
<li><code><a title="praisonai.agents_generator.AgentsGenerator.load_tools_from_module_class" href="#praisonai.agents_generator.AgentsGenerator.load_tools_from_module_class">load_tools_from_module_class</a></code></li>
<li><code><a title="praisonai.agents_generator.AgentsGenerator.load_tools_from_package" href="#praisonai.agents_generator.AgentsGenerator.load_tools_from_package">load_tools_from_package</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
+622
View File
@@ -0,0 +1,622 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.auto API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.auto</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="praisonai.auto.AutoGenerator"><code class="flex name class">
<span>class <span class="ident">AutoGenerator</span></span>
<span>(</span><span>topic='Movie Story writing about AI', agent_file='test.yaml', framework='crewai', config_list: Optional[List[Dict]] = None)</span>
</code></dt>
<dd>
<div class="desc"><p>Initialize the AutoGenerator class with the specified topic, agent file, and framework.
Note: autogen framework is different from this AutoGenerator class.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>topic</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The topic for the generated team structure. Defaults to "Movie Story writing about AI".</dd>
<dt><strong><code>agent_file</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The name of the YAML file to save the generated team structure. Defaults to "test.yaml".</dd>
<dt><strong><code>framework</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The framework for the generated team structure. Defaults to "crewai".</dd>
<dt><strong><code>config_list</code></strong> :&ensp;<code>Optional[List[Dict]]</code>, optional</dt>
<dd>A list containing the configuration details for the OpenAI API.
If None, it defaults to using environment variables or hardcoded values.</dd>
</dl>
<h2 id="attributes">Attributes</h2>
<dl>
<dt><strong><code>config_list</code></strong> :&ensp;<code>list</code></dt>
<dd>A list containing the configuration details for the OpenAI API.</dd>
<dt><strong><code>topic</code></strong> :&ensp;<code>str</code></dt>
<dd>The specified topic for the generated team structure.</dd>
<dt><strong><code>agent_file</code></strong> :&ensp;<code>str</code></dt>
<dd>The specified name of the YAML file to save the generated team structure.</dd>
<dt><strong><code>framework</code></strong> :&ensp;<code>str</code></dt>
<dd>The specified framework for the generated team structure.</dd>
<dt><strong><code>client</code></strong> :&ensp;<code>instructor.Client</code></dt>
<dd>An instance of the instructor.Client class initialized with the specified OpenAI API configuration.</dd>
</dl></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class AutoGenerator:
def __init__(self, topic=&#34;Movie Story writing about AI&#34;, agent_file=&#34;test.yaml&#34;, framework=&#34;crewai&#34;, config_list: Optional[List[Dict]] = None):
&#34;&#34;&#34;
Initialize the AutoGenerator class with the specified topic, agent file, and framework.
Note: autogen framework is different from this AutoGenerator class.
Args:
topic (str, optional): The topic for the generated team structure. Defaults to &#34;Movie Story writing about AI&#34;.
agent_file (str, optional): The name of the YAML file to save the generated team structure. Defaults to &#34;test.yaml&#34;.
framework (str, optional): The framework for the generated team structure. Defaults to &#34;crewai&#34;.
config_list (Optional[List[Dict]], optional): A list containing the configuration details for the OpenAI API.
If None, it defaults to using environment variables or hardcoded values.
Attributes:
config_list (list): A list containing the configuration details for the OpenAI API.
topic (str): The specified topic for the generated team structure.
agent_file (str): The specified name of the YAML file to save the generated team structure.
framework (str): The specified framework for the generated team structure.
client (instructor.Client): An instance of the instructor.Client class initialized with the specified OpenAI API configuration.
&#34;&#34;&#34;
self.config_list = config_list or [
{
&#39;model&#39;: os.environ.get(&#34;OPENAI_MODEL_NAME&#34;, &#34;gpt-4o&#34;),
&#39;base_url&#39;: os.environ.get(&#34;OPENAI_API_BASE&#34;, &#34;https://api.openai.com/v1&#34;),
&#39;api_key&#39;: os.environ.get(&#34;OPENAI_API_KEY&#34;)
}
]
self.topic = topic
self.agent_file = agent_file
self.framework = framework or &#34;crewai&#34;
self.client = instructor.patch(
OpenAI(
base_url=self.config_list[0][&#39;base_url&#39;],
api_key=os.getenv(&#34;OPENAI_API_KEY&#34;),
),
mode=instructor.Mode.JSON,
)
def generate(self):
&#34;&#34;&#34;
Generates a team structure for the specified topic.
Args:
None
Returns:
str: The full path of the YAML file containing the generated team structure.
Raises:
Exception: If the generation process fails.
Usage:
generator = AutoGenerator(framework=&#34;crewai&#34;, topic=&#34;Create a movie script about Cat in Mars&#34;)
path = generator.generate()
print(path)
&#34;&#34;&#34;
response = self.client.chat.completions.create(
model=self.config_list[0][&#39;model&#39;],
response_model=TeamStructure,
max_retries=10,
messages=[
{&#34;role&#34;: &#34;system&#34;, &#34;content&#34;: &#34;You are a helpful assistant designed to output complex team structures.&#34;},
{&#34;role&#34;: &#34;user&#34;, &#34;content&#34;: self.get_user_content()}
]
)
json_data = json.loads(response.model_dump_json())
self.convert_and_save(json_data)
full_path = os.path.abspath(self.agent_file)
return full_path
def convert_and_save(self, json_data):
&#34;&#34;&#34;Converts the provided JSON data into the desired YAML format and saves it to a file.
Args:
json_data (dict): The JSON data representing the team structure.
topic (str, optional): The topic to be inserted into the YAML. Defaults to &#34;Artificial Intelligence&#34;.
agent_file (str, optional): The name of the YAML file to save. Defaults to &#34;test.yaml&#34;.
&#34;&#34;&#34;
yaml_data = {
&#34;framework&#34;: self.framework,
&#34;topic&#34;: self.topic,
&#34;roles&#34;: {},
&#34;dependencies&#34;: []
}
for role_id, role_details in json_data[&#39;roles&#39;].items():
yaml_data[&#39;roles&#39;][role_id] = {
&#34;backstory&#34;: &#34;&#34; + role_details[&#39;backstory&#39;],
&#34;goal&#34;: role_details[&#39;goal&#39;],
&#34;role&#34;: role_details[&#39;role&#39;],
&#34;tasks&#34;: {},
# &#34;tools&#34;: role_details.get(&#39;tools&#39;, []),
&#34;tools&#34;: [&#39;&#39;]
}
for task_id, task_details in role_details[&#39;tasks&#39;].items():
yaml_data[&#39;roles&#39;][role_id][&#39;tasks&#39;][task_id] = {
&#34;description&#34;: &#34;&#34; + task_details[&#39;description&#39;],
&#34;expected_output&#34;: &#34;&#34; + task_details[&#39;expected_output&#39;]
}
# Save to YAML file, maintaining the order
with open(self.agent_file, &#39;w&#39;) as f:
yaml.dump(yaml_data, f, allow_unicode=True, sort_keys=False)
def get_user_content(self):
&#34;&#34;&#34;
Generates a prompt for the OpenAI API to generate a team structure.
Args:
None
Returns:
str: The prompt for the OpenAI API.
Usage:
generator = AutoGenerator(framework=&#34;crewai&#34;, topic=&#34;Create a movie script about Cat in Mars&#34;)
prompt = generator.get_user_content()
print(prompt)
&#34;&#34;&#34;
user_content = &#34;&#34;&#34;Generate a team structure for \&#34;&#34;&#34;&#34; + self.topic + &#34;&#34;&#34;\&#34; task.
No Input data will be provided to the team.
The team will work in sequence. First role will pass the output to the next role, and so on.
The last role will generate the final output.
Think step by step.
With maximum 3 roles, each with 1 task. Include role goals, backstories, task descriptions, and expected outputs.
List of Available Tools: CodeDocsSearchTool, CSVSearchTool, DirectorySearchTool, DOCXSearchTool, DirectoryReadTool, FileReadTool, TXTSearchTool, JSONSearchTool, MDXSearchTool, PDFSearchTool, RagTool, ScrapeElementFromWebsiteTool, ScrapeWebsiteTool, WebsiteSearchTool, XMLSearchTool, YoutubeChannelSearchTool, YoutubeVideoSearchTool.
Only use Available Tools. Do Not use any other tools.
Example Below:
Use below example to understand the structure of the output.
The final role you create should satisfy the provided task: &#34;&#34;&#34; + self.topic + &#34;&#34;&#34;.
{
&#34;roles&#34;: {
&#34;narrative_designer&#34;: {
&#34;role&#34;: &#34;Narrative Designer&#34;,
&#34;goal&#34;: &#34;Create AI storylines&#34;,
&#34;backstory&#34;: &#34;Skilled in narrative development for AI, with a focus on story resonance.&#34;,
&#34;tools&#34;: [&#34;ScrapeWebsiteTool&#34;],
&#34;tasks&#34;: {
&#34;story_concept_development&#34;: {
&#34;description&#34;: &#34;Craft a unique AI story concept with depth and engagement using concept from this page the content https://www.asthebirdfliesblog.com/posts/how-to-write-book-story-development .&#34;,
&#34;expected_output&#34;: &#34;Document with narrative arcs, character bios, and settings.&#34;
}
}
},
&#34;scriptwriter&#34;: {
&#34;role&#34;: &#34;Scriptwriter&#34;,
&#34;goal&#34;: &#34;Write scripts from AI concepts&#34;,
&#34;backstory&#34;: &#34;Expert in dialogue and script structure, translating concepts into scripts.&#34;,
&#34;tasks&#34;: {
&#34;scriptwriting_task&#34;: {
&#34;description&#34;: &#34;Turn narrative concepts into scripts, including dialogue and scenes.&#34;,
&#34;expected_output&#34;: &#34;Production-ready script with dialogue and scene details.&#34;
}
}
}
}
}
&#34;&#34;&#34;
return user_content</code></pre>
</details>
<h3>Methods</h3>
<dl>
<dt id="praisonai.auto.AutoGenerator.convert_and_save"><code class="name flex">
<span>def <span class="ident">convert_and_save</span></span>(<span>self, json_data)</span>
</code></dt>
<dd>
<div class="desc"><p>Converts the provided JSON data into the desired YAML format and saves it to a file.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>json_data</code></strong> :&ensp;<code>dict</code></dt>
<dd>The JSON data representing the team structure.</dd>
<dt><strong><code>topic</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The topic to be inserted into the YAML. Defaults to "Artificial Intelligence".</dd>
<dt><strong><code>agent_file</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The name of the YAML file to save. Defaults to "test.yaml".</dd>
</dl></div>
</dd>
<dt id="praisonai.auto.AutoGenerator.generate"><code class="name flex">
<span>def <span class="ident">generate</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Generates a team structure for the specified topic.</p>
<h2 id="args">Args</h2>
<p>None</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>str</code></dt>
<dd>The full path of the YAML file containing the generated team structure.</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>Exception</code></dt>
<dd>If the generation process fails.</dd>
</dl>
<h2 id="usage">Usage</h2>
<p>generator = AutoGenerator(framework="crewai", topic="Create a movie script about Cat in Mars")
path = generator.generate()
print(path)</p></div>
</dd>
<dt id="praisonai.auto.AutoGenerator.get_user_content"><code class="name flex">
<span>def <span class="ident">get_user_content</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Generates a prompt for the OpenAI API to generate a team structure.</p>
<h2 id="args">Args</h2>
<p>None</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>str</code></dt>
<dd>The prompt for the OpenAI API.</dd>
</dl>
<h2 id="usage">Usage</h2>
<p>generator = AutoGenerator(framework="crewai", topic="Create a movie script about Cat in Mars")
prompt = generator.get_user_content()
print(prompt)</p></div>
</dd>
</dl>
</dd>
<dt id="praisonai.auto.RoleDetails"><code class="flex name class">
<span>class <span class="ident">RoleDetails</span></span>
<span>(</span><span>**data: Any)</span>
</code></dt>
<dd>
<div class="desc"><p>Usage docs: <a href="https://docs.pydantic.dev/2.9/concepts/models/">https://docs.pydantic.dev/2.9/concepts/models/</a></p>
<p>A base class for creating Pydantic models.</p>
<h2 id="attributes">Attributes</h2>
<dl>
<dt><strong><code>__class_vars__</code></strong></dt>
<dd>The names of the class variables defined on the model.</dd>
<dt><strong><code>__private_attributes__</code></strong></dt>
<dd>Metadata about the private attributes of the model.</dd>
<dt><strong><code>__signature__</code></strong></dt>
<dd>The synthesized <code>__init__</code> [<code>Signature</code>][inspect.Signature] of the model.</dd>
<dt><strong><code>__pydantic_complete__</code></strong></dt>
<dd>Whether model building is completed, or if there are still undefined fields.</dd>
<dt><strong><code>__pydantic_core_schema__</code></strong></dt>
<dd>The core schema of the model.</dd>
<dt><strong><code>__pydantic_custom_init__</code></strong></dt>
<dd>Whether the model has a custom <code>__init__</code> function.</dd>
<dt><strong><code>__pydantic_decorators__</code></strong></dt>
<dd>Metadata containing the decorators defined on the model.
This replaces <code>Model.__validators__</code> and <code>Model.__root_validators__</code> from Pydantic V1.</dd>
<dt><strong><code>__pydantic_generic_metadata__</code></strong></dt>
<dd>Metadata for generic models; contains data used for a similar purpose to
<strong>args</strong>, <strong>origin</strong>, <strong>parameters</strong> in typing-module generics. May eventually be replaced by these.</dd>
<dt><strong><code>__pydantic_parent_namespace__</code></strong></dt>
<dd>Parent namespace of the model, used for automatic rebuilding of models.</dd>
<dt><strong><code>__pydantic_post_init__</code></strong></dt>
<dd>The name of the post-init method for the model, if defined.</dd>
<dt><strong><code>__pydantic_root_model__</code></strong></dt>
<dd>Whether the model is a [<code>RootModel</code>][pydantic.root_model.RootModel].</dd>
<dt><strong><code>__pydantic_serializer__</code></strong></dt>
<dd>The <code>pydantic-core</code> <code>SchemaSerializer</code> used to dump instances of the model.</dd>
<dt><strong><code>__pydantic_validator__</code></strong></dt>
<dd>The <code>pydantic-core</code> <code>SchemaValidator</code> used to validate instances of the model.</dd>
<dt><strong><code>__pydantic_extra__</code></strong></dt>
<dd>A dictionary containing extra values, if [<code>extra</code>][pydantic.config.ConfigDict.extra]
is set to <code>'allow'</code>.</dd>
<dt><strong><code>__pydantic_fields_set__</code></strong></dt>
<dd>The names of fields explicitly set during instantiation.</dd>
<dt><strong><code>__pydantic_private__</code></strong></dt>
<dd>Values of private attributes set on the model instance.</dd>
</dl>
<p>Create a new model by parsing and validating input data from keyword arguments.</p>
<p>Raises [<code>ValidationError</code>][pydantic_core.ValidationError] if the input data cannot be
validated to form a valid model.</p>
<p><code>self</code> is explicitly positional-only to allow <code>self</code> as a field name.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class RoleDetails(BaseModel):
role: str
goal: str
backstory: str
tasks: Dict[str, TaskDetails]
tools: List[str]</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>pydantic.main.BaseModel</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="praisonai.auto.RoleDetails.backstory"><code class="name">var <span class="ident">backstory</span> : str</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.RoleDetails.goal"><code class="name">var <span class="ident">goal</span> : str</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.RoleDetails.model_computed_fields"><code class="name">var <span class="ident">model_computed_fields</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.RoleDetails.model_config"><code class="name">var <span class="ident">model_config</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.RoleDetails.model_fields"><code class="name">var <span class="ident">model_fields</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.RoleDetails.role"><code class="name">var <span class="ident">role</span> : str</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.RoleDetails.tasks"><code class="name">var <span class="ident">tasks</span> : Dict[str, <a title="praisonai.auto.TaskDetails" href="#praisonai.auto.TaskDetails">TaskDetails</a>]</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.RoleDetails.tools"><code class="name">var <span class="ident">tools</span> : List[str]</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</dd>
<dt id="praisonai.auto.TaskDetails"><code class="flex name class">
<span>class <span class="ident">TaskDetails</span></span>
<span>(</span><span>**data: Any)</span>
</code></dt>
<dd>
<div class="desc"><p>Usage docs: <a href="https://docs.pydantic.dev/2.9/concepts/models/">https://docs.pydantic.dev/2.9/concepts/models/</a></p>
<p>A base class for creating Pydantic models.</p>
<h2 id="attributes">Attributes</h2>
<dl>
<dt><strong><code>__class_vars__</code></strong></dt>
<dd>The names of the class variables defined on the model.</dd>
<dt><strong><code>__private_attributes__</code></strong></dt>
<dd>Metadata about the private attributes of the model.</dd>
<dt><strong><code>__signature__</code></strong></dt>
<dd>The synthesized <code>__init__</code> [<code>Signature</code>][inspect.Signature] of the model.</dd>
<dt><strong><code>__pydantic_complete__</code></strong></dt>
<dd>Whether model building is completed, or if there are still undefined fields.</dd>
<dt><strong><code>__pydantic_core_schema__</code></strong></dt>
<dd>The core schema of the model.</dd>
<dt><strong><code>__pydantic_custom_init__</code></strong></dt>
<dd>Whether the model has a custom <code>__init__</code> function.</dd>
<dt><strong><code>__pydantic_decorators__</code></strong></dt>
<dd>Metadata containing the decorators defined on the model.
This replaces <code>Model.__validators__</code> and <code>Model.__root_validators__</code> from Pydantic V1.</dd>
<dt><strong><code>__pydantic_generic_metadata__</code></strong></dt>
<dd>Metadata for generic models; contains data used for a similar purpose to
<strong>args</strong>, <strong>origin</strong>, <strong>parameters</strong> in typing-module generics. May eventually be replaced by these.</dd>
<dt><strong><code>__pydantic_parent_namespace__</code></strong></dt>
<dd>Parent namespace of the model, used for automatic rebuilding of models.</dd>
<dt><strong><code>__pydantic_post_init__</code></strong></dt>
<dd>The name of the post-init method for the model, if defined.</dd>
<dt><strong><code>__pydantic_root_model__</code></strong></dt>
<dd>Whether the model is a [<code>RootModel</code>][pydantic.root_model.RootModel].</dd>
<dt><strong><code>__pydantic_serializer__</code></strong></dt>
<dd>The <code>pydantic-core</code> <code>SchemaSerializer</code> used to dump instances of the model.</dd>
<dt><strong><code>__pydantic_validator__</code></strong></dt>
<dd>The <code>pydantic-core</code> <code>SchemaValidator</code> used to validate instances of the model.</dd>
<dt><strong><code>__pydantic_extra__</code></strong></dt>
<dd>A dictionary containing extra values, if [<code>extra</code>][pydantic.config.ConfigDict.extra]
is set to <code>'allow'</code>.</dd>
<dt><strong><code>__pydantic_fields_set__</code></strong></dt>
<dd>The names of fields explicitly set during instantiation.</dd>
<dt><strong><code>__pydantic_private__</code></strong></dt>
<dd>Values of private attributes set on the model instance.</dd>
</dl>
<p>Create a new model by parsing and validating input data from keyword arguments.</p>
<p>Raises [<code>ValidationError</code>][pydantic_core.ValidationError] if the input data cannot be
validated to form a valid model.</p>
<p><code>self</code> is explicitly positional-only to allow <code>self</code> as a field name.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class TaskDetails(BaseModel):
description: str
expected_output: str</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>pydantic.main.BaseModel</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="praisonai.auto.TaskDetails.description"><code class="name">var <span class="ident">description</span> : str</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.TaskDetails.expected_output"><code class="name">var <span class="ident">expected_output</span> : str</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.TaskDetails.model_computed_fields"><code class="name">var <span class="ident">model_computed_fields</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.TaskDetails.model_config"><code class="name">var <span class="ident">model_config</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.TaskDetails.model_fields"><code class="name">var <span class="ident">model_fields</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</dd>
<dt id="praisonai.auto.TeamStructure"><code class="flex name class">
<span>class <span class="ident">TeamStructure</span></span>
<span>(</span><span>**data: Any)</span>
</code></dt>
<dd>
<div class="desc"><p>Usage docs: <a href="https://docs.pydantic.dev/2.9/concepts/models/">https://docs.pydantic.dev/2.9/concepts/models/</a></p>
<p>A base class for creating Pydantic models.</p>
<h2 id="attributes">Attributes</h2>
<dl>
<dt><strong><code>__class_vars__</code></strong></dt>
<dd>The names of the class variables defined on the model.</dd>
<dt><strong><code>__private_attributes__</code></strong></dt>
<dd>Metadata about the private attributes of the model.</dd>
<dt><strong><code>__signature__</code></strong></dt>
<dd>The synthesized <code>__init__</code> [<code>Signature</code>][inspect.Signature] of the model.</dd>
<dt><strong><code>__pydantic_complete__</code></strong></dt>
<dd>Whether model building is completed, or if there are still undefined fields.</dd>
<dt><strong><code>__pydantic_core_schema__</code></strong></dt>
<dd>The core schema of the model.</dd>
<dt><strong><code>__pydantic_custom_init__</code></strong></dt>
<dd>Whether the model has a custom <code>__init__</code> function.</dd>
<dt><strong><code>__pydantic_decorators__</code></strong></dt>
<dd>Metadata containing the decorators defined on the model.
This replaces <code>Model.__validators__</code> and <code>Model.__root_validators__</code> from Pydantic V1.</dd>
<dt><strong><code>__pydantic_generic_metadata__</code></strong></dt>
<dd>Metadata for generic models; contains data used for a similar purpose to
<strong>args</strong>, <strong>origin</strong>, <strong>parameters</strong> in typing-module generics. May eventually be replaced by these.</dd>
<dt><strong><code>__pydantic_parent_namespace__</code></strong></dt>
<dd>Parent namespace of the model, used for automatic rebuilding of models.</dd>
<dt><strong><code>__pydantic_post_init__</code></strong></dt>
<dd>The name of the post-init method for the model, if defined.</dd>
<dt><strong><code>__pydantic_root_model__</code></strong></dt>
<dd>Whether the model is a [<code>RootModel</code>][pydantic.root_model.RootModel].</dd>
<dt><strong><code>__pydantic_serializer__</code></strong></dt>
<dd>The <code>pydantic-core</code> <code>SchemaSerializer</code> used to dump instances of the model.</dd>
<dt><strong><code>__pydantic_validator__</code></strong></dt>
<dd>The <code>pydantic-core</code> <code>SchemaValidator</code> used to validate instances of the model.</dd>
<dt><strong><code>__pydantic_extra__</code></strong></dt>
<dd>A dictionary containing extra values, if [<code>extra</code>][pydantic.config.ConfigDict.extra]
is set to <code>'allow'</code>.</dd>
<dt><strong><code>__pydantic_fields_set__</code></strong></dt>
<dd>The names of fields explicitly set during instantiation.</dd>
<dt><strong><code>__pydantic_private__</code></strong></dt>
<dd>Values of private attributes set on the model instance.</dd>
</dl>
<p>Create a new model by parsing and validating input data from keyword arguments.</p>
<p>Raises [<code>ValidationError</code>][pydantic_core.ValidationError] if the input data cannot be
validated to form a valid model.</p>
<p><code>self</code> is explicitly positional-only to allow <code>self</code> as a field name.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class TeamStructure(BaseModel):
roles: Dict[str, RoleDetails]</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>pydantic.main.BaseModel</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="praisonai.auto.TeamStructure.model_computed_fields"><code class="name">var <span class="ident">model_computed_fields</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.TeamStructure.model_config"><code class="name">var <span class="ident">model_config</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.TeamStructure.model_fields"><code class="name">var <span class="ident">model_fields</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.TeamStructure.roles"><code class="name">var <span class="ident">roles</span> : Dict[str, <a title="praisonai.auto.RoleDetails" href="#praisonai.auto.RoleDetails">RoleDetails</a>]</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="praisonai.auto.AutoGenerator" href="#praisonai.auto.AutoGenerator">AutoGenerator</a></code></h4>
<ul class="">
<li><code><a title="praisonai.auto.AutoGenerator.convert_and_save" href="#praisonai.auto.AutoGenerator.convert_and_save">convert_and_save</a></code></li>
<li><code><a title="praisonai.auto.AutoGenerator.generate" href="#praisonai.auto.AutoGenerator.generate">generate</a></code></li>
<li><code><a title="praisonai.auto.AutoGenerator.get_user_content" href="#praisonai.auto.AutoGenerator.get_user_content">get_user_content</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="praisonai.auto.RoleDetails" href="#praisonai.auto.RoleDetails">RoleDetails</a></code></h4>
<ul class="">
<li><code><a title="praisonai.auto.RoleDetails.backstory" href="#praisonai.auto.RoleDetails.backstory">backstory</a></code></li>
<li><code><a title="praisonai.auto.RoleDetails.goal" href="#praisonai.auto.RoleDetails.goal">goal</a></code></li>
<li><code><a title="praisonai.auto.RoleDetails.model_computed_fields" href="#praisonai.auto.RoleDetails.model_computed_fields">model_computed_fields</a></code></li>
<li><code><a title="praisonai.auto.RoleDetails.model_config" href="#praisonai.auto.RoleDetails.model_config">model_config</a></code></li>
<li><code><a title="praisonai.auto.RoleDetails.model_fields" href="#praisonai.auto.RoleDetails.model_fields">model_fields</a></code></li>
<li><code><a title="praisonai.auto.RoleDetails.role" href="#praisonai.auto.RoleDetails.role">role</a></code></li>
<li><code><a title="praisonai.auto.RoleDetails.tasks" href="#praisonai.auto.RoleDetails.tasks">tasks</a></code></li>
<li><code><a title="praisonai.auto.RoleDetails.tools" href="#praisonai.auto.RoleDetails.tools">tools</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="praisonai.auto.TaskDetails" href="#praisonai.auto.TaskDetails">TaskDetails</a></code></h4>
<ul class="">
<li><code><a title="praisonai.auto.TaskDetails.description" href="#praisonai.auto.TaskDetails.description">description</a></code></li>
<li><code><a title="praisonai.auto.TaskDetails.expected_output" href="#praisonai.auto.TaskDetails.expected_output">expected_output</a></code></li>
<li><code><a title="praisonai.auto.TaskDetails.model_computed_fields" href="#praisonai.auto.TaskDetails.model_computed_fields">model_computed_fields</a></code></li>
<li><code><a title="praisonai.auto.TaskDetails.model_config" href="#praisonai.auto.TaskDetails.model_config">model_config</a></code></li>
<li><code><a title="praisonai.auto.TaskDetails.model_fields" href="#praisonai.auto.TaskDetails.model_fields">model_fields</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="praisonai.auto.TeamStructure" href="#praisonai.auto.TeamStructure">TeamStructure</a></code></h4>
<ul class="">
<li><code><a title="praisonai.auto.TeamStructure.model_computed_fields" href="#praisonai.auto.TeamStructure.model_computed_fields">model_computed_fields</a></code></li>
<li><code><a title="praisonai.auto.TeamStructure.model_config" href="#praisonai.auto.TeamStructure.model_config">model_config</a></code></li>
<li><code><a title="praisonai.auto.TeamStructure.model_fields" href="#praisonai.auto.TeamStructure.model_fields">model_fields</a></code></li>
<li><code><a title="praisonai.auto.TeamStructure.roles" href="#praisonai.auto.TeamStructure.roles">roles</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
+664
View File
@@ -0,0 +1,664 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.cli API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.cli</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.cli.stream_subprocess"><code class="name flex">
<span>def <span class="ident">stream_subprocess</span></span>(<span>command, env=None)</span>
</code></dt>
<dd>
<div class="desc"><p>Execute a subprocess command and stream the output to the terminal in real-time.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>command</code></strong> :&ensp;<code>list</code></dt>
<dd>A list containing the command and its arguments.</dd>
<dt><strong><code>env</code></strong> :&ensp;<code>dict</code>, optional</dt>
<dd>Environment variables for the subprocess.</dd>
</dl></div>
</dd>
</dl>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="praisonai.cli.PraisonAI"><code class="flex name class">
<span>class <span class="ident">PraisonAI</span></span>
<span>(</span><span>agent_file='agents.yaml', framework='', auto=False, init=False, agent_yaml=None, tools=None)</span>
</code></dt>
<dd>
<div class="desc"><p>Initialize the PraisonAI object with default parameters.</p>
<h2 id="parameters">Parameters</h2>
<p>agent_file (str): The default agent file to use. Defaults to "agents.yaml".
framework (str): The default framework to use. Defaults to "crewai".
auto (bool): A flag indicating whether to enable auto mode. Defaults to False.
init (bool): A flag indicating whether to enable initialization mode. Defaults to False.</p>
<h2 id="attributes">Attributes</h2>
<dl>
<dt><strong><code>config_list</code></strong> :&ensp;<code>list</code></dt>
<dd>A list of configuration dictionaries for the OpenAI API.</dd>
<dt><strong><code>agent_file</code></strong> :&ensp;<code>str</code></dt>
<dd>The agent file to use.</dd>
<dt><strong><code>framework</code></strong> :&ensp;<code>str</code></dt>
<dd>The framework to use.</dd>
<dt><strong><code>auto</code></strong> :&ensp;<code>bool</code></dt>
<dd>A flag indicating whether to enable auto mode.</dd>
<dt><strong><code>init</code></strong> :&ensp;<code>bool</code></dt>
<dd>A flag indicating whether to enable initialization mode.</dd>
<dt><strong><code>agent_yaml</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The content of the YAML file. Defaults to None.</dd>
</dl></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class PraisonAI:
def __init__(self, agent_file=&#34;agents.yaml&#34;, framework=&#34;&#34;, auto=False, init=False, agent_yaml=None, tools=None):
&#34;&#34;&#34;
Initialize the PraisonAI object with default parameters.
Parameters:
agent_file (str): The default agent file to use. Defaults to &#34;agents.yaml&#34;.
framework (str): The default framework to use. Defaults to &#34;crewai&#34;.
auto (bool): A flag indicating whether to enable auto mode. Defaults to False.
init (bool): A flag indicating whether to enable initialization mode. Defaults to False.
Attributes:
config_list (list): A list of configuration dictionaries for the OpenAI API.
agent_file (str): The agent file to use.
framework (str): The framework to use.
auto (bool): A flag indicating whether to enable auto mode.
init (bool): A flag indicating whether to enable initialization mode.
agent_yaml (str, optional): The content of the YAML file. Defaults to None.
&#34;&#34;&#34;
self.agent_yaml = agent_yaml
self.config_list = [
{
&#39;model&#39;: os.environ.get(&#34;OPENAI_MODEL_NAME&#34;, &#34;gpt-4o&#34;),
&#39;base_url&#39;: os.environ.get(&#34;OPENAI_API_BASE&#34;, &#34;https://api.openai.com/v1&#34;),
&#39;api_key&#39;: os.environ.get(&#34;OPENAI_API_KEY&#34;)
}
]
self.agent_file = agent_file
self.framework = framework
self.auto = auto
self.init = init
self.tools = tools or [] # Store tool class names as a list
def run(self):
&#34;&#34;&#34;
Run the PraisonAI application.
&#34;&#34;&#34;
self.main()
def main(self):
&#34;&#34;&#34;
The main function of the PraisonAI object. It parses the command-line arguments,
initializes the necessary attributes, and then calls the appropriate methods based on the
provided arguments.
Args:
self (PraisonAI): An instance of the PraisonAI class.
Returns:
Any: Depending on the arguments provided, the function may return a result from the
AgentsGenerator, a deployment result from the CloudDeployer, or a message indicating
the successful creation of a file.
&#34;&#34;&#34;
args = self.parse_args()
if args is None:
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
result = agents_generator.generate_crew_and_kickoff()
return result
if args.deploy:
from .deploy import CloudDeployer
deployer = CloudDeployer()
deployer.run_commands()
return
if getattr(args, &#39;chat&#39;, False):
self.create_chainlit_chat_interface()
return
if getattr(args, &#39;code&#39;, False):
self.create_code_interface()
return
if getattr(args, &#39;realtime&#39;, False):
self.create_realtime_interface()
return
if getattr(args, &#39;call&#39;, False):
call_args = []
if args.public:
call_args.append(&#39;--public&#39;)
call_module.main(call_args)
return
if args.agent_file == &#39;train&#39;:
package_root = os.path.dirname(os.path.abspath(__file__))
config_yaml_destination = os.path.join(os.getcwd(), &#39;config.yaml&#39;)
# Create config.yaml only if it doesn&#39;t exist or --model or --dataset is provided
if not os.path.exists(config_yaml_destination) or args.model or args.dataset:
config = generate_config(
model_name=args.model,
hf_model_name=args.hf,
ollama_model_name=args.ollama,
dataset=[{
&#34;name&#34;: args.dataset
}]
)
with open(&#39;config.yaml&#39;, &#39;w&#39;) as f:
yaml.dump(config, f, default_flow_style=False, indent=2)
# Overwrite huggingface_save and ollama_save if --hf or --ollama are provided
if args.hf:
config[&#34;huggingface_save&#34;] = &#34;true&#34;
if args.ollama:
config[&#34;ollama_save&#34;] = &#34;true&#34;
if &#39;init&#39; in sys.argv:
from praisonai.setup.setup_conda_env import main as setup_conda_main
setup_conda_main()
print(&#34;All packages installed&#34;)
return
try:
result = subprocess.check_output([&#39;conda&#39;, &#39;env&#39;, &#39;list&#39;])
if &#39;praison_env&#39; in result.decode(&#39;utf-8&#39;):
print(&#34;Conda environment &#39;praison_env&#39; found.&#34;)
else:
raise subprocess.CalledProcessError(1, &#39;grep&#39;)
except subprocess.CalledProcessError:
print(&#34;Conda environment &#39;praison_env&#39; not found. Setting it up...&#34;)
from praisonai.setup.setup_conda_env import main as setup_conda_main
setup_conda_main()
print(&#34;All packages installed.&#34;)
train_args = sys.argv[2:] # Get all arguments after &#39;train&#39;
train_script_path = os.path.join(package_root, &#39;train.py&#39;)
# Set environment variables
env = os.environ.copy()
env[&#39;PYTHONUNBUFFERED&#39;] = &#39;1&#39;
stream_subprocess([&#39;conda&#39;, &#39;run&#39;, &#39;--no-capture-output&#39;, &#39;--name&#39;, &#39;praison_env&#39;, &#39;python&#39;, &#39;-u&#39;, train_script_path, &#39;train&#39;], env=env)
return
invocation_cmd = &#34;praisonai&#34;
version_string = f&#34;PraisonAI version {__version__}&#34;
self.framework = args.framework or self.framework
if args.agent_file:
if args.agent_file.startswith(&#34;tests.test&#34;): # Argument used for testing purposes. eg: python -m unittest tests.test
print(&#34;test&#34;)
else:
self.agent_file = args.agent_file
if args.auto or args.init:
temp_topic = &#39; &#39;.join(args.auto) if args.auto else &#39; &#39;.join(args.init)
self.topic = temp_topic
elif self.auto or self.init: # Use the auto attribute if args.auto is not provided
self.topic = self.auto
if args.auto or self.auto:
self.agent_file = &#34;test.yaml&#34;
generator = AutoGenerator(topic=self.topic , framework=self.framework, agent_file=self.agent_file)
self.agent_file = generator.generate()
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
result = agents_generator.generate_crew_and_kickoff()
return result
elif args.init or self.init:
self.agent_file = &#34;agents.yaml&#34;
generator = AutoGenerator(topic=self.topic , framework=self.framework, agent_file=self.agent_file)
self.agent_file = generator.generate()
print(&#34;File {} created successfully&#34;.format(self.agent_file))
return &#34;File {} created successfully&#34;.format(self.agent_file)
if args.ui:
if args.ui == &#34;gradio&#34;:
self.create_gradio_interface()
elif args.ui == &#34;chainlit&#34;:
self.create_chainlit_interface()
else:
# Modify below code to allow default ui
agents_generator = AgentsGenerator(
self.agent_file,
self.framework,
self.config_list,
agent_yaml=self.agent_yaml,
tools=self.tools # Pass tools to AgentsGenerator
)
result = agents_generator.generate_crew_and_kickoff()
return result
else:
agents_generator = AgentsGenerator(
self.agent_file,
self.framework,
self.config_list,
agent_yaml=self.agent_yaml,
tools=self.tools # Pass tools to AgentsGenerator
)
result = agents_generator.generate_crew_and_kickoff()
return result
def parse_args(self):
&#34;&#34;&#34;
Parse the command-line arguments for the PraisonAI CLI.
Args:
self (PraisonAI): An instance of the PraisonAI class.
Returns:
argparse.Namespace: An object containing the parsed command-line arguments.
Raises:
argparse.ArgumentError: If the arguments provided are invalid.
Example:
&gt;&gt;&gt; args = praison_ai.parse_args()
&gt;&gt;&gt; print(args.agent_file) # Output: &#39;agents.yaml&#39;
&#34;&#34;&#34;
parser = argparse.ArgumentParser(prog=&#34;praisonai&#34;, description=&#34;praisonAI command-line interface&#34;)
parser.add_argument(&#34;--framework&#34;, choices=[&#34;crewai&#34;, &#34;autogen&#34;], help=&#34;Specify the framework&#34;)
parser.add_argument(&#34;--ui&#34;, choices=[&#34;chainlit&#34;, &#34;gradio&#34;], help=&#34;Specify the UI framework (gradio or chainlit).&#34;)
parser.add_argument(&#34;--auto&#34;, nargs=argparse.REMAINDER, help=&#34;Enable auto mode and pass arguments for it&#34;)
parser.add_argument(&#34;--init&#34;, nargs=argparse.REMAINDER, help=&#34;Enable auto mode and pass arguments for it&#34;)
parser.add_argument(&#34;agent_file&#34;, nargs=&#34;?&#34;, help=&#34;Specify the agent file&#34;)
parser.add_argument(&#34;--deploy&#34;, action=&#34;store_true&#34;, help=&#34;Deploy the application&#34;)
parser.add_argument(&#34;--model&#34;, type=str, help=&#34;Model name&#34;)
parser.add_argument(&#34;--hf&#34;, type=str, help=&#34;Hugging Face model name&#34;)
parser.add_argument(&#34;--ollama&#34;, type=str, help=&#34;Ollama model name&#34;)
parser.add_argument(&#34;--dataset&#34;, type=str, help=&#34;Dataset name for training&#34;, default=&#34;yahma/alpaca-cleaned&#34;)
parser.add_argument(&#34;--realtime&#34;, action=&#34;store_true&#34;, help=&#34;Start the realtime voice interaction interface&#34;)
parser.add_argument(&#34;--call&#34;, action=&#34;store_true&#34;, help=&#34;Start the PraisonAI Call server&#34;)
parser.add_argument(&#34;--public&#34;, action=&#34;store_true&#34;, help=&#34;Use ngrok to expose the server publicly (only with --call)&#34;)
args, unknown_args = parser.parse_known_args()
if unknown_args and unknown_args[0] == &#39;-b&#39; and unknown_args[1] == &#39;api:app&#39;:
args.agent_file = &#39;agents.yaml&#39;
if args.agent_file == &#39;api:app&#39; or args.agent_file == &#39;/app/api:app&#39;:
args.agent_file = &#39;agents.yaml&#39;
if args.agent_file == &#39;ui&#39;:
args.ui = &#39;chainlit&#39;
if args.agent_file == &#39;chat&#39;:
args.ui = &#39;chainlit&#39;
args.chat = True
if args.agent_file == &#39;code&#39;:
args.ui = &#39;chainlit&#39;
args.code = True
if args.agent_file == &#39;realtime&#39;:
args.realtime = True
if args.agent_file == &#39;call&#39;:
args.call = True
return args
def create_chainlit_chat_interface(self):
&#34;&#34;&#34;
Create a Chainlit interface for the chat application.
This function sets up a Chainlit application that listens for messages.
When a message is received, it runs PraisonAI with the provided message as the topic.
The generated agents are then used to perform tasks.
Returns:
None: This function does not return any value. It starts the Chainlit application.
&#34;&#34;&#34;
if CHAINLIT_AVAILABLE:
import praisonai
os.environ[&#34;CHAINLIT_PORT&#34;] = &#34;8084&#34;
root_path = os.path.join(os.path.expanduser(&#34;~&#34;), &#34;.praison&#34;)
os.environ[&#34;CHAINLIT_APP_ROOT&#34;] = root_path
public_folder = os.path.join(os.path.dirname(praisonai.__file__), &#39;public&#39;)
if not os.path.exists(os.path.join(root_path, &#34;public&#34;)): # Check if the folder exists in the current directory
if os.path.exists(public_folder):
shutil.copytree(public_folder, os.path.join(root_path, &#34;public&#34;), dirs_exist_ok=True)
logging.info(&#34;Public folder copied successfully!&#34;)
else:
logging.info(&#34;Public folder not found in the package.&#34;)
else:
logging.info(&#34;Public folder already exists.&#34;)
chat_ui_path = os.path.join(os.path.dirname(praisonai.__file__), &#39;ui&#39;, &#39;chat.py&#39;)
chainlit_run([chat_ui_path])
else:
print(&#34;ERROR: Chat UI is not installed. Please install it with &#39;pip install \&#34;praisonai\[chat]\&#34;&#39; to use the chat UI.&#34;)
def create_code_interface(self):
&#34;&#34;&#34;
Create a Chainlit interface for the code application.
This function sets up a Chainlit application that listens for messages.
When a message is received, it runs PraisonAI with the provided message as the topic.
The generated agents are then used to perform tasks.
Returns:
None: This function does not return any value. It starts the Chainlit application.
&#34;&#34;&#34;
if CHAINLIT_AVAILABLE:
import praisonai
os.environ[&#34;CHAINLIT_PORT&#34;] = &#34;8086&#34;
root_path = os.path.join(os.path.expanduser(&#34;~&#34;), &#34;.praison&#34;)
os.environ[&#34;CHAINLIT_APP_ROOT&#34;] = root_path
public_folder = os.path.join(os.path.dirname(__file__), &#39;public&#39;)
if not os.path.exists(os.path.join(root_path, &#34;public&#34;)): # Check if the folder exists in the current directory
if os.path.exists(public_folder):
shutil.copytree(public_folder, os.path.join(root_path, &#34;public&#34;), dirs_exist_ok=True)
logging.info(&#34;Public folder copied successfully!&#34;)
else:
logging.info(&#34;Public folder not found in the package.&#34;)
else:
logging.info(&#34;Public folder already exists.&#34;)
code_ui_path = os.path.join(os.path.dirname(praisonai.__file__), &#39;ui&#39;, &#39;code.py&#39;)
chainlit_run([code_ui_path])
else:
print(&#34;ERROR: Code UI is not installed. Please install it with &#39;pip install \&#34;praisonai\[code]\&#34;&#39; to use the code UI.&#34;)
def create_gradio_interface(self):
&#34;&#34;&#34;
Create a Gradio interface for generating agents and performing tasks.
Args:
self (PraisonAI): An instance of the PraisonAI class.
Returns:
None: This method does not return any value. It launches the Gradio interface.
Raises:
None: This method does not raise any exceptions.
Example:
&gt;&gt;&gt; praison_ai.create_gradio_interface()
&#34;&#34;&#34;
if GRADIO_AVAILABLE:
def generate_crew_and_kickoff_interface(auto_args, framework):
&#34;&#34;&#34;
Generate a crew and kick off tasks based on the provided auto arguments and framework.
Args:
auto_args (list): Topic.
framework (str): The framework to use for generating agents.
Returns:
str: A string representing the result of generating the crew and kicking off tasks.
Raises:
None: This method does not raise any exceptions.
Example:
&gt;&gt;&gt; result = generate_crew_and_kickoff_interface(&#34;Create a movie about Cat in Mars&#34;, &#34;crewai&#34;)
&gt;&gt;&gt; print(result)
&#34;&#34;&#34;
self.framework = framework
self.agent_file = &#34;test.yaml&#34;
generator = AutoGenerator(topic=auto_args , framework=self.framework)
self.agent_file = generator.generate()
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
result = agents_generator.generate_crew_and_kickoff()
return result
gr.Interface(
fn=generate_crew_and_kickoff_interface,
inputs=[gr.Textbox(lines=2, label=&#34;Auto Args&#34;), gr.Dropdown(choices=[&#34;crewai&#34;, &#34;autogen&#34;], label=&#34;Framework&#34;)],
outputs=&#34;textbox&#34;,
title=&#34;Praison AI Studio&#34;,
description=&#34;Create Agents and perform tasks&#34;,
theme=&#34;default&#34;
).launch()
else:
print(&#34;ERROR: Gradio is not installed. Please install it with &#39;pip install gradio&#39; to use this feature.&#34;)
def create_chainlit_interface(self):
&#34;&#34;&#34;
Create a Chainlit interface for generating agents and performing tasks.
This function sets up a Chainlit application that listens for messages.
When a message is received, it runs PraisonAI with the provided message as the topic.
The generated agents are then used to perform tasks.
Returns:
None: This function does not return any value. It starts the Chainlit application.
&#34;&#34;&#34;
if CHAINLIT_AVAILABLE:
import praisonai
os.environ[&#34;CHAINLIT_PORT&#34;] = &#34;8082&#34;
# Get the path to the &#39;public&#39; folder within the package
public_folder = os.path.join(os.path.dirname(praisonai.__file__), &#39;public&#39;)
if not os.path.exists(&#34;public&#34;): # Check if the folder exists in the current directory
if os.path.exists(public_folder):
shutil.copytree(public_folder, &#39;public&#39;, dirs_exist_ok=True)
logging.info(&#34;Public folder copied successfully!&#34;)
else:
logging.info(&#34;Public folder not found in the package.&#34;)
else:
logging.info(&#34;Public folder already exists.&#34;)
chainlit_ui_path = os.path.join(os.path.dirname(praisonai.__file__), &#39;chainlit_ui.py&#39;)
chainlit_run([chainlit_ui_path])
else:
print(&#34;ERROR: Chainlit is not installed. Please install it with &#39;pip install \&#34;praisonai\[ui]\&#34;&#39; to use the UI.&#34;)
def create_realtime_interface(self):
&#34;&#34;&#34;
Create a Chainlit interface for the realtime voice interaction application.
&#34;&#34;&#34;
if CHAINLIT_AVAILABLE:
import praisonai
os.environ[&#34;CHAINLIT_PORT&#34;] = &#34;8088&#34; # Ensure this port is not in use by another service
root_path = os.path.join(os.path.expanduser(&#34;~&#34;), &#34;.praison&#34;)
os.environ[&#34;CHAINLIT_APP_ROOT&#34;] = root_path
public_folder = os.path.join(os.path.dirname(praisonai.__file__), &#39;public&#39;)
if not os.path.exists(os.path.join(root_path, &#34;public&#34;)):
if os.path.exists(public_folder):
shutil.copytree(public_folder, os.path.join(root_path, &#34;public&#34;), dirs_exist_ok=True)
logging.info(&#34;Public folder copied successfully!&#34;)
else:
logging.info(&#34;Public folder not found in the package.&#34;)
else:
logging.info(&#34;Public folder already exists.&#34;)
realtime_ui_path = os.path.join(os.path.dirname(praisonai.__file__), &#39;ui&#39;, &#39;realtime.py&#39;)
chainlit_run([realtime_ui_path])
else:
print(&#34;ERROR: Realtime UI is not installed. Please install it with &#39;pip install \&#34;praisonai[realtime]\&#34;&#39; to use the realtime UI.&#34;)</code></pre>
</details>
<h3>Methods</h3>
<dl>
<dt id="praisonai.cli.PraisonAI.create_chainlit_chat_interface"><code class="name flex">
<span>def <span class="ident">create_chainlit_chat_interface</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Create a Chainlit interface for the chat application.</p>
<p>This function sets up a Chainlit application that listens for messages.
When a message is received, it runs PraisonAI with the provided message as the topic.
The generated agents are then used to perform tasks.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>None</code></dt>
<dd>This function does not return any value. It starts the Chainlit application.</dd>
</dl></div>
</dd>
<dt id="praisonai.cli.PraisonAI.create_chainlit_interface"><code class="name flex">
<span>def <span class="ident">create_chainlit_interface</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Create a Chainlit interface for generating agents and performing tasks.</p>
<p>This function sets up a Chainlit application that listens for messages.
When a message is received, it runs PraisonAI with the provided message as the topic.
The generated agents are then used to perform tasks.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>None</code></dt>
<dd>This function does not return any value. It starts the Chainlit application.</dd>
</dl></div>
</dd>
<dt id="praisonai.cli.PraisonAI.create_code_interface"><code class="name flex">
<span>def <span class="ident">create_code_interface</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Create a Chainlit interface for the code application.</p>
<p>This function sets up a Chainlit application that listens for messages.
When a message is received, it runs PraisonAI with the provided message as the topic.
The generated agents are then used to perform tasks.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>None</code></dt>
<dd>This function does not return any value. It starts the Chainlit application.</dd>
</dl></div>
</dd>
<dt id="praisonai.cli.PraisonAI.create_gradio_interface"><code class="name flex">
<span>def <span class="ident">create_gradio_interface</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Create a Gradio interface for generating agents and performing tasks.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>self</code></strong> :&ensp;<code><a title="praisonai.cli.PraisonAI" href="#praisonai.cli.PraisonAI">PraisonAI</a></code></dt>
<dd>An instance of the PraisonAI class.</dd>
</dl>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>None</code></dt>
<dd>This method does not return any value. It launches the Gradio interface.</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>None</code></dt>
<dd>This method does not raise any exceptions.</dd>
</dl>
<h2 id="example">Example</h2>
<pre><code class="language-python-repl">&gt;&gt;&gt; praison_ai.create_gradio_interface()
</code></pre></div>
</dd>
<dt id="praisonai.cli.PraisonAI.create_realtime_interface"><code class="name flex">
<span>def <span class="ident">create_realtime_interface</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Create a Chainlit interface for the realtime voice interaction application.</p></div>
</dd>
<dt id="praisonai.cli.PraisonAI.main"><code class="name flex">
<span>def <span class="ident">main</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>The main function of the PraisonAI object. It parses the command-line arguments,
initializes the necessary attributes, and then calls the appropriate methods based on the
provided arguments.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>self</code></strong> :&ensp;<code><a title="praisonai.cli.PraisonAI" href="#praisonai.cli.PraisonAI">PraisonAI</a></code></dt>
<dd>An instance of the PraisonAI class.</dd>
</dl>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>Any</code></dt>
<dd>Depending on the arguments provided, the function may return a result from the</dd>
</dl>
<p>AgentsGenerator, a deployment result from the CloudDeployer, or a message indicating
the successful creation of a file.</p></div>
</dd>
<dt id="praisonai.cli.PraisonAI.parse_args"><code class="name flex">
<span>def <span class="ident">parse_args</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Parse the command-line arguments for the PraisonAI CLI.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>self</code></strong> :&ensp;<code><a title="praisonai.cli.PraisonAI" href="#praisonai.cli.PraisonAI">PraisonAI</a></code></dt>
<dd>An instance of the PraisonAI class.</dd>
</dl>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>argparse.Namespace</code></dt>
<dd>An object containing the parsed command-line arguments.</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>argparse.ArgumentError</code></dt>
<dd>If the arguments provided are invalid.</dd>
</dl>
<h2 id="example">Example</h2>
<pre><code class="language-python-repl">&gt;&gt;&gt; args = praison_ai.parse_args()
&gt;&gt;&gt; print(args.agent_file) # Output: 'agents.yaml'
</code></pre></div>
</dd>
<dt id="praisonai.cli.PraisonAI.run"><code class="name flex">
<span>def <span class="ident">run</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Run the PraisonAI application.</p></div>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.cli.stream_subprocess" href="#praisonai.cli.stream_subprocess">stream_subprocess</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="praisonai.cli.PraisonAI" href="#praisonai.cli.PraisonAI">PraisonAI</a></code></h4>
<ul class="">
<li><code><a title="praisonai.cli.PraisonAI.create_chainlit_chat_interface" href="#praisonai.cli.PraisonAI.create_chainlit_chat_interface">create_chainlit_chat_interface</a></code></li>
<li><code><a title="praisonai.cli.PraisonAI.create_chainlit_interface" href="#praisonai.cli.PraisonAI.create_chainlit_interface">create_chainlit_interface</a></code></li>
<li><code><a title="praisonai.cli.PraisonAI.create_code_interface" href="#praisonai.cli.PraisonAI.create_code_interface">create_code_interface</a></code></li>
<li><code><a title="praisonai.cli.PraisonAI.create_gradio_interface" href="#praisonai.cli.PraisonAI.create_gradio_interface">create_gradio_interface</a></code></li>
<li><code><a title="praisonai.cli.PraisonAI.create_realtime_interface" href="#praisonai.cli.PraisonAI.create_realtime_interface">create_realtime_interface</a></code></li>
<li><code><a title="praisonai.cli.PraisonAI.main" href="#praisonai.cli.PraisonAI.main">main</a></code></li>
<li><code><a title="praisonai.cli.PraisonAI.parse_args" href="#praisonai.cli.PraisonAI.parse_args">parse_args</a></code></li>
<li><code><a title="praisonai.cli.PraisonAI.run" href="#praisonai.cli.PraisonAI.run">run</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
+279
View File
@@ -0,0 +1,279 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.deploy API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.deploy</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="praisonai.deploy.CloudDeployer"><code class="flex name class">
<span>class <span class="ident">CloudDeployer</span></span>
</code></dt>
<dd>
<div class="desc"><p>A class for deploying a cloud-based application.</p>
<h2 id="attributes">Attributes</h2>
<p>None</p>
<h2 id="methods">Methods</h2>
<p><strong>init</strong>(self):
Loads environment variables from .env file or system and sets them.</p>
<p>Loads environment variables from .env file or system and sets them.</p>
<h2 id="parameters">Parameters</h2>
<p>self: An instance of the CloudDeployer class.</p>
<h2 id="returns">Returns</h2>
<p>None</p>
<h2 id="raises">Raises</h2>
<p>None</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class CloudDeployer:
&#34;&#34;&#34;
A class for deploying a cloud-based application.
Attributes:
None
Methods:
__init__(self):
Loads environment variables from .env file or system and sets them.
&#34;&#34;&#34;
def __init__(self):
&#34;&#34;&#34;
Loads environment variables from .env file or system and sets them.
Parameters:
self: An instance of the CloudDeployer class.
Returns:
None
Raises:
None
&#34;&#34;&#34;
# Load environment variables from .env file or system
load_dotenv()
self.set_environment_variables()
def create_dockerfile(self):
&#34;&#34;&#34;
Creates a Dockerfile for the application.
Parameters:
self: An instance of the CloudDeployer class.
Returns:
None
Raises:
None
This method creates a Dockerfile in the current directory with the specified content.
The Dockerfile is used to build a Docker image for the application.
The content of the Dockerfile includes instructions to use the Python 3.11-slim base image,
set the working directory to /app, copy the current directory contents into the container,
install the required Python packages (flask, praisonai, gunicorn, and markdown),
expose port 8080, and run the application using Gunicorn.
&#34;&#34;&#34;
with open(&#34;Dockerfile&#34;, &#34;w&#34;) as file:
file.write(&#34;FROM python:3.11-slim\n&#34;)
file.write(&#34;WORKDIR /app\n&#34;)
file.write(&#34;COPY . .\n&#34;)
file.write(&#34;RUN pip install flask praisonai==2.0.13 gunicorn markdown\n&#34;)
file.write(&#34;EXPOSE 8080\n&#34;)
file.write(&#39;CMD [&#34;gunicorn&#34;, &#34;-b&#34;, &#34;0.0.0.0:8080&#34;, &#34;api:app&#34;]\n&#39;)
def create_api_file(self):
&#34;&#34;&#34;
Creates an API file for the application.
Parameters:
self (CloudDeployer): An instance of the CloudDeployer class.
Returns:
None
This method creates an API file named &#34;api.py&#34; in the current directory. The file contains a basic Flask application that uses the PraisonAI library to run a simple agent and returns the output as an HTML page. The application listens on the root path (&#34;/&#34;) and uses the Markdown library to format the output.
&#34;&#34;&#34;
with open(&#34;api.py&#34;, &#34;w&#34;) as file:
file.write(&#34;from flask import Flask\n&#34;)
file.write(&#34;from praisonai import PraisonAI\n&#34;)
file.write(&#34;import markdown\n\n&#34;)
file.write(&#34;app = Flask(__name__)\n\n&#34;)
file.write(&#34;def basic():\n&#34;)
file.write(&#34; praisonai = PraisonAI(agent_file=\&#34;agents.yaml\&#34;)\n&#34;)
file.write(&#34; return praisonai.run()\n\n&#34;)
file.write(&#34;@app.route(&#39;/&#39;)\n&#34;)
file.write(&#34;def home():\n&#34;)
file.write(&#34; output = basic()\n&#34;)
file.write(&#34; html_output = markdown.markdown(output)\n&#34;)
file.write(&#34; return f&#39;&lt;html&gt;&lt;body&gt;{html_output}&lt;/body&gt;&lt;/html&gt;&#39;\n\n&#34;)
file.write(&#34;if __name__ == \&#34;__main__\&#34;:\n&#34;)
file.write(&#34; app.run(debug=True)\n&#34;)
def set_environment_variables(self):
&#34;&#34;&#34;Sets environment variables with fallback to .env values or defaults.&#34;&#34;&#34;
os.environ[&#34;OPENAI_MODEL_NAME&#34;] = os.getenv(&#34;OPENAI_MODEL_NAME&#34;, &#34;gpt-4o&#34;)
os.environ[&#34;OPENAI_API_KEY&#34;] = os.getenv(&#34;OPENAI_API_KEY&#34;, &#34;Enter your API key&#34;)
os.environ[&#34;OPENAI_API_BASE&#34;] = os.getenv(&#34;OPENAI_API_BASE&#34;, &#34;https://api.openai.com/v1&#34;)
def run_commands(self):
&#34;&#34;&#34;
Sets environment variables with fallback to .env values or defaults.
Parameters:
None
Returns:
None
Raises:
None
This method sets environment variables for the application. It uses the `os.environ` dictionary to set the following environment variables:
- `OPENAI_MODEL_NAME`: The name of the OpenAI model to use. If not specified in the .env file, it defaults to &#34;gpt-4o&#34;.
- `OPENAI_API_KEY`: The API key for accessing the OpenAI API. If not specified in the .env file, it defaults to &#34;Enter your API key&#34;.
- `OPENAI_API_BASE`: The base URL for the OpenAI API. If not specified in the .env file, it defaults to &#34;https://api.openai.com/v1&#34;.
&#34;&#34;&#34;
self.create_api_file()
self.create_dockerfile()
&#34;&#34;&#34;Runs a sequence of shell commands for deployment, continues on error.&#34;&#34;&#34;
commands = [
&#34;yes | gcloud auth configure-docker us-central1-docker.pkg.dev&#34;,
&#34;gcloud artifacts repositories create praisonai-repository --repository-format=docker --location=us-central1&#34;,
&#34;docker build --platform linux/amd64 -t gcr.io/$(gcloud config get-value project)/praisonai-app:latest .&#34;,
&#34;docker tag gcr.io/$(gcloud config get-value project)/praisonai-app:latest us-central1-docker.pkg.dev/$(gcloud config get-value project)/praisonai-repository/praisonai-app:latest&#34;,
&#34;docker push us-central1-docker.pkg.dev/$(gcloud config get-value project)/praisonai-repository/praisonai-app:latest&#34;,
&#34;gcloud run deploy praisonai-service --image us-central1-docker.pkg.dev/$(gcloud config get-value project)/praisonai-repository/praisonai-app:latest --platform managed --region us-central1 --allow-unauthenticated --set-env-vars OPENAI_MODEL_NAME=${OPENAI_MODEL_NAME},OPENAI_API_KEY=${OPENAI_API_KEY},OPENAI_API_BASE=${OPENAI_API_BASE}&#34;
]
for cmd in commands:
try:
subprocess.run(cmd, shell=True, check=True)
except subprocess.CalledProcessError as e:
print(f&#34;ERROR: Command &#39;{e.cmd}&#39; failed with exit status {e.returncode}&#34;)
print(f&#34;Continuing with the next command...&#34;)</code></pre>
</details>
<h3>Methods</h3>
<dl>
<dt id="praisonai.deploy.CloudDeployer.create_api_file"><code class="name flex">
<span>def <span class="ident">create_api_file</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Creates an API file for the application.</p>
<h2 id="parameters">Parameters</h2>
<p>self (CloudDeployer): An instance of the CloudDeployer class.</p>
<h2 id="returns">Returns</h2>
<p>None
This method creates an API file named "api.py" in the current directory. The file contains a basic Flask application that uses the PraisonAI library to run a simple agent and returns the output as an HTML page. The application listens on the root path ("/") and uses the Markdown library to format the output.</p></div>
</dd>
<dt id="praisonai.deploy.CloudDeployer.create_dockerfile"><code class="name flex">
<span>def <span class="ident">create_dockerfile</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Creates a Dockerfile for the application.</p>
<h2 id="parameters">Parameters</h2>
<p>self: An instance of the CloudDeployer class.</p>
<h2 id="returns">Returns</h2>
<p>None</p>
<h2 id="raises">Raises</h2>
<p>None
This method creates a Dockerfile in the current directory with the specified content.
The Dockerfile is used to build a Docker image for the application.
The content of the Dockerfile includes instructions to use the Python 3.11-slim base image,
set the working directory to /app, copy the current directory contents into the container,
install the required Python packages (flask, praisonai, gunicorn, and markdown),
expose port 8080, and run the application using Gunicorn.</p></div>
</dd>
<dt id="praisonai.deploy.CloudDeployer.run_commands"><code class="name flex">
<span>def <span class="ident">run_commands</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Sets environment variables with fallback to .env values or defaults.</p>
<h2 id="parameters">Parameters</h2>
<p>None</p>
<h2 id="returns">Returns</h2>
<p>None</p>
<h2 id="raises">Raises</h2>
<p>None
This method sets environment variables for the application. It uses the <code>os.environ</code> dictionary to set the following environment variables:</p>
<ul>
<li><code>OPENAI_MODEL_NAME</code>: The name of the OpenAI model to use. If not specified in the .env file, it defaults to "gpt-4o".</li>
<li><code>OPENAI_API_KEY</code>: The API key for accessing the OpenAI API. If not specified in the .env file, it defaults to "Enter your API key".</li>
<li><code>OPENAI_API_BASE</code>: The base URL for the OpenAI API. If not specified in the .env file, it defaults to "https://api.openai.com/v1".</li>
</ul></div>
</dd>
<dt id="praisonai.deploy.CloudDeployer.set_environment_variables"><code class="name flex">
<span>def <span class="ident">set_environment_variables</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Sets environment variables with fallback to .env values or defaults.</p></div>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="praisonai.deploy.CloudDeployer" href="#praisonai.deploy.CloudDeployer">CloudDeployer</a></code></h4>
<ul class="">
<li><code><a title="praisonai.deploy.CloudDeployer.create_api_file" href="#praisonai.deploy.CloudDeployer.create_api_file">create_api_file</a></code></li>
<li><code><a title="praisonai.deploy.CloudDeployer.create_dockerfile" href="#praisonai.deploy.CloudDeployer.create_dockerfile">create_dockerfile</a></code></li>
<li><code><a title="praisonai.deploy.CloudDeployer.run_commands" href="#praisonai.deploy.CloudDeployer.run_commands">run_commands</a></code></li>
<li><code><a title="praisonai.deploy.CloudDeployer.set_environment_variables" href="#praisonai.deploy.CloudDeployer.set_environment_variables">set_environment_variables</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
@@ -0,0 +1,188 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.inbuilt_tools.autogen_tools API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.inbuilt_tools.autogen_tools</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_CSVSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_CSVSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_CodeDocsSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_CodeDocsSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_DOCXSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_DOCXSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_DirectoryReadTool"><code class="name flex">
<span>def <span class="ident">autogen_DirectoryReadTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_DirectorySearchTool"><code class="name flex">
<span>def <span class="ident">autogen_DirectorySearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_FileReadTool"><code class="name flex">
<span>def <span class="ident">autogen_FileReadTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_JSONSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_JSONSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_MDXSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_MDXSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_PDFSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_PDFSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_RagTool"><code class="name flex">
<span>def <span class="ident">autogen_RagTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeElementFromWebsiteTool"><code class="name flex">
<span>def <span class="ident">autogen_ScrapeElementFromWebsiteTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeWebsiteTool"><code class="name flex">
<span>def <span class="ident">autogen_ScrapeWebsiteTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_TXTSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_TXTSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_WebsiteSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_WebsiteSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_XMLSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_XMLSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeChannelSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_YoutubeChannelSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeVideoSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_YoutubeVideoSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.create_autogen_tool_function"><code class="name flex">
<span>def <span class="ident">create_autogen_tool_function</span></span>(<span>tool_name)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai.inbuilt_tools" href="index.html">praisonai.inbuilt_tools</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_CSVSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_CSVSearchTool">autogen_CSVSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_CodeDocsSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_CodeDocsSearchTool">autogen_CodeDocsSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_DOCXSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_DOCXSearchTool">autogen_DOCXSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_DirectoryReadTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_DirectoryReadTool">autogen_DirectoryReadTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_DirectorySearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_DirectorySearchTool">autogen_DirectorySearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_FileReadTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_FileReadTool">autogen_FileReadTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_JSONSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_JSONSearchTool">autogen_JSONSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_MDXSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_MDXSearchTool">autogen_MDXSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_PDFSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_PDFSearchTool">autogen_PDFSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_RagTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_RagTool">autogen_RagTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeElementFromWebsiteTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeElementFromWebsiteTool">autogen_ScrapeElementFromWebsiteTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeWebsiteTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeWebsiteTool">autogen_ScrapeWebsiteTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_TXTSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_TXTSearchTool">autogen_TXTSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_WebsiteSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_WebsiteSearchTool">autogen_WebsiteSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_XMLSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_XMLSearchTool">autogen_XMLSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeChannelSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeChannelSearchTool">autogen_YoutubeChannelSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeVideoSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeVideoSearchTool">autogen_YoutubeVideoSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.create_autogen_tool_function" href="#praisonai.inbuilt_tools.autogen_tools.create_autogen_tool_function">create_autogen_tool_function</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
+67
View File
@@ -0,0 +1,67 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.inbuilt_tools API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.inbuilt_tools</code></h1>
</header>
<section id="section-intro">
</section>
<section>
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
<dl>
<dt><code class="name"><a title="praisonai.inbuilt_tools.autogen_tools" href="autogen_tools.html">praisonai.inbuilt_tools.autogen_tools</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
<section>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="../index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
<ul>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools" href="autogen_tools.html">praisonai.inbuilt_tools.autogen_tools</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
+69
View File
@@ -0,0 +1,69 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.inc.config API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.inc.config</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.inc.config.generate_config"><code class="name flex">
<span>def <span class="ident">generate_config</span></span>(<span>ollama_save=None, huggingface_save=None, train=None, model_name=None, hf_model_name=None, ollama_model_name=None, model_parameters=None, max_seq_length=None, load_in_4bit=None, lora_r=None, lora_target_modules=None, lora_alpha=None, lora_dropout=None, lora_bias=None, use_gradient_checkpointing=None, random_state=None, use_rslora=None, loftq_config=None, dataset=None, dataset_text_field=None, dataset_num_proc=None, packing=None, per_device_train_batch_size=None, gradient_accumulation_steps=None, warmup_steps=None, num_train_epochs=None, max_steps=None, learning_rate=None, logging_steps=None, optim=None, weight_decay=None, lr_scheduler_type=None, seed=None, output_dir=None, quantization_method=None)</span>
</code></dt>
<dd>
<div class="desc"><p>Generates the configuration for PraisonAI with dynamic overrides.</p></div>
</dd>
</dl>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai.inc" href="index.html">praisonai.inc</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.inc.config.generate_config" href="#praisonai.inc.config.generate_config">generate_config</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
+72
View File
@@ -0,0 +1,72 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.inc API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.inc</code></h1>
</header>
<section id="section-intro">
</section>
<section>
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
<dl>
<dt><code class="name"><a title="praisonai.inc.config" href="config.html">praisonai.inc.config</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.inc.models" href="models.html">praisonai.inc.models</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
<section>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="../index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
<ul>
<li><code><a title="praisonai.inc.config" href="config.html">praisonai.inc.config</a></code></li>
<li><code><a title="praisonai.inc.models" href="models.html">praisonai.inc.models</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
Loaded 100 of 4728 files, more files were not shown because too many files have changed in this diff. Show more