docs(agent): add comprehensive module docstring and inline comments

This commit is contained in:
2026-10-26 13:58:12 -03:00
parent 6b11f05dab
commit 9848120a1a
3 changed files with 117 additions and 31 deletions
Binary file not shown.
+72 -29
View File
@@ -1,85 +1,128 @@
#!/bin/bash #!/bin/bash
set -e # =============================================================================
# PsAgentAI - Setup and Run Script
# =============================================================================
# Purpose: Create Python virtual environment, install dependencies,
# validate .env configuration, and start the agent.
# Usage: ./iniciar.sh
# =============================================================================
set -e # Exit immediately on any command failure
# -----------------------------------------------------------------------------
# Banner
# -----------------------------------------------------------------------------
echo "==========================================" echo "=========================================="
echo " PsAgentAI - Personal Agent AI Conversacional" echo " PsAgentAI - Personal Agent AI Conversacional"
echo "==========================================" echo "=========================================="
echo "" echo ""
# Check Python 3 # -----------------------------------------------------------------------------
# Preflight: verify Python 3 is available
# -----------------------------------------------------------------------------
# Check if python3 exists in PATH. If not, instruct the user to install it.
if ! command -v python3 &> /dev/null; then if ! command -v python3 &> /dev/null; then
echo "❌ Python 3 não encontrado. Instale com: sudo apt install python3 python3-venv python3-pip" echo "❌ Python 3 not found. Install with: sudo apt install python3 python3-venv python3-pip"
exit 1 exit 1
fi fi
PYTHON_VERSION=$(python3 --version | cut -d' ' -f2) PYTHON_VERSION=$(python3 --version | cut -d' ' -f2)
echo "✅ Python $PYTHON_VERSION encontrado" echo "✅ Python $PYTHON_VERSION found"
# Create virtual environment # -----------------------------------------------------------------------------
# Virtual environment setup
# -----------------------------------------------------------------------------
# Create an isolated venv under ./venv if it doesn't already exist, then
# activate it so pip/python resolve inside the environment.
VENV_DIR="venv" VENV_DIR="venv"
if [ ! -d "$VENV_DIR" ]; then if [ ! -d "$VENV_DIR" ]; then
echo "" echo ""
echo "📦 Criando ambiente virtual Python..." echo "📦 Creating Python virtual environment..."
python3 -m venv "$VENV_DIR" python3 -m venv "$VENV_DIR"
echo "✅ Ambiente virtual criado em ./$VENV_DIR" echo "✅ Virtual environment created at ./$VENV_DIR"
else else
echo "✅ Ambiente virtual já existe em ./$VENV_DIR" echo "✅ Virtual environment already exists at ./$VENV_DIR"
fi fi
# Activate virtual environment # Activate virtual environment for the current shell session
echo "" echo ""
echo "🔄 Ativando ambiente virtual..." echo "🔄 Activating virtual environment..."
source "$VENV_DIR/bin/activate" source "$VENV_DIR/bin/activate"
# Upgrade pip # -----------------------------------------------------------------------------
# pip upgrade
# -----------------------------------------------------------------------------
# Ensure pip itself is up to date inside the venv before installing deps.
echo "" echo ""
echo "⬆️ Atualizando pip..." echo "⬆️ Upgrading pip..."
pip install --upgrade pip -q pip install --upgrade pip -q
# Install dependencies # -----------------------------------------------------------------------------
# Dependencies installation
# -----------------------------------------------------------------------------
# Install all Python dependencies from requirements.txt quietly.
echo "" echo ""
echo "📥 Instalando dependências..." echo "📥 Installing dependencies..."
pip install -r requirements.txt -q pip install -r requirements.txt -q
echo "✅ Dependências instaladas" echo "✅ Dependencies installed"
# Check .env file # -----------------------------------------------------------------------------
# .env validation
# -----------------------------------------------------------------------------
# If .env is missing, try to copy from .env.example. If neither exists,
# abort with instructions.
echo "" echo ""
if [ ! -f ".env" ]; then if [ ! -f ".env" ]; then
echo "⚠️ Arquivo .env não encontrado!" echo "⚠️ .env file not found!"
echo "📝 Copie o arquivo .env.example para .env e configure suas chaves API." echo "📝 Copy .env.example to .env and configure your API keys."
if [ -f ".env.example" ]; then if [ -f ".env.example" ]; then
cp .env.example .env cp .env.example .env
echo "✅ Arquivo .env criado a partir de .env.example" echo "✅ .env created from .env.example"
echo "⚠️ Por favor, edite o arquivo .env com suas configurações antes de continuar." echo "⚠️ Please edit .env with your configuration before continuing."
else else
echo "❌ Arquivo .env.example não encontrado. Crie o arquivo .env manualmente." echo "❌ .env.example not found. Create .env manually."
exit 1 exit 1
fi fi
else else
echo "✅ Arquivo .env encontrado" echo "✅ .env file found"
fi fi
# Check required env vars # -----------------------------------------------------------------------------
# Required environment variables check
# -----------------------------------------------------------------------------
# Verify that essential variables are populated. Warn if missing, but
# continue so the user can see all warnings at once.
echo "" echo ""
echo "🔍 Verificando configurações..." echo "🔍 Checking configuration..."
# Helper: check a single env var value and print status
check_env_var() { check_env_var() {
if [ -z "$1" ] || [ "$1" = " " ]; then local value="$1"
echo "⚠️ $2 não configurado no .env" local label="$2"
if [ -z "$value" ] || [ "$value" = " " ]; then
echo "⚠️ $label not configured in .env"
else else
echo "✅ $2 configurado" echo "✅ $label configured"
fi fi
} }
# Telegram bot token (required to receive messages)
check_env_var "$(grep -E '^TELEGRAM_BOT_TOKEN=' .env | cut -d'=' -f2-)" "TELEGRAM_BOT_TOKEN" check_env_var "$(grep -E '^TELEGRAM_BOT_TOKEN=' .env | cut -d'=' -f2-)" "TELEGRAM_BOT_TOKEN"
# Telegram chat ID (required for auto-detection / proactive messages)
check_env_var "$(grep -E '^TELEGRAM_CHAT_ID=' .env | cut -d'=' -f2-)" "TELEGRAM_CHAT_ID" check_env_var "$(grep -E '^TELEGRAM_CHAT_ID=' .env | cut -d'=' -f2-)" "TELEGRAM_CHAT_ID"
check_env_var "$(grep -E '^(OPENROUTER_API_KEY|STEPFUN_API_KEY|QWENCLOUD_API_KEY)=' .env | cut -d'=' -f2- | head -1)" "Pelo menos uma chave de API de IA"
# At least one AI provider key (OpenRouter, StepFun, or QwenCloud)
check_env_var "$(grep -E '^(OPENROUTER_API_KEY|STEPFUN_API_KEY|QWENCLOUD_API_KEY)=' .env | cut -d'=' -f2- | head -1)" "At least one AI API key"
echo "" echo ""
echo "==========================================" echo "=========================================="
echo " Iniciando PsAgentAI..." echo " Starting PsAgentAI..."
echo "==========================================" echo "=========================================="
echo "" echo ""
# -----------------------------------------------------------------------------
# Run the agent # Run the agent
# -----------------------------------------------------------------------------
# Execute the main Python script inside the activated virtual environment.
python3 psagentai_agent.py python3 psagentai_agent.py
+45 -2
View File
@@ -1,7 +1,27 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
""" """
PsAgentAI - Personal Conversational AI Agent PsAgentAI - Personal Conversational AI Agent.
Personal Conversational AI Agent system via Telegram
A Telegram-based conversational AI agent that acts as a personal companion.
It maintains long-term memory through user/agent profiles, manages daily routines,
supports file uploads/workspace editing, performs web searches, analyzes images,
and sends proactive messages based on configured schedules.
Main components:
- Telegram bot handlers (commands, messages, voice, photos, documents)
- AI provider abstraction (OpenRouter, StepFun, QwenCloud, llama.cpp)
- Profile management (user and agent) with auto-enrichment
- Conversation context storage organized by date
- Workspace file creation/editing via AI
- Web search integration via DuckDuckGo HTML
- Vision/image analysis support
- Proactive messaging loop with schedule awareness
- System auto-improvement based on conversation analysis
Typical usage:
python3 psagentai_agent.py
Environment variables are loaded from .env via python-dotenv.
""" """
__version__ = "1.0.0" __version__ = "1.0.0"
@@ -52,15 +72,24 @@ logging.basicConfig(
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# ===================== CONFIGURATION ===================== # ===================== CONFIGURATION =====================
# Environment variables loaded from .env. Defaults are provided for optional
# settings; required values must be set before running the agent.
# --- Telegram ---
# Bot token from @BotFather and target chat ID for proactive messages.
TELEGRAM_BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN", "") TELEGRAM_BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN", "")
TELEGRAM_CHAT_ID = os.getenv("TELEGRAM_CHAT_ID", "") TELEGRAM_CHAT_ID = os.getenv("TELEGRAM_CHAT_ID", "")
TELEGRAM_CHAT_ID_FILE = "telegram_chat_id.json" TELEGRAM_CHAT_ID_FILE = "telegram_chat_id.json"
# --- AI provider ---
# Primary model and provider. Provider can be forced via AI_PROVIDER env var.
DEFAULT_MODEL = os.getenv("DEFAULT_MODEL", "poolside/laguna-s-2.1:free") DEFAULT_MODEL = os.getenv("DEFAULT_MODEL", "poolside/laguna-s-2.1:free")
AI_PROVIDER = os.getenv("AI_PROVIDER", "").strip().lower() AI_PROVIDER = os.getenv("AI_PROVIDER", "").strip().lower()
# Fallback chain used when the primary model/provider fails.
FALLBACK_MODELS = os.getenv("FALLBACK_MODELS", "poolside/laguna-s-2.1:free,google/gemini-2.0-flash-lite-preview-02-05:free").split(",") FALLBACK_MODELS = os.getenv("FALLBACK_MODELS", "poolside/laguna-s-2.1:free,google/gemini-2.0-flash-lite-preview-02-05:free").split(",")
# Provider-specific API keys and base URLs.
OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY", "") OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY", "")
OPENROUTER_API_URL = os.getenv("OPENROUTER_API_URL", "https://openrouter.ai/api/v1") OPENROUTER_API_URL = os.getenv("OPENROUTER_API_URL", "https://openrouter.ai/api/v1")
@@ -72,12 +101,20 @@ QWENCLOUD_API_URL = os.getenv("QWENCLOUD_API_URL", "https://dashscope.aliyuncs.c
LLAMA_CPP_API_URL = os.getenv("LLAMA_CPP_API_URL", "http://localhost:8080/v1") LLAMA_CPP_API_URL = os.getenv("LLAMA_CPP_API_URL", "http://localhost:8080/v1")
# --- Behavior tuning ---
# Proactive message interval bounds (minutes).
MIN_INTERVAL_MINUTES = int(os.getenv("MIN_INTERVAL_MINUTES", "3")) MIN_INTERVAL_MINUTES = int(os.getenv("MIN_INTERVAL_MINUTES", "3"))
MAX_INTERVAL_MINUTES = int(os.getenv("MAX_INTERVAL_MINUTES", "30")) MAX_INTERVAL_MINUTES = int(os.getenv("MAX_INTERVAL_MINUTES", "30"))
# Context/history limits.
MAX_HISTORY_LENGTH = int(os.getenv("MAX_HISTORY_LENGTH", "50")) MAX_HISTORY_LENGTH = int(os.getenv("MAX_HISTORY_LENGTH", "50"))
UPLOAD_CONTEXT_MAX_CHARS = int(os.getenv("UPLOAD_CONTEXT_MAX_CHARS", "8000")) UPLOAD_CONTEXT_MAX_CHARS = int(os.getenv("UPLOAD_CONTEXT_MAX_CHARS", "8000"))
# Web search toggle and result cap.
WEB_SEARCH_ENABLED = os.getenv("WEB_SEARCH_ENABLED", "true").lower() in ("true", "1", "yes") WEB_SEARCH_ENABLED = os.getenv("WEB_SEARCH_ENABLED", "true").lower() in ("true", "1", "yes")
WEB_SEARCH_MAX_RESULTS = int(os.getenv("WEB_SEARCH_MAX_RESULTS", "5")) WEB_SEARCH_MAX_RESULTS = int(os.getenv("WEB_SEARCH_MAX_RESULTS", "5"))
# --- Vision / image analysis ---
VISION_MODEL = os.getenv("VISION_MODEL", "meta-llama/llama-4-maverick-17b-128e-instruct") VISION_MODEL = os.getenv("VISION_MODEL", "meta-llama/llama-4-maverick-17b-128e-instruct")
VISION_PROVIDER = os.getenv("VISION_PROVIDER", "").strip().lower() VISION_PROVIDER = os.getenv("VISION_PROVIDER", "").strip().lower()
if not VISION_PROVIDER: if not VISION_PROVIDER:
@@ -86,10 +123,16 @@ if not VISION_PROVIDER:
except Exception: except Exception:
VISION_PROVIDER = "openrouter" VISION_PROVIDER = "openrouter"
# --- Persistence ---
USER_PROFILE_FILE = os.getenv("USER_PROFILE_FILE", "user_profile.json") USER_PROFILE_FILE = os.getenv("USER_PROFILE_FILE", "user_profile.json")
AGENT_PROFILE_FILE = os.getenv("AGENT_PROFILE_FILE", "agent_profile.json") AGENT_PROFILE_FILE = os.getenv("AGENT_PROFILE_FILE", "agent_profile.json")
CONTEXTS_DIR = os.getenv("CONTEXTS_DIR", "contexts") CONTEXTS_DIR = os.getenv("CONTEXTS_DIR", "contexts")
# --- Agent behavior ---
# Minimum lines the agent should produce per response.
MIN_MESSAGE_LINES = int(os.getenv("MIN_MESSAGE_LINES", "3")) MIN_MESSAGE_LINES = int(os.getenv("MIN_MESSAGE_LINES", "3"))
# Auto-improvement system toggle and frequency.
AUTO_IMPROVE_ENABLED = os.getenv("AUTO_IMPROVE_ENABLED", "true").lower() in ("true", "1", "yes") AUTO_IMPROVE_ENABLED = os.getenv("AUTO_IMPROVE_ENABLED", "true").lower() in ("true", "1", "yes")
AUTO_IMPROVE_EVERY = int(os.getenv("AUTO_IMPROVE_EVERY", "20")) AUTO_IMPROVE_EVERY = int(os.getenv("AUTO_IMPROVE_EVERY", "20"))