Files
PraisonAIUI/examples/python/18-full-chat/app.py
T
praisonai-triage-agent[bot]andMervin Praison 6fd27d0ed7 feat: safe_print for examples to avoid cp1252 UnicodeEncodeError (fixes #231)
Add examples/python/_shared/console.py with safe_print/icon helpers that
degrade emoji to ASCII on legacy Windows code pages (cp1252) instead of
crashing, mirroring the CLI _supports_unicode/_icon pattern. Wire the helper
into the high-severity gateway (16, 17, 18) and channel (20-23) examples so
they start on default Windows PowerShell without PYTHONUTF8.

Co-authored-by: Mervin Praison <[email protected]>
2026-07-27 09:04:48 +00:00

193 lines
6.9 KiB
Python

"""PraisonAIUI — Full Chat Example (with Gateway + Page Config).
Clean chat-focused dashboard with curated sidebar pages:
- Uses ``aiui.set_pages()`` to show only essential pages (chat, sessions, agents, usage, config)
- Hides debug/admin pages for a streamlined experience
- Adds a custom "Feature Explorer" page via ``@aiui.page()``
- Registers three agents: Researcher, Writer, Coder
Compare with 17-three-column-demo which shows ALL available pages.
Modes:
1. Gateway mode (recommended) — starts real agent execution + WebSocket
Requires: pip install praisonai praisonaiagents
export OPENAI_API_KEY=sk-...
2. Standalone mode (fallback) — REST APIs only, no agent execution
Usage:
cd examples/python/18-full-chat
pip install -e ../../..
pip install praisonai praisonaiagents # optional, for gateway mode
export OPENAI_API_KEY=sk-... # optional, for gateway mode
python app.py
# Open http://localhost:8082 → click "Feature Explorer" in sidebar
"""
import asyncio
import os
import sys
import praisonaiui as aiui
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
from _shared.console import icon, safe_print
# ── Check gateway availability ──────────────────────────────
try:
from praisonaiagents import Agent
from praisonaiui.integration import AIUIGateway
GATEWAY_OK = True
except ImportError as e:
safe_print(f"{icon('⚠️', '[WARN]')} Gateway dependencies not found: {e}")
safe_print(" Install with: pip install praisonai praisonaiagents")
safe_print(" Falling back to standalone mode (REST APIs only).\n")
GATEWAY_OK = False
aiui.set_style("dashboard")
# ── Page curation ───────────────────────────────────────────
aiui.set_pages([
"chat", # Main chat interface
"sessions", # Session management
"agents", # Agent configuration
"usage", # Usage metrics
"config", # Configuration settings
])
# ── Agent definitions ───────────────────────────────────────
AGENTS = [
{
"agent_id": "researcher",
"name": "Researcher",
"description": "Research assistant — finds and summarizes information",
"instructions": (
"You are a research assistant. Provide well-structured answers "
"with key facts. Keep responses concise but informative."
),
"model": os.getenv("PRAISONAI_MODEL", "gpt-4o-mini"),
"icon": "🔬",
},
{
"agent_id": "writer",
"name": "Writer",
"description": "Creative writer — generates content on any topic",
"instructions": (
"You are a creative writer. Write engaging content in a clear, "
"professional style. Keep responses focused and well-organized."
),
"model": os.getenv("PRAISONAI_MODEL", "gpt-4o-mini"),
"icon": "✍️",
},
{
"agent_id": "coder",
"name": "Coder",
"description": "Coding assistant — Python, JavaScript, and more",
"instructions": (
"You are a coding assistant. Write clean, well-commented "
"code with explanations. Support Python, JavaScript, and "
"other popular languages."
),
"model": os.getenv("PRAISONAI_MODEL", "gpt-4o-mini"),
"icon": "💻",
},
]
# ── Register the Three-Column Explorer page ──────────────────
@aiui.page(
"explorer",
title="Feature Explorer",
icon="🔬",
group="Control",
order=55,
)
async def explorer_page():
"""Three-column feature explorer — custom view renders in JS."""
return aiui.layout([
aiui.text("Feature Explorer loads via custom view module."),
])
# ── Register agents in dashboard CRUD ───────────────────────
def _register_agents_in_dashboard():
"""Bridge gateway agents into the dashboard agents_crud feature."""
from praisonaiui.features.agents import get_agent_registry
registry = get_agent_registry()
existing = registry.list_all()
existing_names = {a.get("name") for a in existing}
for agent_def in AGENTS:
if agent_def["name"] in existing_names:
continue
registry.create({
"name": agent_def["name"],
"description": agent_def["description"],
"instructions": agent_def["instructions"],
"model": agent_def["model"],
"icon": agent_def["icon"],
})
safe_print(f" {icon('✓', '[OK]')} Agent: {agent_def['name']}")
# ── Main ────────────────────────────────────────────────────
async def main():
port = int(os.getenv("PORT", "8082"))
host = os.getenv("HOST", "127.0.0.1")
if GATEWAY_OK:
safe_print(f"{icon('🚀', '[START]')} Starting with Gateway mode (full execution + streaming)")
safe_print()
gateway = AIUIGateway(host=host, port=port)
# Register agents with gateway for real execution
for agent_def in AGENTS:
agent = Agent(
name=agent_def["name"],
instructions=agent_def["instructions"],
llm=agent_def["model"],
reflection=False,
)
gateway.register_agent(agent, agent_id=agent_def["agent_id"])
safe_print(f" {icon('✓', '[OK]')} Gateway: {agent_def['name']} ({agent_def['model']})")
# Also register in dashboard CRUD
_register_agents_in_dashboard()
safe_print()
safe_print(f" Dashboard: http://localhost:{port}")
safe_print(f" Explorer: http://localhost:{port} {icon('→', '->')} {icon('🔬', '')} Feature Explorer")
safe_print(f" WebSocket: ws://localhost:{port}/ws")
safe_print()
await gateway.start()
else:
# Standalone: REST APIs only, no agent execution
safe_print(f"{icon('📦', '[INFO]')} Starting in standalone mode (REST APIs only, no agent execution)")
import uvicorn
from praisonaiui.server import create_app
_register_agents_in_dashboard()
app = create_app()
safe_print()
safe_print(f" Dashboard: http://localhost:{port}")
safe_print(f" Explorer: http://localhost:{port} {icon('→', '->')} {icon('🔬', '')} Feature Explorer")
safe_print(" Note: POST endpoints may fail without gateway")
safe_print()
config = uvicorn.Config(app, host=host, port=port, log_level="info")
server = uvicorn.Server(config)
await server.serve()
if __name__ == "__main__":
asyncio.run(main())